From 791be217afd1549e8183bdb97fce0077c166dd41 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Mon, 12 Sep 2022 15:44:48 +0300 Subject: [PATCH 001/794] Fix problem with determine of font name. --- DocxRenderer/src/logic/Page.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index d39b86f255f..337ba6e1e86 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -326,7 +326,7 @@ namespace NSDocxRenderer m_oFontManager.LoadFont(0, !bIsPath); - if (bIsPath) + if (!bIsPath) m_oFontManager.GenerateFontName2(oText); if (fabs(dTextW) < 0.01 || (dTextW > 10)) @@ -371,7 +371,7 @@ namespace NSDocxRenderer m_pStyleManager->m_pCurrentStyle->m_oFont = m_oFontManager.m_oFont.m_oFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - if (bIsPath) + if (!bIsPath) { m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_oFontManager.m_strCurrentPickFont; m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_oFontManager.m_lCurrentPictFontStyle; From 7a276227d341cdb70bf23756100b9b358f256407 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Fri, 16 Sep 2022 16:41:31 +0300 Subject: [PATCH 002/794] Modified the packing of lines by paragraphs and the definition of the type of paragraph alignment. --- DocxRenderer/src/logic/Page.cpp | 230 +++++++++++------- DocxRenderer/src/logic/elements/Paragraph.cpp | 115 ++++++++- DocxRenderer/src/logic/elements/Paragraph.h | 25 +- DocxRenderer/src/logic/elements/TextLine.cpp | 32 --- DocxRenderer/src/logic/elements/TextLine.h | 2 - DocxRenderer/src/resources/Constants.h | 4 +- 6 files changed, 269 insertions(+), 139 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 337ba6e1e86..dbdd8fc0697 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -239,12 +239,12 @@ namespace NSDocxRenderer if (0x00 != (lType & 0x01)) { pLastShape->m_bIsNoStroke = false; - pLastShape->m_oPen = *m_pPen; + pLastShape->m_oPen = *m_pPen; } if (0x00 != (lType >> 8)) { pLastShape->m_bIsNoFill = false; - pLastShape->m_oBrush = *m_pBrush; + pLastShape->m_oBrush = *m_pBrush; } return; } @@ -265,12 +265,12 @@ namespace NSDocxRenderer if (0x00 != (lType & 0x01)) { pShape->m_bIsNoStroke = false; - pShape->m_oPen = *m_pPen; + pShape->m_oPen = *m_pPen; } if (0x00 != (lType >> 8)) { pShape->m_bIsNoFill = false; - pShape->m_oBrush = *m_pBrush; + pShape->m_oBrush = *m_pBrush; } if (pShape->m_bIsNoStroke) @@ -397,8 +397,8 @@ namespace NSDocxRenderer if (pCurrShape->m_bIsNotNecessaryToUse || pCurrShape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || //рассматриваем только тонкие объекты - (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && - pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) + (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && + pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) { continue; } @@ -674,7 +674,6 @@ namespace NSDocxRenderer pLine->SortConts(); pLine->CalculateWidth(); - //pLine->DetermineAssumedTextAlignmentType(m_dWidth); pLine->MergeConts(); } @@ -806,7 +805,7 @@ namespace NSDocxRenderer m_pCurrentLine = pLine; m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) + pCont->m_eVertAlignType != eVertAlignType::vatUnknown) { //note считаем, что линия может иметь только один тип m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; @@ -818,7 +817,7 @@ namespace NSDocxRenderer if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) { if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) + pCont->m_eVertAlignType != eVertAlignType::vatUnknown) { //note считаем, что линия может иметь только один тип m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; @@ -832,7 +831,7 @@ namespace NSDocxRenderer { m_pCurrentLine = m_arTextLine[i]; if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) + pCont->m_eVertAlignType != eVertAlignType::vatUnknown) { //note считаем, что линия может иметь только один тип m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; @@ -846,7 +845,7 @@ namespace NSDocxRenderer m_pCurrentLine = pLine; m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) + pCont->m_eVertAlignType != eVertAlignType::vatUnknown) { //note считаем, что линия может иметь только один тип m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; @@ -899,7 +898,6 @@ namespace NSDocxRenderer if (pCont->m_pCont) { - //pCont->m_pFontStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; pCont->m_pFontStyle = m_pStyleManager->GetStyle(); @@ -928,7 +926,6 @@ namespace NSDocxRenderer if (pCont->m_pCont) { - //pCont->m_pFontStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; pCont->m_pFontStyle = m_pStyleManager->GetStyle(); @@ -971,7 +968,7 @@ namespace NSDocxRenderer { if (!pDominantShape || (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && - pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) + pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) { pDominantShape = pCont->m_pShape; } @@ -1050,7 +1047,7 @@ namespace NSDocxRenderer pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > c_dSTANDART_STRING_HEIGHT_MM) && (pTextLine->m_dLeft == pFirstLine->m_dLeft)) || - ((pTextLine->m_dLeft != pFirstLine->m_dLeft) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos))) + ((pTextLine->m_dLeft != pFirstLine->m_dLeft) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos))) { pParagraph->m_dLeft = pTextLine->m_dLeft; pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight; @@ -1094,13 +1091,7 @@ namespace NSDocxRenderer void CPage::BuildByTypePlainParagraph() { - //todo не отображается перенос в линии - //todo если в линии есть перенос нужно обеъдинить строки в один параграф - //todo в зависимости от очередности загрузки файлов проявляется проблема со шрифтами - текст в некоторых конвертированных файлах становится жирным, зачеркнутым или курсив. С одним файлом проблем не наблюдалось - //todo добавить различные типы текста для распознавания: обычный-сплошной, списки-содержание и тд - - CTextLine* pCurrLine; - CTextLine* pNextLine; + CTextLine* pCurrLine, *pNextLine, *pNextNextLine; double dCurrRight = 0, dNextRight = 0; double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0; double dBeforeSpacingWithShapes = 0; @@ -1108,7 +1099,7 @@ namespace NSDocxRenderer double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; eVerticalCrossingType eCrossingType; - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; + bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7, bIf8; size_t nIndexForCheking = c_nAntiZero; @@ -1145,9 +1136,6 @@ namespace NSDocxRenderer if (bIf1) { - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bool bIsPassed = false; double dCurrentAdditive = 0.0; @@ -1182,28 +1170,77 @@ namespace NSDocxRenderer } } + bool bIsSingleLineParagraph = false; + if (bIf1) { + dNextRight = pNextLine->CalculateRightBorder(m_dWidth); + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + //Высота строк должна быть примерно одинаковой - bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) <= c_dTHE_SAME_STRING_Y_PRECISION_MM; - // - bIf3 = true; //pCurrLine->AreAlignmentsAppropriate(pNextLine); + bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //расстрояние между строк тоже одинаково - bIf4 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //или - bIf5 = dCurrBeforeSpacing > dNextBeforeSpacing; - //есть отступ или нет отступа - bIf6 = pCurrLine->m_dLeft >= pNextLine->m_dLeft; - //следующая строка либо короче, либо такая же - bIf7 = (fabs(dCurrRight - dNextRight) <= c_dERROR_OF_RIGHT_BORDERS_MM || - dCurrRight < dNextRight); + bIf4 = dCurrBeforeSpacing > dNextBeforeSpacing; + //нет отступа + bIf5 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + //есть отступ + bIf6 = pCurrLine->m_dLeft > pNextLine->m_dLeft; + //совпадают правые границы + bIf7 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + size_t nNextIndex = nIndex+1; + pNextNextLine = GetNextTextLine(nNextIndex); + + bIf8 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && + (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); + + if (pNextNextLine) + { + double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + + if (bIf2 && (bIf3 || bIf4)) + { + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + pNextNextLine = nullptr; + } + } + else + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + if (dNextBeforeSpacing < dNextNextBeforeSpacing) + { + pNextNextLine = nullptr; + } + else + { + bIsSingleLineParagraph = true; + } + } + else + { + pNextNextLine = nullptr; + } + } + } + } } - if (bIf1 && bIf2 && bIf3 && (bIf4 || bIf5) && bIf6 && bIf7) + bool bIsUseNextNextLine = true; + CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( + pCurrLine, pNextLine, pNextNextLine, m_dWidth, bIsUseNextNextLine, bIsSingleLineParagraph); + + if (bIf1 && !bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && (bIf5 || bIf6 || bIf7) && bIf8) { //наверное это сплошной текст auto pParagraph = new CParagraph(m_eTextAssociationType); pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; + pParagraph->m_eTextAlignmentType = eTextAlignmentType; //делаем абзац в сплошном тексте pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; @@ -1213,14 +1250,9 @@ namespace NSDocxRenderer pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); pParagraph->m_dWidth = std::max(pCurrLine->m_dWidth + pCurrLine->m_arConts.back()->m_dSpaceWidthMM, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; + pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - if (fabs(dCurrRight - dNextRight) <= c_dERROR_OF_RIGHT_BORDERS_MM) //предположение - { - pParagraph->m_eTextAlignmentType = CParagraph::tatByWidth; - } - //размер строк во всем параграфе pParagraph->m_dHeight = pCurrLine->m_dHeight; pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); @@ -1243,65 +1275,77 @@ namespace NSDocxRenderer dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; double dCorrectionBeforeSpacing = dCurrBeforeSpacing; - - double dPrevRight = dCurrRight; dCurrRight = dNextRight; - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - } - - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && - fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM && //высота строк должна быть примерно одинаковой - fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM && //расстрояние между строк тоже одинаково - (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) && - ((fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_LEFT_BORDERS_MM && //у последующих строк нет отступа относительно предыдущей непервой строки - (fabs(dCurrRight - dNextRight) < c_dERROR_OF_RIGHT_BORDERS_MM || //а следующая строка либо такая же - (dCurrRight < dNextRight && fabs(dPrevRight - dCurrRight) <= c_dERROR_OF_RIGHT_BORDERS_MM)))) //либо короче, но предыдущие равны - ) + if (bIsUseNextNextLine) { - //Объединим 2 параграфа-строчки - pParagraph->m_arLines.push_back(pNextLine); + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dNextRight = pNextLine->CalculateRightBorder(m_dWidth); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - pParagraph->m_dRight = std::min(pParagraph->m_dRight, dCurrRight); - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dWidth = std::max(pParagraph->m_dWidth, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); + bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf4 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf5 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf6 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } - if (!IsShadingPresent(pCurrLine, pNextLine)) + //проверим, подходят ли следующие строчки для текущего pParagraph + while(pNextLine && bIf2 && bIf3 && bIf4 && bIf5 && bIf6) { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; - } + //Объединим 2 параграфа-строчки + pParagraph->m_arLines.push_back(pNextLine); - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + pParagraph->m_dRight = std::min(pParagraph->m_dRight, dNextRight); + pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dWidth = std::max(pParagraph->m_dWidth, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале + if (!IsShadingPresent(pCurrLine, pNextLine)) + { + pParagraph->m_bIsShadingPresent = false; + pParagraph->m_lColorOfShadingFill = c_iWhiteColor; + } - dPrevRight = dCurrRight; - dCurrRight = dNextRight; + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале + dCurrRight = dNextRight; + + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dNextRight = pNextLine->CalculateRightBorder(m_dWidth); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + + bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf4 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf5 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf6 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } } } if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) { CreateSingleLineShape(pNextLine); nIndex++; @@ -1310,6 +1354,10 @@ namespace NSDocxRenderer //коррекция pParagraph->m_dHeight += dCorrectionBeforeSpacing; pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); + if (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter) + { + pParagraph->m_dFirstLine = 0; + } pParagraph->m_dSpaceBefore += dBeforeSpacingWithShapes; dBeforeSpacingWithShapes = 0; @@ -1371,9 +1419,9 @@ namespace NSDocxRenderer bool CPage::IsShadingPresent(const CTextLine *pLine1, const CTextLine *pLine2) { if (pLine1->m_pDominantShape && pLine2->m_pDominantShape && - pLine1->m_pDominantShape->m_oBrush.Color1 == pLine2->m_pDominantShape->m_oBrush.Color1 && - fabs(pLine1->m_pDominantShape->m_dLeft - pLine2->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(pLine1->m_pDominantShape->m_dWidth - pLine2->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) + pLine1->m_pDominantShape->m_oBrush.Color1 == pLine2->m_pDominantShape->m_oBrush.Color1 && + fabs(pLine1->m_pDominantShape->m_dLeft - pLine2->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(pLine1->m_pDominantShape->m_dWidth - pLine2->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) { return true; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index cfe9f343039..0d46e95d224 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -96,7 +96,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"\""); } if (m_dRight > 0) - { + { oWriter.WriteString(L" w:right=\""); oWriter.AddInt(static_cast(m_dRight * c_dMMToDx)); oWriter.WriteString(L"\""); @@ -222,4 +222,117 @@ namespace NSDocxRenderer pNext->m_bIsNotNecessaryToUse = true; } } + + CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) + { + if (!pCurrentLine || !pNextLine) + { + return tatUnknown; + } + + double dCurrLeft = pCurrentLine->m_dLeft; + double dNextLeft = pNextLine->m_dLeft; + double dNextNextLeft = pNextNextLine ? pNextNextLine->m_dLeft : 0; + + double dCurrRight = pCurrentLine->CalculateRightBorder(dPageWidth); + double dNextRight = pNextLine->CalculateRightBorder(dPageWidth); + double dNextNextRight = pNextNextLine ? pNextNextLine->CalculateRightBorder(dPageWidth) : 0; + + bool bIf1 = fabs(dCurrLeft - dNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf2 = pNextNextLine && fabs(dNextLeft - dNextNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf3 = dCurrLeft != dNextLeft && dCurrLeft > dNextLeft; + + bool bIf4 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf5 = fabs(dNextRight - dNextNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + if (pNextNextLine) + { + if (bIf1 && bIf2) + { + if (bIf4) + { + return tatByWidth; + } + else + { + return tatByLeftEdge; + } + } + else if (bIf3 && bIf2) + { + if (bIf4) + { + return tatByWidth; + } + else + { + return tatByLeftEdge; + } + } + else if (bIf4 && bIf5 && !(bIf1 && !bIf2 && dNextLeft > dNextNextLeft)) + { + return tatByRightEdge; + } + else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) + { + bIsUseNextNextLine = false; + return tatByWidth; + } + else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) + { + bIsSingleLineParagraph = true; + return tatByWidth; + } + else if (!bIf1 && !bIf2 && !bIf4 && !bIf5) + { + return tatByCenter; + } + else + { + return tatByWidth; + } + } + else + { + if (bIf4) + { + if (bIf1) + { + return tatByWidth; + } + else if (bIf3 && dCurrLeft < dNextLeft) + { + return tatByRightEdge; + } + else + { + return tatByWidth; + } + } + else if (dCurrRight < dNextRight) + { + if (bIf1 || bIf3) + { + return tatByWidth; + } + else + { + return tatByCenter; + } + } + else if (dCurrRight > dNextRight) + { + if (bIf1) + { + return tatByLeftEdge; + } + else if (bIf3) + { + return tatByCenter; + } + } + } + + return tatUnknown; + } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 5cd6a42ff83..b032cecb803 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -34,20 +34,20 @@ namespace NSDocxRenderer }; // text frame properties - TextConversionType m_eTextConversionType {tctUnknown}; - bool m_bIsNeedFirstLineIndent {false}; - bool m_bIsAroundTextWrapping {true}; //по умолчанию обтекание включено, если отсутсвует w:wrap - bool m_bIsShadingPresent {false}; - LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR - TextAlignmentType m_eTextAlignmentType {tatUnknown}; + TextConversionType m_eTextConversionType {tctUnknown}; + bool m_bIsNeedFirstLineIndent {false}; + bool m_bIsAroundTextWrapping {true}; //по умолчанию обтекание включено, если отсутсвует w:wrap + bool m_bIsShadingPresent {false}; + LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR + TextAlignmentType m_eTextAlignmentType {tatUnknown}; // geometry paragraph - double m_dRight {0.0}; //сдвиг относительно правого края страницы - double m_dFirstLine {0.0}; //сдвиг относительно m_dLeft + double m_dRight {0.0}; //сдвиг относительно правого края страницы + double m_dFirstLine {0.0}; //сдвиг относительно m_dLeft - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dBaselinePos {0.0}; + double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dBaselinePos {0.0}; TextAssociationType m_eTextAssociationType {tatPlainParagraph}; std::vector m_arLines; @@ -61,5 +61,8 @@ namespace NSDocxRenderer void RemoveHighlightColor(); void MergeLines(); + + static TextAlignmentType DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, + double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph); }; } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 96d38113cee..e4421b0282e 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -174,38 +174,6 @@ namespace NSDocxRenderer m_dRight = m_dLeft + m_dWidth; } - void CTextLine::DetermineAssumedTextAlignmentType(double dWidthOfPage) - { - //рассматриваем строки, которые короче трети ширины страницы - double maxTextLineWidth = dWidthOfPage/3; //нужна какая-нибудь отправная точка... - double delta = 2 * c_dCENTER_POSITION_ERROR_MM; //координата m_dWidth/2 +- c_dCENTER_POSITION_ERROR_MM - - if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta && //если середины линий по x одинаковы - m_dWidth < maxTextLineWidth ) - { - m_eAlignmentType = atatByCenter; - } - else if ((m_dLeft + m_dWidth/2) > (dWidthOfPage/2 + c_dCENTER_POSITION_ERROR_MM) && //середина строки правее центра страницы - m_dWidth < maxTextLineWidth) - { - m_eAlignmentType = atatByRightEdge; - } - else if ((m_dLeft + m_dWidth/2) < (dWidthOfPage/2 - c_dCENTER_POSITION_ERROR_MM) && //середина строки левее центра страницы - m_dWidth < maxTextLineWidth) - { - m_eAlignmentType = atatByLeftEdge; - } - else if (fabs(dWidthOfPage/2 - m_dLeft - m_dWidth/2) <= delta && - m_dWidth > maxTextLineWidth + maxTextLineWidth/2 ) - { - m_eAlignmentType = atatByWidth; - } - else - { - m_eAlignmentType = atatUnknown; - } - } - bool CTextLine::AreAlignmentsAppropriate(const CTextLine *pLine) { if ((m_eAlignmentType == pLine->m_eAlignmentType && m_eAlignmentType!= atatByLeftEdge) || diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 3f0d7477bb2..1baa8605af3 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -43,8 +43,6 @@ namespace NSDocxRenderer void MergeConts(); //Вычисляем ширину сложной строки void CalculateWidth(); - //Пытаемся понять тип выравнивания для текущей строки - void DetermineAssumedTextAlignmentType(double dWidthOfPage); //Определяем на основании выравнивания подходят ли текущая и следующая строки для добавления в параграф bool AreAlignmentsAppropriate(const CTextLine* pLine); diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index 3b9b1ed7b39..9d23e91c68c 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -19,8 +19,7 @@ const double c_dDegreeToAngle = 60000.0; const double c_dSTANDART_STRING_HEIGHT_MM = 4.2333333333333334; const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.01; const double c_dLINE_DISTANCE_ERROR_MM = 0.5; -const double c_dERROR_OF_RIGHT_BORDERS_MM = 0.5; -const double c_dERROR_OF_LEFT_BORDERS_MM = 0.1; +const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 0.5; const double c_dCENTER_POSITION_ERROR_MM = 1.5; const double c_dTHE_STRING_X_PRECISION_MM = 0.5; const double c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM = 0.1; @@ -28,6 +27,7 @@ const double c_dGRAPHICS_ERROR_MM = 0.5; const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3; const double c_dMAX_LINE_HEIGHT_MM = 2.5; const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; +const double c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH = 0.8; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; From 35cc9e4f203685d2e91888e7d3401b52ab1adbe3 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Sat, 17 Sep 2022 15:19:13 +0300 Subject: [PATCH 003/794] Added new TextAssociationType - tatParagraphToShape. Added changes to logic of determing paragraphs. Some fixes 6. --- DocxRenderer/src/logic/Page.cpp | 290 ++++++++++++++---- DocxRenderer/src/logic/Page.h | 3 + DocxRenderer/src/logic/elements/ContText.cpp | 5 +- DocxRenderer/src/logic/elements/OldShape.cpp | 2 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 20 +- DocxRenderer/src/logic/elements/Paragraph.h | 8 +- 6 files changed, 258 insertions(+), 70 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index dbdd8fc0697..b6766958ba7 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -14,19 +14,19 @@ namespace NSDocxRenderer NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager) { - m_pFont = pFont; - m_pPen = pPen; - m_pBrush = pBrush; - m_pShadow = pShadow; - m_pEdgeText = pEdge; + m_pFont = pFont; + m_pPen = pPen; + m_pBrush = pBrush; + m_pShadow = pShadow; + m_pEdgeText = pEdge; - m_pTransform = pMatrix; - m_pSimpleGraphicsConverter = pSimple; + m_pTransform = pMatrix; + m_pSimpleGraphicsConverter = pSimple; m_pStyleManager = pStyleManager; - m_oFontManager.m_pFont = m_pFont; - m_oFontManager.m_pTransform = m_pTransform; + m_oFontManager.m_pFont = m_pFont; + m_oFontManager.m_pTransform = m_pTransform; m_pCurrentLine = nullptr; @@ -678,6 +678,7 @@ namespace NSDocxRenderer } if (m_eTextAssociationType == tatPlainParagraph || + m_eTextAssociationType == tatParagraphToShape || m_eTextAssociationType == tatShapeLine || m_eTextAssociationType == tatPlainLine) { @@ -882,6 +883,7 @@ namespace NSDocxRenderer } auto pLineNext = GetNextTextLine(i); + double dFontSize = 0;; if (pLine->m_eVertAlignType == eVertAlignType::vatSuperscript && pLineNext->m_eVertAlignType == eVertAlignType::vatBase) @@ -889,24 +891,36 @@ namespace NSDocxRenderer pLine->m_bIsNotNecessaryToUse = true; for (const auto &pCont : pLine->m_arConts) { - if (pCont->m_bIsNotNecessaryToUse) + if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) { continue; } - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + dFontSize = pCont->m_pCont->m_pFontStyle->m_oFont.Size; + break; + } - if (pCont->m_pCont) + for (const auto &pCont : pLine->m_arConts) + { + if (pCont->m_bIsNotNecessaryToUse) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + continue; } + pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; + pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + if (pLineNext->m_dLeft > pCont->m_dLeft) { pLineNext->m_dLeft = pCont->m_dLeft; } + if (pLineNext->m_dRight < pCont->m_dRight) + { + pLineNext->m_dRight = pCont->m_dRight; + } pLineNext->m_arConts.push_back(new CContText(*pCont)); } @@ -917,24 +931,36 @@ namespace NSDocxRenderer pLineNext->m_bIsNotNecessaryToUse = true; for (const auto &pCont : pLineNext->m_arConts) { - if (pCont->m_bIsNotNecessaryToUse) + if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) { continue; } - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; + dFontSize = pCont->m_pCont->m_pFontStyle->m_oFont.Size; + break; + } - if (pCont->m_pCont) + for (const auto &pCont : pLineNext->m_arConts) + { + if (pCont->m_bIsNotNecessaryToUse) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = pCont->m_pCont->m_pFontStyle->m_oFont.Size; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + continue; } + pCont->m_eVertAlignType = eVertAlignType::vatSubscript; + + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; + pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + if (pLine->m_dLeft > pCont->m_dLeft) { pLine->m_dLeft = pCont->m_dLeft; } + if (pLine->m_dRight < pCont->m_dRight) + { + pLine->m_dRight = pCont->m_dRight; + } pLine->m_arConts.push_back(new CContText(*pCont)); } @@ -1001,6 +1027,7 @@ namespace NSDocxRenderer BuildByTypeShapeLine(); break; case tatPlainParagraph: + case tatParagraphToShape: BuildByTypePlainParagraph(); break; default: @@ -1091,9 +1118,9 @@ namespace NSDocxRenderer void CPage::BuildByTypePlainParagraph() { - CTextLine* pCurrLine, *pNextLine, *pNextNextLine; + CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; double dCurrRight = 0, dNextRight = 0; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0; + double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; double dBeforeSpacingWithShapes = 0; //note Все параграфы были сдвинуты на данное значение от верхнего края страницы double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; @@ -1111,6 +1138,7 @@ namespace NSDocxRenderer continue; } + dPrevBeforeSpacing = dCurrBeforeSpacing; dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; @@ -1130,6 +1158,10 @@ namespace NSDocxRenderer dCurrRight = pCurrLine->CalculateRightBorder(m_dWidth); pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + if (m_eTextAssociationType == tatParagraphToShape) + { + pPrevLine = GetPrevTextLine(nIndex); + } //Это не последняя строка bIf1 = pNextLine ? true : false; @@ -1170,6 +1202,9 @@ namespace NSDocxRenderer } } + dCurrBeforeSpacing += dBeforeSpacingWithShapes; + dBeforeSpacingWithShapes = 0; + bool bIsSingleLineParagraph = false; if (bIf1) @@ -1235,31 +1270,49 @@ namespace NSDocxRenderer CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( pCurrLine, pNextLine, pNextNextLine, m_dWidth, bIsUseNextNextLine, bIsSingleLineParagraph); - if (bIf1 && !bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && (bIf5 || bIf6 || bIf7) && bIf8) + auto pParagraph = new CParagraph(m_eTextAssociationType); + pParagraph->m_eTextAlignmentType = eTextAlignmentType; + if (m_eTextAssociationType == tatPlainParagraph) { - //наверное это сплошной текст - auto pParagraph = new CParagraph(m_eTextAssociationType); pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; - pParagraph->m_eTextAlignmentType = eTextAlignmentType; - - //делаем абзац в сплошном тексте - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; + } + else + { + pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; + } - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - pParagraph->m_dRight = std::min(dCurrRight, dNextRight); + if (!bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && bIf1) + { pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dRight = std::min(dCurrRight, dNextRight); pParagraph->m_dWidth = std::max(pCurrLine->m_dWidth + pCurrLine->m_arConts.back()->m_dSpaceWidthMM, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; + if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) + { + pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; + pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; + } + } + else + { + pParagraph->m_dLeft = pCurrLine->m_dLeft; + pParagraph->m_dRight = dCurrRight; + pParagraph->m_dWidth = pCurrLine->m_dWidth; + } + + pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - //размер строк во всем параграфе - pParagraph->m_dHeight = pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + //размер строк во всем параграфе + pParagraph->m_dHeight = pCurrLine->m_dHeight; + pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - //Объединим 2 строчки в параграф - pParagraph->m_arLines.push_back(pCurrLine); + pParagraph->m_arLines.push_back(pCurrLine); + pParagraph->m_nNumLines++; + + if (bIf1 && !bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && (bIf5 || bIf6 || bIf7) && bIf8) + { pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; if (IsShadingPresent(pCurrLine, pNextLine)) { @@ -1272,6 +1325,7 @@ namespace NSDocxRenderer pCurrLine = pNextLine; pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + dPrevBeforeSpacing = dCurrBeforeSpacing; dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; double dCorrectionBeforeSpacing = dCurrBeforeSpacing; @@ -1300,8 +1354,8 @@ namespace NSDocxRenderer //проверим, подходят ли следующие строчки для текущего pParagraph while(pNextLine && bIf2 && bIf3 && bIf4 && bIf5 && bIf6) { - //Объединим 2 параграфа-строчки pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; pParagraph->m_dRight = std::min(pParagraph->m_dRight, dNextRight); pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); @@ -1318,6 +1372,7 @@ namespace NSDocxRenderer pCurrLine = pNextLine; pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + dPrevBeforeSpacing = dCurrBeforeSpacing; dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале @@ -1344,8 +1399,8 @@ namespace NSDocxRenderer } if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) { CreateSingleLineShape(pNextLine); nIndex++; @@ -1354,26 +1409,31 @@ namespace NSDocxRenderer //коррекция pParagraph->m_dHeight += dCorrectionBeforeSpacing; pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); - if (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter) - { - pParagraph->m_dFirstLine = 0; - } - - pParagraph->m_dSpaceBefore += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; pParagraph->RemoveHighlightColor(); pParagraph->MergeLines(); - - m_arParagraphs.push_back(pParagraph); } else { - //будет отдельной параграфом-строчкой - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; + if (pCurrLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + } + + if (m_eTextAssociationType == tatParagraphToShape) + { + bool bIsSameTypeText = (pPrevLine && + fabs(pPrevLine->m_dHeight - pCurrLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM); - CreateSingleLineParagraph(pCurrLine, &dCurrRight, &dCurrBeforeSpacing); + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); + } + else + { + m_arParagraphs.push_back(pParagraph); } if (nIndexForCheking != c_nAntiZero) @@ -1382,6 +1442,11 @@ namespace NSDocxRenderer nIndexForCheking = c_nAntiZero; } } + + if (m_eTextAssociationType == tatParagraphToShape) + { + CorrectionParagraphsInShapes(); + } } CTextLine* CPage::GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking) @@ -1416,6 +1481,30 @@ namespace NSDocxRenderer return pLine; } + CTextLine* CPage::GetPrevTextLine(size_t nCurrentIndex) + { + CTextLine* pLine = nullptr; + + if (nCurrentIndex) + { + for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; nIndex--) + { + pLine = m_arTextLine[nIndex]; + + if (pLine->m_bIsNotNecessaryToUse) + { + pLine = nullptr; + continue; + } + else + { + break; + } + } + } + return pLine; + } + bool CPage::IsShadingPresent(const CTextLine *pLine1, const CTextLine *pLine2) { if (pLine1->m_pDominantShape && pLine2->m_pDominantShape && @@ -1447,7 +1536,6 @@ namespace NSDocxRenderer } pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); - pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; if (pLine->m_pDominantShape) { @@ -1500,8 +1588,8 @@ namespace NSDocxRenderer auto pShape = new CShape(); pShape->m_arParagraphs.push_back(pParagraph); pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dTop; + pShape->m_dLeft = pLine->m_dLeft; + pShape->m_dTop = pLine->m_dTop; pShape->m_dWidth = pLine->m_dWidth; pShape->m_dHeight = pLine->m_dHeight; pShape->m_bIsBehindDoc = false; @@ -1509,6 +1597,92 @@ namespace NSDocxRenderer m_arShapes.push_back(pShape); } + void CPage::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText) + { + if (!pParagraph) + { + return; + } + + CShape* pShape; + + if (bIsSameTypeText && !m_arShapes.empty()) + { + pShape = m_arShapes.back(); + pShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + } + else + { + pShape = new CShape(); + pParagraph->m_dSpaceBefore = 0; + pShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines; + } + + if (pShape->m_dLeft > 0) + { + pShape->m_dLeft = std::min(pShape->m_dLeft, pParagraph->m_dLeft); + } + else + { + pShape->m_dLeft = pParagraph->m_dLeft; + } + + if (pShape->m_dTop > 0) + { + pShape->m_dTop = std::min(pShape->m_dTop, pParagraph->m_dTop); + } + else + { + pShape->m_dTop = pParagraph->m_dTop; + } + + if (pShape->m_dRight > 0) + { + pShape->m_dRight = std::min(pShape->m_dRight, pParagraph->m_dRight); + } + else + { + pShape->m_dRight = pParagraph->m_dRight; + } + + pShape->m_dWidth = m_dWidth - pShape->m_dLeft - pShape->m_dRight; + + pShape->m_arParagraphs.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + if (!bIsSameTypeText) + { + m_arShapes.push_back(pShape); + } + } + + void CPage::CorrectionParagraphsInShapes() + { + for (auto pShape : m_arShapes) + { + if (pShape->m_bIsNotNecessaryToUse || + pShape->m_eType != CShape::eShapeType::stTextBox || + pShape->m_arParagraphs.empty()) + { + continue; + } + + for (auto pParagraph : pShape->m_arParagraphs) + { + if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) + { + pParagraph->m_bIsNeedFirstLineIndent = true; + pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; + pParagraph->m_dLeft = 0; + } + + pParagraph->m_dLeft = pParagraph->m_dLeft > pShape->m_dLeft ? pParagraph->m_dLeft - pShape->m_dLeft : 0 ; + pParagraph->m_dRight = pParagraph->m_dRight - pShape->m_dRight; + } + } + } + void CPage::Merge(double dAffinity) { size_t nCount = m_arTextLine.size(); diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 98cb0d94dbc..fa35e49f244 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -119,10 +119,13 @@ namespace NSDocxRenderer void CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing); void CreateSingleLineOldShape(CTextLine *pLine); void CreateSingleLineShape(CTextLine *pLine); + void CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText); + void CorrectionParagraphsInShapes(); bool IsShadingPresent(const CTextLine* pLine1, const CTextLine* pLine2); private: CTextLine* GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking = nullptr); + CTextLine* GetPrevTextLine(size_t nCurrentIndex); }; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index b7bfa8cd32d..f083d21e5f9 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -266,9 +266,12 @@ namespace NSDocxRenderer bool bIf10 = m_bIsOutlinePresent == pCont->m_bIsOutlinePresent; bool bIf11 = m_bIsEmbossPresent == pCont->m_bIsEmbossPresent; bool bIf12 = m_bIsEngravePresent == pCont->m_bIsEngravePresent; + bool bIf13 = m_eVertAlignType == pCont->m_eVertAlignType; + bool bIf14 = m_eVertAlignType == eVertAlignType::vatUnknown && pCont->m_eVertAlignType == eVertAlignType::vatBase; + bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && - bIf8 && bIf9 && bIf10 && bIf11 && bIf12) + bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) { return true; } diff --git a/DocxRenderer/src/logic/elements/OldShape.cpp b/DocxRenderer/src/logic/elements/OldShape.cpp index abb60fe012c..3e6c44565c9 100644 --- a/DocxRenderer/src/logic/elements/OldShape.cpp +++ b/DocxRenderer/src/logic/elements/OldShape.cpp @@ -156,7 +156,7 @@ namespace NSDocxRenderer oWriter.ClearNoAttack(); } - void COldShape::ToXml(NSStringUtils::CStringBuilder &oWriter) + void COldShape::ToXml(NSStringUtils::CStringBuilder& oWriter) { if (m_bIsNotNecessaryToUse) { diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 0d46e95d224..3f3e5a84498 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -35,7 +35,8 @@ namespace NSDocxRenderer { oWriter.WriteString(L" 0) { oWriter.WriteString(L" w:before=\""); oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); oWriter.WriteString(L"\""); } - if (m_eTextConversionType == tctTextToShape) + if (m_dSpaceAfter > 0) { oWriter.WriteString(L" w:after=\""); oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); @@ -110,7 +111,8 @@ namespace NSDocxRenderer oWriter.WriteString(L"/>"); //конец w:ind - if (m_eTextAssociationType == tatPlainParagraph) + if (m_eTextAssociationType == tatPlainParagraph || + m_eTextAssociationType == tatParagraphToShape) { switch (m_eTextAlignmentType) { @@ -199,8 +201,7 @@ namespace NSDocxRenderer auto pCont = pNext->m_arConts.front(); - if (pLastCont->IsEqual(pCont) && - pLastCont->m_eVertAlignType == pCont->m_eVertAlignType) + if (pLastCont->IsEqual(pCont)) { pLastCont->m_oText += pCont->m_oText; pLastCont->m_dWidth += pCont->m_dWidth; @@ -245,6 +246,9 @@ namespace NSDocxRenderer bool bIf4 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; bool bIf5 = fabs(dNextRight - dNextNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf6 = fabs(dCurrLeft + pCurrentLine->m_dWidth/2 - dNextLeft - pNextLine->m_dWidth/2) < 0.5; + bool bIf7 = pNextNextLine && fabs(dNextLeft + pNextLine->m_dWidth/2 - dNextNextLeft - pNextNextLine->m_dWidth/2) < 0.5; + if (pNextNextLine) { if (bIf1 && bIf2) @@ -283,7 +287,7 @@ namespace NSDocxRenderer bIsSingleLineParagraph = true; return tatByWidth; } - else if (!bIf1 && !bIf2 && !bIf4 && !bIf5) + else if (!bIf1 && !bIf2 && !bIf4 && !bIf5 && bIf6 && bIf7) { return tatByCenter; } @@ -326,7 +330,7 @@ namespace NSDocxRenderer { return tatByLeftEdge; } - else if (bIf3) + else if (bIf3 && bIf6) { return tatByCenter; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index b032cecb803..e3086b17d42 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -10,7 +10,8 @@ namespace NSDocxRenderer tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. tatPlainLine = 2, // Каждая линия - параграф обычный tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. - tatPlainParagraph = 4 // Линии объединяются в параграфы + tatPlainParagraph = 4, // Линии объединяются в параграфы + tatParagraphToShape = 5 // Параграфы записываем в шейпы }; class CParagraph : public CBaseItem @@ -47,10 +48,13 @@ namespace NSDocxRenderer double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dBaselinePos {0.0}; + TextAssociationType m_eTextAssociationType {tatPlainParagraph}; std::vector m_arLines; + + size_t m_nNumLines {0}; + public: CParagraph(const TextAssociationType& eType); virtual ~CParagraph(); From cc69b4b8308a1d00a155dc4f4655687ce4ebc804 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Thu, 22 Sep 2022 12:31:25 +0300 Subject: [PATCH 004/794] All paragraphs on one page add to general text shape now. --- DocxRenderer/src/logic/Page.cpp | 63 +++++++++++++++++++++++++++++++-- DocxRenderer/src/logic/Page.h | 3 ++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index b6766958ba7..d9ed85e97bb 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -28,6 +28,7 @@ namespace NSDocxRenderer m_oFontManager.m_pFont = m_pFont; m_oFontManager.m_pTransform = m_pTransform; + m_pGeneralTextShape = nullptr; m_pCurrentLine = nullptr; m_dLastTextX = -1; @@ -45,6 +46,7 @@ namespace NSDocxRenderer ClearShapes(); ClearImages(); + m_pGeneralTextShape = nullptr; m_pCurrentLine = nullptr; m_dLastTextX = -1; @@ -1425,11 +1427,13 @@ namespace NSDocxRenderer if (m_eTextAssociationType == tatParagraphToShape) { - bool bIsSameTypeText = (pPrevLine && + /*bool bIsSameTypeText = (pPrevLine && fabs(pPrevLine->m_dHeight - pCurrLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM); - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText);*/ + + AddParagraphToGeneralTextShape(pParagraph); } else { @@ -1657,6 +1661,61 @@ namespace NSDocxRenderer } } + void CPage::AddParagraphToGeneralTextShape(CParagraph* pParagraph) + { + if (!pParagraph) + { + return; + } + + if (!m_pGeneralTextShape) + { + m_pGeneralTextShape = new CShape(); + + pParagraph->m_dSpaceBefore = 0; + m_pGeneralTextShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines; + m_pGeneralTextShape->m_eType = CShape::eShapeType::stTextBox; + m_pGeneralTextShape->m_bIsBehindDoc = false; + + m_arShapes.push_back(m_pGeneralTextShape); + } + else + { + m_pGeneralTextShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + } + + m_pGeneralTextShape->m_arParagraphs.push_back(pParagraph); + + if (m_pGeneralTextShape->m_dLeft > 0) + { + m_pGeneralTextShape->m_dLeft = std::min(m_pGeneralTextShape->m_dLeft, pParagraph->m_dLeft); + } + else + { + m_pGeneralTextShape->m_dLeft = pParagraph->m_dLeft; + } + + if (m_pGeneralTextShape->m_dTop > 0) + { + m_pGeneralTextShape->m_dTop = std::min(m_pGeneralTextShape->m_dTop, pParagraph->m_dTop); + } + else + { + m_pGeneralTextShape->m_dTop = pParagraph->m_dTop; + } + + if (m_pGeneralTextShape->m_dRight > 0) + { + m_pGeneralTextShape->m_dRight = std::min(m_pGeneralTextShape->m_dRight, pParagraph->m_dRight); + } + else + { + m_pGeneralTextShape->m_dRight = pParagraph->m_dRight; + } + + m_pGeneralTextShape->m_dWidth = m_dWidth - m_pGeneralTextShape->m_dLeft - m_pGeneralTextShape->m_dRight; + } + void CPage::CorrectionParagraphsInShapes() { for (auto pShape : m_arShapes) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index fa35e49f244..c8858f6434c 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -34,6 +34,8 @@ namespace NSDocxRenderer std::vector m_arShapes; std::vector m_arParagraphs; + CShape* m_pGeneralTextShape{nullptr}; + CTextLine* m_pCurrentLine {nullptr}; CFontManager m_oFontManager; @@ -120,6 +122,7 @@ namespace NSDocxRenderer void CreateSingleLineOldShape(CTextLine *pLine); void CreateSingleLineShape(CTextLine *pLine); void CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText); + void AddParagraphToGeneralTextShape(CParagraph* pParagraph); void CorrectionParagraphsInShapes(); bool IsShadingPresent(const CTextLine* pLine1, const CTextLine* pLine2); From e35a27e9dcf8cfde7c75de32ed8779d31cf97564 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Mon, 26 Sep 2022 12:51:29 +0300 Subject: [PATCH 005/794] Added recognition of Diacritical Symbols. Paragraphs are allocated to shapes based on the distance between them. --- DocxRenderer/src/logic/Page.cpp | 184 +++++++++---------- DocxRenderer/src/logic/Page.h | 34 ++-- DocxRenderer/src/logic/elements/BaseItem.cpp | 26 ++- DocxRenderer/src/logic/elements/BaseItem.h | 18 +- DocxRenderer/src/logic/elements/ContText.cpp | 8 +- DocxRenderer/src/resources/utils.h | 10 + 6 files changed, 145 insertions(+), 135 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index d9ed85e97bb..bbc783710d5 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -27,8 +27,6 @@ namespace NSDocxRenderer m_oFontManager.m_pFont = m_pFont; m_oFontManager.m_pTransform = m_pTransform; - - m_pGeneralTextShape = nullptr; m_pCurrentLine = nullptr; m_dLastTextX = -1; @@ -46,7 +44,6 @@ namespace NSDocxRenderer ClearShapes(); ClearImages(); - m_pGeneralTextShape = nullptr; m_pCurrentLine = nullptr; m_dLastTextX = -1; @@ -62,6 +59,7 @@ namespace NSDocxRenderer void CPage::ClearTextData() { m_arSymbol.clear(); + m_arDiacriticalSymbol.clear(); } void CPage::ClearTextLines() @@ -363,8 +361,8 @@ namespace NSDocxRenderer pCont->m_dLastX = dTextX; pCont->m_dTop = dBaseLinePos - dTextH - m_oFontManager.m_oFont.m_dBaselineOffset; - pCont->m_dWidth = dTextW; - pCont->m_dHeight = dTextH; + pCont->m_dWidth = dTextW; + pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; pCont->m_oText = oText; @@ -383,7 +381,14 @@ namespace NSDocxRenderer pCont->m_dSpaceWidthMM = m_oFontManager.m_dSpaceWidthMM; - m_arSymbol.push_back(pCont); + if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) + { + m_arDiacriticalSymbol.push_back(pCont); + } + else + { + m_arSymbol.push_back(pCont); + } } void CPage::AnalyzeCollectedShapes() @@ -701,6 +706,7 @@ namespace NSDocxRenderer } SelectCurrentLine(pCont); + AddDiacriticalSymbols(pCont); CContText* pLastCont = nullptr; size_t nCountConts = m_pCurrentLine->m_arConts.size(); @@ -857,6 +863,53 @@ namespace NSDocxRenderer return; } + void CPage::AddDiacriticalSymbols(CContText *pCont) + { + if (!m_arDiacriticalSymbol.empty()) + { + for (auto pDiacriticalCont : m_arDiacriticalSymbol) + { + if (pDiacriticalCont->m_bIsNotNecessaryToUse) + { + continue; + } + + eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pDiacriticalCont); + eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pDiacriticalCont); + + if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; + bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; + + bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || + eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; + bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; + + if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) + { + pCont->m_oText += pDiacriticalCont->m_oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + } + else if (bIf3 && bIf7) + { + NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); + oText += pCont->m_oText; + pCont->m_oText = oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + } + } + } + } + } + void CPage::CollectDublicateLines(const CContText *pCont) { if (pCont->m_iNumDuplicates > 0) @@ -1128,7 +1181,7 @@ namespace NSDocxRenderer double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; eVerticalCrossingType eCrossingType; - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7, bIf8; + bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; size_t nIndexForCheking = c_nAntiZero; @@ -1165,10 +1218,7 @@ namespace NSDocxRenderer pPrevLine = GetPrevTextLine(nIndex); } - //Это не последняя строка - bIf1 = pNextLine ? true : false; - - if (bIf1) + if (pNextLine) { eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bool bIsPassed = false; @@ -1177,13 +1227,13 @@ namespace NSDocxRenderer switch (eCrossingType) { case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: + case eVerticalCrossingType::vctCurrentBelowNext: dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; dPreviousStringBaseline = pNextLine->m_dBaselinePos; bIsPassed = true; break; case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: + case eVerticalCrossingType::vctCurrentAboveNext: case eVerticalCrossingType::vctDublicate: dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; bIsPassed = true; @@ -1209,35 +1259,35 @@ namespace NSDocxRenderer bool bIsSingleLineParagraph = false; - if (bIf1) + if (pNextLine) { dNextRight = pNextLine->CalculateRightBorder(m_dWidth); dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); //Высота строк должна быть примерно одинаковой - bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //расстрояние между строк тоже одинаково - bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //или - bIf4 = dCurrBeforeSpacing > dNextBeforeSpacing; + bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; //нет отступа - bIf5 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; //есть отступ - bIf6 = pCurrLine->m_dLeft > pNextLine->m_dLeft; + bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; //совпадают правые границы - bIf7 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bIf6 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; size_t nNextIndex = nIndex+1; pNextNextLine = GetNextTextLine(nNextIndex); - bIf8 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && + bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); if (pNextNextLine) { double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - if (bIf2 && (bIf3 || bIf4)) + if (bIf1 && (bIf2 || bIf3)) { if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) { @@ -1283,7 +1333,7 @@ namespace NSDocxRenderer pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; } - if (!bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && bIf1) + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) { pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); pParagraph->m_dRight = std::min(dCurrRight, dNextRight); @@ -1311,7 +1361,7 @@ namespace NSDocxRenderer pParagraph->m_arLines.push_back(pCurrLine); pParagraph->m_nNumLines++; - if (bIf1 && !bIsSingleLineParagraph && bIf2 && (bIf3 || bIf4) && (bIf5 || bIf6 || bIf7) && bIf8) + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) { pParagraph->m_arLines.push_back(pNextLine); pParagraph->m_nNumLines++; @@ -1341,20 +1391,20 @@ namespace NSDocxRenderer dNextRight = pNextLine->CalculateRightBorder(m_dWidth); eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf4 = (eCrossingType == eVerticalCrossingType::vctUnknown || + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf5 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf6 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); } //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && bIf2 && bIf3 && bIf4 && bIf5 && bIf6) + while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) { pParagraph->m_arLines.push_back(pNextLine); pParagraph->m_nNumLines++; @@ -1386,16 +1436,16 @@ namespace NSDocxRenderer dNextRight = pNextLine->CalculateRightBorder(m_dWidth); eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bIf2 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf3 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf4 = (eCrossingType == eVerticalCrossingType::vctUnknown || + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf5 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf6 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); } } } @@ -1427,13 +1477,8 @@ namespace NSDocxRenderer if (m_eTextAssociationType == tatParagraphToShape) { - /*bool bIsSameTypeText = (pPrevLine && - fabs(pPrevLine->m_dHeight - pCurrLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM && - fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM); - - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText);*/ - - AddParagraphToGeneralTextShape(pParagraph); + bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); } else { @@ -1661,61 +1706,6 @@ namespace NSDocxRenderer } } - void CPage::AddParagraphToGeneralTextShape(CParagraph* pParagraph) - { - if (!pParagraph) - { - return; - } - - if (!m_pGeneralTextShape) - { - m_pGeneralTextShape = new CShape(); - - pParagraph->m_dSpaceBefore = 0; - m_pGeneralTextShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines; - m_pGeneralTextShape->m_eType = CShape::eShapeType::stTextBox; - m_pGeneralTextShape->m_bIsBehindDoc = false; - - m_arShapes.push_back(m_pGeneralTextShape); - } - else - { - m_pGeneralTextShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; - } - - m_pGeneralTextShape->m_arParagraphs.push_back(pParagraph); - - if (m_pGeneralTextShape->m_dLeft > 0) - { - m_pGeneralTextShape->m_dLeft = std::min(m_pGeneralTextShape->m_dLeft, pParagraph->m_dLeft); - } - else - { - m_pGeneralTextShape->m_dLeft = pParagraph->m_dLeft; - } - - if (m_pGeneralTextShape->m_dTop > 0) - { - m_pGeneralTextShape->m_dTop = std::min(m_pGeneralTextShape->m_dTop, pParagraph->m_dTop); - } - else - { - m_pGeneralTextShape->m_dTop = pParagraph->m_dTop; - } - - if (m_pGeneralTextShape->m_dRight > 0) - { - m_pGeneralTextShape->m_dRight = std::min(m_pGeneralTextShape->m_dRight, pParagraph->m_dRight); - } - else - { - m_pGeneralTextShape->m_dRight = pParagraph->m_dRight; - } - - m_pGeneralTextShape->m_dWidth = m_dWidth - m_pGeneralTextShape->m_dLeft - m_pGeneralTextShape->m_dRight; - } - void CPage::CorrectionParagraphsInShapes() { for (auto pShape : m_arShapes) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index c8858f6434c..e3f794f50b6 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -10,36 +10,34 @@ namespace NSDocxRenderer class CPage { public: - NSStructures::CFont* m_pFont {nullptr}; - NSStructures::CPen* m_pPen {nullptr}; - NSStructures::CBrush* m_pBrush {nullptr}; - NSStructures::CShadow* m_pShadow {nullptr}; - NSStructures::CEdgeText* m_pEdgeText {nullptr}; + NSStructures::CFont* m_pFont {nullptr}; + NSStructures::CPen* m_pPen {nullptr}; + NSStructures::CBrush* m_pBrush {nullptr}; + NSStructures::CShadow* m_pShadow {nullptr}; + NSStructures::CEdgeText* m_pEdgeText {nullptr}; - Aggplus::CMatrix* m_pTransform {nullptr}; + Aggplus::CMatrix* m_pTransform {nullptr}; Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; CStyleManager* m_pStyleManager {nullptr}; - - CVectorGraphics m_oVector; + CVectorGraphics m_oVector; double m_dWidth {0.0}; double m_dHeight {0.0}; - LONG m_lCurrentCommand {0}; + LONG m_lCurrentCommand {0}; std::vector m_arImages; - std::vector m_arSymbol ; + std::vector m_arSymbol; + std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; - std::vector m_arShapes; + std::vector m_arShapes; std::vector m_arParagraphs; - CShape* m_pGeneralTextShape{nullptr}; - - CTextLine* m_pCurrentLine {nullptr}; + CTextLine* m_pCurrentLine {nullptr}; - CFontManager m_oFontManager; - CFontManagerLight m_oFontManagerLight; + CFontManager m_oFontManager; + CFontManagerLight m_oFontManagerLight; TextAssociationType m_eTextAssociationType {tatPlainLine}; @@ -63,7 +61,6 @@ namespace NSDocxRenderer void ClearShapes(); void ClearParagraphs(); - void SelectCurrentLine(const CContText* pCont); //удаляем то, что выходит за границы страницы void DeleteTextClipPage(); @@ -99,6 +96,8 @@ namespace NSDocxRenderer //набивается содержимым вектор m_arTextLine void AnalyzeLines(); void BuildLines(); + void AddDiacriticalSymbols(CContText* pCont); + void SelectCurrentLine(const CContText* pCont); void CollectDublicateLines(const CContText *pCont); void MergeLinesByVertAlignType(); void DetermineDominantGraphics(); @@ -122,7 +121,6 @@ namespace NSDocxRenderer void CreateSingleLineOldShape(CTextLine *pLine); void CreateSingleLineShape(CTextLine *pLine); void CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText); - void AddParagraphToGeneralTextShape(CParagraph* pParagraph); void CorrectionParagraphsInShapes(); bool IsShadingPresent(const CTextLine* pLine1, const CTextLine* pLine2); diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 333d9d9932e..e470dc4a174 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -46,24 +46,29 @@ namespace NSDocxRenderer } else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop) { - return eVerticalCrossingType::vctCurrentAboveNext; + return eVerticalCrossingType::vctCurrentBelowNext; } else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos) { - return eVerticalCrossingType::vctCurrentBelowNext; + return eVerticalCrossingType::vctCurrentAboveNext; } else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) { return eVerticalCrossingType::vctDublicate; } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + } else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { - return eVerticalCrossingType::vctTopBordersMatch; + return eVerticalCrossingType::vctTopBorderMatch; } else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { - return eVerticalCrossingType::vctBottomBordersMatch; + return eVerticalCrossingType::vctBottomBorderMatch; } else if (m_dBaselinePos < oSrc->m_dTop) { @@ -89,11 +94,11 @@ namespace NSDocxRenderer { return eHorizontalCrossingType::hctCurrentOutsideNext; } - else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight > oSrc->m_dLeft) + else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight >= oSrc->m_dLeft) { return eHorizontalCrossingType::hctCurrentLeftOfNext; } - else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft < oSrc->m_dRight) + else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft <= oSrc->m_dRight) { return eHorizontalCrossingType::hctCurrentRightOfNext; } @@ -102,13 +107,18 @@ namespace NSDocxRenderer { return eHorizontalCrossingType::hctDublicate; } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftAndRightBordersMatch; + } else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { - return eHorizontalCrossingType::hctLeftBordersMatch; + return eHorizontalCrossingType::hctLeftBorderMatch; } else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { - return eHorizontalCrossingType::hctRightBordersMatch; + return eHorizontalCrossingType::hctRightBorderMatch; } else if (m_dRight < oSrc->m_dLeft) { diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 23525509115..e948362baef 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -11,8 +11,9 @@ namespace NSDocxRenderer vctCurrentAboveNext, vctCurrentBelowNext, vctDublicate, - vctTopBordersMatch, - vctBottomBordersMatch, + vctTopAndBottomBordersMatch, + vctTopBorderMatch, + vctBottomBorderMatch, vctNoCrossingCurrentAboveNext, vctNoCrossingCurrentBelowNext }; @@ -25,8 +26,9 @@ namespace NSDocxRenderer hctCurrentLeftOfNext, hctCurrentRightOfNext, hctDublicate, - hctLeftBordersMatch, - hctRightBordersMatch, + hctLeftAndRightBordersMatch, + hctLeftBorderMatch, + hctRightBorderMatch, hctNoCrossingCurrentLeftOfNext, hctNoCrossingCurrentRightOfNext }; @@ -36,11 +38,11 @@ namespace NSDocxRenderer public: enum class ElemType { - etContText = 0, + etContText = 0, etTextLine = 1, - etParagraph = 2, - etImage = 3, - etShape = 4, + etParagraph = 2, + etImage = 3, + etShape = 4, etOldShape = 5, }; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index f083d21e5f9..b6f3201b22e 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -329,8 +329,8 @@ namespace NSDocxRenderer bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) { //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше //Условие пересечения по горизонтали bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее @@ -404,9 +404,9 @@ namespace NSDocxRenderer bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) { //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentBelowNext || eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //Условие пересечения по горизонтали bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index ed85a99f766..afe0cd02acb 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -32,6 +32,16 @@ inline bool IsUnicodeSymbol(const int& symbol ) return false; } + +inline bool IsDiacriticalMark(const int& symbol ) +{ + if ( 0x0300 <= symbol && 0x036F >= symbol ) + { + return true; + } + return false; +} + // 2-byte number inline short little_endian_2_big_endian( short s ) { From 742ed66df1dd997c55523f677b79c3e9e218ba08 Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Wed, 28 Sep 2022 07:24:44 +0300 Subject: [PATCH 006/794] Refactoring. Optimized operating logic. Conversion time is reduced. --- DocxRenderer/DocxRenderer.cpp | 3 + DocxRenderer/DocxRenderer.pro | 1 - DocxRenderer/src/logic/Document.cpp | 95 ++- DocxRenderer/src/logic/Document.h | 78 +- DocxRenderer/src/logic/Page.cpp | 745 ++++++++---------- DocxRenderer/src/logic/Page.h | 18 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 267 ++++--- DocxRenderer/src/logic/elements/BaseItem.h | 5 +- DocxRenderer/src/logic/elements/ContText.cpp | 90 ++- DocxRenderer/src/logic/elements/ContText.h | 12 +- DocxRenderer/src/logic/elements/OldShape.cpp | 4 +- DocxRenderer/src/logic/elements/OldShape.h | 7 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 16 +- DocxRenderer/src/logic/elements/Paragraph.h | 5 +- DocxRenderer/src/logic/elements/Shape.cpp | 2 +- DocxRenderer/src/logic/elements/Shape.h | 13 +- DocxRenderer/src/logic/elements/TextLine.cpp | 69 +- DocxRenderer/src/logic/elements/TextLine.h | 18 +- DocxRenderer/src/logic/managers/FontManager.h | 8 +- .../src/logic/managers/FontManagerBase.cpp | 8 +- .../src/logic/managers/StyleManager.cpp | 6 +- DocxRenderer/src/resources/SortElements.h | 79 -- DocxRenderer/src/resources/utils.h | 11 + 23 files changed, 771 insertions(+), 789 deletions(-) delete mode 100644 DocxRenderer/src/resources/SortElements.h diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 07613afdf7f..4252d7c5961 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -94,12 +94,15 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; int nPagesCount = pFile->GetPagesCount(); + m_pInternal->m_oDocument.m_lNumberPages = nPagesCount; + for (int i = 0; i < nPagesCount; ++i) { //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; NewPage(); BeginCommand(c_nPageType); m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; + m_pInternal->m_oDocument.m_lPagesCount = i; double dPageDpiX, dPageDpiY; double dWidth, dHeight; diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 86f16ea6b9d..c181228655a 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -44,7 +44,6 @@ HEADERS += \ src/resources/ImageInfo.h \ src/resources/LinesTable.h \ src/resources/SingletonTemplate.h \ - src/resources/SortElements.h \ src/resources/VectorGraphics.h \ src/resources/resources.h \ src/resources/utils.h \ diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 0621c7e0475..3981601b311 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -3,10 +3,12 @@ namespace NSDocxRenderer { CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : - m_pAppFonts(pFonts), m_oCurrentPage(pFonts) + m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts) { m_oSimpleGraphicsConverter.SetRenderer(pRenderer); - m_oWriter.AddSize(10000); + + m_oFontManager.m_pFont = &m_oFont; + m_oFontManager.m_pTransform = &m_oTransform; } void CDocument::Clear() { @@ -21,23 +23,17 @@ namespace NSDocxRenderer m_lClipMode = 0; m_lPagesCount = 0; - m_oWriter.Clear(); + m_mapXmlString.clear(); } CDocument::~CDocument() { m_lClipMode = 0; RELEASEINTERFACE(m_pFontManager); + m_mapXmlString.clear(); } HRESULT CDocument::NewPage() { - if (0 != m_lPagesCount) - { - m_oCurrentPage.WriteSectionToFile(false, m_oWriter); - m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData()); - m_oWriter.ClearNoAttack(); - } - m_oPen.SetDefaultParams(); m_oBrush.SetDefaultParams(); m_oFont.SetDefaultParams(); @@ -46,7 +42,6 @@ namespace NSDocxRenderer m_oTransform.Reset(); - ++m_lPagesCount; m_oCurrentPage.Clear(); return S_OK; @@ -58,8 +53,8 @@ namespace NSDocxRenderer } HRESULT CDocument::put_Height(double dHeight) { - m_dHeight = dHeight; - m_oCurrentPage.m_dHeight = dHeight; + m_dHeight = dHeight; + m_oCurrentPage.m_dHeight = dHeight; return S_OK; } HRESULT CDocument::get_Width(double* dWidth) @@ -69,8 +64,8 @@ namespace NSDocxRenderer } HRESULT CDocument::put_Width(double dWidth) { - m_dWidth = dWidth; - m_oCurrentPage.m_dWidth = dWidth; + m_dWidth = dWidth; + m_oCurrentPage.m_dWidth = dWidth; return S_OK; } HRESULT CDocument::get_DpiX(double* dDpiX) @@ -516,7 +511,7 @@ namespace NSDocxRenderer unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); if (nLen == 0) return S_OK; - if (nLen != nGidsCount && 0 != nGidsCount) + if (nLen != nGidsCount && 0 != nGidsCount) { delete [] pUnicodes; return S_OK; @@ -535,9 +530,6 @@ namespace NSDocxRenderer m_lCurrentCommandType = (LONG)lType; m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; - if (c_nTextType == lType) - m_oCurrentPage.m_dLastTextX_block = -1; - return S_OK; } HRESULT CDocument::EndCommand(DWORD lType) @@ -550,21 +542,16 @@ namespace NSDocxRenderer if (c_nPageType == lType) { - // нужно записать страницу в файл - m_oCurrentPage.AnalyzeCollectedShapes(); - m_oCurrentPage.AnalyzeCollectedSymbols(); - m_oCurrentPage.AnalyzeLines(); - m_oCurrentPage.BuildByType(); - m_oCurrentPage.ToXml(m_oWriter); + auto pWriter = new NSStringUtils::CStringBuilder(); + pWriter->AddSize(100000); + m_oCurrentPage.ProcessingAndRecordingOfPageData(*pWriter, m_lPagesCount, m_lNumberPages); + m_mapXmlString[m_lPagesCount] = std::move(pWriter); } else if (c_nPathType == lType) { m_oCurrentPage.End(); } - if (c_nTextType == lType) - m_oCurrentPage.m_dLastTextX_block = -1; - return S_OK; } //-------- Функции для работы с Graphics Path ----------------------------------------------- @@ -826,19 +813,33 @@ namespace NSDocxRenderer Clear(); m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager); + m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager); m_oImageManager.NewDocument(); m_oStyleManager.NewDocument(); + m_oFontManager.Init(); + // media m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); - m_oCurrentPage.m_oFontManager.Init(); + return true; + } + + void CDocument::Close() + { + BuildDocumentXml(); + BuildDocumentXmlRels(); + BuildFontTableXml(); + BuildStylesXml(); + } + + void CDocument::BuildDocumentXml() + { + NSFile::CFileBinary oDocumentStream; - m_oDocumentStream.CloseFile(); - m_oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); - m_oDocumentStream.WriteStringUTF8(L"\ + oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); + oDocumentStream.WriteStringUTF8(L"\ \ "); - return true; - } - - void CDocument::Close() - { - BuildDocumentXmlRels(); - BuildFontTableXml(); - BuildStylesXml(); + for (size_t i = 0; i < m_mapXmlString.size(); ++i) + { + oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData()); + } - // document - m_oCurrentPage.WriteSectionToFile(true, m_oWriter); - m_oWriter.WriteString(L""); - m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData()); - m_oWriter.ClearNoAttack(); + oDocumentStream.WriteStringUTF8(L""); - m_oDocumentStream.CloseFile(); + oDocumentStream.CloseFile(); } void CDocument::BuildDocumentXmlRels() @@ -952,8 +945,8 @@ namespace NSDocxRenderer xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">"); - CFontTable* pFontTable = &m_oCurrentPage.m_oFontManager.m_oFontTable; - for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); iterFont++) + CFontTable* pFontTable = &m_oFontManager.m_oFontTable; + for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); ++iterFont) { CFontTableEntry& oEntry = iterFont->second; @@ -1202,9 +1195,9 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - for (const auto &pStyle : m_oStyleManager.m_arStyles) + for (size_t i = 0; i < m_oStyleManager.m_arStyles.size(); ++i) { - pStyle->ToXml(oWriter); + m_oStyleManager.m_arStyles[i]->ToXml(oWriter); } oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index c27fc561d13..68a98ec05b0 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -8,55 +8,56 @@ namespace NSDocxRenderer { class CDocument - { - public: + { + public: NSFonts::IApplicationFonts* m_pAppFonts; - NSStructures::CPen m_oPen; - NSStructures::CBrush m_oBrush; - NSStructures::CFont m_oFont; - NSStructures::CShadow m_oShadow; - NSStructures::CEdgeText m_oEdge; + NSStructures::CPen m_oPen; + NSStructures::CBrush m_oBrush; + NSStructures::CFont m_oFont; + NSStructures::CShadow m_oShadow; + NSStructures::CEdgeText m_oEdge; - NSStructures::CFont m_oInstalledFont; + NSStructures::CFont m_oInstalledFont; NSFonts::IFontManager* m_pFontManager {nullptr}; Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - Aggplus::CMatrix m_oTransform; + Aggplus::CMatrix m_oTransform; - LONG m_lCurrentCommandType {0}; + LONG m_lCurrentCommandType {0}; - LONG m_lClipMode; - CPage m_oCurrentPage; + LONG m_lClipMode; + CPage m_oCurrentPage; - CImageManager m_oImageManager; + CImageManager m_oImageManager; CStyleManager m_oStyleManager; + CFontManager m_oFontManager; - double m_dWidth {0.0}; - double m_dHeight {0.0}; + double m_dWidth {0.0}; + double m_dHeight {0.0}; - double m_dDpiX {72.0}; - double m_dDpiY {72.0}; + double m_dDpiX {72.0}; + double m_dDpiY {72.0}; - std::wstring m_strTempDirectory {L""}; + std::wstring m_strTempDirectory {L""}; std::wstring m_strDstFilePath; - NSFile::CFileBinary m_oDocumentStream; - LONG m_lPagesCount {0}; + LONG m_lPagesCount {0}; + LONG m_lNumberPages{0}; - NSStringUtils::CStringBuilder m_oWriter; - bool m_bIsNeedPDFTextAnalyzer {false}; + bool m_bIsNeedPDFTextAnalyzer {false}; bool m_bIsDisablePageCommand {false}; // disable commands inside draw function - public: + std::map m_mapXmlString; + public: CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); void Clear(); ~CDocument(); - public: + public: HRESULT NewPage(); HRESULT get_Height(double* dHeight); @@ -65,8 +66,8 @@ namespace NSDocxRenderer HRESULT put_Width(double dWidth); HRESULT get_DpiX(double* dDpiX); HRESULT get_DpiY(double* dDpiY); - //-------- Функции для задания настроек текста ---------------------------------------------- - // pen -------------------------------------------------------------------------------------- + //-------- Функции для задания настроек текста ---------------------------------------------- + // pen -------------------------------------------------------------------------------------- HRESULT get_PenColor(LONG* lColor); HRESULT put_PenColor(LONG lColor); HRESULT get_PenAlpha(LONG* lAlpha); @@ -88,7 +89,7 @@ namespace NSDocxRenderer HRESULT get_PenMiterLimit(double* val); HRESULT put_PenMiterLimit(double val); HRESULT PenDashPattern(double* pPattern, LONG lCount); - // brush ------------------------------------------------------------------------------------ + // brush ------------------------------------------------------------------------------------ HRESULT get_BrushType(LONG* lType); HRESULT put_BrushType(LONG lType); HRESULT get_BrushColor1(LONG* lColor); @@ -108,7 +109,7 @@ namespace NSDocxRenderer HRESULT get_BrushLinearAngle(double* dAngle); HRESULT put_BrushLinearAngle(double dAngle); HRESULT BrushRect(bool val, double left, double top, double width, double height); - // font ------------------------------------------------------------------------------------- + // font ------------------------------------------------------------------------------------- HRESULT get_FontName(std::wstring* sName); HRESULT put_FontName(std::wstring sName); HRESULT get_FontPath(std::wstring* sPath); @@ -123,7 +124,7 @@ namespace NSDocxRenderer HRESULT put_FontCharSpace(double dSpace); HRESULT get_FontFaceIndex(int* lFaceIndex); HRESULT put_FontFaceIndex(const int& lFaceIndex); - // shadow ----------------------------------------------------------------------------------- + // shadow ----------------------------------------------------------------------------------- HRESULT get_ShadowDistanceX(double* val); HRESULT put_ShadowDistanceX(double val); HRESULT get_ShadowDistanceY(double* val); @@ -136,7 +137,7 @@ namespace NSDocxRenderer HRESULT put_ShadowAlpha(LONG val); HRESULT get_ShadowVisible(INT* val); HRESULT put_ShadowVisible(INT val); - // edge ------------------------------------------------------------------------------------- + // edge ------------------------------------------------------------------------------------- HRESULT get_EdgeVisible(LONG* val); HRESULT put_EdgeVisible(LONG val); HRESULT get_EdgeColor(LONG* val); @@ -145,7 +146,7 @@ namespace NSDocxRenderer HRESULT put_EdgeAlpha(LONG val); HRESULT get_EdgeDist(double* val); HRESULT put_EdgeDist(double val); - //-------- Функции для вывода текста -------------------------------------------------------- + //-------- Функции для вывода текста -------------------------------------------------------- HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaseLineOffset = 0); @@ -155,10 +156,10 @@ namespace NSDocxRenderer virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //-------- Маркеры для команд --------------------------------------------------------------- + //-------- Маркеры для команд --------------------------------------------------------------- HRESULT BeginCommand(DWORD lType); HRESULT EndCommand(DWORD lType); - //-------- Функции для работы с Graphics Path ----------------------------------------------- + //-------- Функции для работы с Graphics Path ----------------------------------------------- HRESULT PathCommandMoveTo(double fX, double fY); HRESULT PathCommandLineTo(double fX, double fY); HRESULT PathCommandLinesTo(double* pPoints, LONG lCount); @@ -178,27 +179,28 @@ namespace NSDocxRenderer HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags); HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); - //-------- Функции для вывода изображений -------------------------------------------------- + //-------- Функции для вывода изображений -------------------------------------------------- HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight); HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight); - //------------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------------ HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF); HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); HRESULT ResetTransform(void); HRESULT get_ClipMode(LONG* plMode); HRESULT put_ClipMode(LONG lMode); - protected: + protected: void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); void _SetFont(); - public: - + public: + bool CreateDocument(); void Close(); + void BuildDocumentXml(); void BuildDocumentXmlRels(); void BuildFontTableXml(); void BuildStylesXml(); diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index bbc783710d5..15a790a99ae 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1,18 +1,17 @@ #include "Page.h" #include "../resources/Constants.h" -#include "../resources/SortElements.h" #include "../resources/utils.h" #include namespace NSDocxRenderer { - CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManager(pFonts), m_oFontManagerLight(pFonts) + CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManagerLight(pFonts) { } void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager) + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager) { m_pFont = pFont; m_pPen = pPen; @@ -24,15 +23,10 @@ namespace NSDocxRenderer m_pSimpleGraphicsConverter = pSimple; m_pStyleManager = pStyleManager; + m_pFontManager = pFontManager; - m_oFontManager.m_pFont = m_pFont; - m_oFontManager.m_pTransform = m_pTransform; m_pCurrentLine = nullptr; - m_dLastTextX = -1; - m_dLastTextY = -1; - m_dLastTextX_block = m_dLastTextX; - CShape::ResetRelativeHeight(); } @@ -45,10 +39,6 @@ namespace NSDocxRenderer ClearImages(); m_pCurrentLine = nullptr; - - m_dLastTextX = -1; - m_dLastTextY = -1; - m_dLastTextX_block = m_dLastTextX; } void CPage::ClearImages() @@ -58,7 +48,6 @@ namespace NSDocxRenderer void CPage::ClearTextData() { - m_arSymbol.clear(); m_arDiacriticalSymbol.clear(); } @@ -87,8 +76,10 @@ namespace NSDocxRenderer if (m_bIsDeleteTextClipPage) { // удалим все линии, которые выходят за границы страницы - for (const auto &pLine : m_arTextLine) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { + auto pLine = m_arTextLine[i]; + if (pLine->m_dTop >= m_dHeight || pLine->m_dBaselinePos <= 0) { pLine->m_bIsNotNecessaryToUse = true; @@ -117,24 +108,24 @@ namespace NSDocxRenderer if (x1 <= x2) { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; + pImage->m_dLeft = x1; + pImage->m_dWidth = x2 - x1; } else { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; + pImage->m_dLeft = x2; + pImage->m_dWidth = x1 - x2; } if (y1 <= y2) { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; + pImage->m_dTop = y1; + pImage->m_dHeight = y2 - y1; } else { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; + pImage->m_dTop = y2; + pImage->m_dHeight = y1 - y2; } pImage->m_dRotate = 0.0; @@ -158,24 +149,24 @@ namespace NSDocxRenderer if (x1 <= x2) { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; + pImage->m_dLeft = x1; + pImage->m_dWidth = x2 - x1; } else { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; + pImage->m_dLeft = x2; + pImage->m_dWidth = x1 - x2; } if (y1 <= y2) { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; + pImage->m_dTop = y1; + pImage->m_dHeight = y2 - y1; } else { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; + pImage->m_dTop = y2; + pImage->m_dHeight = y1 - y2; } pImage->m_dRotate = dRotation; @@ -324,10 +315,10 @@ namespace NSDocxRenderer bool bIsPath = ((nullptr == pGids) && !bIsPDFAnalyzer) ? false : true; - m_oFontManager.LoadFont(0, !bIsPath); + m_pFontManager->LoadFont(0, !bIsPath); if (!bIsPath) - m_oFontManager.GenerateFontName2(oText); + m_pFontManager->GenerateFontName2(oText); if (fabs(dTextW) < 0.01 || (dTextW > 10)) { @@ -338,29 +329,28 @@ namespace NSDocxRenderer if (nullptr != pGids) { - m_oFontManager.SetStringGid(1); - m_oFontManager.MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + m_pFontManager->SetStringGid(1); + m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); } else { // такого быть не должно (только из xps) - m_oFontManager.SetStringGid(0); - m_oFontManager.MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + m_pFontManager->SetStringGid(0); + m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); } dTextW = _w; } double dBaseLinePos = dTextY + fBaseLineOffset; - dTextH = m_oFontManager.GetFontHeight(); + dTextH = m_pFontManager->GetFontHeight(); auto pCont = new CContText(&m_oFontManagerLight, m_pStyleManager); pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dLastX = dTextX; - pCont->m_dTop = dBaseLinePos - dTextH - m_oFontManager.m_oFont.m_dBaselineOffset; + pCont->m_dTop = dBaseLinePos - dTextH - m_pFontManager->m_oFont.m_dBaselineOffset; pCont->m_dWidth = dTextW; pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; @@ -368,18 +358,18 @@ namespace NSDocxRenderer pCont->m_oText = oText; //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = m_oFontManager.m_oFont.m_oFont; + m_pStyleManager->m_pCurrentStyle->m_oFont = m_pFontManager->m_oFont.m_oFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; if (!bIsPath) { - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_oFontManager.m_strCurrentPickFont; - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_oFontManager.m_lCurrentPictFontStyle; + m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontManager->m_strCurrentPickFont; + m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_pFontManager->m_lCurrentPictFontStyle; } pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - pCont->m_dSpaceWidthMM = m_oFontManager.m_dSpaceWidthMM; + pCont->m_dSpaceWidthMM = m_pFontManager->m_dSpaceWidthMM; if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) { @@ -387,8 +377,50 @@ namespace NSDocxRenderer } else { - m_arSymbol.push_back(pCont); + AddContToTextLine(pCont); + } + } + + void CPage::AddContToTextLine(CContText *pCont) + { + if (nullptr == m_pCurrentLine) + { + auto pLine = new CTextLine(); + m_pCurrentLine = pLine; + m_pCurrentLine->AddContent(pCont); + m_arTextLine.push_back(pLine); + return; + } + + if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine->AddContent(pCont); + return; } + + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine = m_arTextLine[i]; + m_pCurrentLine->AddContent(pCont); + return; + } + } + + auto pLine = new CTextLine(); + m_pCurrentLine = pLine; + m_pCurrentLine->AddContent(pCont); + m_arTextLine.push_back(pLine); + } + + void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) + { + AnalyzeCollectedShapes(); + AnalyzeCollectedTextLines(); + BuildByType(); + ToXml(oWriter); + WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } void CPage::AnalyzeCollectedShapes() @@ -417,17 +449,20 @@ namespace NSDocxRenderer for (size_t j = i+1; j < m_arShapes.size(); ++j) { auto pNextShape = m_arShapes[j]; - bool bIf1 = !pNextShape->m_bIsNotNecessaryToUse; - bool bIf2 = pCurrShape->IsCorrelated(pNextShape); + if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossing(pNextShape)) + { + continue; + } + bool bIf1 = pCurrShape->IsCorrelated(pNextShape); //note довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры - bool bIf3 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); - bool bIf4 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); + bool bIf2 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); + bool bIf3 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); //линия должна быть одного размера по высоте - bool bIf5 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; + bool bIf4 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; //все должно быть на одной линии - bool bIf6 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; + bool bIf5 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; - if (bIf1 && bIf2 && (bIf3 || bIf4) && bIf5 && bIf6) //все должно быть на одной линии + if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) //все должно быть на одной линии { arCurrShapes.push_back(pNextShape); } @@ -464,109 +499,172 @@ namespace NSDocxRenderer } } - void CPage::AnalyzeCollectedSymbols() + void CPage::AnalyzeCollectedTextLines() { - for (size_t i = 0; i < m_arSymbol.size(); i++) + SortElements(m_arTextLine); + for (size_t i = 0; i < m_arTextLine.size(); ++i) { - auto pCont = m_arSymbol[i]; + m_arTextLine[i]->SortConts(); + } + + AnalyzeCollectedConts(); + + DetermineStrikeoutsUnderlinesHighlights(); - if (pCont->m_bIsNotNecessaryToUse || - m_arSymbol.size() < 2 || - i >= m_arSymbol.size() - 1) + AddDiacriticalSymbols(); + + MergeLinesByVertAlignType(); + + BuildLines(); + + DetermineDominantGraphics(); + + DeleteTextClipPage(); + } + + void CPage::AnalyzeCollectedConts() + { + for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) + { + auto pCurrLine = m_arTextLine[uCurrLineIndex]; + + if (pCurrLine->m_bIsNotNecessaryToUse) { continue; } - for (size_t j = i + 1; j < m_arSymbol.size(); j++) + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) { - auto pNext = m_arSymbol[j]; + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - if (pNext->m_bIsNotNecessaryToUse) + if (pCurrCont->m_bIsNotNecessaryToUse) { continue; } - eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pNext); - eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pNext); - - if (pCont->IsThereAreFontEffects(pNext, eVType, eHType)) + for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? + uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLine.size(); ++uNextLineIndex) { - if (pCont->m_bIsNotNecessaryToUse) - { - break; - } - else + auto pNextLine = m_arTextLine[uNextLineIndex]; + + if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossing(pNextLine)) { continue; } - } - if (pCont->IsVertAlignTypeBetweenConts(pNext, eVType, eHType)) - { - continue; - } + for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; + uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) + { + auto pNextCont = pNextLine->m_arConts[uNextContIndex]; - if (pCont->IsDuplicate(pNext, eVType)) - { - continue; + if (pNextCont->m_bIsNotNecessaryToUse) + { + continue; + } + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont); + + if (pCurrCont->IsThereAreFontEffects(pNextCont, eVType, eHType)) + { + pCurrLine->CheckLineToNecessaryToUse(); + break; + } + + if (pCurrCont->IsVertAlignTypeBetweenConts(pNextCont, eVType, eHType)) + { + pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); + pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); + if ((pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript && + pNextLine->m_eVertAlignType == eVertAlignType::vatBase) || + (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase && + pNextLine->m_eVertAlignType == eVertAlignType::vatSubscript)) + { + pCurrLine->m_pLine = pNextLine; + } + break; + } + + if (pCurrCont->IsDuplicate(pNextCont, eVType)) + { + break; + } + } + + pNextLine->CheckLineToNecessaryToUse(); } } } - - DetermineStrikeoutsUnderlinesHighlights(); } void CPage::DetermineStrikeoutsUnderlinesHighlights() { - for (const auto &pShape : m_arShapes) + for (size_t i = 0; i < m_arShapes.size(); ++i) { + auto pShape = m_arShapes[i]; + if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || pShape->m_bIsNotNecessaryToUse) { continue; } - for (const auto &pCont : m_arSymbol) + for (size_t j = 0; j < m_arTextLine.size(); ++j) { - if (pCont->m_bIsNotNecessaryToUse) + auto pCurrLine = m_arTextLine[j]; + + if (pCurrLine->m_bIsNotNecessaryToUse || + (pCurrLine->AreObjectsNoCrossing(pShape) && + (pCurrLine->m_dTop > pShape->m_dBaselinePos || + pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) { continue; } - eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pShape); - eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pShape); + for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) + { + auto pCurrCont = pCurrLine->m_arConts[k]; - bool bIf1 = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; - bool bIf2 = IsLineCrossingText(pShape, pCont, eHType); - bool bIf3 = IsLineBelowText(pShape, pCont, eHType); - bool bIf4 = IsItHighlightingBackground(pShape, pCont, eHType); + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } - if (bIf1 && (bIf2 || bIf3 || bIf4)) - { - pShape->m_bIsNotNecessaryToUse = true; - } + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); - if (!bIf1) - { - bool bIf1 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf2 = pCont->m_bIsShadowPresent && pCont->m_bIsOutlinePresent; - bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; - bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + bool bIf1 = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; + bool bIf2 = IsLineCrossingText(pShape, pCurrCont, eHType); + bool bIf3 = IsLineBelowText(pShape, pCurrCont, eHType); + bool bIf4 = IsItHighlightingBackground(pShape, pCurrCont, eHType); - if ((bIf1 || bIf2) && bIf3 && (bIf4 || bIf5)) + if (bIf1 && (bIf2 || bIf3 || bIf4)) { - if (!bIf2) + pShape->m_bIsNotNecessaryToUse = true; + } + + if (!bIf1) + { + bool bIf1 = pCurrCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; + bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; + bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + + if ((bIf1 || bIf2) && bIf3 && (bIf4 || bIf5)) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + if (!bIf2) + { + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCurrCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; + pCurrCont->m_pFontStyle = m_pStyleManager->GetStyle(); - pCont->m_bIsShadowPresent = true; - pCont->m_bIsOutlinePresent = true; - } + pCurrCont->m_bIsShadowPresent = true; + pCurrCont->m_bIsOutlinePresent = true; + } - pShape->m_bIsNotNecessaryToUse = true; + pShape->m_bIsNotNecessaryToUse = true; + } } } } @@ -664,363 +762,210 @@ namespace NSDocxRenderer return false; } - void CPage::AnalyzeLines() + void CPage::AddDiacriticalSymbols() { - BuildLines(); - - SortElements(m_arTextLine); - - MergeLinesByVertAlignType(); - - for (auto pLine : m_arTextLine) - { - if (pLine->m_bIsNotNecessaryToUse) - { - continue; - } - - pLine->SortConts(); - pLine->CalculateWidth(); - pLine->MergeConts(); - } - - if (m_eTextAssociationType == tatPlainParagraph || - m_eTextAssociationType == tatParagraphToShape || - m_eTextAssociationType == tatShapeLine || - m_eTextAssociationType == tatPlainLine) + if (m_arDiacriticalSymbol.empty()) { - DetermineDominantGraphics(); + return; } - DeleteTextClipPage(); - } - - void CPage::BuildLines() - { - //note Элементы в m_arSymbol в случайных местах страницы - for (const auto &pCont : m_arSymbol) + for (size_t i = 0; i < m_arDiacriticalSymbol.size(); ++i) { - if (pCont->m_bIsNotNecessaryToUse) + auto pDiacriticalCont = m_arDiacriticalSymbol[i]; + if (pDiacriticalCont->m_bIsNotNecessaryToUse) { continue; } - SelectCurrentLine(pCont); - AddDiacriticalSymbols(pCont); - - CContText* pLastCont = nullptr; - size_t nCountConts = m_pCurrentLine->m_arConts.size(); - if (nCountConts != 0) - pLastCont = m_pCurrentLine->m_arConts.back(); - - if (nullptr == pLastCont) - { - // первое слово в линии - auto pNewCont = new CContText(*pCont); - - pNewCont->m_dLastX = pCont->m_dLeft; + bool isBreak = false; - m_pCurrentLine->AddCont(pNewCont); - m_dLastTextX = pNewCont->m_dLeft; - m_dLastTextY = pNewCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - - CollectDublicateLines(pCont); - continue; - } - - if (pLastCont->IsEqual(pCont)) + for (size_t j = 0; j < m_arTextLine.size(); ++j) { - bool bIsConditionPassed = false; + auto pCurrLine = m_arTextLine[j]; - // настройки одинаковые. теперь смотрим, на расположение - if (fabs(pLastCont->m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) + if (pCurrLine->m_bIsNotNecessaryToUse || + pCurrLine->AreObjectsNoCrossing(pDiacriticalCont)) { - // продолжаем слово - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - else if ((pLastCont->m_dRight < pCont->m_dLeft) && ((pCont->m_dLeft - pLastCont->m_dRight) < pCont->m_dSpaceWidthMM)) - { - // продолжаем слово с пробелом - pLastCont->m_oText += uint32_t(' '); - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - else if (fabs(pCont->m_dBaselinePos - pLastCont->m_dBaselinePos) < 0.01 && - fabs(m_dLastTextY - pLastCont->m_dBaselinePos) < 0.01 && - fabs(m_dLastTextX - pLastCont->m_dLastX) < 0.01) - { - // идет текст подряд, но с расстояниями что-то не так. смотрим - если новый текст идет после предыдущего, но - // просто левее чем предыдущий x + w - то считаем это нормальным. и дописываем слово. корректируя длину - if (pCont->m_dLeft < pLastCont->m_dRight && pCont->m_dLeft > pLastCont->m_dLastX) - { - // продолжаем слово - pLastCont->m_oText += pCont->m_oText; - double dNewW = (pCont->m_dRight - pLastCont->m_dLeft); - if (pLastCont->m_dWidth < dNewW) - pLastCont->m_dWidth = dNewW; - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - // еще одна заглушка на большой пробел - добавляем пробел, потом в линии все разрулится через spacing - else if (pCont->m_dLeft > pLastCont->m_dRight && (pCont->m_dLeft - pLastCont->m_dRight) < 5 && fabs(m_dLastTextX_block - m_dLastTextX) < 0.01) - { - // продолжаем слово с пробелом - pLastCont->m_oText += uint32_t(' '); - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth = (pCont->m_dRight - pLastCont->m_dLeft); - pLastCont->m_dRight = pLastCont->m_dLeft + pLastCont->m_dWidth; - bIsConditionPassed = true; - } - } - - if (bIsConditionPassed) - { - m_dLastTextX = pCont->m_dLeft; - m_dLastTextY = pCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - pLastCont->m_dLastX = pCont->m_dLeft; - if (!pLastCont->m_pCont) - { - pLastCont->m_pCont = pCont->m_pCont; - pLastCont->m_eVertAlignType = pCont->m_eVertAlignType; - } - CollectDublicateLines(pCont); continue; } - } - - // либо пробел большой между словами, либо новый текст левее, либо настройки не те (шрифт, кисть) - // либо все вместе... просто добавл¤ем новое слово - m_pCurrentLine->AddCont(new CContText(*pCont)); - m_dLastTextX = pCont->m_dLeft; - m_dLastTextY = pCont->m_dBaselinePos; - m_dLastTextX_block = m_dLastTextX; - CollectDublicateLines(pCont); - } - } - - void CPage::SelectCurrentLine(const CContText *pCont) - { - if ((nullptr == m_pCurrentLine) || (tatBlockChar == m_eTextAssociationType)) - { - // пустая (в плане текста) страница - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - m_arTextLine.push_back(pLine); - return; - } - - if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - return; - } - - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentLine = m_arTextLine[i]; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - return; - } - } - // линия не нашлась - не беда - создадим новую - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->m_dBaselinePos = pCont->m_dBaselinePos; - if (m_pCurrentLine->m_eVertAlignType == eVertAlignType::vatUnknown && - pCont->m_eVertAlignType != eVertAlignType::vatUnknown) - { - //note считаем, что линия может иметь только один тип - m_pCurrentLine->m_eVertAlignType = pCont->m_eVertAlignType; - } - m_arTextLine.push_back(pLine); - return; - } - - void CPage::AddDiacriticalSymbols(CContText *pCont) - { - if (!m_arDiacriticalSymbol.empty()) - { - for (auto pDiacriticalCont : m_arDiacriticalSymbol) - { - if (pDiacriticalCont->m_bIsNotNecessaryToUse) + for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) { - continue; - } - - eVerticalCrossingType eVType = pCont->GetVerticalCrossingType(pDiacriticalCont); - eHorizontalCrossingType eHType = pCont->GetHorizontalCrossingType(pDiacriticalCont); + auto pCurrCont = pCurrLine->m_arConts[k]; - if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; - bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; - bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; - bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; - - bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || - eVType == eVerticalCrossingType::vctCurrentAboveNext; - bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; - bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; - - if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) + if (pCurrCont->m_bIsNotNecessaryToUse) { - pCont->m_oText += pDiacriticalCont->m_oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; + continue; } - else if (bIf3 && bIf7) + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pDiacriticalCont); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pDiacriticalCont); + + if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) { - NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); - oText += pCont->m_oText; - pCont->m_oText = oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; + bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; + bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; + + bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || + eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; + bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; + + if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) + { + pCurrCont->m_oText += pDiacriticalCont->m_oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + isBreak = true; + break; + } + else if (bIf3 && bIf7) + { + NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); + oText += pCurrCont->m_oText; + pCurrCont->m_oText = oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + isBreak = true; + break; + } } } + if (isBreak) + { + break; + } } } } - void CPage::CollectDublicateLines(const CContText *pCont) - { - if (pCont->m_iNumDuplicates > 0) - { - //todo обработать случаи когда в одной строке разное количество разных символов-дубликатов - m_pCurrentLine->m_iNumDuplicates = std::max(m_pCurrentLine->m_iNumDuplicates, pCont->m_iNumDuplicates); - } - } - void CPage::MergeLinesByVertAlignType() { - for (size_t i = 0; i < m_arTextLine.size(); i++) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { - auto pLine = m_arTextLine[i]; + auto pCurrLine = m_arTextLine[i]; - if (pLine->m_bIsNotNecessaryToUse) + if (pCurrLine->m_bIsNotNecessaryToUse) { continue; } - if (pLine->m_eVertAlignType != eVertAlignType::vatUnknown) + if (pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript) { - if (i > m_arTextLine.size() - 2) + auto pBaseLine = pCurrLine->m_pLine; + if (pBaseLine) { - continue; - } + double dFontSize = 0; - auto pLineNext = GetNextTextLine(i); - double dFontSize = 0;; - - if (pLine->m_eVertAlignType == eVertAlignType::vatSuperscript && - pLineNext->m_eVertAlignType == eVertAlignType::vatBase) - { - pLine->m_bIsNotNecessaryToUse = true; - for (const auto &pCont : pLine->m_arConts) + for (size_t j = 0; j < pBaseLine->m_arConts.size(); ++j) { + auto pCont = pBaseLine->m_arConts[j]; if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) { continue; } - dFontSize = pCont->m_pCont->m_pFontStyle->m_oFont.Size; + dFontSize = pCont->m_pFontStyle->m_oFont.Size; break; } - for (const auto &pCont : pLine->m_arConts) + for (auto pCont : pCurrLine->m_arConts) { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - if (pLineNext->m_dLeft > pCont->m_dLeft) + if (pBaseLine->m_dLeft > pCont->m_dLeft) { - pLineNext->m_dLeft = pCont->m_dLeft; + pBaseLine->m_dLeft = pCont->m_dLeft; } - if (pLineNext->m_dRight < pCont->m_dRight) + if (pBaseLine->m_dRight < pCont->m_dRight) { - pLineNext->m_dRight = pCont->m_dRight; + pBaseLine->m_dRight = pCont->m_dRight; } - pLineNext->m_arConts.push_back(new CContText(*pCont)); + pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; + + pBaseLine->m_arConts.push_back(std::move(pCont)); } + SortElements(pBaseLine->m_arConts); + pCurrLine->m_bIsNotNecessaryToUse = true; } - else if (pLine->m_eVertAlignType == eVertAlignType::vatBase && - pLineNext->m_eVertAlignType == eVertAlignType::vatSubscript) + } + else if (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase) + { + auto pSubLine = pCurrLine->m_pLine; + if (pSubLine) { - pLineNext->m_bIsNotNecessaryToUse = true; - for (const auto &pCont : pLineNext->m_arConts) + double dFontSize = 0; + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) { + auto pCont = pCurrLine->m_arConts[j]; if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) { continue; } - dFontSize = pCont->m_pCont->m_pFontStyle->m_oFont.Size; + dFontSize = pCont->m_pFontStyle->m_oFont.Size; break; } - for (const auto &pCont : pLineNext->m_arConts) + for (auto pCont : pSubLine->m_arConts) { - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - if (pLine->m_dLeft > pCont->m_dLeft) + if (pCurrLine->m_dLeft > pCont->m_dLeft) { - pLine->m_dLeft = pCont->m_dLeft; + pCurrLine->m_dLeft = pCont->m_dLeft; } - if (pLine->m_dRight < pCont->m_dRight) + if (pCurrLine->m_dRight < pCont->m_dRight) { - pLine->m_dRight = pCont->m_dRight; + pCurrLine->m_dRight = pCont->m_dRight; } - pLine->m_arConts.push_back(new CContText(*pCont)); + pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; + + pCurrLine->m_arConts.push_back(std::move(pCont)); } + SortElements(pCurrLine->m_arConts); + pSubLine->m_bIsNotNecessaryToUse = true; + } + } + } + } + + void CPage::BuildLines() + { + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + auto pCurrLine = m_arTextLine[i]; + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto pCurrCont = pCurrLine->m_arConts[j]; + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCurrCont->m_iNumDuplicates > 0) + { + pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); } } + + pCurrLine->MergeConts(); } } @@ -1028,15 +973,17 @@ namespace NSDocxRenderer { CShape* pDominantShape = nullptr; - for (const auto &pLine : m_arTextLine) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { + auto pLine = m_arTextLine[i]; if (pLine->m_bIsNotNecessaryToUse) { continue; } - for (const auto &pCont : pLine->m_arConts) + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) { + auto pCont = pLine->m_arConts[j]; if (pCont->m_bIsNotNecessaryToUse) { continue; @@ -1092,8 +1039,9 @@ namespace NSDocxRenderer void CPage::BuildByTypeBlockChar() { - for (const auto &pLine : m_arTextLine) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { + auto pLine = m_arTextLine[i]; auto pParagraph = new CParagraph(m_eTextAssociationType); pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; @@ -1153,8 +1101,9 @@ namespace NSDocxRenderer Merge(c_dSTANDART_STRING_HEIGHT_MM / 3); double dPreviousStringBaseline = 0; - for (const auto &pLine : m_arTextLine) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { + auto pLine = m_arTextLine[i]; double dBeforeSpacing = pLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pLine->m_dBaselinePos; double dRight = pLine->CalculateRightBorder(m_dWidth); @@ -1165,9 +1114,9 @@ namespace NSDocxRenderer void CPage::BuildByTypeShapeLine() { - for (const auto &pLine : m_arTextLine) + for (size_t i = 0; i < m_arTextLine.size(); ++i) { - CreateSingleLineShape(pLine); + CreateSingleLineShape(m_arTextLine[i]); } } @@ -1502,7 +1451,7 @@ namespace NSDocxRenderer { CTextLine* pLine = nullptr; - for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLine.size(); nIndex++) + for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLine.size(); ++nIndex) { pLine = m_arTextLine[nIndex]; bool bIf1 = pLine->m_bIsNotNecessaryToUse; @@ -1536,7 +1485,7 @@ namespace NSDocxRenderer if (nCurrentIndex) { - for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; nIndex--) + for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) { pLine = m_arTextLine[nIndex]; @@ -1708,8 +1657,9 @@ namespace NSDocxRenderer void CPage::CorrectionParagraphsInShapes() { - for (auto pShape : m_arShapes) + for (size_t i = 0; i < m_arShapes.size(); ++i) { + auto pShape = m_arShapes[i]; if (pShape->m_bIsNotNecessaryToUse || pShape->m_eType != CShape::eShapeType::stTextBox || pShape->m_arParagraphs.empty()) @@ -1717,8 +1667,9 @@ namespace NSDocxRenderer continue; } - for (auto pParagraph : pShape->m_arParagraphs) + for (size_t j = 0; j < pShape->m_arParagraphs.size(); ++j) { + auto pParagraph = pShape->m_arParagraphs[j]; if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) { pParagraph->m_bIsNeedFirstLineIndent = true; @@ -1761,7 +1712,7 @@ namespace NSDocxRenderer //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст oWriter.WriteString(L""); - for (size_t i = 0; i < m_arImages.size(); i++) + for (size_t i = 0; i < m_arImages.size(); ++i) { m_arImages[i]->ToXml(oWriter); } @@ -1776,7 +1727,7 @@ namespace NSDocxRenderer //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст oWriter.WriteString(L""); - for (size_t i = 0; i < m_arShapes.size(); i++) + for (size_t i = 0; i < m_arShapes.size(); ++i) { m_arShapes[i]->ToXml(oWriter); } @@ -1784,7 +1735,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - for (size_t i = 0; i < m_arParagraphs.size(); i++) + for (size_t i = 0; i < m_arParagraphs.size(); ++i) { m_arParagraphs[i]->ToXml(oWriter); } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index e3f794f50b6..ba0db43c5af 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -20,6 +20,7 @@ namespace NSDocxRenderer Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; CStyleManager* m_pStyleManager {nullptr}; + CFontManager* m_pFontManager {nullptr}; CVectorGraphics m_oVector; double m_dWidth {0.0}; @@ -28,7 +29,6 @@ namespace NSDocxRenderer LONG m_lCurrentCommand {0}; std::vector m_arImages; - std::vector m_arSymbol; std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; std::vector m_arShapes; @@ -36,23 +36,18 @@ namespace NSDocxRenderer CTextLine* m_pCurrentLine {nullptr}; - CFontManager m_oFontManager; CFontManagerLight m_oFontManagerLight; TextAssociationType m_eTextAssociationType {tatPlainLine}; bool m_bIsDeleteTextClipPage {true}; - double m_dLastTextX {-1}; - double m_dLastTextY {-1}; - double m_dLastTextX_block {-1}; - public: CPage(NSFonts::IApplicationFonts* pFonts); ~CPage(); void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager); + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager* pFontManager); void Clear(); void ClearImages(); @@ -82,23 +77,26 @@ namespace NSDocxRenderer void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); + void AddContToTextLine(CContText *pCont); + + void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); void AnalyzeCollectedShapes(); void DetermineLinesType(); //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить - void AnalyzeCollectedSymbols(); + void AnalyzeCollectedTextLines(); + void AnalyzeCollectedConts(); void DetermineStrikeoutsUnderlinesHighlights(); bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + void AddDiacriticalSymbols(); //набивается содержимым вектор m_arTextLine void AnalyzeLines(); void BuildLines(); void AddDiacriticalSymbols(CContText* pCont); - void SelectCurrentLine(const CContText* pCont); - void CollectDublicateLines(const CContText *pCont); void MergeLinesByVertAlignType(); void DetermineDominantGraphics(); diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index e470dc4a174..2a7eb72c962 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -4,133 +4,172 @@ namespace NSDocxRenderer { - CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) + CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) + { + if (this == &oSrc) { - if (this == &oSrc) - { - return *this; - } + return *this; + } - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; + m_eType = oSrc.m_eType; + m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - m_dLeft = oSrc.m_dLeft; - m_dTop = oSrc.m_dTop; - m_dWidth = oSrc.m_dWidth; - m_dHeight = oSrc.m_dHeight; - m_dBaselinePos = oSrc.m_dBaselinePos; - m_dRight = oSrc.m_dRight; + m_dLeft = oSrc.m_dLeft; + m_dTop = oSrc.m_dTop; + m_dWidth = oSrc.m_dWidth; + m_dHeight = oSrc.m_dHeight; + m_dBaselinePos = oSrc.m_dBaselinePos; + m_dRight = oSrc.m_dRight; - return *this; + return *this; + } + + bool CBaseItem::IsBigger(const CBaseItem* oSrc) + { + return (m_dLeft > oSrc->m_dLeft) ? true : false; + } + + bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) + { + return (m_dLeft >= oSrc->m_dLeft) ? true : false; + } + + void CBaseItem::AddContent(CBaseItem* pObj) + { + m_dBaselinePos = std::max(m_dBaselinePos, pObj->m_dBaselinePos); + + if ((pObj->m_dLeft < m_dLeft) || (pObj->m_dLeft > 0 && m_dLeft == 0.0)) + { + m_dLeft = pObj->m_dLeft; } - bool CBaseItem::IsBigger(const CBaseItem* oSrc) + if ((pObj->m_dRight > m_dRight) || (pObj->m_dRight > 0 && m_dRight == 0.0)) { - return (m_dLeft > oSrc->m_dLeft) ? true : false; + m_dRight = pObj->m_dRight; } - bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) + if (m_dTop > pObj->m_dTop || m_dTop == 0.0) { - return (m_dLeft >= oSrc->m_dLeft) ? true : false; + m_dTop = pObj->m_dTop; } - eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) - { - if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentInsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentOutsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop) - { - return eVerticalCrossingType::vctCurrentBelowNext; - } - else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentAboveNext; - } - else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && - m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) - { - return eVerticalCrossingType::vctDublicate; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && - fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopAndBottomBordersMatch; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopBorderMatch; - } - else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctBottomBorderMatch; - } - else if (m_dBaselinePos < oSrc->m_dTop) - { - return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - } - else - { - return eVerticalCrossingType::vctUnknown; - } + m_dWidth = m_dRight - m_dLeft; + m_dHeight = m_dBaselinePos - m_dTop; + } + + eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) + { + if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentInsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentOutsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && + (m_dBaselinePos >= oSrc->m_dTop || fabs(m_dBaselinePos - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && + (m_dTop <= oSrc->m_dBaselinePos || fabs(m_dTop - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentBelowNext; + } + else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && + m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) + { + return eVerticalCrossingType::vctDublicate; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopBorderMatch; + } + else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctBottomBorderMatch; + } + else if (m_dBaselinePos < oSrc->m_dTop) + { + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; } + else + { + return eVerticalCrossingType::vctUnknown; + } + } - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) - { - if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentInsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentOutsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight >= oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft <= oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentRightOfNext; - } - else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && - m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) - { - return eHorizontalCrossingType::hctDublicate; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM && - fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftAndRightBordersMatch; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftBorderMatch; - } - else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctRightBorderMatch; - } - else if (m_dRight < oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - } - else - { - return eHorizontalCrossingType::hctUnknown; - } + eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) + { + if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentInsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentOutsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && + (m_dRight >= oSrc->m_dLeft || fabs(m_dRight - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && + (m_dLeft <= oSrc->m_dRight || fabs(m_dLeft - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentRightOfNext; + } + else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && + m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) + { + return eHorizontalCrossingType::hctDublicate; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftAndRightBordersMatch; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftBorderMatch; + } + else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctRightBorderMatch; + } + else if (m_dRight < oSrc->m_dLeft) + { + return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + } + else + { + return eHorizontalCrossingType::hctUnknown; + } + } + + bool CBaseItem::AreObjectsNoCrossing(const CBaseItem* pLine) + { + eVerticalCrossingType eVType = this->GetVerticalCrossingType(pLine); + + if (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + return true; } + return false; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index e948362baef..f6ac05851aa 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -63,6 +63,7 @@ namespace NSDocxRenderer public: CBaseItem(const ElemType& eType): m_eType(eType) {} virtual ~CBaseItem() {} + virtual void Clear() = 0; CBaseItem& operator=(const CBaseItem& oSrc); @@ -84,10 +85,12 @@ namespace NSDocxRenderer virtual bool IsBigger(const CBaseItem* oSrc); virtual bool IsBiggerOrEqual(const CBaseItem* oSrc); + virtual void AddContent(CBaseItem* pObj); virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - virtual void Clear() = 0; eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); + + bool AreObjectsNoCrossing(const CBaseItem* oSrc); }; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index b6f3201b22e..0730ac3706b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -30,6 +30,50 @@ namespace NSDocxRenderer return 0; } + CContText& CContText::operator= (const CContText& rCont) + { + if (this == &rCont) + { + return *this; + } + + CBaseItem::operator=(rCont); + + m_pFontStyle = rCont.m_pFontStyle; + + m_bIsStrikeoutPresent = rCont.m_bIsStrikeoutPresent; + m_bIsDoubleStrikeout = rCont.m_bIsDoubleStrikeout; + + m_bIsHighlightPresent = rCont.m_bIsHighlightPresent; + m_lHighlightColor = rCont.m_lHighlightColor; + + m_bIsUnderlinePresent = rCont.m_bIsUnderlinePresent; + m_eUnderlineType = rCont.m_eUnderlineType; + m_lUnderlineColor = rCont.m_lUnderlineColor; + + m_bIsShadowPresent = rCont.m_bIsShadowPresent; + m_bIsOutlinePresent = rCont.m_bIsOutlinePresent; + m_bIsEmbossPresent = rCont.m_bIsEmbossPresent; + m_bIsEngravePresent = rCont.m_bIsEngravePresent; + + m_oText =rCont.m_oText; + + m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; + m_bSpaceIsNotNeeded = rCont.m_bSpaceIsNotNeeded; + + m_eVertAlignType = rCont.m_eVertAlignType; + + m_pManagerLight = rCont.m_pManagerLight; + m_pStyleManager = rCont.m_pStyleManager; + + m_pShape = rCont.m_pShape; + m_pCont = rCont.m_pCont; + + m_iNumDuplicates = rCont.m_iNumDuplicates; + + return *this; + } + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) { if (m_bIsNotNecessaryToUse) @@ -49,7 +93,7 @@ namespace NSDocxRenderer if (!m_pFontStyle->m_strPickFontName.empty() && !m_oText.empty()) { if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) + m_eVertAlignType != eVertAlignType::vatSuperscript) { // нужно перемерять... m_pManagerLight->LoadFont(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, false); @@ -271,7 +315,7 @@ namespace NSDocxRenderer bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && - bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) + bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) { return true; } @@ -317,7 +361,7 @@ namespace NSDocxRenderer bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) { if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) + m_oText == pCont->m_oText) { pCont->m_bIsNotNecessaryToUse = true; m_iNumDuplicates++; @@ -329,8 +373,8 @@ namespace NSDocxRenderer bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) { //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже //Условие пересечения по горизонтали bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее @@ -349,22 +393,22 @@ namespace NSDocxRenderer //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. if (bIf5 && bIf6) { - if (m_bIsEmbossPresent && bIf11) + if (m_bIsEmbossPresent && bIf12) { - if (bIf2 && bIf4) + if (bIf1 && bIf3) { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; + m_bIsEmbossPresent = true; + pCont->m_bIsNotNecessaryToUse = true; return true; } } - if (m_bIsEngravePresent && bIf9) + if (m_bIsEngravePresent && bIf10) { - if (bIf2 && bIf4) + if (bIf1 && bIf3) { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; + m_bIsEngravePresent = true; + pCont->m_bIsNotNecessaryToUse = true; return true; } } @@ -384,17 +428,19 @@ namespace NSDocxRenderer } //Emboss - else if (bIf2 && bIf4 && bIf10) + //Первый проход + //c_iBlackColor -> c_iBlackColor -> c_iGreyColor2 + else if (bIf1 && bIf3 && bIf9) { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; + pCont->m_bIsEmbossPresent = true; + m_bIsNotNecessaryToUse = true; return true; } //Engrave - else if (bIf2 && bIf4 && bIf12) + else if (bIf1 && bIf3 && bIf11) { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; + pCont->m_bIsEngravePresent = true; + m_bIsNotNecessaryToUse = true; return true; } } @@ -404,9 +450,9 @@ namespace NSDocxRenderer bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) { //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentBelowNext || + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //Условие пересечения по горизонтали bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && @@ -463,6 +509,6 @@ namespace NSDocxRenderer double CContText::CalculateThinSpace() { - return m_dSpaceWidthMM; + return m_dSpaceWidthMM * 0.7; } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 978e443f4d6..da10e96b8e4 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -41,7 +41,6 @@ namespace NSDocxRenderer NSStringUtils::CStringUTF32 m_oText; - double m_dLastX {0}; double m_dSpaceWidthMM {0}; bool m_bSpaceIsNotNeeded {false}; @@ -57,22 +56,21 @@ namespace NSDocxRenderer public: CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); - ~CContText(); + virtual ~CContText(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final {}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void Clear() override final; + CContText& operator= (const CContText& rCont); double GetIntersect(const CContText* pCont) const; - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void AddWideSpaceToXml(double dSpacingMM, NSStringUtils::CStringBuilder& oWriter, bool bIsNeedSaveFormat = false); bool IsEqual(const CContText* pCont); - UINT GetNumberOfFeatures(); - bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); diff --git a/DocxRenderer/src/logic/elements/OldShape.cpp b/DocxRenderer/src/logic/elements/OldShape.cpp index 3e6c44565c9..1148fb8535c 100644 --- a/DocxRenderer/src/logic/elements/OldShape.cpp +++ b/DocxRenderer/src/logic/elements/OldShape.cpp @@ -242,9 +242,9 @@ namespace NSDocxRenderer { oWriter.WriteString(L""); - for (const auto& pParagraph : m_arParagraphs) + for (size_t i = 0; i < m_arParagraphs.size(); ++i) { - pParagraph->ToXml(oWriter); + m_arParagraphs[i]->ToXml(oWriter); } oWriter.WriteString(L""); } diff --git a/DocxRenderer/src/logic/elements/OldShape.h b/DocxRenderer/src/logic/elements/OldShape.h index 6fd6f520783..b3d09091097 100644 --- a/DocxRenderer/src/logic/elements/OldShape.h +++ b/DocxRenderer/src/logic/elements/OldShape.h @@ -32,12 +32,13 @@ namespace NSDocxRenderer public: COldShape(); virtual ~COldShape(); - void Clear() override final; + virtual void Clear() override final; + + virtual void AddContent(CBaseItem* pObj) override final{}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); void WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; }; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 3f3e5a84498..f09f6d8663f 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -148,9 +148,9 @@ namespace NSDocxRenderer oWriter.WriteString(L""); - for(const auto &pLine : m_arLines) + for(size_t i = 0; i < m_arLines.size(); ++i) { - pLine->ToXml(oWriter); + m_arLines[i]->ToXml(oWriter); } oWriter.WriteString(L""); @@ -163,12 +163,15 @@ namespace NSDocxRenderer return; } - for(const auto &pLine : m_arLines) + + for(size_t i = 0; i < m_arLines.size(); ++i) { + auto pLine = m_arLines[i]; if (pLine->m_pDominantShape) { - for (const auto &pCont : pLine->m_arConts) + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) { + auto pCont = pLine->m_arConts[j]; if (m_lColorOfShadingFill == pCont->m_lHighlightColor) { pCont->m_bIsHighlightPresent = false; @@ -182,7 +185,7 @@ namespace NSDocxRenderer { auto pLine = m_arLines.front(); - for(size_t i = 1; i < m_arLines.size(); i++) + for(size_t i = 1; i < m_arLines.size(); ++i) { auto pLastCont = pLine->m_arConts.back(); size_t iNumConts = pLine->m_arConts.size() - 1; @@ -212,8 +215,9 @@ namespace NSDocxRenderer pCont->m_bIsNotNecessaryToUse = true; } - for (const auto &pCont : pNext->m_arConts) + for (size_t j = 0; j < pNext->m_arConts.size(); ++j) { + auto pCont = pNext->m_arConts[j]; if (!pCont->m_bIsNotNecessaryToUse) { pLine->m_arConts.push_back(pCont); diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index e3086b17d42..493f608767e 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -58,9 +58,10 @@ namespace NSDocxRenderer public: CParagraph(const TextAssociationType& eType); virtual ~CParagraph(); - void Clear() override final; + virtual void Clear() override final; - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void AddContent(CBaseItem* pObj) override final{}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void RemoveHighlightColor(); diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 17478339afa..36cf602afea 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -887,7 +887,7 @@ namespace NSDocxRenderer { oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php oWriter.WriteString(L""); - for (size_t i = 0; i < m_arParagraphs.size(); i++) + for (size_t i = 0; i < m_arParagraphs.size(); ++i) { m_arParagraphs[i]->ToXml(oWriter); } diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index a96207695ae..1f622128594 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -32,8 +32,8 @@ namespace NSDocxRenderer public: eShapeType m_eType {eShapeType::stUnknown}; std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; + NSStructures::CBrush m_oBrush; + NSStructures::CPen m_oPen; double m_dRotate {0.0}; bool m_bIsNoFill {true}; @@ -56,24 +56,21 @@ namespace NSDocxRenderer public: CShape(); + CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); virtual ~CShape(); virtual void Clear() override final; - CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); + virtual void AddContent(CBaseItem* pObj) override final{}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void GetDataFromVector(const CVectorGraphics& oVector); - void WritePath(const CVectorGraphics& oVector); - void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); - bool IsItFitLine(); bool IsCorrelated(const CShape* pShape); void ChangeGeometryOfDesiredShape(CShape* pShape); - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index e4421b0282e..17946d50b19 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -1,6 +1,5 @@ #include "TextLine.h" #include "../../resources/Constants.h" -#include "../../resources/SortElements.h" #include "../../resources/utils.h" namespace NSDocxRenderer @@ -19,25 +18,16 @@ namespace NSDocxRenderer Clear(); } - void CTextLine::AddCont(CContText *pCont) + void CTextLine::AddContent(CBaseItem *pObj) { - m_dBaselinePos = std::max(m_dBaselinePos, pCont->m_dBaselinePos); + CBaseItem::AddContent(pObj); - if ( ( pCont->m_dLeft > 0 ) && ( ( m_dLeft == 0 ) || ( pCont->m_dLeft < m_dLeft ) ) ) - m_dLeft = pCont->m_dLeft; - - if (m_dHeight < pCont->m_dHeight) - m_dHeight = pCont->m_dHeight; - - if (m_dTop > pCont->m_dTop || m_dTop == 0.0) - m_dTop = pCont->m_dTop; - - if (pCont->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) + if (dynamic_cast(pObj)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) { - m_eVertAlignType = pCont->m_eVertAlignType; + m_eVertAlignType = dynamic_cast(pObj)->m_eVertAlignType; } - m_arConts.push_back(pCont); + m_arConts.push_back(dynamic_cast(pObj)); } bool CTextLine::IsBigger(const CBaseItem* oSrc) @@ -56,6 +46,18 @@ namespace NSDocxRenderer SortElements(m_arConts); } + void CTextLine::CheckLineToNecessaryToUse() + { + for (size_t i = 0; i < m_arConts.size(); ++i) + { + if (!m_arConts[i]->m_bIsNotNecessaryToUse) + { + return; + } + } + m_bIsNotNecessaryToUse = true; + } + void CTextLine::Merge(CTextLine* pLine) { size_t nCount = pLine->m_arConts.size(); @@ -74,9 +76,9 @@ namespace NSDocxRenderer m_dHeight = (pLine->m_dBaselinePos - m_dBaselinePos + m_dHeight); } - for (const auto &pCont : pLine->m_arConts) + for (size_t i = 0; i < pLine->m_arConts.size(); ++i) { - m_arConts.push_back(new CContText(*pCont)); + m_arConts.push_back(new CContText(*m_arConts[i])); } SortConts(); @@ -100,8 +102,9 @@ namespace NSDocxRenderer continue; } - bool bIsEqual = pFirst->IsEqual(pCurrent) && pFirst->m_eVertAlignType == pCurrent->m_eVertAlignType; - bool bIsBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateThinSpace(); + bool bIsEqual = pFirst->IsEqual(pCurrent); + bool bIsBigDelta = ((pFirst->m_dRight < pCurrent->m_dLeft) && ((pCurrent->m_dLeft - pFirst->m_dRight) < pCurrent->m_dSpaceWidthMM)) || + fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace(); bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); if (bIsVeryBigDelta) @@ -112,16 +115,25 @@ namespace NSDocxRenderer } else if (bIsEqual) { - if (bIsBigDelta) + if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) + { + pFirst->m_oText += pCurrent->m_oText; + } + else if (bIsBigDelta) { - pFirst->m_oText += L" "; - pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; + pFirst->m_oText += uint32_t(' '); + pFirst->m_oText += pCurrent->m_oText; } - pFirst->m_oText += pCurrent->m_oText; - pFirst->m_dWidth += pCurrent->m_dWidth; + pFirst->m_dWidth = pCurrent->m_dRight - pFirst->m_dLeft; pFirst->m_dRight = pCurrent->m_dRight; + if (!pFirst->m_pCont) + { + pFirst->m_pCont = pCurrent->m_pCont; + pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; + } + pFirst->m_bSpaceIsNotNeeded = true; pCurrent->m_bIsNotNecessaryToUse = true; } @@ -188,9 +200,10 @@ namespace NSDocxRenderer void CTextLine::SetVertAlignType(const eVertAlignType& oType) { - for (const auto &pCont : m_arConts) + m_eVertAlignType = oType; + for (size_t i = 0; i < m_arConts.size(); ++i) { - pCont->m_eVertAlignType = oType; + m_arConts[i]->m_eVertAlignType = oType; } } @@ -211,9 +224,9 @@ namespace NSDocxRenderer if (nCount <= 1) return false; - for (size_t i = 0; i < nCount; i++) + for (size_t i = 0; i < nCount; ++i) { - for (size_t j = i + 1; j < nCount; j++) + for (size_t j = i + 1; j < nCount; ++j) { if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10) return true; diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 1baa8605af3..60f911818c2 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -21,24 +21,26 @@ namespace NSDocxRenderer eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - const CShape* m_pDominantShape {nullptr}; + CTextLine* m_pLine {nullptr}; + CShape* m_pDominantShape {nullptr}; UINT m_iNumDuplicates {0}; public: CTextLine(); - void Clear() override final; + virtual ~CTextLine(); + virtual void Clear() override final; + virtual bool IsBigger(const CBaseItem* oSrc) override final; + virtual bool IsBiggerOrEqual(const CBaseItem* oSrc) override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - ~CTextLine(); - - void AddCont(CContText *pCont); - bool IsBigger(const CBaseItem* oSrc) override final; - bool IsBiggerOrEqual(const CBaseItem* oSrc) override final; void SortConts(); + void CheckLineToNecessaryToUse(); + //Объединяем слова из двух строк void Merge(CTextLine* pLine); bool IsForceBlock(); - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void MergeConts(); //Вычисляем ширину сложной строки diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 05cfbf5d08d..322375ad665 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -36,12 +36,12 @@ namespace NSDocxRenderer class CFontManager : public CFontManagerBase { public: - NSStructures::CFont* m_pFont {nullptr}; - Aggplus::CMatrix* m_pTransform {nullptr}; - double m_dSpaceWidthMM {0.0}; + NSStructures::CFont* m_pFont {nullptr}; + Aggplus::CMatrix* m_pTransform {nullptr}; + double m_dSpaceWidthMM {0.0}; public: - CFontTable m_oFontTable; + CFontTable m_oFontTable; public: CFontManager(NSFonts::IApplicationFonts* pFonts); diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp index b66ac57a82b..b3c32a99d92 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ b/DocxRenderer/src/logic/managers/FontManagerBase.cpp @@ -471,7 +471,7 @@ namespace NSFontManager BYTE pPanose[10]; m_pManager->GetFile()->GetPanose(pPanose); m_oFont.m_strPANOSE.clear(); - for ( int i = 0; i < 10; i++ ) + for ( int i = 0; i < 10; ++i ) { m_oFont.m_strPANOSE += ToHexString(pPanose[i]); } @@ -482,11 +482,11 @@ namespace NSFontManager // Signature m_oFont.m_arSignature.clear(); - for ( unsigned int i = 0; i < 6; i++ ) + for ( unsigned int i = 0; i < 6; ++i ) { DWORD value = 0; - for ( unsigned long bit = 0; bit < 32; bit++ ) + for ( unsigned long bit = 0; bit < 32; ++bit ) { if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) { @@ -662,7 +662,7 @@ namespace NSFontManager if (sName.length() > 7 && sName.at(6) == '+') { bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; nIndex++) + for (int nIndex = 0; nIndex < 6; ++nIndex) { wchar_t nChar = sName.at(nIndex); if (nChar < 'A' || nChar > 'Z') diff --git a/DocxRenderer/src/logic/managers/StyleManager.cpp b/DocxRenderer/src/logic/managers/StyleManager.cpp index 87c1ca2ef15..e6d9e7977f2 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.cpp +++ b/DocxRenderer/src/logic/managers/StyleManager.cpp @@ -25,11 +25,11 @@ namespace NSDocxRenderer std::shared_ptr CStyleManager::GetStyle() { - for (const auto &pStyle : m_arStyles) + for (size_t i = 0; i < m_arStyles.size(); ++i) { - if (pStyle->IsEqual(m_pCurrentStyle)) + if (m_arStyles[i]->IsEqual(m_pCurrentStyle)) { - return pStyle; + return m_arStyles[i]; } } diff --git a/DocxRenderer/src/resources/SortElements.h b/DocxRenderer/src/resources/SortElements.h deleted file mode 100644 index e696ea09bae..00000000000 --- a/DocxRenderer/src/resources/SortElements.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include - -// у класса T должен быть метод IsBigger, IsBiggerOrEqual -template -void SortElements(std::vector& oArray) -{ - int nSize = (int)oArray.size(); - - // handle 0, 1 and 2 elements - if (nSize <= 1) - return; - if (nSize == 2) - { - if (oArray[0]->IsBigger(oArray[1])) - { - std::swap(oArray[0], oArray[1]); - } - return; - } - - T* tTemp; - - // arrange elements as tree with greater elements appearing first - int nIndex = (nSize >> 1) - 1, nCurr = 0, nNext = 0; - int nLast = nSize - 1; - int nHalf = nSize >> 1; - do - { - // save element at start of chain - tTemp = oArray[nIndex]; - - nCurr = nIndex; - while (nCurr < nHalf) - { - nNext = (nCurr << 1) + 1; - if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext]))) - nNext++; - if (tTemp->IsBiggerOrEqual(oArray[nNext])) - break; - - // promote element in chain - oArray[nCurr] = oArray[nNext]; - nCurr = nNext; - } - - // restore element at end of chain - oArray[nCurr] = tTemp; - } - while (nIndex--); - - // sequentially reduce tree size by removing maximum element and rebalancing - nIndex = nSize; - while (--nIndex) - { - // save element at start of chain - tTemp = oArray[nIndex]; - oArray[nIndex] = oArray[0]; - - nCurr = 0; - nLast = nIndex - 1; - nHalf = nIndex >> 1; - while (nCurr < nHalf) - { - nNext = (nCurr << 1) + 1; - if (nNext < nLast && (oArray[nNext + 1]->IsBigger(oArray[nNext]))) - nNext++; - if (tTemp->IsBiggerOrEqual(oArray[nNext])) - break; - - // promote element in chain - oArray[nCurr] = oArray[nNext]; - nCurr = nNext; - } - - // restore element at end of chain - oArray[nCurr] = tTemp; - } -} diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index afe0cd02acb..c848290d6b1 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,6 +1,8 @@ #pragma once #include "../DesktopEditor/common/Types.h" #include "../DesktopEditor/common/StringUTF32.h" +#include +#include inline LONG ConvertColorBGRToRGB(LONG lBGR) { @@ -55,3 +57,12 @@ inline int little_endian_2_big_endian( int i ) { return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); } + +// у класса T должен быть метод IsBigger +template +void SortElements(std::vector& oArray) +{ + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + return b->IsBigger(a); + }); +} From 0a1e90958c7237019601b8c7b0d0733c1e3a4a8a Mon Sep 17 00:00:00 2001 From: SEAlGo Date: Mon, 3 Oct 2022 23:03:56 +0300 Subject: [PATCH 007/794] Added base classes for table decoding. Added a Converter class for use in various objects. Added additional comments to the code. Added tasks under the //todo label. --- DocxRenderer/DocxRenderer.cpp | 2 +- DocxRenderer/DocxRenderer.h | 2 +- DocxRenderer/DocxRenderer.pro | 8 +- DocxRenderer/readme.md | 39 +- DocxRenderer/src/logic/Document.cpp | 15 + DocxRenderer/src/logic/Page.cpp | 1318 ++++++++--------- DocxRenderer/src/logic/Page.h | 51 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 41 +- DocxRenderer/src/logic/elements/BaseItem.h | 46 +- DocxRenderer/src/logic/elements/Cell.cpp | 214 +++ DocxRenderer/src/logic/elements/Cell.h | 87 ++ DocxRenderer/src/logic/elements/ContText.cpp | 19 +- DocxRenderer/src/logic/elements/ContText.h | 4 +- DocxRenderer/src/logic/elements/Converter.cpp | 747 ++++++++++ DocxRenderer/src/logic/elements/Converter.h | 30 + DocxRenderer/src/logic/elements/Image.h | 1 + DocxRenderer/src/logic/elements/OldShape.cpp | 254 ---- DocxRenderer/src/logic/elements/Paragraph.cpp | 107 +- DocxRenderer/src/logic/elements/Paragraph.h | 34 +- DocxRenderer/src/logic/elements/Shape.cpp | 154 +- DocxRenderer/src/logic/elements/Shape.h | 8 +- DocxRenderer/src/logic/elements/Table.cpp | 220 +++ DocxRenderer/src/logic/elements/Table.h | 43 + DocxRenderer/src/logic/elements/TextLine.cpp | 104 +- DocxRenderer/src/logic/elements/TextLine.h | 22 +- .../src/logic/managers/StyleManager.h | 1 - DocxRenderer/src/logic/styles/FontStyle.cpp | 8 +- DocxRenderer/src/logic/styles/FontStyle.h | 10 +- DocxRenderer/src/resources/LinesTable.h | 12 +- DocxRenderer/src/resources/utils.h | 11 - DocxRenderer/test/main.cpp | 11 +- 31 files changed, 2266 insertions(+), 1357 deletions(-) create mode 100644 DocxRenderer/src/logic/elements/Cell.cpp create mode 100644 DocxRenderer/src/logic/elements/Cell.h create mode 100644 DocxRenderer/src/logic/elements/Converter.cpp create mode 100644 DocxRenderer/src/logic/elements/Converter.h delete mode 100644 DocxRenderer/src/logic/elements/OldShape.cpp create mode 100644 DocxRenderer/src/logic/elements/Table.cpp create mode 100644 DocxRenderer/src/logic/elements/Table.h diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 4252d7c5961..4824f36f2a2 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -80,7 +80,7 @@ HRESULT CDocxRenderer::Close() return hr; } -HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType) +HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType) { m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; return S_OK; diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index 3646de58195..d3f355b3803 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -187,7 +187,7 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); // методы, которыми будет пользоваться конвертер - HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); + HRESULT SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType); int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); private: diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index c181228655a..3a6af0ca05c 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -27,11 +27,13 @@ LIBS += -lgdi32 \ HEADERS += \ src/logic/elements/BaseItem.h \ + src/logic/elements/Cell.h \ src/logic/elements/ContText.h \ + src/logic/elements/Converter.h \ src/logic/elements/Image.h \ - src/logic/elements/OldShape.h \ src/logic/elements/Paragraph.h \ src/logic/elements/Shape.h \ + src/logic/elements/Table.h \ src/logic/elements/TextLine.h \ src/logic/managers/ImageManager.h \ src/logic/managers/FontManager.h \ @@ -53,11 +55,13 @@ HEADERS += \ SOURCES += \ src/logic/elements/BaseItem.cpp \ + src/logic/elements/Cell.cpp \ src/logic/elements/ContText.cpp \ + src/logic/elements/Converter.cpp \ src/logic/elements/Image.cpp \ - src/logic/elements/OldShape.cpp \ src/logic/elements/Paragraph.cpp \ src/logic/elements/Shape.cpp \ + src/logic/elements/Table.cpp \ src/logic/elements/TextLine.cpp \ src/logic/managers/FontManager.cpp \ src/logic/managers/FontManagerBase.cpp \ diff --git a/DocxRenderer/readme.md b/DocxRenderer/readme.md index af6b4370148..dfaddbc3823 100644 --- a/DocxRenderer/readme.md +++ b/DocxRenderer/readme.md @@ -1,3 +1,5 @@ +Логика описана в CPage::ProcessingAndRecordingOfPageData + I Этап 1. Собираются шейпы с векторной графикой (DrawPath -> m_arShapes) @@ -5,42 +7,33 @@ I Этап - определяется тип шейпа VectorTexture или VectorGraphics - первоначально определяем положение на стронице (перед текстом/позади текста - пока плохо работает, когда удалялись белые прямоугольники было лучше) - задаются геометрические параметры - - определяется тип графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтип (LongDash, Dash, Dot, Wave) + - определяется тип графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтип (LongDash, Dash, Dot, Wave) 2. Собираются шейпы-картинки (WriteImage -> m_arImages) - задаются геометрические параметры и тип шейпа Picture -3. Собираются буквы (CollectTextData -> m_arSymbol) +3. Собираются буквы и сразу распределются по текстовым линиям. Отдельно собираются DiacriticalSymbol (CollectTextData -> m_arTextLine, m_arDiacriticalSymbol) - отбрасываем все пробелы (нужно будет добавить доп юникоды для других типов пробелов) - работа FontManager - задаются геометрические параметры - - генерим или проверяем на наличие стиль (коприуются и анализируются текущие Font, Brush, PickFontName, PickFontStyle) + - генерим или проверяем на наличие стиль (копируются и анализируются текущие Font, Brush, PickFontName, PickFontStyle) II Этап Собрали все объекты для текущей страницы. Начинаем анализ. -1. Анализируем графику - AnalyzeCollectedShapes() +1. Анализируем графику - AnalyzeCollectedShapes() + - BuildTables(); - собираем таблицы из шейпов (в разработке) - DetermineLinesType() - превращаем шейпы в горизонтальные линии в зависимости от геометрии, удаляем обработанные шейпы, определяем тип полученной линии на основании типа графики (Rectangle, Curve, ComplicatedFigure, NoGraphics) и подтипа (LongDash, Dash, Dot, Wave). (2 вложенных цикла m_arShapes - m_arShapes с сортировкой вектора) -2. AnalyzeCollectedSymbols() - добавляем свойства каждому символу отдельно +2. AnalyzeCollectedTextLines() - добавляем свойства каждому символу отдельно - Определяем взаимотношения между символами - FontEffects, VertAlignTypeBetweenConts, IsDuplicate (2 вложенных цикла m_arSymbol - m_arSymbol) (удаляем отработанные символы) - DetermineStrikeoutsUnderlinesHighlights() - определяем взаимоотношения между графикой и символами Strikeouts, Underlines, Highlights, FontEffect (2 вложенных цикла m_arShapes - m_arSymbol) (удаляем отработанные шейпы) - -III Этап - AnalyzeLines() - Все свойства получены, можно собирать линии - -1. BuildLines() - сборка линий, создаются новый линии со своими векторами символов/слов/предложений, (1 цикл m_arSymbol), - - собирается вектор m_arTextLine - - задаются геометрические параметры линии - - определяется отношение VertAlign между линиями - - определяется количество линий-дубликатов -2. Сортировка линий по высоте -3. Сшиваются линии с VertAlign (1 цикл m_arTextLine), -4. CalculateWidth () - Высчитываем ширину линии (2 вложенных цикла m_arTextLine - m_arConts) -5. MergeConts() - Сшиваем буквы/слова/предложения в строке с одним стилем (2 вложенных цикла m_arTextLine - m_arConts) -6. DetermineDominantGraphics() - нужно, чтобы выделить шейп, который будет использоваться в качестве шейдинга параграфа (2 вложенных цикла m_arTextLine - m_arConts) -7. DeleteTextClipPage() - удаление линий вне страницы (1 цикл m_arTextLine) - -IV Этап BuildByTypePlainParagraph() - Распределение линий по параграфам и шейпам + - AddDiacriticalSymbols() - добавляем DiacriticalSymbol + - MergeLinesByVertAlignType() - объединяем линии с определенными eVertAlignType + - DeleteTextClipPage() - удаление линий вне страницы (1 цикл m_arTextLine) + - DetermineTextColumns() - определяем колонки текста и добавляем в таблицу (в разработке) + - BuildLines() - собираем из символов слова, добавляем пробелы + - DetermineDominantGraphics() - нужно, чтобы выделить шейп, который будет использоваться в качестве шейдинга параграфа (2 вложенных цикла m_arTextLine - m_arConts) + - BuildParagraphes() - собираем из текстовых строк параграфы/шейпы и добавляем в m_arOutputObjects -V Этап ToXml +III Этап ToXml diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 3981601b311..0a7fe08e2ca 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -1195,6 +1195,21 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + for (size_t i = 0; i < m_oStyleManager.m_arStyles.size(); ++i) { m_oStyleManager.m_arStyles[i]->ToXml(oWriter); diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 15a790a99ae..8e7ed8bb504 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1,5 +1,7 @@ #include "Page.h" +#include "elements/Converter.h" #include "../resources/Constants.h" +#include "../resources/SingletonTemplate.h" #include "../resources/utils.h" #include @@ -26,6 +28,7 @@ namespace NSDocxRenderer m_pFontManager = pFontManager; m_pCurrentLine = nullptr; + m_pCurrentRow = nullptr; CShape::ResetRelativeHeight(); } @@ -34,11 +37,14 @@ namespace NSDocxRenderer { ClearTextData(); ClearTextLines(); - ClearParagraphs(); + ClearOutputObjects(); ClearShapes(); ClearImages(); + ClearTables(); + m_pCurrentLine = nullptr; + m_pCurrentRow = nullptr; } void CPage::ClearImages() @@ -61,9 +67,37 @@ namespace NSDocxRenderer m_arShapes.clear(); } - void CPage::ClearParagraphs() + void CPage::ClearOutputObjects() { - m_arParagraphs.clear(); + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); + } + + void CPage::ClearTables() + { + m_arPeaks.clear(); + m_arCells.clear(); + m_arRows.clear(); + m_arTables.clear(); } CPage::~CPage() @@ -367,16 +401,20 @@ namespace NSDocxRenderer m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_pFontManager->m_lCurrentPictFontStyle; } + //первичное получение стиля для текущего символа + //при дальнейшем анализе может измениться pCont->m_pFontStyle = m_pStyleManager->GetStyle(); pCont->m_dSpaceWidthMM = m_pFontManager->m_dSpaceWidthMM; if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) { + //собираем отдельно, т.к. такие символы не имею размера m_dWidth m_arDiacriticalSymbol.push_back(pCont); } else { + //остальные символы сразу добавляем в текстовые линии AddContToTextLine(pCont); } } @@ -418,18 +456,389 @@ namespace NSDocxRenderer { AnalyzeCollectedShapes(); AnalyzeCollectedTextLines(); - BuildByType(); ToXml(oWriter); WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } void CPage::AnalyzeCollectedShapes() { + //BuildTables(); DetermineLinesType(); } + void CPage::BuildTables() + { + //Графика таблиц парсится в условные 2 типа: + //1 - С выделение отдельных узлов (peak) в местах пересечения линий + //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки + //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек + + //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа + //Для реализации 2го - нужно сначала создать peak в местах пересечения линий + //Основная причина почему так - нужно удалять все шейпы после парсинга + + //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) + //todo реализовать парсинг таблиц 2-го типа + //todo необходимо в созданные cells добавить содержимое из m_arTextLine по геометрическому признаку (буквы должны находится внутри ячеек) + //todo зетем собрать TextLine и Paragraph для каждой ячейки + //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape + + CollectPeaks(); + CreatCells(); + BuildRows(); + + CTable* pCurrTable = nullptr; + CRow* pFirstRow = nullptr; + + if (!m_arRows.empty()) + { + pCurrTable = new CTable(); + m_arTables.push_back(pCurrTable); + + pFirstRow = m_arRows.front(); + pCurrTable->AddContent(pFirstRow); + } + + for (size_t i = 1; i < m_arRows.size(); ++i) + { + auto pCurrRow = m_arRows[i]; + + eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); + eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); + + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; + + if (bIf1 && bIf2) + { + pCurrTable->AddContent(pCurrRow); + pFirstRow = pCurrRow; + } + else + { + pCurrTable = new CTable(); + m_arTables.push_back(pCurrTable); + + pFirstRow = pCurrRow; + pCurrTable->AddContent(pFirstRow); + } + } + + for (size_t i = 0; i < m_arTables.size(); ++i) + { + m_arTables[i]->CalculateColumnWidth(); + } + } + + void CPage::CollectPeaks() + { + for (size_t i = 0; i< m_arShapes.size(); ++i) + { + auto pCurrShape = m_arShapes[i]; + + if (pCurrShape->m_bIsNotNecessaryToUse) + { + continue; + } + + //нашли вершину + if (pCurrShape->IsPeak()) + { + CPeak* pCurrPeak = nullptr; + + //ищем стороны + for (size_t j = 0; j < m_arShapes.size(); ++j) + { + auto pNextShape = m_arShapes[j]; + + if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) + { + continue; + } + + eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); + eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); + + //проверяем, подходит ли сторона + bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && + (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); + bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && + (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); + + if (bIf1 || bIf2) + { + if (!pCurrPeak) + { + pCurrPeak = new CPeak(pCurrShape); + pCurrShape->m_bIsNotNecessaryToUse = true; + pCurrShape->m_bIsUseInTable = true; + m_arPeaks.push_back(pCurrPeak); + } + + if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) + { + if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) + { + pCurrPeak->m_pLines[CPeak::dI] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) + { + pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + } + if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) + { + if (eVType == eVerticalCrossingType::vctCurrentAboveNext) + { + pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) + { + pCurrPeak->m_pLines[CPeak::dII] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + } + } + } + } + } + } + + void CPage::CreatCells() + { + //Cells + // II | I + // | + //-----Peak--- + // | + // III | IV + //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку + CCell *pCellI, *pCellII, *pCellIII, *pCellIV; + + for (size_t i = 0; i < m_arPeaks.size(); ++i) + { + CPeak* pPeak = m_arPeaks[i]; + pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; + //Lines from peak + // VI II V + // | + // III <- Peak -> I + // | + // VII IV VIII + + //Corners + //Обозначение углов в ячейке + // IV------III + // | | + // | Cell | + // | | + // I--------II + + bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия + bool bIsII = pPeak->m_pLines[CPeak::dII]; + bool bIsIII = pPeak->m_pLines[CPeak::dIII]; + bool bIsIV = pPeak->m_pLines[CPeak::dIV]; + + //Если ячейки уже есть + //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) + //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются + //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных + for (size_t j = 0; j < m_arCells.size(); ++j) + { + auto pSaveCell = m_arCells[j]; + for (size_t k = 0; k < CCell::cNumCorners; ++k) + { + auto pSavePeak = pSaveCell->m_pPeaks[k]; + if (pSavePeak) + { + if (pPeak->m_pLines[CPeak::dI] && + pSavePeak->m_pLines[CPeak::dIII] && + pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) + { + if (k == CCell::cII) + { + pCellI = pSaveCell; + pCellI->SetParameters(pPeak, CCell::cI); + } + else if (k == CCell::cIII) + { + pCellIV = pSaveCell; + pCellIV->SetParameters(pPeak, CCell::cIV); + } + } + + if (pPeak->m_pLines[CPeak::dII] && + pSavePeak->m_pLines[CPeak::dIV] && + pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) + { + if (k == CCell::cIII) + { + pCellII = pSaveCell; + pCellII->SetParameters(pPeak, CCell::cII); + } + else if (k == CCell::cIV) + { + pCellI = pSaveCell; + pCellI->SetParameters(pPeak, CCell::cI); + } + } + + if (pPeak->m_pLines[CPeak::dIII] && + pSavePeak->m_pLines[CPeak::dI] && + pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) + { + if (k == CCell::cI) + { + pCellII = pSaveCell; + pCellII->SetParameters(pPeak, CCell::cII); + } + else if (k == CCell::cIV) + { + pCellIII = pSaveCell; + pCellIII->SetParameters(pPeak, CCell::cIII); + } + } + + if (pPeak->m_pLines[CPeak::dIV] && + pSavePeak->m_pLines[CPeak::dII] && + pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) + { + if (k == CCell::cI) + { + pCellIV = pSaveCell; + pCellIV->SetParameters(pPeak, CCell::cIV); + } + else if (k == CCell::cII) + { + pCellIII = pSaveCell; + pCellIII->SetParameters(pPeak, CCell::cIII); + } + } + } + } + } + + //Если ячейка еще не построена по заданным углам - создаем ячейку + if (bIsI && bIsII) + { + if (!pCellI) + { + pCellI = new CCell(); + pCellI->SetParameters(pPeak, CCell::cI); + m_arCells.push_back(pCellI); + } + } + if (bIsII && bIsIII) + { + if (!pCellII) + { + pCellII = new CCell(); + pCellII->SetParameters(pPeak, CCell::cII); + m_arCells.push_back(pCellII); + } + } + if (bIsIII && bIsIV) + { + if (!pCellIII) + { + pCellIII = new CCell(); + pCellIII->SetParameters(pPeak, CCell::cIII); + m_arCells.push_back(pCellIII); + } + } + if (bIsIV && bIsI) + { + if (!pCellIV) + { + pCellIV = new CCell(); + pCellIV->SetParameters(pPeak, CCell::cIV); + m_arCells.push_back(pCellIV); + } + } + } + + //удаляем использованные шейпы + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + if (m_arShapes[i]->m_bIsUseInTable) + { + m_arShapes[i]->m_bIsNotNecessaryToUse = true; + } + } + } + + void CPage::BuildRows() + { + //когда созданы все ячейки, собираем их в ряды + for (size_t i = 0; i < m_arCells.size(); ++i) + { + auto pCell = m_arCells[i]; + + if (pCell->m_bIsNotNecessaryToUse) + { + continue; + } + + SelectCurrentRow(pCell); + m_pCurrentRow->AddContent(pCell); + } + + CBaseItem::SortByBaseline(m_arRows); + for (size_t i = 0; i < m_arRows.size(); ++i) + { + CBaseItem::SortByLeft(m_arRows[i]->m_arCells); + } + } + + void CPage::SelectCurrentRow(const CCell *pCell) + { + //логика аналогична AddContToTextLine + //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала + if (nullptr == m_pCurrentRow) + { + auto pRow = new CRow(); + m_pCurrentRow = pRow; + m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; + m_arRows.push_back(pRow); + return; + } + + if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return; + } + + for (size_t i = 0; i < m_arRows.size(); ++i) + { + if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentRow = m_arRows[i]; + return; + } + } + + auto pRow = new CRow(); + m_pCurrentRow = pRow; + m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; + m_arRows.push_back(pRow); + return; + } + void CPage::DetermineLinesType() { + //определяются типы только горизонтальных линий. + //Входные данные представляют собой набор прямоугольников на одной линии + //При определении типа линии используется крайний левый шейп, который + //увеличивается в размере на ширину последующих за ним шейпов. + //Последующие шейпы помечаются как m_bIsNotNecessaryToUse + + //todo добавить аналогичное определение для вертикальных линий + //нужно для определения границ таблицы + //note определение типов линий нужно сделать до распознования таблиц, когда линия несплошная + for (size_t i = 0; i < m_arShapes.size(); ++i) { auto pCurrShape = m_arShapes[i]; @@ -449,7 +858,7 @@ namespace NSDocxRenderer for (size_t j = i+1; j < m_arShapes.size(); ++j) { auto pNextShape = m_arShapes[j]; - if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossing(pNextShape)) + if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossingByVertically(pNextShape)) //note значительно ускоряет работу { continue; } @@ -468,20 +877,19 @@ namespace NSDocxRenderer } } - //Отсортируем собранный массив по x - size_t nCurrShapesCount = arCurrShapes.size(); - if (nCurrShapesCount > 1) + if (arCurrShapes.size() > 1) { - SortElements(arCurrShapes); + //Отсортируем собранный массив по x + CBaseItem::SortByLeft(arCurrShapes); pCurrShape = arCurrShapes[0]; //сравнение - for (size_t k = 1; k < nCurrShapesCount; ++k) + for (size_t k = 1; k < arCurrShapes.size(); ++k) { auto pNextShape = arCurrShapes[k]; //note логика работатет только если arCurrShapes отсортирован по m_dLeft - pCurrShape->DetermineLineType(pNextShape, k == nCurrShapesCount - 1); + pCurrShape->DetermineLineType(pNextShape, k == arCurrShapes.size() - 1); if (pCurrShape->m_bIsNotNecessaryToUse) { @@ -490,7 +898,7 @@ namespace NSDocxRenderer } } } - else if (nCurrShapesCount == 1) + else if (arCurrShapes.size() == 1) { arCurrShapes[0]->DetermineLineType(); } @@ -501,10 +909,12 @@ namespace NSDocxRenderer void CPage::AnalyzeCollectedTextLines() { - SortElements(m_arTextLine); + //вся логика основана на отсортированных списках объектов + //todo для увеличения производительности можно попробовать использовать другие контейнеры + CBaseItem::SortByBaseline(m_arTextLine); for (size_t i = 0; i < m_arTextLine.size(); ++i) { - m_arTextLine[i]->SortConts(); + CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); } AnalyzeCollectedConts(); @@ -515,15 +925,19 @@ namespace NSDocxRenderer MergeLinesByVertAlignType(); - BuildLines(); + DeleteTextClipPage(); - DetermineDominantGraphics(); + //DetermineTextColumns(); - DeleteTextClipPage(); + SingletonInstance().BuildLines(m_arTextLine); + SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, + CBaseItem::ElemType::etParagraph, + m_arTextLine, m_arTables, m_arOutputObjects); } void CPage::AnalyzeCollectedConts() { + //определение различных эффектов на основании взаимного расположения символов for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) { auto pCurrLine = m_arTextLine[uCurrLineIndex]; @@ -547,7 +961,7 @@ namespace NSDocxRenderer { auto pNextLine = m_arTextLine[uNextLineIndex]; - if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossing(pNextLine)) + if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine)) //note значительно ускоряет работу { continue; } @@ -599,6 +1013,7 @@ namespace NSDocxRenderer void CPage::DetermineStrikeoutsUnderlinesHighlights() { + //определение различных эффектов на основании взаимного расположения символов и шейпов for (size_t i = 0; i < m_arShapes.size(); ++i) { auto pShape = m_arShapes[i]; @@ -614,7 +1029,7 @@ namespace NSDocxRenderer auto pCurrLine = m_arTextLine[j]; if (pCurrLine->m_bIsNotNecessaryToUse || - (pCurrLine->AreObjectsNoCrossing(pShape) && + (pCurrLine->AreObjectsNoCrossingByVertically(pShape) && (pCurrLine->m_dTop > pShape->m_dBaselinePos || pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) { @@ -703,6 +1118,7 @@ namespace NSDocxRenderer bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) { + //todo распознавание работает не для всех размеров шрифтов - возможно 0.15 мало или улучшить логику bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || pShape->m_eGraphicsType == eGraphicsType::gtCurve) && pShape->m_eLineType != eLineType::ltUnknown; @@ -784,7 +1200,7 @@ namespace NSDocxRenderer auto pCurrLine = m_arTextLine[j]; if (pCurrLine->m_bIsNotNecessaryToUse || - pCurrLine->AreObjectsNoCrossing(pDiacriticalCont)) + pCurrLine->AreObjectsNoCrossingByVertically(pDiacriticalCont)) { continue; } @@ -892,7 +1308,7 @@ namespace NSDocxRenderer pBaseLine->m_arConts.push_back(std::move(pCont)); } - SortElements(pBaseLine->m_arConts); + CBaseItem::SortByLeft(pBaseLine->m_arConts); pCurrLine->m_bIsNotNecessaryToUse = true; } } @@ -934,810 +1350,288 @@ namespace NSDocxRenderer pCurrLine->m_arConts.push_back(std::move(pCont)); } - SortElements(pCurrLine->m_arConts); + CBaseItem::SortByLeft(pCurrLine->m_arConts); pSubLine->m_bIsNotNecessaryToUse = true; } } } } - void CPage::BuildLines() + void CPage::DetermineTextColumns() { - for (size_t i = 0; i < m_arTextLine.size(); ++i) + std::vector keys; + std::vector arConts; + CTable* pTable = nullptr; + + //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу + //Выбирается первая строка и относительно нее проверяются все последующие строки - + //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, + //то добавляем uFirstContIndex в keys. + //Todo улучшить локигу определения keys + for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLine.size(); ++uFirstLineIndex) { - auto pCurrLine = m_arTextLine[i]; - if (pCurrLine->m_bIsNotNecessaryToUse) + auto pFirstLine = m_arTextLine[uFirstLineIndex]; + + if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLine.size() - 1) { continue; } - for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) - { - auto pCurrCont = pCurrLine->m_arConts[j]; - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } + CTextLine* pFlagLine = nullptr; - if (pCurrCont->m_iNumDuplicates > 0) - { - pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); - } - } - - pCurrLine->MergeConts(); - } - } - - void CPage::DetermineDominantGraphics() - { - CShape* pDominantShape = nullptr; - - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pLine = m_arTextLine[i]; - if (pLine->m_bIsNotNecessaryToUse) + //первоначальное определение индексов pFirstLine, где могут присутствовать колонки + for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) { - continue; - } + auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; - for (size_t j = 0; j < pLine->m_arConts.size(); ++j) - { - auto pCont = pLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse) + if (pFirtsCont->m_bIsNotNecessaryToUse) { continue; } - if (pCont->m_pShape && pCont->m_pShape != pDominantShape) + for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) { - if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && - pCont->m_pShape->m_dRight > pCont->m_dRight) + auto pCurrLine = m_arTextLine[uCurrLineIndex]; + + if (pCurrLine->m_bIsNotNecessaryToUse) { - if (!pDominantShape || - (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && - pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) - { - pDominantShape = pCont->m_pShape; - } + continue; } - } - } - pLine->m_pDominantShape = pDominantShape; - pDominantShape = nullptr; - } - } - - void CPage::BuildByType() - { - if (m_arTextLine.empty()) - return; - - switch (m_eTextAssociationType) - { - case tatBlockChar: - BuildByTypeBlockChar(); - break; - case tatBlockLine: - BuildByTypeBlockLine(); - break; - case tatPlainLine: - BuildByTypePlainLine(); - break; - case tatShapeLine: - BuildByTypeShapeLine(); - break; - case tatPlainParagraph: - case tatParagraphToShape: - BuildByTypePlainParagraph(); - break; - default: - break; - } - } - - void CPage::BuildByTypeBlockChar() - { - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pLine = m_arTextLine[i]; - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; + auto pPrevLine = m_arTextLine[uCurrLineIndex-1]; - pParagraph->m_arLines.push_back(pLine); - - m_arParagraphs.push_back(pParagraph); - } - } - - void CPage::BuildByTypeBlockLine() - { - auto pFirstLine = m_arTextLine[0]; - - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - pParagraph->m_dLeft = pFirstLine->m_dLeft; - pParagraph->m_dTop = pFirstLine->m_dBaselinePos - pFirstLine->m_dHeight; - double dCurrentTop = pParagraph->m_dTop; - - pParagraph->m_arLines.push_back(pFirstLine); - - m_arParagraphs.push_back(pParagraph); - - for (size_t i = 1; i < m_arTextLine.size(); ++i) - { - auto pTextLine = m_arTextLine[i]; - - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToFrame; - - if (((fabs(pTextLine->m_dBaselinePos - pTextLine->m_dHeight - pFirstLine->m_dBaselinePos) > c_dSTANDART_STRING_HEIGHT_MM) && (pTextLine->m_dLeft == pFirstLine->m_dLeft)) || - ((pTextLine->m_dLeft != pFirstLine->m_dLeft) && (pTextLine->m_dBaselinePos != pFirstLine->m_dBaselinePos))) - { - pParagraph->m_dLeft = pTextLine->m_dLeft; - pParagraph->m_dTop = pTextLine->m_dBaselinePos - pTextLine->m_dHeight; - dCurrentTop = pParagraph->m_dTop; - } - else - { - pParagraph->m_dLeft = pFirstLine->m_dLeft; - pParagraph->m_dTop = dCurrentTop; - } - - pFirstLine = pTextLine; - - pParagraph->m_arLines.push_back(pTextLine); - m_arParagraphs.push_back(pParagraph); - } - } - - void CPage::BuildByTypePlainLine() - { - Merge(c_dSTANDART_STRING_HEIGHT_MM / 3); - - double dPreviousStringBaseline = 0; - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pLine = m_arTextLine[i]; - double dBeforeSpacing = pLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pLine->m_dBaselinePos; - double dRight = pLine->CalculateRightBorder(m_dWidth); - - CreateSingleLineParagraph(pLine, &dRight, &dBeforeSpacing); - } - } - - void CPage::BuildByTypeShapeLine() - { - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - CreateSingleLineShape(m_arTextLine[i]); - } - } + if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) + { + //Нашли линию, до которой будет таблица/ряд + pFlagLine = pCurrLine; + break; + } - void CPage::BuildByTypePlainParagraph() - { - CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; - double dCurrRight = 0, dNextRight = 0; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; - double dBeforeSpacingWithShapes = 0; - //note Все параграфы были сдвинуты на данное значение от верхнего края страницы - double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; - eVerticalCrossingType eCrossingType; + size_t numConts = arConts.size(); - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) + { + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - size_t nIndexForCheking = c_nAntiZero; + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } - for (size_t nIndex = 0; nIndex < m_arTextLine.size(); ++nIndex) - { - pCurrLine = m_arTextLine[nIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } + eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || + eHType == eHorizontalCrossingType::hctLeftBorderMatch) + { + //Добавили Cont-ориентир + arConts.push_back(pCurrCont); + break; + } + } - if (pCurrLine->m_iNumDuplicates > 0) - { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; + if (numConts == arConts.size()) + { + //не было добавления Cont, значит дальше можно не проверять + break; + } + } - auto iNumDuplicates = pCurrLine->m_iNumDuplicates; - CreateSingleLineShape(pCurrLine); - while (iNumDuplicates > 0) + if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) { - CreateSingleLineShape(pCurrLine); - iNumDuplicates--; + keys.push_back(uFirstContIndex); + arConts.clear(); } - continue; } - dCurrRight = pCurrLine->CalculateRightBorder(m_dWidth); - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - if (m_eTextAssociationType == tatParagraphToShape) - { - pPrevLine = GetPrevTextLine(nIndex); - } + size_t uLastLineIndexInCell = 0; - if (pNextLine) + //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то + //начинаем распределять символы из всех строк до pFlagLine по высоте и + //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) + //Повторяем это действие, пока не пробежимся по всем keys + if (keys.size() > 1) { - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bool bIsPassed = false; - double dCurrentAdditive = 0.0; - - switch (eCrossingType) - { - case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; - dPreviousStringBaseline = pNextLine->m_dBaselinePos; - bIsPassed = true; - break; - case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: - case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; - bIsPassed = true; - break; - default: - break; - } + auto pRow = new CRow(); - if (bIsPassed) + for (size_t i = 0; i < keys.size(); ++i) { - CreateSingleLineShape(pCurrLine); - CreateSingleLineShape(pNextLine); + auto pCell = new CCell(); - dBeforeSpacingWithShapes += dCurrentAdditive; + for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLine.size(); ++uLineIndex) + { + auto pCurrLine = m_arTextLine[uLineIndex]; - nIndex++; - continue; - } - } + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; + if (pFlagLine == pCurrLine) + { + uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); + break; + } - bool bIsSingleLineParagraph = false; + CTextLine* pCellLine = nullptr; + CContText* pFlagCont = nullptr; + CContText* pFirstCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i]]; - if (pNextLine) - { - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - - //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; - //расстрояние между строк тоже одинаково - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - //или - bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; - //нет отступа - bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - //есть отступ - bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; - //совпадают правые границы - bIf6 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - size_t nNextIndex = nIndex+1; - pNextNextLine = GetNextTextLine(nNextIndex); - - bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && - (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); - - if (pNextNextLine) - { - double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + if (i < keys.size() - 1) + { + pFlagCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i+1]]; + } - if (bIf1 && (bIf2 || bIf3)) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + + if (pCurrCont->m_bIsNotNecessaryToUse) { - pNextNextLine = nullptr; + continue; } - } - else - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + + eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); + + if (pFlagCont) { - if (dNextBeforeSpacing < dNextNextBeforeSpacing) + eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); + if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && + eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) { - pNextNextLine = nullptr; + if (!pCellLine) + { + pCellLine = new CTextLine(); + } + pCellLine->AddContent(new CContText(*pCurrCont)); + pCurrCont->m_bIsNotNecessaryToUse = true; } else { - bIsSingleLineParagraph = true; + break; } } else { - pNextNextLine = nullptr; + if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + if (!pCellLine) + { + pCellLine = new CTextLine(); + } + pCellLine->AddContent(new CContText(*pCurrCont)); + pCurrCont->m_bIsNotNecessaryToUse = true; + } } } - } - } - } - - bool bIsUseNextNextLine = true; - CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( - pCurrLine, pNextLine, pNextNextLine, m_dWidth, bIsUseNextNextLine, bIsSingleLineParagraph); - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextAlignmentType = eTextAlignmentType; - if (m_eTextAssociationType == tatPlainParagraph) - { - pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; - } - else - { - pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; - } - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) - { - pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dRight = std::min(dCurrRight, dNextRight); - pParagraph->m_dWidth = std::max(pCurrLine->m_dWidth + pCurrLine->m_arConts.back()->m_dSpaceWidthMM, - pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) - { - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - } - } - else - { - pParagraph->m_dLeft = pCurrLine->m_dLeft; - pParagraph->m_dRight = dCurrRight; - pParagraph->m_dWidth = pCurrLine->m_dWidth; - } - - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - - //размер строк во всем параграфе - pParagraph->m_dHeight = pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - - pParagraph->m_arLines.push_back(pCurrLine); - pParagraph->m_nNumLines++; - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - if (IsShadingPresent(pCurrLine, pNextLine)) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - double dCorrectionBeforeSpacing = dCurrBeforeSpacing; - dCurrRight = dNextRight; - - if (bIsUseNextNextLine) - { - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - pParagraph->m_dRight = std::min(pParagraph->m_dRight, dNextRight); - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dWidth = std::max(pParagraph->m_dWidth, pNextLine->m_dWidth + pNextLine->m_arConts.back()->m_dSpaceWidthMM); - - if (!IsShadingPresent(pCurrLine, pNextLine)) + if (pCellLine) { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; + pCell->AddContent(pCellLine); } - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале - dCurrRight = dNextRight; - - if (pNextLine) + if (i >= keys.size() - 1) { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dNextRight = pNextLine->CalculateRightBorder(m_dWidth); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || dCurrRight < dNextRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + pCurrLine->CheckLineToNecessaryToUse(); } } + + SingletonInstance().BuildLines(pCell->m_arTextLine); + SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etCell, + pCell->m_arTextLine, pCell->m_arOutputObjects); + + pRow->AddContent(pCell); } - if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + if (pFlagLine) { - CreateSingleLineShape(pNextLine); - nIndex++; + uFirstLineIndex = uLastLineIndexInCell; } - //коррекция - pParagraph->m_dHeight += dCorrectionBeforeSpacing; - pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); - - pParagraph->RemoveHighlightColor(); - pParagraph->MergeLines(); - } - else - { - if (pCurrLine->m_pDominantShape) + //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы + if (!pTable) { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); + pTable = new CTable(); + m_arTables.push_back(pTable); } - } - if (m_eTextAssociationType == tatParagraphToShape) - { - bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); - } - else - { - m_arParagraphs.push_back(pParagraph); + pTable->AddContent(pRow); + pTable->CalculateColumnWidth(); } - if (nIndexForCheking != c_nAntiZero) - { - nIndex = nIndexForCheking - 1; - nIndexForCheking = c_nAntiZero; - } - } - - if (m_eTextAssociationType == tatParagraphToShape) - { - CorrectionParagraphsInShapes(); + keys.clear(); + arConts.clear(); } } - CTextLine* CPage::GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking) + void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) { - CTextLine* pLine = nullptr; + bool bIsTextShapePresent = false; - for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLine.size(); ++nIndex) + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - pLine = m_arTextLine[nIndex]; - bool bIf1 = pLine->m_bIsNotNecessaryToUse; - bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; - - if (bIf1 || bIf2) - { - if (bIf2) - { - if (*pIndexForCheking == c_nAntiZero) - { - *pIndexForCheking = nIndex; - } - } - - nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки - pLine = nullptr; - continue; - } - else + if (m_arOutputObjects[i]->m_eType == CBaseItem::ElemType::etShape) { + bIsTextShapePresent = true; break; } } - return pLine; - } - - CTextLine* CPage::GetPrevTextLine(size_t nCurrentIndex) - { - CTextLine* pLine = nullptr; - - if (nCurrentIndex) - { - for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) - { - pLine = m_arTextLine[nIndex]; - - if (pLine->m_bIsNotNecessaryToUse) - { - pLine = nullptr; - continue; - } - else - { - break; - } - } - } - return pLine; - } - bool CPage::IsShadingPresent(const CTextLine *pLine1, const CTextLine *pLine2) - { - if (pLine1->m_pDominantShape && pLine2->m_pDominantShape && - pLine1->m_pDominantShape->m_oBrush.Color1 == pLine2->m_pDominantShape->m_oBrush.Color1 && - fabs(pLine1->m_pDominantShape->m_dLeft - pLine2->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(pLine1->m_pDominantShape->m_dWidth - pLine2->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - return true; - } - - return false; - } - - void CPage::CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToParagraph; - pParagraph->m_arLines.push_back(pLine); - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dTop; - pParagraph->m_dFirstLine = 0; - pParagraph->m_dRight = *pRight; - pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dHeight; - if (*pBeforeSpacing < 0) - { - pParagraph->m_dHeight += *pBeforeSpacing; - } + bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); - pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); - - if (pLine->m_pDominantShape) + if (bIsNeedWP) { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - m_arParagraphs.push_back(pParagraph); - } - - void CPage::CreateSingleLineOldShape(CTextLine *pLine) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; - pParagraph->m_arLines.push_back(pLine); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); + oWriter.WriteString(L""); + //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст + oWriter.WriteString(L""); } - auto pShape = std::make_shared(); - pShape->m_arParagraphs.push_back(pParagraph); - - //todo В итоге Left и Top смещаются на несколько мм. не использовать margin-left и margin-top. - pShape->m_dLeft = pLine->m_dLeft - COldShape::POSITION_CORRECTION_FOR_X_MM; //подобранная константа - pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight - COldShape::POSITION_CORRECTION_FOR_Y_MM;//подобранная константа - pShape->m_dWidth = pLine->m_dWidth + COldShape::SIZE_CORRECTION_FOR_X_MM; //5мм мало для длинной строки - pShape->m_dHeight = pLine->m_dHeight + COldShape::SIZE_CORRECTION_FOR_Y_MM; - - //m_arGraphicItems.push_back(pShape); - } - - void CPage::CreateSingleLineShape(CTextLine *pLine) - { - auto pParagraph = new CParagraph(m_eTextAssociationType); - pParagraph->m_eTextConversionType = CParagraph::tctTextToShape; - pParagraph->m_arLines.push_back(pLine); - - if (pLine->m_pDominantShape) + for (size_t i = 0; i < m_arImages.size(); ++i) { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); + m_arImages[i]->ToXml(oWriter); } - auto pShape = new CShape(); - pShape->m_arParagraphs.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dTop; - pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; - pShape->m_bIsBehindDoc = false; - - m_arShapes.push_back(pShape); - } - - void CPage::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText) - { - if (!pParagraph) - { - return; - } - - CShape* pShape; - - if (bIsSameTypeText && !m_arShapes.empty()) - { - pShape = m_arShapes.back(); - pShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; - } - else - { - pShape = new CShape(); - pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight += pParagraph->m_dHeight * pParagraph->m_nNumLines; - } - - if (pShape->m_dLeft > 0) - { - pShape->m_dLeft = std::min(pShape->m_dLeft, pParagraph->m_dLeft); - } - else - { - pShape->m_dLeft = pParagraph->m_dLeft; - } - - if (pShape->m_dTop > 0) - { - pShape->m_dTop = std::min(pShape->m_dTop, pParagraph->m_dTop); - } - else - { - pShape->m_dTop = pParagraph->m_dTop; - } - - if (pShape->m_dRight > 0) - { - pShape->m_dRight = std::min(pShape->m_dRight, pParagraph->m_dRight); - } - else - { - pShape->m_dRight = pParagraph->m_dRight; - } - - pShape->m_dWidth = m_dWidth - pShape->m_dLeft - pShape->m_dRight; - - pShape->m_arParagraphs.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_bIsBehindDoc = false; - - if (!bIsSameTypeText) - { - m_arShapes.push_back(pShape); - } - } - - void CPage::CorrectionParagraphsInShapes() - { - for (size_t i = 0; i < m_arShapes.size(); ++i) + for (size_t i = 0; i < m_arShapes.size(); ++i) { - auto pShape = m_arShapes[i]; - if (pShape->m_bIsNotNecessaryToUse || - pShape->m_eType != CShape::eShapeType::stTextBox || - pShape->m_arParagraphs.empty()) - { - continue; - } - - for (size_t j = 0; j < pShape->m_arParagraphs.size(); ++j) - { - auto pParagraph = pShape->m_arParagraphs[j]; - if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) - { - pParagraph->m_bIsNeedFirstLineIndent = true; - pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; - pParagraph->m_dLeft = 0; - } - - pParagraph->m_dLeft = pParagraph->m_dLeft > pShape->m_dLeft ? pParagraph->m_dLeft - pShape->m_dLeft : 0 ; - pParagraph->m_dRight = pParagraph->m_dRight - pShape->m_dRight; - } + m_arShapes[i]->ToXml(oWriter); } - } - void CPage::Merge(double dAffinity) - { - size_t nCount = m_arTextLine.size(); - if (1 < nCount) + if (bIsTextShapePresent) { - auto pPrev = m_arTextLine[0]; - for (size_t i = 1; i < nCount; ++i) + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - auto pNext = m_arTextLine[i]; + auto pObj = m_arOutputObjects[i]; - if (fabs(pNext->m_dBaselinePos - pPrev->m_dBaselinePos) < dAffinity) + switch(pObj->m_eType) { - pPrev->Merge(pNext); - pNext->m_bIsNotNecessaryToUse = true; - continue; + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; } - pPrev = pNext; } } - } - void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (!m_arImages.empty()) + if (bIsNeedWP) { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); - - for (size_t i = 0; i < m_arImages.size(); ++i) - { - m_arImages[i]->ToXml(oWriter); - } - oWriter.WriteString(L""); } - // drawings - if (!m_arShapes.empty()) + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); + auto pObj = m_arOutputObjects[i]; - for (size_t i = 0; i < m_arShapes.size(); ++i) + switch(pObj->m_eType) { - m_arShapes[i]->ToXml(oWriter); + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; } - - oWriter.WriteString(L""); - } - - for (size_t i = 0; i < m_arParagraphs.size(); ++i) - { - m_arParagraphs[i]->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index ba0db43c5af..f54039c0692 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -1,10 +1,11 @@ #pragma once #include "../DesktopEditor/graphics/pro/Graphics.h" -#include "elements/OldShape.h" #include "elements/Paragraph.h" #include "elements/Shape.h" +#include "elements/Table.h" #include "managers/StyleManager.h" + namespace NSDocxRenderer { class CPage @@ -32,13 +33,20 @@ namespace NSDocxRenderer std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; std::vector m_arShapes; - std::vector m_arParagraphs; + + std::vector m_arOutputObjects; + + std::vector m_arPeaks; + std::vector m_arCells; + std::vector m_arRows; + std::vector m_arTables; CTextLine* m_pCurrentLine {nullptr}; + CRow* m_pCurrentRow {nullptr}; CFontManagerLight m_oFontManagerLight; - TextAssociationType m_eTextAssociationType {tatPlainLine}; + eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; bool m_bIsDeleteTextClipPage {true}; @@ -54,7 +62,9 @@ namespace NSDocxRenderer void ClearTextData(); void ClearTextLines(); void ClearShapes(); - void ClearParagraphs(); + void ClearOutputObjects(); + + void ClearTables(); //удаляем то, что выходит за границы страницы void DeleteTextClipPage(); @@ -82,6 +92,11 @@ namespace NSDocxRenderer void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); void AnalyzeCollectedShapes(); + void BuildTables(); + void CollectPeaks(); + void CreatCells(); + void BuildRows(); + void SelectCurrentRow(const CCell *pCell); void DetermineLinesType(); //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить @@ -92,39 +107,13 @@ namespace NSDocxRenderer bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); void AddDiacriticalSymbols(); - - //набивается содержимым вектор m_arTextLine - void AnalyzeLines(); - void BuildLines(); - void AddDiacriticalSymbols(CContText* pCont); void MergeLinesByVertAlignType(); + void DetermineTextColumns(); void DetermineDominantGraphics(); - void BuildByType(); - void BuildByTypeBlockChar(); - void BuildByTypeBlockLine(); - void BuildByTypePlainLine(); - void BuildByTypeShapeLine(); - void BuildByTypePlainParagraph(); - - //Объединяем строки, которые находятся на расстроянии не большем dAffinity - void Merge(double dAffinity); - //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку void ToXml(NSStringUtils::CStringBuilder& oWriter); void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); - - void CreateSingleLineParagraph(CTextLine *pLine, const double *pRight, const double *pBeforeSpacing); - void CreateSingleLineOldShape(CTextLine *pLine); - void CreateSingleLineShape(CTextLine *pLine); - void CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText); - void CorrectionParagraphsInShapes(); - - bool IsShadingPresent(const CTextLine* pLine1, const CTextLine* pLine2); - - private: - CTextLine* GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking = nullptr); - CTextLine* GetPrevTextLine(size_t nCurrentIndex); }; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 2a7eb72c962..cb0707ea032 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -24,16 +24,6 @@ namespace NSDocxRenderer return *this; } - bool CBaseItem::IsBigger(const CBaseItem* oSrc) - { - return (m_dLeft > oSrc->m_dLeft) ? true : false; - } - - bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dLeft >= oSrc->m_dLeft) ? true : false; - } - void CBaseItem::AddContent(CBaseItem* pObj) { m_dBaselinePos = std::max(m_dBaselinePos, pObj->m_dBaselinePos); @@ -161,9 +151,9 @@ namespace NSDocxRenderer } } - bool CBaseItem::AreObjectsNoCrossing(const CBaseItem* pLine) + bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) { - eVerticalCrossingType eVType = this->GetVerticalCrossingType(pLine); + eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); if (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) @@ -172,4 +162,31 @@ namespace NSDocxRenderer } return false; } + + bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) + { + eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); + + if (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + return true; + } + return false; + } + + double CBaseItem::CalculateBeforeSpacing(double dPreviousBaseline) + { + return m_dTop - dPreviousBaseline; + } + + bool CBaseItem::IsCurrentLeftOfNext(const CBaseItem* oSrc) + { + return m_dLeft < oSrc->m_dLeft; + } + + bool CBaseItem::IsCurrentAboveOfNext(const CBaseItem* oSrc) + { + return m_dBaselinePos < oSrc->m_dBaselinePos; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index f6ac05851aa..ce5a31568b4 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,5 +1,6 @@ #pragma once #include "../DesktopEditor/common/StringBuilder.h" +#include namespace NSDocxRenderer { @@ -43,7 +44,9 @@ namespace NSDocxRenderer etParagraph = 2, etImage = 3, etShape = 4, - etOldShape = 5, + etCell = 5, + etRow = 6, + etTable = 7, }; ElemType m_eType; @@ -67,30 +70,35 @@ namespace NSDocxRenderer CBaseItem& operator=(const CBaseItem& oSrc); - friend bool operator == (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft == rh.m_dLeft) ? true : false; - } + virtual void AddContent(CBaseItem* pObj); + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; + + eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); + eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); + + bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj); + bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj); - friend bool operator < (const CBaseItem& lh, const CBaseItem& rh) + double CalculateBeforeSpacing(double dPreviousBaseline); + + template + static void SortByLeft(std::vector& oArray) { - return (lh.m_dLeft < rh.m_dLeft) ? true : false; + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + return a->IsCurrentLeftOfNext(a); + }); } - friend bool operator > (const CBaseItem& lh, const CBaseItem& rh) + template + static void SortByBaseline(std::vector& oArray) { - return (lh.m_dLeft > rh.m_dLeft) ? true : false; + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + return a->IsCurrentAboveOfNext(b); + }); } - virtual bool IsBigger(const CBaseItem* oSrc); - virtual bool IsBiggerOrEqual(const CBaseItem* oSrc); - - virtual void AddContent(CBaseItem* pObj); - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - - eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); - - bool AreObjectsNoCrossing(const CBaseItem* oSrc); + private: + bool IsCurrentLeftOfNext(const CBaseItem* oSrc); + bool IsCurrentAboveOfNext(const CBaseItem* oSrc); }; } diff --git a/DocxRenderer/src/logic/elements/Cell.cpp b/DocxRenderer/src/logic/elements/Cell.cpp new file mode 100644 index 00000000000..3d976e8b210 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Cell.cpp @@ -0,0 +1,214 @@ +#include "Cell.h" +#include "Shape.h" + +namespace NSDocxRenderer +{ + CCell::CCell() : CBaseItem(ElemType::etCell) + { + } + + CCell::~CCell() + { + Clear(); + } + + void CCell::Clear() + { + m_arTextLine.clear(); + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); + } + + void CCell::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arTextLine.push_back(dynamic_cast(pObj)); + } + + void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"dxa\"/>"); + + if (m_bIsvMergeStart) + { + oWriter.WriteString(L""); + } + else if (m_bIsvMerge) + { + oWriter.WriteString(L""); + } + + if (m_uGridSpan > 1) + { + oWriter.WriteString(L""); + } + if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || + !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) + { + oWriter.WriteString(L""); + if (!m_bIsTopBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsLeftBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsBottomBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsRightBorder) + { + oWriter.WriteString(L""); + } + if (m_bIsDiagonalDownBorder) + { + oWriter.WriteString(L""); + } + if (m_bIsDiagonalUpBorder) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + + if (m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); + } + else + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } + } + } + + oWriter.WriteString(L""); + } + + void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) + { + m_pPeaks[eCorner] = pPeak; + + switch (eCorner) + { + case cI: + if (pPeak->m_pLines[CPeak::dI]) + { + m_bIsLeftBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dII]) + { + m_bIsBottomBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cII: + if (pPeak->m_pLines[CPeak::dII]) + { + m_bIsRightBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dIII]) + { + m_bIsBottomBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cIII: + if (pPeak->m_pLines[CPeak::dIV]) + { + m_bIsRightBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dIII]) + { + m_bIsTopBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cIV: + if (pPeak->m_pLines[CPeak::dIV]) + { + m_bIsLeftBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dI]) + { + m_bIsTopBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + default: + break; + } + + if (m_dLeft != 0 && m_dRight != 0) + { + m_dWidth = m_dRight - m_dLeft; + } + + if (m_dTop != 0 && m_dBaselinePos != 0) + { + m_dHeight = m_dBaselinePos - m_dTop; + } + } +} diff --git a/DocxRenderer/src/logic/elements/Cell.h b/DocxRenderer/src/logic/elements/Cell.h new file mode 100644 index 00000000000..fbcdba89148 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Cell.h @@ -0,0 +1,87 @@ +#pragma once +#include "Paragraph.h" + +namespace NSDocxRenderer +{ + class CPeak + { + public: + // + // VI II V + // | + // III <- Peak -> I + // | + // VII IV VIII + //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) + enum eDirections + { + dI = 0, + dII = 1, + dIII = 2, + dIV = 3, + dV = 4, + dVI = 5, + dVII = 6, + dVIII = 7, + dNumDirections = 8 + }; + + public: + CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak + CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон + + public: + CPeak(CShape* pPeak) : m_pPeak(pPeak) {} + }; + + class CCell : public CBaseItem + { + public: + //Corners + // IV------III + // | | + // | Cell | + // | | + // I--------II + //У каждой ячейки может быть только 4 угла ) + enum eCorners + { + cI = 0, + cII = 1, + cIII = 2, + cIV = 3, + cNumCorners = 4 + }; + public: + bool m_bIsvMergeStart {false}; + bool m_bIsvMerge {false}; + + bool m_bIsTopBorder {false}; + bool m_bIsLeftBorder {false}; + bool m_bIsBottomBorder {false}; + bool m_bIsRightBorder {false}; + + bool m_bIsDiagonalDownBorder {false}; + bool m_bIsDiagonalUpBorder {false}; + + UINT m_uGridSpan {1}; + + CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки + + //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами + //- дополнительное выделение памяти. Возможно нужно просто делать move. + std::vector m_arTextLine; + //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. + //Возможно подойдет вывод из CShape::BuildPictureProperties + std::vector m_arOutputObjects; + + public: + CCell(); + virtual ~CCell(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + + void SetParameters(CPeak *pPeak, eCorners eCorner); + }; +} diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 0730ac3706b..164277e262b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -10,6 +10,12 @@ namespace NSDocxRenderer { } + CContText::CContText(const CContText& rCont): + CBaseItem(ElemType::etContText) + { + *this = rCont; + } + CContText::~CContText() { Clear(); @@ -20,16 +26,6 @@ namespace NSDocxRenderer m_pFontStyle = nullptr; } - double CContText::GetIntersect(const CContText* pCont) const - { - double d1 = std::max(m_dLeft, pCont->m_dLeft); - double d2 = std::min(m_dLeft + m_dWidth, pCont->m_dLeft + pCont->m_dWidth); - - if (d2 > d1) - return d2 - d1; - return 0; - } - CContText& CContText::operator= (const CContText& rCont) { if (this == &rCont) @@ -391,6 +387,7 @@ namespace NSDocxRenderer //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. + //todo существует проблема неправильного определением FontEffects с физически пересекаемыми строчками - файл generaltest.pdf p.14 if (bIf5 && bIf6) { if (m_bIsEmbossPresent && bIf12) @@ -504,11 +501,13 @@ namespace NSDocxRenderer double CContText::CalculateWideSpace() { + //note подобранное условие - не везде хорошо работает return m_dSpaceWidthMM * 4; } double CContText::CalculateThinSpace() { + //note подобранное условие - не везде хорошо работает return m_dSpaceWidthMM * 0.7; } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index da10e96b8e4..a410a596dd9 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -56,6 +56,7 @@ namespace NSDocxRenderer public: CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); + CContText(const CContText& rCont); virtual ~CContText(); virtual void Clear() override final; virtual void AddContent(CBaseItem* pObj) override final {}; @@ -63,12 +64,9 @@ namespace NSDocxRenderer CContText& operator= (const CContText& rCont); - double GetIntersect(const CContText* pCont) const; - void AddWideSpaceToXml(double dSpacingMM, NSStringUtils::CStringBuilder& oWriter, bool bIsNeedSaveFormat = false); - bool IsEqual(const CContText* pCont); UINT GetNumberOfFeatures(); bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp new file mode 100644 index 00000000000..60ed6de3f98 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -0,0 +1,747 @@ +#include "Converter.h" +#include "Shape.h" +#include "src/resources/utils.h" + +namespace NSDocxRenderer +{ + //общая функция для сборки строк в любом текстовом объекте + void CConverter::BuildLines(std::vector& rTextLines) + { + for (size_t i = 0; i < rTextLines.size(); ++i) + { + auto pCurrLine = rTextLines[i]; + + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto pCurrCont = pCurrLine->m_arConts[j]; + + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCurrCont->m_iNumDuplicates > 0) + { + pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); + } + } + + pCurrLine->MergeConts(); + } + + DetermineDominantGraphics(rTextLines); + } + + void CConverter::DetermineDominantGraphics(std::vector& rTextLines) + { + CShape* pDominantShape = nullptr; + + for (size_t i = 0; i < rTextLines.size(); ++i) + { + auto pLine = rTextLines[i]; + if (pLine->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto pCont = pLine->m_arConts[j]; + if (pCont->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCont->m_pShape && pCont->m_pShape != pDominantShape) + { + if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && + pCont->m_pShape->m_dRight > pCont->m_dRight) + { + if (!pDominantShape || + (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && + pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) + { + pDominantShape = pCont->m_pShape; + } + } + } + } + + pLine->m_pDominantShape = pDominantShape; + pDominantShape = nullptr; + } + } + + void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, + std::vector& rTextLines, + std::vector& rOutputObjects) + { + std::vector oStubVector; //просто объект-заглушка + BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects); + } + + // eBaseType == etCell или etParagraph + // eType == 2 - 5 из eTextAssociationType + void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector &rOutputObjects) + { + CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; + double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; + double dBeforeSpacingWithShapes = 0; + //note Все параграфы были сдвинуты на данное значение от верхнего края страницы + double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; + eVerticalCrossingType eCrossingType; + + bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; + bool bIsNeedParagraphToShape = eType == eTextAssociationType::tatParagraphToShape && eBaseType == CBaseItem::ElemType::etParagraph; + + CTable* pCurrTable = nullptr; + size_t nTableIndex = 0; + + size_t nIndexForCheking = c_nAntiZero; + + if (!rTables.empty()) + { + CBaseItem::SortByBaseline(rTables); + pCurrTable = rTables.front(); + nTableIndex = 0; + + //Если линий нет, то добавлем сразу + if (rTextLines.empty()) + { + for (size_t i = 0; i < rTables.size(); ++i) + { + if (bIsNeedParagraphToShape) + { + CreateShapeFormTable(pCurrTable, rOutputObjects); + } + else + { + rOutputObjects.push_back(rTables[i]); + } + } + } + } + + CBaseItem::SortByBaseline(rTextLines); + + for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) + { + pCurrLine = rTextLines[nIndex]; + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + if (eType == eTextAssociationType::tatShapeLine) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + continue; + } + + + while (pCurrTable) + { + eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); + + //добавляем таблицу в общий массив, если она идет после текущей строки + if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + if (bIsNeedParagraphToShape) + { + CreateShapeFormTable(pCurrTable, rOutputObjects); + } + else + { + rOutputObjects.push_back(pCurrTable); + } + dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); + pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + if (eType != eTextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) + { + pCurrTable->m_bIsNeedSpacing = true; + } + dPreviousStringBaseline = pCurrTable->m_dBaselinePos; + pCurrTable = nullptr; + //таблицы отсортированы, можно сразу взять следующую для проверки + for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) + { + pCurrTable = rTables[i]; + } + } + else + { + break; + } + } + + dPrevBeforeSpacing = dCurrBeforeSpacing; + if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) + { + dCurrBeforeSpacing = 0; + } + else + { + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + } + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + + //Если у текущей линии есть дубликаты, то создаем из них шейпы + if (pCurrLine->m_iNumDuplicates > 0) + { + dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; + + auto iNumDuplicates = pCurrLine->m_iNumDuplicates; + CreateSingleLineShape(pCurrLine, rOutputObjects); + while (iNumDuplicates > 0) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + iNumDuplicates--; + } + continue; + } + + if (eType == eTextAssociationType::tatPlainLine) + { + CreateSingleLineParagraph(pCurrLine, dPageWidth, &dCurrBeforeSpacing, rOutputObjects); + continue; + } + + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + if (bIsNeedParagraphToShape) + { + pPrevLine = GetPrevTextLine(nIndex, rTextLines); + } + + //Если две линии пересекаются, то создаем из них шейпы + if (pNextLine) + { + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + bool bIsPassed = false; + double dCurrentAdditive = 0.0; + + switch (eCrossingType) + { + case eVerticalCrossingType::vctCurrentInsideNext: + case eVerticalCrossingType::vctCurrentBelowNext: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; + dPreviousStringBaseline = pNextLine->m_dBaselinePos; + bIsPassed = true; + break; + case eVerticalCrossingType::vctCurrentOutsideNext: + case eVerticalCrossingType::vctCurrentAboveNext: + case eVerticalCrossingType::vctDublicate: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; + bIsPassed = true; + break; + default: + break; + } + + if (bIsPassed) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + CreateSingleLineShape(pNextLine, rOutputObjects); + + dBeforeSpacingWithShapes += dCurrentAdditive; + + nIndex++; + continue; + } + } + + dCurrBeforeSpacing += dBeforeSpacingWithShapes; + dBeforeSpacingWithShapes = 0; + + bool bIsSingleLineParagraph = false; + + //Логика определения параметров для DetermineTextAlignmentType + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + + //Высота строк должна быть примерно одинаковой + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + //расстрояние между строк тоже одинаково + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + //или + bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; + //нет отступа + bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + //есть отступ + bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; + //совпадают правые границы + bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + size_t nNextIndex = nIndex+1; + pNextNextLine = GetNextTextLine(nNextIndex, rTextLines); + + bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && + (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); + + if (pNextNextLine) + { + double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + + if (bIf1 && (bIf2 || bIf3)) + { + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + pNextNextLine = nullptr; + } + } + else + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + if (dNextBeforeSpacing < dNextNextBeforeSpacing) + { + pNextNextLine = nullptr; + } + else + { + bIsSingleLineParagraph = true; + } + } + else + { + pNextNextLine = nullptr; + } + } + } + } + } + + bool bIsUseNextNextLine = true; + CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( + pCurrLine, pNextLine, pNextNextLine, dPageWidth, bIsUseNextNextLine, bIsSingleLineParagraph); + + auto pParagraph = new CParagraph(); + pParagraph->m_eTextAlignmentType = eTextAlignmentType; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) + { + pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) + { + pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; + pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; + } + } + else + { + pParagraph->m_dLeft = pCurrLine->m_dLeft; + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = pCurrLine->m_dRight; + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pCurrLine->m_dWidth; + + pParagraph->m_bIsNeedFirstLineIndent = false; + pParagraph->m_dFirstLine = 0; + } + + pParagraph->m_dTop = pCurrLine->m_dTop; + pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; + pParagraph->m_dHeight = pCurrLine->m_dHeight; + + //размер строк во всем параграфе + pParagraph->m_dLineHeight= pCurrLine->m_dHeight; + pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + + pParagraph->m_arLines.push_back(pCurrLine); + pParagraph->m_nNumLines++; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + if (pCurrLine->IsShadingPresent(pNextLine)) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + double dCorrectionBeforeSpacing = dCurrBeforeSpacing; + + if (bIsUseNextNextLine) + { + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + + //проверим, подходят ли следующие строчки для текущего pParagraph + while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; + + if (!pCurrLine->IsShadingPresent(pNextLine)) + { + pParagraph->m_bIsShadingPresent = false; + pParagraph->m_lColorOfShadingFill = c_iWhiteColor; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале + + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + } + } + + if (eCrossingType != eVerticalCrossingType::vctUnknown && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + CreateSingleLineShape(pNextLine, rOutputObjects); + nIndex++; + } + + //коррекция + pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; + pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); + + pParagraph->RemoveHighlightColor(); + pParagraph->MergeLines(); + } + else + { + if (pCurrLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + } + + if (bIsNeedParagraphToShape) + { + bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText, dPageWidth, rOutputObjects); + } + else + { + rOutputObjects.push_back(pParagraph); + } + + if (nIndexForCheking != c_nAntiZero) + { + nIndex = nIndexForCheking - 1; + nIndexForCheking = c_nAntiZero; + } + } + + if (bIsNeedParagraphToShape) + { + CorrectionObjectesInShapes(rOutputObjects, dPageWidth); + } + + std::sort(rOutputObjects.begin(), rOutputObjects.end(), [](CBaseItem* a, CBaseItem* b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + } + + void CConverter::CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, + const double *pBeforeSpacing, std::vector& rOutputObjects) + { + auto pParagraph = new CParagraph(); + pParagraph->m_arLines.push_back(pLine); + + pParagraph->m_dLeft = pLine->m_dLeft; + pParagraph->m_dTop = pLine->m_dTop; + pParagraph->m_dFirstLine = 0; + pParagraph->m_dRight = pLine->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pLine->m_dWidth; + pParagraph->m_dHeight = pLine->m_dHeight; + if (*pBeforeSpacing < 0) + { + pParagraph->m_dHeight += *pBeforeSpacing; + } + + pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + rOutputObjects.push_back(pParagraph); + } + + void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector &rOutputObjects) + { + auto pParagraph = new CParagraph(); + pParagraph->m_arLines.push_back(pLine); + pParagraph->m_dRightBorder = 0; + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + auto pShape = new CShape(); + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_dLeft = pLine->m_dLeft; + pShape->m_dTop = pLine->m_dTop; + pShape->m_dWidth = pLine->m_dWidth; + pShape->m_dHeight = pLine->m_dHeight; + pShape->m_bIsBehindDoc = false; + + rOutputObjects.push_back(pShape); + } + + void CConverter::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText, double dPageWidth, + std::vector &rOutputObjects) + { + if (!pParagraph) + { + return; + } + + bool bIsShapesPresent = false; + CShape* pBackShape = nullptr; + + for (size_t i = 0; i < rOutputObjects.size(); ++i) + { + if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + { + continue; + } + bIsShapesPresent = true; + pBackShape = dynamic_cast(rOutputObjects[i]); + } + + CShape* pShape; + + if (bIsSameTypeText && bIsShapesPresent) + { + pShape = pBackShape; + pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + } + else + { + pShape = new CShape(); + pParagraph->m_dSpaceBefore = 0; + pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines; + } + + pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; + pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; + pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; + pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; + pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + + pParagraph->m_dLeftBorder = 0; + pParagraph->m_dRightBorder = 0; + + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + if (!bIsSameTypeText) + { + rOutputObjects.push_back(pShape); + } + } + + void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) + { + if (!pTable) + { + return; + } + + CShape* pShape; + + pShape = new CShape(); + pShape->m_dHeight = pTable->m_dHeight; + pShape->m_dLeft = pTable->m_dLeft; + pShape->m_dTop =pTable->m_dTop; + pShape->m_dRight = pTable->m_dRight; + pShape->m_dBaselinePos = pTable->m_dBaselinePos; + pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + + pShape->m_arOutputObjects.push_back(pTable); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + rOutputObjects.push_back(pShape); + } + + void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) + { + for (size_t i = 0; i < rOutputObjects.size(); ++i) + { + if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + { + continue; + } + + auto pShape = dynamic_cast(rOutputObjects[i]); + + if (pShape->m_bIsNotNecessaryToUse || + pShape->m_eType != CShape::eShapeType::stTextBox || + pShape->m_arOutputObjects.empty()) + { + continue; + } + + for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) + { + auto pObj = pShape->m_arOutputObjects[j]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + { + auto pParagraph = dynamic_cast(pObj); + + if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) + { + pParagraph->m_bIsNeedFirstLineIndent = true; + pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; + pParagraph->m_dLeft = 0; + } + + pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; + pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; + } + break; + case CBaseItem::ElemType::etTable: + { + auto pTable = dynamic_cast(pObj); + //todo + } + break; + default: + break; + } + + } + } + } + + CTextLine* CConverter::GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking) + { + CTextLine* pLine = nullptr; + + for (size_t nIndex = nCurrentIndex + 1; nIndex < rTextLines.size(); ++nIndex) + { + pLine = rTextLines[nIndex]; + bool bIf1 = pLine->m_bIsNotNecessaryToUse; + bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; + + if (bIf1 || bIf2) + { + if (bIf2) + { + if (*pIndexForCheking == c_nAntiZero) + { + *pIndexForCheking = nIndex; + } + } + + nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки + pLine = nullptr; + continue; + } + else + { + break; + } + } + return pLine; + } + + CTextLine* CConverter::GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines) + { + CTextLine* pLine = nullptr; + + if (nCurrentIndex) + { + for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) + { + pLine = rTextLines[nIndex]; + + if (pLine->m_bIsNotNecessaryToUse) + { + pLine = nullptr; + continue; + } + else + { + break; + } + } + } + return pLine; + } +} diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h new file mode 100644 index 00000000000..8733e8872d1 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Converter.h @@ -0,0 +1,30 @@ +#pragma once +#include "Table.h" + +namespace NSDocxRenderer +{ + class CConverter + { + public: + void BuildLines(std::vector& rTextLines); + void DetermineDominantGraphics(std::vector& rTextLines); + + void BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector &rOutputObjects); + void BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector &rOutputObjects); + + void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector &rOutputObjects); + void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); + void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector &rOutputObjects); + void CreateShapeFormTable(CTable* pParagraph, std::vector &rOutputObjects); + void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); + + private: + CTextLine* GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking = nullptr); + CTextLine* GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines); + }; + +} diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index a8ecbda02a8..fe7e2eb8f66 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -21,6 +21,7 @@ namespace NSDocxRenderer CImage(); CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); void Clear() override final; + void AddContent(CBaseItem* pObj) override final{}; void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; }; diff --git a/DocxRenderer/src/logic/elements/OldShape.cpp b/DocxRenderer/src/logic/elements/OldShape.cpp deleted file mode 100644 index 1148fb8535c..00000000000 --- a/DocxRenderer/src/logic/elements/OldShape.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "OldShape.h" -#include "../../resources/utils.h" - -namespace NSDocxRenderer -{ - const double COldShape::POSITION_CORRECTION_FOR_X_MM = 3.0; - const double COldShape::POSITION_CORRECTION_FOR_Y_MM = 2.0; - const double COldShape::SIZE_CORRECTION_FOR_X_MM = 10.0; - const double COldShape::SIZE_CORRECTION_FOR_Y_MM = 5.0; - - COldShape::COldShape() : CBaseItem(ElemType::etOldShape) - { - } - - COldShape::~COldShape() - { - Clear(); - } - - void COldShape::Clear() - { - m_arParagraphs.clear(); - } - - void COldShape::GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize) - { - m_dLeft = oVector.m_dLeft; - m_dTop = oVector.m_dTop; - m_dWidth = oVector.m_dRight - m_dLeft; - m_dHeight = oVector.m_dBottom - m_dTop; - - if (m_dWidth < 0.0001) - m_dWidth = 0.0001; - if (m_dHeight < 0.0001) - m_dHeight = 0.0001; - - m_dBaselinePos = m_dTop + m_dHeight; - m_dRight = m_dLeft + m_dWidth; - - m_lCoordSizeX = lCoordSize; - m_lCoordSizeY = lCoordSize; - - if (0x00 == (lType & 0x01)) - { - m_bIsNoStroke = true; - } - if (0x00 == (lType >> 8)) - { - m_bIsNoFill = true; - } - - WritePath(oVector, lType, lCoordSize); - } - - void COldShape::WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize) - { - size_t nCount = oVector.GetCurSize(); - double *pData = oVector.m_pData; - - double dWidth = oVector.m_dRight - m_dLeft; - double dHeight = oVector.m_dBottom - m_dTop; - - NSStringUtils::CStringBuilder oWriter; - - while (nCount > 0) - { - CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('m'); - oWriter.AddInt(lX); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY); - - nCount -= 3; - break; - } - case CVectorGraphics::vgtLine: - { - LONG lX = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('l'); - oWriter.AddInt(lX); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY); - - nCount -= 3; - break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY1 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX2 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY2 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX3 = static_cast((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY3 = static_cast((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - oWriter.AddCharSafe('c'); - oWriter.AddInt(lX1); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY1); - oWriter.AddCharSafe(','); - oWriter.AddInt(lX2); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY2); - oWriter.AddCharSafe(','); - oWriter.AddInt(lX3); - oWriter.AddCharSafe(','); - oWriter.AddInt(lY3); - - nCount -= 7; - break; - } - case CVectorGraphics::vgtClose: - default: - oWriter.AddCharSafe('x'); - --nCount; - break; - } - } - - if (0x00 == (lType & 0x01)) - { - //m_bIsNoStroke = true; - oWriter.WriteString(L"ns"); - } - if (0x00 == (lType >> 8)) - { - //m_bIsNoFill = true; - oWriter.WriteString(L"nf"); - } - - oWriter.AddCharSafe('e'); - - m_strPath = oWriter.GetData(); - oWriter.ClearNoAttack(); - } - - void COldShape::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString( - L"(m_lCoordSizeX)); - oWriter.AddCharSafe(','); - oWriter.AddInt(static_cast(m_lCoordSizeY)); - oWriter.WriteString(L"\" path=\""); - oWriter.WriteString(m_strPath); - if (c_BrushTypeTexture == m_oBrush.Type) - { - // у нас нет таких шейпов в pdf/xps - oWriter.WriteString(L"\" fillcolor=\"transparent"); - } - else - { - oWriter.WriteString(L"\" fillcolor=\"#"); - oWriter.WriteHexInt3(static_cast(ConvertColorBGRToRGB(m_oBrush.Color1))); - } - oWriter.WriteString(L"\" strokecolor=\"#"); - oWriter.WriteHexInt3(static_cast(ConvertColorBGRToRGB(m_oPen.Color))); - oWriter.WriteString(L"\" strokeweight=\""); - oWriter.AddDouble(m_oPen.Size, 2); - oWriter.WriteString(L"mm\">"); - - std::wstring g_string_fill_opacity = L""; - std::wstring g_string_stroke_opacity = L""; - - if (c_BrushTypeTexture == m_oBrush.Type && !m_bIsNoFill) - { - oWriter.WriteString(L""); - - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"(m_oBrush.TextureAlpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - else - { - if (0xFF != m_oBrush.Alpha1) - { - oWriter.WriteString(L"(m_oBrush.Alpha1 / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"(m_oPen.Alpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - - oWriter.WriteString(L""); - - if (!m_arParagraphs.empty()) - { - oWriter.WriteString(L""); - - for (size_t i = 0; i < m_arParagraphs.size(); ++i) - { - m_arParagraphs[i]->ToXml(oWriter); - } - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } -} // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index f09f6d8663f..e8df40e7397 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -4,8 +4,7 @@ namespace NSDocxRenderer { - CParagraph::CParagraph(const TextAssociationType& eType): - CBaseItem(ElemType::etParagraph), m_eTextAssociationType(eType) + CParagraph::CParagraph(): CBaseItem(ElemType::etParagraph) { } @@ -29,42 +28,6 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - switch (m_eTextConversionType) - { - case tctTextToFrame: - { - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L" w:y=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L"/>"); //конец w:framePr - break; - } - case tctTextToShape: - case tctTextToParagraph: - { oWriter.WriteString(L" 0) { @@ -80,26 +43,26 @@ namespace NSDocxRenderer oWriter.WriteString(L"\""); } - if (m_dHeight > 0) + if (m_dLineHeight > 0) { oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToDx)); + oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки } oWriter.WriteString(L"/>"); //конец w:spacing oWriter.WriteString(L" 0) + if (m_dLeftBorder > 0) { oWriter.WriteString(L" w:left=\""); - oWriter.AddInt(static_cast(m_dLeft * c_dMMToDx)); + oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); oWriter.WriteString(L"\""); } - if (m_dRight > 0) + if (m_dRightBorder > 0) { oWriter.WriteString(L" w:right=\""); - oWriter.AddInt(static_cast(m_dRight * c_dMMToDx)); + oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края oWriter.WriteString(L"\""); } if (m_bIsNeedFirstLineIndent) @@ -110,28 +73,23 @@ namespace NSDocxRenderer } oWriter.WriteString(L"/>"); //конец w:ind - - if (m_eTextAssociationType == tatPlainParagraph || - m_eTextAssociationType == tatParagraphToShape) + switch (m_eTextAlignmentType) { - switch (m_eTextAlignmentType) - { - case tatByCenter: - oWriter.WriteString(L""); - break; - case tatByRightEdge: - oWriter.WriteString(L""); - break; - case tatByWidth: - oWriter.WriteString(L""); - break; - case tatByLeftEdge: - oWriter.WriteString(L""); - break; - case tatUnknown: - default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять - break; - } + case tatByCenter: + oWriter.WriteString(L""); + break; + case tatByRightEdge: + oWriter.WriteString(L""); + break; + case tatByWidth: + oWriter.WriteString(L""); + break; + case tatByLeftEdge: + oWriter.WriteString(L""); + break; + case tatUnknown: + default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять + break; } if (m_bIsShadingPresent) @@ -140,11 +98,6 @@ namespace NSDocxRenderer oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill)); oWriter.WriteString(L"\"/>"); } - break; - } - default: - break; - } oWriter.WriteString(L""); @@ -239,9 +192,9 @@ namespace NSDocxRenderer double dNextLeft = pNextLine->m_dLeft; double dNextNextLeft = pNextNextLine ? pNextNextLine->m_dLeft : 0; - double dCurrRight = pCurrentLine->CalculateRightBorder(dPageWidth); - double dNextRight = pNextLine->CalculateRightBorder(dPageWidth); - double dNextNextRight = pNextNextLine ? pNextNextLine->CalculateRightBorder(dPageWidth) : 0; + double dCurrRight = pCurrentLine->m_dRight; + double dNextRight = pNextLine->m_dRight; + double dNextNextRight = pNextNextLine ? pNextNextLine->m_dRight : 0; bool bIf1 = fabs(dCurrLeft - dNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; bool bIf2 = pNextNextLine && fabs(dNextLeft - dNextNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; @@ -281,12 +234,12 @@ namespace NSDocxRenderer { return tatByRightEdge; } - else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) + else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) { bIsUseNextNextLine = false; return tatByWidth; } - else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) + else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) { bIsSingleLineParagraph = true; return tatByWidth; @@ -317,7 +270,7 @@ namespace NSDocxRenderer return tatByWidth; } } - else if (dCurrRight < dNextRight) + else if (dCurrRight > dNextRight) { if (bIf1 || bIf3) { @@ -328,7 +281,7 @@ namespace NSDocxRenderer return tatByCenter; } } - else if (dCurrRight > dNextRight) + else if (dCurrRight < dNextRight) { if (bIf1) { diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 493f608767e..bf8c2e00d54 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -4,14 +4,14 @@ namespace NSDocxRenderer { - enum TextAssociationType + enum class eTextAssociationType { - tatBlockChar = 0, // Каждый символ во фрейме - tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. - tatPlainLine = 2, // Каждая линия - параграф обычный - tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. - tatPlainParagraph = 4, // Линии объединяются в параграфы - tatParagraphToShape = 5 // Параграфы записываем в шейпы + tatBlockChar = 0, // Каждый символ во фрейме + tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. + tatPlainLine = 2, // Каждая линия - параграф обычный + tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. + tatPlainParagraph = 4, // Все линии объединяются в параграфы + tatParagraphToShape = 5 // Параграфы записываем в шейпы }; class CParagraph : public CBaseItem @@ -26,37 +26,27 @@ namespace NSDocxRenderer tatByWidth }; - enum TextConversionType - { - tctUnknown, - tctTextToParagraph, - tctTextToFrame, - tctTextToShape - }; - // text frame properties - TextConversionType m_eTextConversionType {tctUnknown}; bool m_bIsNeedFirstLineIndent {false}; - bool m_bIsAroundTextWrapping {true}; //по умолчанию обтекание включено, если отсутсвует w:wrap bool m_bIsShadingPresent {false}; LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR TextAlignmentType m_eTextAlignmentType {tatUnknown}; // geometry paragraph - double m_dRight {0.0}; //сдвиг относительно правого края страницы - double m_dFirstLine {0.0}; //сдвиг относительно m_dLeft + double m_dLeftBorder {0.0}; //сдвиг относительно левого края страницы/шейпа/таблицы + double m_dRightBorder {0.0}; //сдвиг относительно правого края страницы/шейпа/таблицы + double m_dFirstLine {0.0}; //сдвиг относительно m_dLeftBorder double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - - TextAssociationType m_eTextAssociationType {tatPlainParagraph}; + double m_dLineHeight {0.0}; std::vector m_arLines; size_t m_nNumLines {0}; public: - CParagraph(const TextAssociationType& eType); + CParagraph(); virtual ~CParagraph(); virtual void Clear() override final; diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 36cf602afea..671dbfe3447 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -1,7 +1,8 @@ #include "Shape.h" -#include +#include "Table.h" #include "../../resources/Constants.h" #include "../../resources/utils.h" +#include namespace NSDocxRenderer { @@ -27,7 +28,27 @@ namespace NSDocxRenderer void CShape::Clear() { - m_arParagraphs.clear(); + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); } UINT CShape::GenerateShapeId() @@ -186,23 +207,48 @@ namespace NSDocxRenderer { m_eGraphicsType = eGraphicsType::gtRectangle; - if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman - { - m_eSimpleLineType = eSimpleLineType::sltLongDash; - } - else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash + if (dHeight < 0.7) { - m_eSimpleLineType = eSimpleLineType::sltDash; + if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltHLongDash; + } + else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltHDash; + } + else //максимальна точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltHDot; + } } - else //максимальна точка - 0.5mm + else if (dWidth < 0.7) { - m_eSimpleLineType = eSimpleLineType::sltDot; + if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltVLongDash; + } + else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltVDash; + } + else //максимальна точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltVDot; + } } } else if (nCurves > 0 && nPeacks <= 1) //1 move { m_eGraphicsType = eGraphicsType::gtCurve; - m_eSimpleLineType = eSimpleLineType::sltWave; + if (dHeight < dWidth) + { + m_eSimpleLineType = eSimpleLineType::sltHWave; + } + else + { + m_eSimpleLineType = eSimpleLineType::sltVWave; + } } else if (nCurves > 0 && nPeacks > 1) { @@ -212,8 +258,8 @@ namespace NSDocxRenderer bool CShape::IsItFitLine() { - return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltDot || m_eSimpleLineType == eSimpleLineType::sltDash || m_eSimpleLineType == eSimpleLineType::sltLongDash)) || - (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltWave); + return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) || + (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave); } bool CShape::IsCorrelated(const CShape *pShape) @@ -290,16 +336,26 @@ namespace NSDocxRenderer pModObject->m_dRight = pModObject->m_dLeft + pModObject->m_dWidth; } + bool CShape::IsPeak() + { + return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; + } + + bool CShape::IsSide() + { + return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; + } + void CShape::DetermineLineType(CShape *pShape, bool bIsLast) { if (!pShape) { //Если нашелся один шейп в линии - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltLongDash) + if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltWave) + else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) { m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; } @@ -352,7 +408,7 @@ namespace NSDocxRenderer fabs(m_dLeft - pShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) { //Условие первого определения - if (m_eSimpleLineType == eSimpleLineType::sltLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltLongDash) + if (m_eSimpleLineType == eSimpleLineType::sltHLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) { if (m_dTop < pShape->m_dTop) { @@ -367,7 +423,7 @@ namespace NSDocxRenderer ChangeGeometryOfDesiredShape(pShape); } } - else if (m_eSimpleLineType == eSimpleLineType::sltWave && pShape->m_eSimpleLineType == eSimpleLineType::sltWave) + else if (m_eSimpleLineType == eSimpleLineType::sltHWave && pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) { if (m_dTop < pShape->m_dTop) { @@ -394,11 +450,11 @@ namespace NSDocxRenderer if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) { //расстояние между объектами на одной линии должно быть небольшим - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltLongDash) + if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltWave) + else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) { m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; } @@ -412,25 +468,25 @@ namespace NSDocxRenderer { switch (m_eSimpleLineType) { - case eSimpleLineType::sltDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) + case eSimpleLineType::sltHDot: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; } break; - case eSimpleLineType::sltDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) + case eSimpleLineType::sltHDash: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; } break; - case eSimpleLineType::sltLongDash: + case eSimpleLineType::sltHLongDash: if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; @@ -441,8 +497,8 @@ namespace NSDocxRenderer } break; - case eSimpleLineType::sltWave: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltWave) + case eSimpleLineType::sltHWave: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) { m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; } @@ -461,8 +517,8 @@ namespace NSDocxRenderer switch (m_eSimpleLineType) { - case eSimpleLineType::sltDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) + case eSimpleLineType::sltHDot: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted || m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) @@ -475,28 +531,28 @@ namespace NSDocxRenderer pShape->m_eLineType == eLineType::ltUnknown) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; - m_eSimpleLineType = eSimpleLineType::sltDot; + m_eSimpleLineType = eSimpleLineType::sltHDot; bIsConditionPassed = true; } } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) { if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltDash; + m_eSimpleLineType = eSimpleLineType::sltHDash; bIsConditionPassed = true; } else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltDash; + m_eSimpleLineType = eSimpleLineType::sltHDash; bIsConditionPassed = true; } } break; - case eSimpleLineType::sltDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltDash) + case eSimpleLineType::sltHDash: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) { if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash || m_eLineType == eLineType::ltDashedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) @@ -510,25 +566,25 @@ namespace NSDocxRenderer bIsConditionPassed = true; } } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltDot) + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) { m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - m_eSimpleLineType = eSimpleLineType::sltDot; + m_eSimpleLineType = eSimpleLineType::sltHDot; bIsConditionPassed = true; } else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltDot; + m_eSimpleLineType = eSimpleLineType::sltHDot; bIsConditionPassed = true; } } break; - case eSimpleLineType::sltLongDash: + case eSimpleLineType::sltHLongDash: if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7 || m_eLineType == eLineType::ltThick || m_eLineType == eLineType::ltSingle) { @@ -543,7 +599,7 @@ namespace NSDocxRenderer } break; - case eSimpleLineType::sltWave: + case eSimpleLineType::sltHWave: if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave || m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) && pShape->m_eLineType == eLineType::ltUnknown) @@ -883,13 +939,25 @@ namespace NSDocxRenderer void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) { - if (m_eType == eShapeType::stTextBox && !m_arParagraphs.empty()) + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) { oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php oWriter.WriteString(L""); - for (size_t i = 0; i < m_arParagraphs.size(); ++i) + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - m_arParagraphs[i]->ToXml(oWriter); + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } } oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 1f622128594..ee887ad4b67 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -40,11 +40,13 @@ namespace NSDocxRenderer bool m_bIsNoStroke {true}; bool m_bIsBehindDoc {true}; + bool m_bIsUseInTable {false}; + eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; eLineType m_eLineType {eLineType::ltUnknown}; - std::vector m_arParagraphs; + std::vector m_arOutputObjects; std::shared_ptr m_pImageInfo {nullptr}; @@ -59,7 +61,6 @@ namespace NSDocxRenderer CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); virtual ~CShape(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final{}; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; @@ -69,6 +70,9 @@ namespace NSDocxRenderer bool IsItFitLine(); bool IsCorrelated(const CShape* pShape); void ChangeGeometryOfDesiredShape(CShape* pShape); + + bool IsPeak(); + bool IsSide(); void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp new file mode 100644 index 00000000000..55ab2c035fd --- /dev/null +++ b/DocxRenderer/src/logic/elements/Table.cpp @@ -0,0 +1,220 @@ +#include "Table.h" + +namespace NSDocxRenderer +{ + CRow::CRow() : CBaseItem(ElemType::etTable) + { + } + + CRow::~CRow() + { + Clear(); + } + + void CRow::Clear() + { + m_arCells.clear(); + } + + void CRow::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arCells.push_back(dynamic_cast(pObj)); + } + + CTable::CTable() : CBaseItem(ElemType::etTable) + { + + } + + CTable::~CTable() + { + Clear(); + } + + void CTable::Clear() + { + m_arRows.clear(); + } + + void CTable::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arRows.push_back(dynamic_cast(pObj)); + } + + void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + if (m_bIsNeedSpacing) + { + oWriter.WriteString(L" 0) + { + oWriter.WriteString(L" w:before=\""); + oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dSpaceAfter > 0) + { + oWriter.WriteString(L" w:after=\""); + oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dLineHeight > 0) + { + oWriter.WriteString(L" w:line=\""); + oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + } + oWriter.WriteString(L"/>"); //конец w:spacing + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"dxa\"/>"); + } + else + { + oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); + oWriter.WriteString(L"\" w:tblpY=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"auto\"/>"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + for (size_t i = 0; i < m_arColumnWidths.size(); ++i) + { + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + + for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) + { + auto pRow = m_arRows[nRow]; + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"m_dHeight * c_dMMToDx); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + for (size_t j = 0; j < pRow->m_arCells.size(); ++j) + { + pRow->m_arCells[j]->ToXml(oWriter); + } + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + } + + //note: для полной таблицы, составляющей в сумме ячеек прямоугольник + void CTable::CalculateColumnWidth() + { + m_arColumnWidths.clear(); + + if (m_arRows.empty()) + { + return; + } + + //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают + //if (m_arRows.size() == 1) + { + for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) + { + m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); + } + return; + } + + double dMinWidth = 0; + double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы + CCell* pCurrCellWithMinWidth = nullptr; + + //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать + //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы + while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! + { + //находим минимальный width после текущей dCurrLeftBorder + for (size_t i = 0; i < m_arRows.size(); ++i) + { + for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) + { + auto pCell = m_arRows[i]->m_arCells[j]; + + if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) + { + if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) + { + dMinWidth = pCell->m_dRight - dCurrLeftBorder; + pCurrCellWithMinWidth = pCell; + } + break; + } + } + } + + m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); + + //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки + for (size_t i = 0; i < m_arRows.size(); ++i) + { + for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) + { + auto pCell = m_arRows[i]->m_arCells[j]; + + if (dCurrLeftBorder < pCell->m_dRight && + fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && + pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && + fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) + { + ++pCell->m_uGridSpan; + break; + } + } + } + + //сдвигаем dCurrLeftBorder + dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; + } + } +} diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h new file mode 100644 index 00000000000..1c7819e8c49 --- /dev/null +++ b/DocxRenderer/src/logic/elements/Table.h @@ -0,0 +1,43 @@ +#pragma once +#include "Cell.h" + +namespace NSDocxRenderer +{ + class CRow : public CBaseItem + { + public: + std::vector m_arCells; + + public: + CRow(); + virtual ~CRow(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final {} + }; + + class CTable : public CBaseItem + { + public: + std::vector m_arColumnWidths; //общее количество колонок в таблице + std::vector m_arRows; + + double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dLineHeight {0.0}; + bool m_bIsNeedSpacing {false}; + + public: + CTable(); + virtual ~CTable(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + + double CalculateBeforeSpacing(double dPreviousStringBaseline) + { + return m_dTop - dPreviousStringBaseline; + } + void CalculateColumnWidth(); + }; +} diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 17946d50b19..9a153478e16 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -1,6 +1,7 @@ #include "TextLine.h" #include "../../resources/Constants.h" #include "../../resources/utils.h" +#include "src/logic/elements/Shape.h" namespace NSDocxRenderer { @@ -30,22 +31,6 @@ namespace NSDocxRenderer m_arConts.push_back(dynamic_cast(pObj)); } - bool CTextLine::IsBigger(const CBaseItem* oSrc) - { - return (m_dBaselinePos > dynamic_cast(oSrc)->m_dBaselinePos) ? true : false; - } - - bool CTextLine::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dBaselinePos >= dynamic_cast(oSrc)->m_dBaselinePos) ? true : false; - } - - void CTextLine::SortConts() - { - // сортировка непрерывных слов по m_dX - SortElements(m_arConts); - } - void CTextLine::CheckLineToNecessaryToUse() { for (size_t i = 0; i < m_arConts.size(); ++i) @@ -58,34 +43,6 @@ namespace NSDocxRenderer m_bIsNotNecessaryToUse = true; } - void CTextLine::Merge(CTextLine* pLine) - { - size_t nCount = pLine->m_arConts.size(); - if (0 != nCount) - { - if (pLine->m_dLeft < m_dLeft) - { - m_dLeft = pLine->m_dLeft; - } - if (pLine->m_dBaselinePos < m_dBaselinePos) - { - m_dHeight = (m_dBaselinePos - pLine->m_dBaselinePos + pLine->m_dHeight); - } - else - { - m_dHeight = (pLine->m_dBaselinePos - m_dBaselinePos + m_dHeight); - } - - for (size_t i = 0; i < pLine->m_arConts.size(); ++i) - { - m_arConts.push_back(new CContText(*m_arConts[i])); - } - - SortConts(); - CalculateWidth(); - } - } - void CTextLine::MergeConts() { if (m_arConts.empty()) @@ -102,6 +59,7 @@ namespace NSDocxRenderer continue; } + //todo возможно стоит доработать логику bool bIsEqual = pFirst->IsEqual(pCurrent); bool bIsBigDelta = ((pFirst->m_dRight < pCurrent->m_dLeft) && ((pCurrent->m_dLeft - pFirst->m_dRight) < pCurrent->m_dSpaceWidthMM)) || fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace(); @@ -169,35 +127,6 @@ namespace NSDocxRenderer } } - void CTextLine::CalculateWidth() - { - if (m_arConts.empty()) - { - return; - } - - m_dWidth = m_arConts[0]->m_dWidth; - - for (size_t i = 1; i < m_arConts.size(); ++i) - { - m_dWidth += m_arConts[i]->m_dLeft - (m_arConts[i-1]->m_dLeft + m_arConts[i-1]->m_dWidth); - m_dWidth += m_arConts[i]->m_dWidth; - } - m_dRight = m_dLeft + m_dWidth; - } - - bool CTextLine::AreAlignmentsAppropriate(const CTextLine *pLine) - { - if ((m_eAlignmentType == pLine->m_eAlignmentType && m_eAlignmentType!= atatByLeftEdge) || - (m_eAlignmentType == atatByWidth && pLine->m_eAlignmentType == atatByLeftEdge) || - (m_eAlignmentType == atatByWidth && pLine->m_eAlignmentType == atatUnknown) || - (m_eAlignmentType == atatUnknown && pLine->m_eAlignmentType == atatByWidth)) - { - return true; - } - return false; - } - void CTextLine::SetVertAlignType(const eVertAlignType& oType) { m_eVertAlignType = oType; @@ -207,31 +136,16 @@ namespace NSDocxRenderer } } - double CTextLine::CalculateBeforeSpacing(double dPreviousStringBaseline) + bool CTextLine::IsShadingPresent(const CTextLine *pLine) { - return m_dBaselinePos - dPreviousStringBaseline - m_dHeight; - } - - double CTextLine::CalculateRightBorder(const double& dPageWidth) - { - return dPageWidth - (m_dLeft + m_dWidth); - } - - bool CTextLine::IsForceBlock() - { - // линия отсортирована, так что сравниваем только соседние conts - size_t nCount = m_arConts.size(); - if (nCount <= 1) - return false; - - for (size_t i = 0; i < nCount; ++i) + if (m_pDominantShape && pLine->m_pDominantShape && + m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && + fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) { - for (size_t j = i + 1; j < nCount; ++j) - { - if (m_arConts[i]->GetIntersect(m_arConts[j]) > 10) - return true; - } + return true; } + return false; } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 60f911818c2..dd70a3c29b2 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -21,7 +21,8 @@ namespace NSDocxRenderer eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CTextLine* m_pLine {nullptr}; + CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + CShape* m_pDominantShape {nullptr}; UINT m_iNumDuplicates {0}; @@ -29,29 +30,12 @@ namespace NSDocxRenderer CTextLine(); virtual ~CTextLine(); virtual void Clear() override final; - virtual bool IsBigger(const CBaseItem* oSrc) override final; - virtual bool IsBiggerOrEqual(const CBaseItem* oSrc) override final; virtual void AddContent(CBaseItem* pObj) override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void SortConts(); - void CheckLineToNecessaryToUse(); - - //Объединяем слова из двух строк - void Merge(CTextLine* pLine); - bool IsForceBlock(); - void MergeConts(); - //Вычисляем ширину сложной строки - void CalculateWidth(); - //Определяем на основании выравнивания подходят ли текущая и следующая строки для добавления в параграф - bool AreAlignmentsAppropriate(const CTextLine* pLine); - void SetVertAlignType(const eVertAlignType& oType); - - //Вычисляем - double CalculateBeforeSpacing(double dPreviousStringBaseline); - double CalculateRightBorder(const double& dPageWidth); + bool IsShadingPresent(const CTextLine* pLine); }; } diff --git a/DocxRenderer/src/logic/managers/StyleManager.h b/DocxRenderer/src/logic/managers/StyleManager.h index c555ad96da8..29115298b9e 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.h +++ b/DocxRenderer/src/logic/managers/StyleManager.h @@ -1,5 +1,4 @@ #pragma once -#include #include "../styles/FontStyle.h" namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index aff9871cd0a..da1d6c778ff 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -47,11 +47,11 @@ namespace NSDocxRenderer CBaseStyle::operator=(oSrc); - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; + m_oFont = oSrc.m_oFont; + m_oBrush = oSrc.m_oBrush; - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; + m_strPickFontName = oSrc.m_strPickFontName; + m_lPickFontStyle = oSrc.m_lPickFontStyle; } bool CFontStyle::IsEqual(std::shared_ptr oSrc) diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 469ad7c0ac0..89539e0b591 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -9,14 +9,14 @@ namespace NSDocxRenderer class CFontStyle : public CBaseStyle { public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; + NSStructures::CFont m_oFont; + NSStructures::CBrush m_oBrush; - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; + std::wstring m_strPickFontName {L""}; + LONG m_lPickFontStyle {0}; private: - std::wstring m_strStyleId {L""}; + std::wstring m_strStyleId {L""}; public: CFontStyle(); diff --git a/DocxRenderer/src/resources/LinesTable.h b/DocxRenderer/src/resources/LinesTable.h index 0716e56eef8..2535f1e58d5 100644 --- a/DocxRenderer/src/resources/LinesTable.h +++ b/DocxRenderer/src/resources/LinesTable.h @@ -6,10 +6,14 @@ enum class eSimpleLineType { sltUnknown, - sltDot, - sltDash, - sltLongDash, - sltWave + sltHDot, //Horizontal + sltVDot, //Vertical + sltHDash, + sltVDash, + sltHLongDash, + sltVLongDash, + sltHWave, + sltVWave }; enum class eLineType diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index c848290d6b1..afe0cd02acb 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,8 +1,6 @@ #pragma once #include "../DesktopEditor/common/Types.h" #include "../DesktopEditor/common/StringUTF32.h" -#include -#include inline LONG ConvertColorBGRToRGB(LONG lBGR) { @@ -57,12 +55,3 @@ inline int little_endian_2_big_endian( int i ) { return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); } - -// у класса T должен быть метод IsBigger -template -void SortElements(std::vector& oArray) -{ - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return b->IsBigger(a); - }); -} diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 81289049a36..95f7673b426 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -165,12 +165,11 @@ int main(int argc, char *argv[]) std::wstring sZip = L"/" + sFileName + L".zip"; // проверить все режимы - NSDocxRenderer::TextAssociationType taType; - //taType = NSDocxRenderer::tatBlockChar; - //taType = NSDocxRenderer::tatBlockLine; - //taType = NSDocxRenderer::tatPlainLine; - //taType = NSDocxRenderer::tatShapeLine; - taType = NSDocxRenderer::tatPlainParagraph; + NSDocxRenderer::eTextAssociationType taType; + //taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; + //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; + //taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; + taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; oDocxRenderer.SetTextAssociationType(taType); oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); From 74c4bf6236d74f9f24d7c441092abce270bcc810 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 19 Jan 2023 14:02:27 +0300 Subject: [PATCH 008/794] Fix docx_renderer test build --- DocxRenderer/test/main.cpp | 12 ++++++------ DocxRenderer/test/test.pro | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 95f7673b426..61745fc1e35 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -35,7 +35,7 @@ #include "../../DesktopEditor/graphics/pro/Graphics.h" #include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" -#include "../../PdfReader/PdfReader.h" +#include "../../PdfFile/PdfFile.h" #include "../../DjVuFile/DjVu.h" #include "../../XpsFile/XpsFile.h" #include "../DocxRenderer.h" @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = NSFile::GetProcessDirectory() + L"/temp"; - std::wstring sTempDirOut = NSFile::GetProcessDirectory() + L"/temp/output"; + std::wstring sTempDir = L""; + std::wstring sTempDirOut = L""; if (!NSDirectory::Exists(sTempDir)) NSDirectory::CreateDirectory(sTempDir); @@ -91,9 +91,9 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - //sSourceFiles.push_back(L"C:\\File.pdf"); + sSourceFiles.push_back(L""); - std::wstring sTextDirOut = NSFile::GetProcessDirectory() + L"/text"; + std::wstring sTextDirOut = L""; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); @@ -113,7 +113,7 @@ int main(int argc, char *argv[]) switch (nFileType) { case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: - pReader = new PdfReader::CPdfReader(pFonts); + pReader = new CPdfFile(pFonts); break; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: pReader = new CXpsFile(pFonts); diff --git a/DocxRenderer/test/test.pro b/DocxRenderer/test/test.pro index 44bab3ae049..bf9b253f02d 100644 --- a/DocxRenderer/test/test.pro +++ b/DocxRenderer/test/test.pro @@ -13,7 +13,7 @@ CORE_ROOT_DIR = $$PWD/../.. PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfReader, DjVuFile, XpsFile, PdfWriter, DocxRenderer) +ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfFile, DjVuFile, XpsFile, DocxRenderer) core_linux:include($$PWD/../../Common/3dParty/icu/icu.pri) core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32 @@ -25,7 +25,7 @@ SOURCES += main.cpp SOURCES += \ $$CORE_ROOT_DIR/Common/OfficeFileFormatChecker2.cpp \ $$CORE_ROOT_DIR/Common/3dParty/pole/pole.cpp \ - $$CORE_ROOT_DIR/Common/DocxFormat/Source/Base/unicode_util.cpp + $$CORE_ROOT_DIR/OOXML/Base/unicode_util.cpp DESTDIR = $$PWD_ROOT_DIR/build From 5cac25286da5f519a828d74a0e0d1cebae5dd24e Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 19 Feb 2023 12:27:08 +0300 Subject: [PATCH 009/794] Refactoring --- DocxRenderer/src/logic/Page.cpp | 133 +++++++++--------- DocxRenderer/src/logic/elements/ContText.cpp | 3 + .../src/logic/managers/FontManager.cpp | 42 +++--- .../src/logic/managers/FontManagerBase.cpp | 88 ++++++------ .../src/logic/managers/FontManagerBase.h | 2 +- 5 files changed, 134 insertions(+), 134 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 8e7ed8bb504..9054ccfa4c8 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -384,7 +384,7 @@ namespace NSDocxRenderer pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dTop = dBaseLinePos - dTextH - m_pFontManager->m_oFont.m_dBaselineOffset; + pCont->m_dTop = dBaseLinePos - dTextH - m_pFontManager->m_oFontAdvanced.m_dBaselineOffset; pCont->m_dWidth = dTextW; pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; @@ -392,7 +392,7 @@ namespace NSDocxRenderer pCont->m_oText = oText; //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = m_pFontManager->m_oFont.m_oFont; + m_pStyleManager->m_pCurrentStyle->m_oFont = m_pFontManager->m_oFontAdvanced.m_oFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; if (!bIsPath) @@ -918,13 +918,9 @@ namespace NSDocxRenderer } AnalyzeCollectedConts(); - DetermineStrikeoutsUnderlinesHighlights(); - AddDiacriticalSymbols(); - - MergeLinesByVertAlignType(); - + MergeLinesByVertAlignType(); DeleteTextClipPage(); //DetermineTextColumns(); @@ -937,44 +933,42 @@ namespace NSDocxRenderer void CPage::AnalyzeCollectedConts() { - //определение различных эффектов на основании взаимного расположения символов + // определение различных эффектов на основании взаимного расположения символов + + // идем по всем текстовым линиям for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) { + // берем текущую линию auto pCurrLine = m_arTextLine[uCurrLineIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { continue; - } + // символы в текущей линии for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) { + // берем символ в текущей линии auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - if (pCurrCont->m_bIsNotNecessaryToUse) - { continue; - } + // берем вторую линию, если символ последний - то начиная со следуюущей, иначе с той же for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLine.size(); ++uNextLineIndex) { auto pNextLine = m_arTextLine[uNextLineIndex]; - if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine)) //note значительно ускоряет работу - { + // значительно ускоряет работу, то есть если никак не перескается - некст + if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine)) continue; - } + // посимвольно смотрим некст линию - если та же то следующий символ, если другая - то с нуля for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) { + // берем символ во второй линии auto pNextCont = pNextLine->m_arConts[uNextContIndex]; - if (pNextCont->m_bIsNotNecessaryToUse) - { continue; - } eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont); eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont); @@ -1018,11 +1012,8 @@ namespace NSDocxRenderer { auto pShape = m_arShapes[i]; - if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || - pShape->m_bIsNotNecessaryToUse) - { + if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || pShape->m_bIsNotNecessaryToUse) continue; - } for (size_t j = 0; j < m_arTextLine.size(); ++j) { @@ -1048,17 +1039,40 @@ namespace NSDocxRenderer eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); - bool bIf1 = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; - bool bIf2 = IsLineCrossingText(pShape, pCurrCont, eHType); - bool bIf3 = IsLineBelowText(pShape, pCurrCont, eHType); - bool bIf4 = IsItHighlightingBackground(pShape, pCurrCont, eHType); - - if (bIf1 && (bIf2 || bIf3 || bIf4)) - { + bool bIsComplicatedFigure = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; + bool bIsLineCrossingText = IsLineCrossingText(pShape, pCurrCont, eHType); + bool bIsLineBelowText = IsLineBelowText(pShape, pCurrCont, eHType); + bool bIsItHighlightingBackground = IsItHighlightingBackground(pShape, pCurrCont, eHType); + + if(bIsLineCrossingText) + { + pCurrCont->m_bIsStrikeoutPresent = true; + if (pShape->m_eLineType == eLineType::ltDouble) + pCurrCont->m_bIsDoubleStrikeout = true; + } + + if(bIsLineBelowText) + { + pCurrCont->m_bIsUnderlinePresent = true; + pCurrCont->m_eUnderlineType = pShape->m_eLineType; + + // почему 0.3? + pCurrCont->m_lUnderlineColor = pShape->m_dHeight > 0.3 ? pShape->m_oBrush.Color1 : pShape->m_oPen.Color; + } + + if(bIsItHighlightingBackground) + { + //Удовлетворяет расположением и размером - привязываем указатель на картинку + pCurrCont->m_pShape = pShape; + pCurrCont->m_bIsHighlightPresent = true; + pCurrCont->m_lHighlightColor = pShape->m_oBrush.Color1; + } + + // проверили - удаляем + if (bIsComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) pShape->m_bIsNotNecessaryToUse = true; - } - if (!bIf1) + if (!bIsComplicatedFigure) { bool bIf1 = pCurrCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; @@ -1088,32 +1102,26 @@ namespace NSDocxRenderer bool CPage::IsLineCrossingText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) { - double dTopBorder = pCont->m_dTop + pCont->m_dHeight/3; //note Height - это максимально возможный размер символа. Больше реального размера. + // Height - это максимально возможный размер символа. Больше реального размера. + double dTopBorder = pCont->m_dTop + pCont->m_dHeight / 3; bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle && pShape->m_eLineType != eLineType::ltUnknown; - //Условие пересечения по вертикали + + // Условие пересечения по вертикали bool bIf2 = pShape->m_dTop > dTopBorder && pShape->m_dBaselinePos < pCont->m_dBaselinePos; - //Условие пересечения по горизонтали + + // Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Условие для размеров по высоте + + // Условие для размеров по высоте bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; - if (bIf1 && bIf2 && bIf3 && bIf4) - { - pCont->m_bIsStrikeoutPresent = true;; - if (pShape->m_eLineType == eLineType::ltDouble) - { - pCont->m_bIsDoubleStrikeout = true; - } - return true; - } - - return false; + return bIf1 && bIf2 && bIf3 && bIf4; } bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) @@ -1121,27 +1129,22 @@ namespace NSDocxRenderer //todo распознавание работает не для всех размеров шрифтов - возможно 0.15 мало или улучшить логику bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || pShape->m_eGraphicsType == eGraphicsType::gtCurve) && - pShape->m_eLineType != eLineType::ltUnknown; + pShape->m_eLineType != eLineType::ltUnknown; + //Условие по вертикали bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.15; + //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + //Условие для размеров по высоте bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; - if (bIf1 && bIf2 && bIf3 && bIf4) - { - pCont->m_bIsUnderlinePresent = true;; - pCont->m_eUnderlineType = pShape->m_eLineType; - pCont->m_lUnderlineColor = pShape->m_dHeight > 0.3 ? pShape->m_oBrush.Color1 : pShape->m_oPen.Color; - return true; - } - - return false; + return bIf1 && bIf2 && bIf3 && bIf4; } bool CPage::IsItHighlightingBackground(CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) @@ -1151,31 +1154,25 @@ namespace NSDocxRenderer double dSomeBaseLine3 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.25; bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle; + //Условие пересечения по вертикали bool bIf2 = (dSomeBaseLine1 > pShape->m_dTop && dSomeBaseLine1 < pShape->m_dBaselinePos && dSomeBaseLine2 > pShape->m_dTop && dSomeBaseLine2 < pShape->m_dBaselinePos && dSomeBaseLine3 > pShape->m_dTop && dSomeBaseLine3 < pShape->m_dBaselinePos); + //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + //Цвета должны быть разными bool bIf4 = pCont->m_pFontStyle->m_oBrush.Color1 != pShape->m_oBrush.Color1; bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; bool bIf6 = pShape->m_bIsNoFill == false; bool bIf7 = pShape->m_bIsNoStroke == true; - if (bIf1 && bIf2 && bIf3 && bIf4 && !bIf5 && bIf6 && bIf7) - { - //Удовлетворяет расположением и размером - привязываем указатель на картинку - pCont->m_pShape = pShape; - pCont->m_bIsHighlightPresent = true; - pCont->m_lHighlightColor = pShape->m_oBrush.Color1; - return true; - } - - return false; + return bIf1 && bIf2 && bIf3 && bIf4 && !bIf5 && bIf6 && bIf7; } void CPage::AddDiacriticalSymbols() diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 164277e262b..2051d21a53b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -371,12 +371,15 @@ namespace NSDocxRenderer //Условие пересечения по вертикали bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже + //Условие пересечения по горизонтали bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее + //Размеры шрифта и текст должны бать одинаковыми bool bIf5 = m_pFontStyle->m_oFont.Size == pCont->m_pFontStyle->m_oFont.Size; bool bIf6 = m_oText == pCont->m_oText; + //Цвет тени должен быть серым bool bIf7 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; bool bIf8 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 78ea14ecb1f..5a8fcff0e8b 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -36,16 +36,16 @@ namespace NSDocxRenderer void CFontManager::AddFontToMap() { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_oFont.m_strFamilyName)) + if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_oFontAdvanced.m_strFamilyName)) { CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_oFont.m_strFamilyName; - oEntry.m_strPANOSE = m_oFont.m_strPANOSE; - oEntry.m_lStyle = m_oFont.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFont.m_arSignature; + oEntry.m_strFamilyName = m_oFontAdvanced.m_strFamilyName; + oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; + oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; + oEntry.m_bIsFixedWidth = m_oFontAdvanced.m_bIsFixedWidth; + oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; - m_oFontTable.m_mapTable.insert(std::pair(m_oFont.m_strFamilyName, oEntry)); + m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); } } @@ -61,26 +61,26 @@ namespace NSDocxRenderer m_pFont->Size = dSizeFont; - if (m_pFont->IsEqual2(&m_oFont.m_oFont)) + if (m_pFont->IsEqual2(&m_oFontAdvanced.m_oFont)) { m_pFont->Size = dSize; m_pManager->SetCharSpacing(dPix); return; } - m_oFont.m_oFont = *m_pFont; + m_oFontAdvanced.m_oFont = *m_pFont; m_pFont->Size = dSize; if (m_pFont->Path.empty()) { - CFontManagerBase::LoadFontByName(m_oFont.m_oFont.Name, m_oFont.m_oFont.Size, m_oFont.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); + CFontManagerBase::LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); } else { - CFontManagerBase::LoadFontByFile(m_oFont.m_oFont.Path, m_oFont.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex); + CFontManagerBase::LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex); - m_pFont->SetStyle(m_oFont.m_lStyle); - m_oFont.m_oFont.SetStyle(m_oFont.m_lStyle); + m_pFont->SetStyle(m_oFontAdvanced.m_lStyle); + m_oFontAdvanced.m_oFont.SetStyle(m_oFontAdvanced.m_lStyle); } int bIsGID = m_pManager->GetStringGID(); @@ -177,16 +177,16 @@ namespace NSDocxRenderer { LoadFont(); - double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent; + double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; d1 /= 2.0; - d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); + d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); return d1; } double CFontManager::GetFontHeight() { - return c_dPtToMM * (m_oFont.m_dLineSpacing * m_oFont.m_oFont.Size ) / m_oFont.m_dEmHeight; + return c_dPtToMM * (m_oFontAdvanced.m_dLineSpacing * m_oFontAdvanced.m_oFont.Size ) / m_oFontAdvanced.m_dEmHeight; } void CFontManager::SetStringGid(const LONG& lGid) @@ -205,12 +205,12 @@ namespace NSDocxRenderer { CFontTableEntry oEntry; oEntry.m_strFamilyName = m_strCurrentPickFont; - oEntry.m_strPANOSE = m_oFont.m_strPANOSE; - oEntry.m_lStyle = m_oFont.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFont.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFont.m_arSignature; + oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; + oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; + oEntry.m_bIsFixedWidth = m_oFontAdvanced.m_bIsFixedWidth; + oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; - m_oFontTable.m_mapTable.insert(std::pair(m_oFont.m_strFamilyName, oEntry)); + m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); } } } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp index b3c32a99d92..ee89f1db8d5 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ b/DocxRenderer/src/logic/managers/FontManagerBase.cpp @@ -337,7 +337,7 @@ namespace NSFontManager LoadFontMetrics(); LoadFontParams(); - m_oFont.m_lAvgWidth = -1; + m_oFontAdvanced.m_lAvgWidth = -1; } void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) @@ -347,10 +347,10 @@ namespace NSFontManager LoadFontMetrics(); LoadFontParams(); - m_oFont.m_oFont.Name = m_pManager->GetName(); - m_oFont.m_strFamilyName = m_oFont.m_oFont.Name; + m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); + m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; - m_oFont.m_lAvgWidth = -1; + m_oFontAdvanced.m_lAvgWidth = -1; bool bIsCID = false; std::wstring sFileExt = NSFile::GetFileExtention(strPath); @@ -384,7 +384,7 @@ namespace NSFontManager { std::wstring sValue = oCurNode.GetAttribute(L"value"); try { - m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue); + m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); } catch (std::invalid_argument &) {} } } @@ -401,7 +401,7 @@ namespace NSFontManager { std::wstring sValue = oCurNode.GetAttribute(L"value"); try { - m_oFont.m_lAvgWidth = (SHORT)std::stol(sValue); + m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); } catch (std::invalid_argument &) {} } } @@ -413,21 +413,21 @@ namespace NSFontManager { LoadFont(); - double d1 = 3 * (m_oFont.m_dLineSpacing - m_oFont.m_dDescent) - m_oFont.m_dAscent; + double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; d1 /= 2.0; - d1 *= (m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); - m_oFont.m_dBaselineOffset = d1; + d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); + m_oFontAdvanced.m_dBaselineOffset = d1; } void CFontManagerBase::LoadFontMetrics() { - m_oFont.m_dAscent = m_pManager->GetAscender(); - m_oFont.m_dDescent = m_pManager->GetDescender(); - m_oFont.m_dLineSpacing = m_pManager->GetLineHeight(); - m_oFont.m_dEmHeight = m_pManager->GetUnitsPerEm(); + m_oFontAdvanced.m_dAscent = m_pManager->GetAscender(); + m_oFontAdvanced.m_dDescent = m_pManager->GetDescender(); + m_oFontAdvanced.m_dLineSpacing = m_pManager->GetLineHeight(); + m_oFontAdvanced.m_dEmHeight = m_pManager->GetUnitsPerEm(); - m_oFont.m_dBaselineOffset = (c_dPtToMM * m_oFont.m_dDescent * m_oFont.m_oFont.Size / m_oFont.m_dEmHeight); + m_oFontAdvanced.m_dBaselineOffset = (c_dPtToMM * m_oFontAdvanced.m_dDescent * m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); } std::wstring CFontManagerBase::ToHexString( BYTE uc ) @@ -455,32 +455,32 @@ namespace NSFontManager if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) return; - m_oFont.m_strFamilyName = m_oFont.m_oFont.Name; + m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; - m_oFont.m_lStyle = 0x00; + m_oFontAdvanced.m_lStyle = 0x00; if (m_pManager->GetFile()->IsBold()) { - m_oFont.m_lStyle |= 0x01; + m_oFontAdvanced.m_lStyle |= 0x01; } if (m_pManager->GetFile()->IsItalic()) { - m_oFont.m_lStyle |= 0x02; + m_oFontAdvanced.m_lStyle |= 0x02; } // PANOSE BYTE pPanose[10]; m_pManager->GetFile()->GetPanose(pPanose); - m_oFont.m_strPANOSE.clear(); + m_oFontAdvanced.m_strPANOSE.clear(); for ( int i = 0; i < 10; ++i ) { - m_oFont.m_strPANOSE += ToHexString(pPanose[i]); + m_oFontAdvanced.m_strPANOSE += ToHexString(pPanose[i]); } // IsFixed - m_oFont.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); + m_oFontAdvanced.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); // Signature - m_oFont.m_arSignature.clear(); + m_oFontAdvanced.m_arSignature.clear(); for ( unsigned int i = 0; i < 6; ++i ) { @@ -494,7 +494,7 @@ namespace NSFontManager } } - m_oFont.m_arSignature.push_back(value); + m_oFontAdvanced.m_arSignature.push_back(value); } } @@ -512,10 +512,10 @@ namespace NSFontManager bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText) { - if (m_oFont.m_oFont.Path.empty() || oText.empty()) + if (m_oFontAdvanced.m_oFont.Path.empty() || oText.empty()) { - m_strCurrentPickFont = m_oFont.m_strFamilyName; - m_lCurrentPictFontStyle = m_oFont.m_lStyle; + m_strCurrentPickFont = m_oFontAdvanced.m_strFamilyName; + m_lCurrentPictFontStyle = m_oFontAdvanced.m_lStyle; return false; } @@ -530,7 +530,7 @@ namespace NSFontManager { std::list::iterator posOld = pos; CFontPickUp& oPick = *(pos++); - if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFont.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) + if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) { // нашли! ничего подбирать не нужно // нужно просто выкинуть этот шрифт наверх @@ -545,14 +545,14 @@ namespace NSFontManager CFontPickUp oPick; oPick.m_lRangeNum = lRangeNum; oPick.m_lRange = lRange; - oPick.m_oFont = m_oFont; - oPick.m_strPickFont = m_oFont.m_strFamilyName; - oPick.m_lPickStyle = m_oFont.m_lStyle; - - UINT dwR1 = m_oFont.m_arSignature[0]; - UINT dwR2 = m_oFont.m_arSignature[1]; - UINT dwR3 = m_oFont.m_arSignature[2]; - UINT dwR4 = m_oFont.m_arSignature[3]; + oPick.m_oFont = m_oFontAdvanced; + oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; + oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; + + UINT dwR1 = m_oFontAdvanced.m_arSignature[0]; + UINT dwR2 = m_oFontAdvanced.m_arSignature[1]; + UINT dwR3 = m_oFontAdvanced.m_arSignature[2]; + UINT dwR4 = m_oFontAdvanced.m_arSignature[3]; UINT dwCodePage1 = 0; UINT dwCodePage2 = 0; @@ -576,10 +576,10 @@ namespace NSFontManager NSFonts::CFontSelectFormat oFormat; std::wstring sFontNameSelect = L""; - if (m_oFont.m_strFamilyName.empty() && !m_oFont.m_oFont.Path.empty()) + if (m_oFontAdvanced.m_strFamilyName.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) sFontNameSelect = m_strDefaultFont; else - sFontNameSelect = m_oFont.m_strFamilyName; + sFontNameSelect = m_oFontAdvanced.m_strFamilyName; bool bSelectBold = false; bool bSelectItalic = false; @@ -587,11 +587,11 @@ namespace NSFontManager oFormat.wsName = new std::wstring(sFontNameSelect); - if (!m_oFont.m_strPANOSE.empty()) + if (!m_oFontAdvanced.m_strPANOSE.empty()) { oFormat.pPanose = new BYTE[10]; - const wchar_t* pPanoseStr = m_oFont.m_strPANOSE.c_str(); + const wchar_t* pPanoseStr = m_oFontAdvanced.m_strPANOSE.c_str(); for (int i = 0; i < 10; ++i) { oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]); @@ -599,11 +599,11 @@ namespace NSFontManager } } - oFormat.bBold = new INT(((m_oFont.m_lStyle & 0x01) == 0x01) ? 1 : 0); - oFormat.bItalic = new INT(((m_oFont.m_lStyle & 0x02) == 0x02) ? 1 : 0); - oFormat.bFixedWidth = new INT(m_oFont.m_bIsFixedWidth ? 1 : 0); - if (-1 != m_oFont.m_lAvgWidth) - oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFont.m_lAvgWidth); + oFormat.bBold = new INT(((m_oFontAdvanced.m_lStyle & 0x01) == 0x01) ? 1 : 0); + oFormat.bItalic = new INT(((m_oFontAdvanced.m_lStyle & 0x02) == 0x02) ? 1 : 0); + oFormat.bFixedWidth = new INT(m_oFontAdvanced.m_bIsFixedWidth ? 1 : 0); + if (-1 != m_oFontAdvanced.m_lAvgWidth) + oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFontAdvanced.m_lAvgWidth); oFormat.ulRange1 = new UINT(dwR1); oFormat.ulRange2 = new UINT(dwR2); oFormat.ulRange3 = new UINT(dwR3); diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.h b/DocxRenderer/src/logic/managers/FontManagerBase.h index 7e29b7acade..64f14dfebc0 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.h +++ b/DocxRenderer/src/logic/managers/FontManagerBase.h @@ -103,7 +103,7 @@ namespace NSFontManager public: - CFontAdvanced m_oFont; + CFontAdvanced m_oFontAdvanced; //для подбора шрифтов CUnicodeRanges m_oRanges; From 623e6644781db123fb3a9ff5af46b89ac24873a8 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 19 Feb 2023 12:37:53 +0300 Subject: [PATCH 010/794] indents update tabs instead of spaces --- DocxRenderer/DocxRenderer.cpp | 308 +- DocxRenderer/DocxRenderer.h | 284 +- DocxRenderer/src/logic/Document.cpp | 2430 ++++++------- DocxRenderer/src/logic/Document.h | 394 +-- DocxRenderer/src/logic/Page.cpp | 3118 ++++++++--------- DocxRenderer/src/logic/Page.h | 216 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 370 +- DocxRenderer/src/logic/elements/BaseItem.h | 194 +- DocxRenderer/src/logic/elements/Cell.cpp | 416 +-- DocxRenderer/src/logic/elements/Cell.h | 142 +- DocxRenderer/src/logic/elements/ContText.cpp | 1012 +++--- DocxRenderer/src/logic/elements/ContText.h | 102 +- DocxRenderer/src/logic/elements/Converter.cpp | 1480 ++++---- DocxRenderer/src/logic/elements/Converter.h | 40 +- DocxRenderer/src/logic/elements/Image.cpp | 86 +- DocxRenderer/src/logic/elements/Image.h | 24 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 584 +-- DocxRenderer/src/logic/elements/Paragraph.h | 112 +- DocxRenderer/src/logic/elements/Shape.cpp | 1980 +++++------ DocxRenderer/src/logic/elements/Shape.h | 166 +- DocxRenderer/src/logic/elements/Table.cpp | 430 +-- DocxRenderer/src/logic/elements/Table.h | 64 +- DocxRenderer/src/logic/elements/TextLine.cpp | 376 +- DocxRenderer/src/logic/elements/TextLine.h | 70 +- .../src/logic/managers/FontManager.cpp | 436 +-- DocxRenderer/src/logic/managers/FontManager.h | 126 +- .../src/logic/managers/FontManagerBase.cpp | 1244 +++---- .../src/logic/managers/FontManagerBase.h | 224 +- .../src/logic/managers/ImageManager.cpp | 406 +-- .../src/logic/managers/ImageManager.h | 50 +- .../src/logic/managers/StyleManager.cpp | 76 +- .../src/logic/managers/StyleManager.h | 24 +- DocxRenderer/src/logic/styles/BaseStyle.h | 74 +- DocxRenderer/src/logic/styles/FontStyle.cpp | 330 +- DocxRenderer/src/logic/styles/FontStyle.h | 36 +- DocxRenderer/src/resources/ColorTable.h | 102 +- DocxRenderer/src/resources/ImageInfo.h | 74 +- DocxRenderer/src/resources/LinesTable.h | 130 +- .../src/resources/SingletonTemplate.h | 20 +- DocxRenderer/src/resources/VectorGraphics.cpp | 334 +- DocxRenderer/src/resources/VectorGraphics.h | 90 +- DocxRenderer/src/resources/resources.cpp | 74 +- DocxRenderer/src/resources/utils.h | 44 +- DocxRenderer/test/main.cpp | 16 +- 44 files changed, 9154 insertions(+), 9154 deletions(-) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 4824f36f2a2..e296338e9a2 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -37,493 +37,493 @@ class CDocxRenderer_Private { - public: - NSDocxRenderer::CDocument m_oDocument; - std::wstring m_sTempDirectory; +public: + NSDocxRenderer::CDocument m_oDocument; + std::wstring m_sTempDirectory; - public: - CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts) - { - } - ~CDocxRenderer_Private() - { +public: + CDocxRenderer_Private(NSFonts::IApplicationFonts* pFonts, IRenderer* pRenderer) : m_oDocument(pRenderer, pFonts) + { + } + ~CDocxRenderer_Private() + { - } + } }; CDocxRenderer::CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts) { - m_pInternal = new CDocxRenderer_Private(pAppFonts, this); + m_pInternal = new CDocxRenderer_Private(pAppFonts, this); } CDocxRenderer::~CDocxRenderer() { - RELEASEOBJECT(m_pInternal); + RELEASEOBJECT(m_pInternal); } HRESULT CDocxRenderer::CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress) { - m_pInternal->m_oDocument.m_strDstFilePath = wsPath; - m_pInternal->m_oDocument.m_strTempDirectory = bIsOutCompress ? - NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory) : - m_pInternal->m_sTempDirectory; - m_pInternal->m_oDocument.CreateDocument(); - return S_OK; + m_pInternal->m_oDocument.m_strDstFilePath = wsPath; + m_pInternal->m_oDocument.m_strTempDirectory = bIsOutCompress ? + NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory) : + m_pInternal->m_sTempDirectory; + m_pInternal->m_oDocument.CreateDocument(); + return S_OK; } HRESULT CDocxRenderer::Close() { - COfficeUtils oCOfficeUtils(nullptr); - HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true); - if (!m_pInternal->m_oDocument.m_strTempDirectory.empty()) - NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory); - m_pInternal->m_oDocument.m_strTempDirectory = L""; - return hr; + COfficeUtils oCOfficeUtils(nullptr); + HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true); + if (!m_pInternal->m_oDocument.m_strTempDirectory.empty()) + NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory); + m_pInternal->m_oDocument.m_strTempDirectory = L""; + return hr; } HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType) { - m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; - return S_OK; + m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; + return S_OK; } int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) { - CreateNewFile(sDstFile, bIsOutCompress); + CreateNewFile(sDstFile, bIsOutCompress); - if (odftPDF == pFile->GetType()) - m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; + if (odftPDF == pFile->GetType()) + m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; - int nPagesCount = pFile->GetPagesCount(); - m_pInternal->m_oDocument.m_lNumberPages = nPagesCount; + int nPagesCount = pFile->GetPagesCount(); + m_pInternal->m_oDocument.m_lNumberPages = nPagesCount; - for (int i = 0; i < nPagesCount; ++i) - { - //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; - NewPage(); - BeginCommand(c_nPageType); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; - m_pInternal->m_oDocument.m_lPagesCount = i; + for (int i = 0; i < nPagesCount; ++i) + { + //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; + NewPage(); + BeginCommand(c_nPageType); + m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; + m_pInternal->m_oDocument.m_lPagesCount = i; - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; - put_Width(dWidth); - put_Height(dHeight); + put_Width(dWidth); + put_Height(dHeight); - pFile->DrawPageOnRenderer(this, i, nullptr); + pFile->DrawPageOnRenderer(this, i, nullptr); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; - EndCommand(c_nPageType); - } + m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; + EndCommand(c_nPageType); + } - HRESULT hr = S_OK; - m_pInternal->m_oDocument.Close(); - if (bIsOutCompress) - hr = Close(); - return (hr == S_OK) ? 0 : 1; + HRESULT hr = S_OK; + m_pInternal->m_oDocument.Close(); + if (bIsOutCompress) + hr = Close(); + return (hr == S_OK) ? 0 : 1; } HRESULT CDocxRenderer::SetTempFolder(const std::wstring& wsPath) { - m_pInternal->m_sTempDirectory = wsPath; - return S_OK; + m_pInternal->m_sTempDirectory = wsPath; + return S_OK; } //---------------------------------------------------------------------------------------- // Тип рендерера //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_Type(LONG* lType) { - *lType = c_nDocxWriter; - return S_OK; + *lType = c_nDocxWriter; + return S_OK; } //---------------------------------------------------------------------------------------- // Функции для работы со страницей //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::NewPage() { - return m_pInternal->m_oDocument.NewPage(); + return m_pInternal->m_oDocument.NewPage(); } HRESULT CDocxRenderer::get_Height(double* dHeight) { - return m_pInternal->m_oDocument.get_Height(dHeight); + return m_pInternal->m_oDocument.get_Height(dHeight); } HRESULT CDocxRenderer::put_Height(const double& dHeight) { - return m_pInternal->m_oDocument.put_Height(dHeight); + return m_pInternal->m_oDocument.put_Height(dHeight); } HRESULT CDocxRenderer::get_Width(double* dWidth) { - return m_pInternal->m_oDocument.get_Width(dWidth); + return m_pInternal->m_oDocument.get_Width(dWidth); } HRESULT CDocxRenderer::put_Width(const double& dWidth) { - return m_pInternal->m_oDocument.put_Width(dWidth); + return m_pInternal->m_oDocument.put_Width(dWidth); } HRESULT CDocxRenderer::get_DpiX(double* dDpiX) { - return m_pInternal->m_oDocument.get_DpiX(dDpiX); + return m_pInternal->m_oDocument.get_DpiX(dDpiX); } HRESULT CDocxRenderer::get_DpiY(double* dDpiY) { - return m_pInternal->m_oDocument.get_DpiY(dDpiY); + return m_pInternal->m_oDocument.get_DpiY(dDpiY); } //---------------------------------------------------------------------------------------- // Функции для работы с Pen //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_PenColor(LONG* lColor) { - return m_pInternal->m_oDocument.get_PenColor(lColor); + return m_pInternal->m_oDocument.get_PenColor(lColor); } HRESULT CDocxRenderer::put_PenColor(const LONG& lColor) { - return m_pInternal->m_oDocument.put_PenColor(lColor); + return m_pInternal->m_oDocument.put_PenColor(lColor); } HRESULT CDocxRenderer::get_PenAlpha(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_PenAlpha(lAlpha); + return m_pInternal->m_oDocument.get_PenAlpha(lAlpha); } HRESULT CDocxRenderer::put_PenAlpha(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_PenAlpha(lAlpha); + return m_pInternal->m_oDocument.put_PenAlpha(lAlpha); } HRESULT CDocxRenderer::get_PenSize(double* dSize) { - return m_pInternal->m_oDocument.get_PenSize(dSize); + return m_pInternal->m_oDocument.get_PenSize(dSize); } HRESULT CDocxRenderer::put_PenSize(const double& dSize) { - return m_pInternal->m_oDocument.put_PenSize(dSize); + return m_pInternal->m_oDocument.put_PenSize(dSize); } HRESULT CDocxRenderer::get_PenDashStyle(BYTE* nDashStyle) { - return m_pInternal->m_oDocument.get_PenDashStyle(nDashStyle); + return m_pInternal->m_oDocument.get_PenDashStyle(nDashStyle); } HRESULT CDocxRenderer::put_PenDashStyle(const BYTE& nDashStyle) { - return m_pInternal->m_oDocument.put_PenDashStyle(nDashStyle); + return m_pInternal->m_oDocument.put_PenDashStyle(nDashStyle); } HRESULT CDocxRenderer::get_PenLineStartCap(BYTE* nCapStyle) { - return m_pInternal->m_oDocument.get_PenLineStartCap(nCapStyle); + return m_pInternal->m_oDocument.get_PenLineStartCap(nCapStyle); } HRESULT CDocxRenderer::put_PenLineStartCap(const BYTE& nCapStyle) { - return m_pInternal->m_oDocument.put_PenLineStartCap(nCapStyle); + return m_pInternal->m_oDocument.put_PenLineStartCap(nCapStyle); } HRESULT CDocxRenderer::get_PenLineEndCap(BYTE* nCapStyle) { - return m_pInternal->m_oDocument.get_PenLineEndCap(nCapStyle); + return m_pInternal->m_oDocument.get_PenLineEndCap(nCapStyle); } HRESULT CDocxRenderer::put_PenLineEndCap(const BYTE& nCapStyle) { - return m_pInternal->m_oDocument.put_PenLineEndCap(nCapStyle); + return m_pInternal->m_oDocument.put_PenLineEndCap(nCapStyle); } HRESULT CDocxRenderer::get_PenLineJoin(BYTE* nJoinStyle) { - return m_pInternal->m_oDocument.get_PenLineJoin(nJoinStyle); + return m_pInternal->m_oDocument.get_PenLineJoin(nJoinStyle); } HRESULT CDocxRenderer::put_PenLineJoin(const BYTE& nJoinStyle) { - return m_pInternal->m_oDocument.put_PenLineJoin(nJoinStyle); + return m_pInternal->m_oDocument.put_PenLineJoin(nJoinStyle); } HRESULT CDocxRenderer::get_PenDashOffset(double* dOffset) { - return m_pInternal->m_oDocument.get_PenDashOffset(dOffset); + return m_pInternal->m_oDocument.get_PenDashOffset(dOffset); } HRESULT CDocxRenderer::put_PenDashOffset(const double& dOffset) { - return m_pInternal->m_oDocument.put_PenDashOffset(dOffset); + return m_pInternal->m_oDocument.put_PenDashOffset(dOffset); } HRESULT CDocxRenderer::get_PenAlign(LONG* lAlign) { - return m_pInternal->m_oDocument.get_PenAlign(lAlign); + return m_pInternal->m_oDocument.get_PenAlign(lAlign); } HRESULT CDocxRenderer::put_PenAlign(const LONG& lAlign) { - return m_pInternal->m_oDocument.put_PenAlign(lAlign); + return m_pInternal->m_oDocument.put_PenAlign(lAlign); } HRESULT CDocxRenderer::get_PenMiterLimit(double* dMiter) { - return m_pInternal->m_oDocument.get_PenMiterLimit(dMiter); + return m_pInternal->m_oDocument.get_PenMiterLimit(dMiter); } HRESULT CDocxRenderer::put_PenMiterLimit(const double& dMiter) { - return m_pInternal->m_oDocument.put_PenMiterLimit(dMiter); + return m_pInternal->m_oDocument.put_PenMiterLimit(dMiter); } HRESULT CDocxRenderer::PenDashPattern(double* pPattern, LONG lCount) { - return m_pInternal->m_oDocument.PenDashPattern(pPattern, lCount); + return m_pInternal->m_oDocument.PenDashPattern(pPattern, lCount); } //---------------------------------------------------------------------------------------- // Функции для работы с Brush //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_BrushType(LONG* lType) { - return m_pInternal->m_oDocument.get_BrushType(lType); + return m_pInternal->m_oDocument.get_BrushType(lType); } HRESULT CDocxRenderer::put_BrushType(const LONG& lType) { - return m_pInternal->m_oDocument.put_BrushType(lType); + return m_pInternal->m_oDocument.put_BrushType(lType); } HRESULT CDocxRenderer::get_BrushColor1(LONG* lColor) { - return m_pInternal->m_oDocument.get_BrushColor1(lColor); + return m_pInternal->m_oDocument.get_BrushColor1(lColor); } HRESULT CDocxRenderer::put_BrushColor1(const LONG& lColor) { - return m_pInternal->m_oDocument.put_BrushColor1(lColor); + return m_pInternal->m_oDocument.put_BrushColor1(lColor); } HRESULT CDocxRenderer::get_BrushAlpha1(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushAlpha1(lAlpha); + return m_pInternal->m_oDocument.get_BrushAlpha1(lAlpha); } HRESULT CDocxRenderer::put_BrushAlpha1(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushAlpha1(lAlpha); + return m_pInternal->m_oDocument.put_BrushAlpha1(lAlpha); } HRESULT CDocxRenderer::get_BrushColor2(LONG* lColor) { - return m_pInternal->m_oDocument.get_BrushColor2(lColor); + return m_pInternal->m_oDocument.get_BrushColor2(lColor); } HRESULT CDocxRenderer::put_BrushColor2(const LONG& lColor) { - return m_pInternal->m_oDocument.put_BrushColor2(lColor); + return m_pInternal->m_oDocument.put_BrushColor2(lColor); } HRESULT CDocxRenderer::get_BrushAlpha2(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushAlpha2(lAlpha); + return m_pInternal->m_oDocument.get_BrushAlpha2(lAlpha); } HRESULT CDocxRenderer::put_BrushAlpha2(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushAlpha2(lAlpha); + return m_pInternal->m_oDocument.put_BrushAlpha2(lAlpha); } HRESULT CDocxRenderer::get_BrushTexturePath(std::wstring* wsPath) { - return m_pInternal->m_oDocument.get_BrushTexturePath(wsPath); + return m_pInternal->m_oDocument.get_BrushTexturePath(wsPath); } HRESULT CDocxRenderer::put_BrushTexturePath(const std::wstring& wsPath) { - return m_pInternal->m_oDocument.put_BrushTexturePath(wsPath); + return m_pInternal->m_oDocument.put_BrushTexturePath(wsPath); } HRESULT CDocxRenderer::get_BrushTextureMode(LONG* lMode) { - return m_pInternal->m_oDocument.get_BrushTextureMode(lMode); + return m_pInternal->m_oDocument.get_BrushTextureMode(lMode); } HRESULT CDocxRenderer::put_BrushTextureMode(const LONG& lMode) { - return m_pInternal->m_oDocument.put_BrushTextureMode(lMode); + return m_pInternal->m_oDocument.put_BrushTextureMode(lMode); } HRESULT CDocxRenderer::get_BrushTextureAlpha(LONG* lAlpha) { - return m_pInternal->m_oDocument.get_BrushTextureAlpha(lAlpha); + return m_pInternal->m_oDocument.get_BrushTextureAlpha(lAlpha); } HRESULT CDocxRenderer::put_BrushTextureAlpha(const LONG& lAlpha) { - return m_pInternal->m_oDocument.put_BrushTextureAlpha(lAlpha); + return m_pInternal->m_oDocument.put_BrushTextureAlpha(lAlpha); } HRESULT CDocxRenderer::get_BrushLinearAngle(double* dAngle) { - return m_pInternal->m_oDocument.get_BrushLinearAngle(dAngle); + return m_pInternal->m_oDocument.get_BrushLinearAngle(dAngle); } HRESULT CDocxRenderer::put_BrushLinearAngle(const double& dAngle) { - return m_pInternal->m_oDocument.put_BrushLinearAngle(dAngle); + return m_pInternal->m_oDocument.put_BrushLinearAngle(dAngle); } HRESULT CDocxRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) { - return m_pInternal->m_oDocument.BrushRect(nVal, dLeft, dTop, dWidth, dHeight); + return m_pInternal->m_oDocument.BrushRect(nVal, dLeft, dTop, dWidth, dHeight); } HRESULT CDocxRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) { - // TODO: - return S_OK; + // TODO: + return S_OK; } HRESULT CDocxRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) { - // TODO: - return S_OK; + // TODO: + return S_OK; } //---------------------------------------------------------------------------------------- // Функции для работы со шрифтами //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_FontName(std::wstring* wsName) { - return m_pInternal->m_oDocument.get_FontName(wsName); + return m_pInternal->m_oDocument.get_FontName(wsName); } HRESULT CDocxRenderer::put_FontName(const std::wstring& wsName) { - return m_pInternal->m_oDocument.put_FontName(wsName); + return m_pInternal->m_oDocument.put_FontName(wsName); } HRESULT CDocxRenderer::get_FontPath(std::wstring* wsPath) { - return m_pInternal->m_oDocument.get_FontPath(wsPath); + return m_pInternal->m_oDocument.get_FontPath(wsPath); } HRESULT CDocxRenderer::put_FontPath(const std::wstring& wsPath) { - return m_pInternal->m_oDocument.put_FontPath(wsPath); + return m_pInternal->m_oDocument.put_FontPath(wsPath); } HRESULT CDocxRenderer::get_FontSize(double* dSize) { - return m_pInternal->m_oDocument.get_FontSize(dSize); + return m_pInternal->m_oDocument.get_FontSize(dSize); } HRESULT CDocxRenderer::put_FontSize(const double& dSize) { - return m_pInternal->m_oDocument.put_FontSize(dSize); + return m_pInternal->m_oDocument.put_FontSize(dSize); } HRESULT CDocxRenderer::get_FontStyle(LONG* lStyle) { - return m_pInternal->m_oDocument.get_FontStyle(lStyle); + return m_pInternal->m_oDocument.get_FontStyle(lStyle); } HRESULT CDocxRenderer::put_FontStyle(const LONG& lStyle) { - return m_pInternal->m_oDocument.put_FontStyle(lStyle); + return m_pInternal->m_oDocument.put_FontStyle(lStyle); } HRESULT CDocxRenderer::get_FontStringGID(INT* bGid) { - return m_pInternal->m_oDocument.get_FontStringGID(bGid); + return m_pInternal->m_oDocument.get_FontStringGID(bGid); } HRESULT CDocxRenderer::put_FontStringGID(const INT& bGid) { - return m_pInternal->m_oDocument.put_FontStringGID(bGid); + return m_pInternal->m_oDocument.put_FontStringGID(bGid); } HRESULT CDocxRenderer::get_FontCharSpace(double* dSpace) { - return m_pInternal->m_oDocument.get_FontCharSpace(dSpace); + return m_pInternal->m_oDocument.get_FontCharSpace(dSpace); } HRESULT CDocxRenderer::put_FontCharSpace(const double& dSpace) { - return m_pInternal->m_oDocument.put_FontCharSpace(dSpace); + return m_pInternal->m_oDocument.put_FontCharSpace(dSpace); } HRESULT CDocxRenderer::get_FontFaceIndex(int* lFaceIndex) { - return m_pInternal->m_oDocument.get_FontFaceIndex(lFaceIndex); + return m_pInternal->m_oDocument.get_FontFaceIndex(lFaceIndex); } HRESULT CDocxRenderer::put_FontFaceIndex(const int& lFaceIndex) { - return m_pInternal->m_oDocument.put_FontFaceIndex(lFaceIndex); + return m_pInternal->m_oDocument.put_FontFaceIndex(lFaceIndex); } //---------------------------------------------------------------------------------------- // Функции для вывода текста //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextCHAR((int)lUnicode, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextCHAR((int)lUnicode, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawText(wsUnicodeText, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawText(wsUnicodeText, dX, dY, dW, dH); } HRESULT CDocxRenderer::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.CommandDrawTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); + return m_pInternal->m_oDocument.CommandDrawTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); } //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::BeginCommand(const DWORD& lType) { - return m_pInternal->m_oDocument.BeginCommand(lType); + return m_pInternal->m_oDocument.BeginCommand(lType); } HRESULT CDocxRenderer::EndCommand(const DWORD& lType) { - return m_pInternal->m_oDocument.EndCommand(lType); + return m_pInternal->m_oDocument.EndCommand(lType); } //---------------------------------------------------------------------------------------- // Функции для работы с патом //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::PathCommandMoveTo(const double& dX, const double& dY) { - return m_pInternal->m_oDocument.PathCommandMoveTo(dX, dY); + return m_pInternal->m_oDocument.PathCommandMoveTo(dX, dY); } HRESULT CDocxRenderer::PathCommandLineTo(const double& dX, const double& dY) { - return m_pInternal->m_oDocument.PathCommandLineTo(dX, dY); + return m_pInternal->m_oDocument.PathCommandLineTo(dX, dY); } HRESULT CDocxRenderer::PathCommandLinesTo(double* pPoints, const int& nCount) { - return m_pInternal->m_oDocument.PathCommandLinesTo(pPoints, nCount); + return m_pInternal->m_oDocument.PathCommandLinesTo(pPoints, nCount); } HRESULT CDocxRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) { - return m_pInternal->m_oDocument.PathCommandCurveTo(dX1, dY1, dX2, dY2, dXe, dYe); + return m_pInternal->m_oDocument.PathCommandCurveTo(dX1, dY1, dX2, dY2, dXe, dYe); } HRESULT CDocxRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount) { - return m_pInternal->m_oDocument.PathCommandCurvesTo(pPoints, nCount); + return m_pInternal->m_oDocument.PathCommandCurvesTo(pPoints, nCount); } HRESULT CDocxRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) { - return m_pInternal->m_oDocument.PathCommandArcTo(dX, dY, dW, dH, dStartAngle, dSweepAngle); + return m_pInternal->m_oDocument.PathCommandArcTo(dX, dY, dW, dH, dStartAngle, dSweepAngle); } HRESULT CDocxRenderer::PathCommandClose() { - return m_pInternal->m_oDocument.PathCommandClose(); + return m_pInternal->m_oDocument.PathCommandClose(); } HRESULT CDocxRenderer::PathCommandEnd() { - return m_pInternal->m_oDocument.PathCommandEnd(); + return m_pInternal->m_oDocument.PathCommandEnd(); } HRESULT CDocxRenderer::DrawPath(const LONG& lType) { - return m_pInternal->m_oDocument.DrawPath(lType); + return m_pInternal->m_oDocument.DrawPath(lType); } HRESULT CDocxRenderer::PathCommandStart() { - return m_pInternal->m_oDocument.PathCommandStart(); + return m_pInternal->m_oDocument.PathCommandStart(); } HRESULT CDocxRenderer::PathCommandGetCurrentPoint(double* dX, double* dY) { - return m_pInternal->m_oDocument.PathCommandGetCurrentPoint(dX, dY); + return m_pInternal->m_oDocument.PathCommandGetCurrentPoint(dX, dY); } HRESULT CDocxRenderer::PathCommandTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextCHAR((int)lUnicode, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextCHAR((int)lUnicode, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextExCHAR((int)lUnicode, (int)lGid, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandText(wsUnicodeText, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandText(wsUnicodeText, dX, dY, dW, dH); } HRESULT CDocxRenderer::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.PathCommandTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); + return m_pInternal->m_oDocument.PathCommandTextEx(wsUnicodeText, pGids, nGidsCount, dX, dY, dW, dH); } //---------------------------------------------------------------------------------------- // Функции для вывода изображений //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH) { - return m_pInternal->m_oDocument.DrawImage(pImage, dX, dY, dW, dH); + return m_pInternal->m_oDocument.DrawImage(pImage, dX, dY, dW, dH); } HRESULT CDocxRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { - return m_pInternal->m_oDocument.DrawImageFromFile(wsImagePath,dX, dY, dW, dH); + return m_pInternal->m_oDocument.DrawImageFromFile(wsImagePath,dX, dY, dW, dH); } //---------------------------------------------------------------------------------------- // Функции для выставления преобразования //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) { - return m_pInternal->m_oDocument.SetTransform(dM11, dM12, dM21, dM22, dX, dY); + return m_pInternal->m_oDocument.SetTransform(dM11, dM12, dM21, dM22, dX, dY); } HRESULT CDocxRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) { - return m_pInternal->m_oDocument.GetTransform(dM11, dM12, dM21, dM22, dX, dY); + return m_pInternal->m_oDocument.GetTransform(dM11, dM12, dM21, dM22, dX, dY); } HRESULT CDocxRenderer::ResetTransform() { - return m_pInternal->m_oDocument.ResetTransform(); + return m_pInternal->m_oDocument.ResetTransform(); } //---------------------------------------------------------------------------------------- @@ -531,11 +531,11 @@ HRESULT CDocxRenderer::ResetTransform() //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::get_ClipMode(LONG* lMode) { - return m_pInternal->m_oDocument.get_ClipMode(lMode); + return m_pInternal->m_oDocument.get_ClipMode(lMode); } HRESULT CDocxRenderer::put_ClipMode(const LONG& lMode) { - return m_pInternal->m_oDocument.put_ClipMode(lMode); + return m_pInternal->m_oDocument.put_ClipMode(lMode); } //---------------------------------------------------------------------------------------- @@ -543,13 +543,13 @@ HRESULT CDocxRenderer::put_ClipMode(const LONG& lMode) //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::CommandLong(const LONG& lType, const LONG& lCommand) { - return S_OK; + return S_OK; } HRESULT CDocxRenderer::CommandDouble(const LONG& lType, const double& dCommand) { - return S_OK; + return S_OK; } HRESULT CDocxRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) { - return S_OK; + return S_OK; } diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index d3f355b3803..3295b3e8c7f 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -46,150 +46,150 @@ class CDocxRenderer_Private; class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer { - public: - CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts); - virtual ~CDocxRenderer(); +public: + CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts); + virtual ~CDocxRenderer(); - HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true); - HRESULT Close(); + HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true); + HRESULT Close(); - HRESULT SetTempFolder(const std::wstring& wsPath); - //---------------------------------------------------------------------------------------- - // Тип рендерера - //---------------------------------------------------------------------------------------- - virtual HRESULT get_Type(LONG* lType); - //---------------------------------------------------------------------------------------- - // Функции для работы со страницей - //---------------------------------------------------------------------------------------- - virtual HRESULT NewPage(); - virtual HRESULT get_Height(double* dHeight); - virtual HRESULT put_Height(const double& dHeight); - virtual HRESULT get_Width(double* dWidth); - virtual HRESULT put_Width(const double& dWidth); - virtual HRESULT get_DpiX(double* dDpiX); - virtual HRESULT get_DpiY(double* dDpiY); - //---------------------------------------------------------------------------------------- - // Функции для работы с Pen - //---------------------------------------------------------------------------------------- - virtual HRESULT get_PenColor(LONG* lColor); - virtual HRESULT put_PenColor(const LONG& lColor); - virtual HRESULT get_PenAlpha(LONG* lAlpha); - virtual HRESULT put_PenAlpha(const LONG& lAlpha); - virtual HRESULT get_PenSize(double* dSize); - virtual HRESULT put_PenSize(const double& dSize); - virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); - virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); - virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); - virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); - virtual HRESULT get_PenDashOffset(double* dOffset); - virtual HRESULT put_PenDashOffset(const double& dOffset); - virtual HRESULT get_PenAlign(LONG* lAlign); - virtual HRESULT put_PenAlign(const LONG& lAlign); - virtual HRESULT get_PenMiterLimit(double* dMiter); - virtual HRESULT put_PenMiterLimit(const double& dMiter); - virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); - //---------------------------------------------------------------------------------------- - // Функции для работы с Brush - //---------------------------------------------------------------------------------------- - virtual HRESULT get_BrushType(LONG* lType); - virtual HRESULT put_BrushType(const LONG& lType); - virtual HRESULT get_BrushColor1(LONG* lColor); - virtual HRESULT put_BrushColor1(const LONG& lColor); - virtual HRESULT get_BrushAlpha1(LONG* lAlpha); - virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); - virtual HRESULT get_BrushColor2(LONG* lColor); - virtual HRESULT put_BrushColor2(const LONG& lColor); - virtual HRESULT get_BrushAlpha2(LONG* lAlpha); - virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); - virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); - virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); - virtual HRESULT get_BrushTextureMode(LONG* lMode); - virtual HRESULT put_BrushTextureMode(const LONG& lMode); - virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); - virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); - virtual HRESULT get_BrushLinearAngle(double* dAngle); - virtual HRESULT put_BrushLinearAngle(const double& dAngle); - virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); - //---------------------------------------------------------------------------------------- - // Функции для работы со шрифтами - //---------------------------------------------------------------------------------------- - virtual HRESULT get_FontName(std::wstring* wsName); - virtual HRESULT put_FontName(const std::wstring& wsName); - virtual HRESULT get_FontPath(std::wstring* wsPath); - virtual HRESULT put_FontPath(const std::wstring& wsPath); - virtual HRESULT get_FontSize(double* dSize); - virtual HRESULT put_FontSize(const double& dSize); - virtual HRESULT get_FontStyle(LONG* lStyle); - virtual HRESULT put_FontStyle(const LONG& lStyle); - virtual HRESULT get_FontStringGID(INT* bGid); - virtual HRESULT put_FontStringGID(const INT& bGid); - virtual HRESULT get_FontCharSpace(double* dSpace); - virtual HRESULT put_FontCharSpace(const double& dSpace); - virtual HRESULT get_FontFaceIndex(int* lFaceIndex); - virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); - //---------------------------------------------------------------------------------------- - // Функции для вывода текста - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Маркеры команд - //---------------------------------------------------------------------------------------- - virtual HRESULT BeginCommand(const DWORD& lType); - virtual HRESULT EndCommand(const DWORD& lType); - //---------------------------------------------------------------------------------------- - // Функции для работы с патом - //---------------------------------------------------------------------------------------- - virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); - virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); - virtual HRESULT PathCommandClose(); - virtual HRESULT PathCommandEnd(); - virtual HRESULT DrawPath(const LONG& lType); - virtual HRESULT PathCommandStart(); - virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); - virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Функции для вывода изображений - //---------------------------------------------------------------------------------------- - virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); - //---------------------------------------------------------------------------------------- - // Функции для выставления преобразования - //---------------------------------------------------------------------------------------- - virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); - virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); - virtual HRESULT ResetTransform(); - //---------------------------------------------------------------------------------------- - // Тип клипа - //---------------------------------------------------------------------------------------- - virtual HRESULT get_ClipMode(LONG* lMode); - virtual HRESULT put_ClipMode(const LONG& lMode); - //---------------------------------------------------------------------------------------- - // Дополнительные функции - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); - virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); + HRESULT SetTempFolder(const std::wstring& wsPath); + //---------------------------------------------------------------------------------------- + // Тип рендерера + //---------------------------------------------------------------------------------------- + virtual HRESULT get_Type(LONG* lType); + //---------------------------------------------------------------------------------------- + // Функции для работы со страницей + //---------------------------------------------------------------------------------------- + virtual HRESULT NewPage(); + virtual HRESULT get_Height(double* dHeight); + virtual HRESULT put_Height(const double& dHeight); + virtual HRESULT get_Width(double* dWidth); + virtual HRESULT put_Width(const double& dWidth); + virtual HRESULT get_DpiX(double* dDpiX); + virtual HRESULT get_DpiY(double* dDpiY); + //---------------------------------------------------------------------------------------- + // Функции для работы с Pen + //---------------------------------------------------------------------------------------- + virtual HRESULT get_PenColor(LONG* lColor); + virtual HRESULT put_PenColor(const LONG& lColor); + virtual HRESULT get_PenAlpha(LONG* lAlpha); + virtual HRESULT put_PenAlpha(const LONG& lAlpha); + virtual HRESULT get_PenSize(double* dSize); + virtual HRESULT put_PenSize(const double& dSize); + virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); + virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); + virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); + virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); + virtual HRESULT get_PenDashOffset(double* dOffset); + virtual HRESULT put_PenDashOffset(const double& dOffset); + virtual HRESULT get_PenAlign(LONG* lAlign); + virtual HRESULT put_PenAlign(const LONG& lAlign); + virtual HRESULT get_PenMiterLimit(double* dMiter); + virtual HRESULT put_PenMiterLimit(const double& dMiter); + virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); + //---------------------------------------------------------------------------------------- + // Функции для работы с Brush + //---------------------------------------------------------------------------------------- + virtual HRESULT get_BrushType(LONG* lType); + virtual HRESULT put_BrushType(const LONG& lType); + virtual HRESULT get_BrushColor1(LONG* lColor); + virtual HRESULT put_BrushColor1(const LONG& lColor); + virtual HRESULT get_BrushAlpha1(LONG* lAlpha); + virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); + virtual HRESULT get_BrushColor2(LONG* lColor); + virtual HRESULT put_BrushColor2(const LONG& lColor); + virtual HRESULT get_BrushAlpha2(LONG* lAlpha); + virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); + virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); + virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); + virtual HRESULT get_BrushTextureMode(LONG* lMode); + virtual HRESULT put_BrushTextureMode(const LONG& lMode); + virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); + virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); + virtual HRESULT get_BrushLinearAngle(double* dAngle); + virtual HRESULT put_BrushLinearAngle(const double& dAngle); + virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); + //---------------------------------------------------------------------------------------- + // Функции для работы со шрифтами + //---------------------------------------------------------------------------------------- + virtual HRESULT get_FontName(std::wstring* wsName); + virtual HRESULT put_FontName(const std::wstring& wsName); + virtual HRESULT get_FontPath(std::wstring* wsPath); + virtual HRESULT put_FontPath(const std::wstring& wsPath); + virtual HRESULT get_FontSize(double* dSize); + virtual HRESULT put_FontSize(const double& dSize); + virtual HRESULT get_FontStyle(LONG* lStyle); + virtual HRESULT put_FontStyle(const LONG& lStyle); + virtual HRESULT get_FontStringGID(INT* bGid); + virtual HRESULT put_FontStringGID(const INT& bGid); + virtual HRESULT get_FontCharSpace(double* dSpace); + virtual HRESULT put_FontCharSpace(const double& dSpace); + virtual HRESULT get_FontFaceIndex(int* lFaceIndex); + virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); + //---------------------------------------------------------------------------------------- + // Функции для вывода текста + //---------------------------------------------------------------------------------------- + virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + //---------------------------------------------------------------------------------------- + // Маркеры команд + //---------------------------------------------------------------------------------------- + virtual HRESULT BeginCommand(const DWORD& lType); + virtual HRESULT EndCommand(const DWORD& lType); + //---------------------------------------------------------------------------------------- + // Функции для работы с патом + //---------------------------------------------------------------------------------------- + virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); + virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); + virtual HRESULT PathCommandClose(); + virtual HRESULT PathCommandEnd(); + virtual HRESULT DrawPath(const LONG& lType); + virtual HRESULT PathCommandStart(); + virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); + virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + //---------------------------------------------------------------------------------------- + // Функции для вывода изображений + //---------------------------------------------------------------------------------------- + virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); + //---------------------------------------------------------------------------------------- + // Функции для выставления преобразования + //---------------------------------------------------------------------------------------- + virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); + virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); + virtual HRESULT ResetTransform(); + //---------------------------------------------------------------------------------------- + // Тип клипа + //---------------------------------------------------------------------------------------- + virtual HRESULT get_ClipMode(LONG* lMode); + virtual HRESULT put_ClipMode(const LONG& lMode); + //---------------------------------------------------------------------------------------- + // Дополнительные функции + //---------------------------------------------------------------------------------------- + virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); + virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); + virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - // методы, которыми будет пользоваться конвертер - HRESULT SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType); - int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); + // методы, которыми будет пользоваться конвертер + HRESULT SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType); + int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); - private: - CDocxRenderer_Private* m_pInternal; +private: + CDocxRenderer_Private* m_pInternal; }; diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 0a7fe08e2ca..856cbc4ebcb 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -2,1221 +2,1221 @@ namespace NSDocxRenderer { - CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : - m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts) - { - m_oSimpleGraphicsConverter.SetRenderer(pRenderer); - - m_oFontManager.m_pFont = &m_oFont; - m_oFontManager.m_pTransform = &m_oTransform; - } - void CDocument::Clear() - { - m_oPen.SetDefaultParams(); - m_oBrush.SetDefaultParams(); - m_oFont.SetDefaultParams(); - m_oShadow.SetDefaultParams(); - m_oEdge.SetDefaultParams(); - - m_oTransform.Reset(); - - m_lClipMode = 0; - - m_lPagesCount = 0; - m_mapXmlString.clear(); - } - - CDocument::~CDocument() { - m_lClipMode = 0; - RELEASEINTERFACE(m_pFontManager); - m_mapXmlString.clear(); - } - - HRESULT CDocument::NewPage() - { - m_oPen.SetDefaultParams(); - m_oBrush.SetDefaultParams(); - m_oFont.SetDefaultParams(); - m_oShadow.SetDefaultParams(); - m_oEdge.SetDefaultParams(); - - m_oTransform.Reset(); - - m_oCurrentPage.Clear(); - - return S_OK; - } - HRESULT CDocument::get_Height(double* dHeight) - { - *dHeight = m_dHeight; - return S_OK; - } - HRESULT CDocument::put_Height(double dHeight) - { - m_dHeight = dHeight; - m_oCurrentPage.m_dHeight = dHeight; - return S_OK; - } - HRESULT CDocument::get_Width(double* dWidth) - { - *dWidth = m_dWidth; - return S_OK; - } - HRESULT CDocument::put_Width(double dWidth) - { - m_dWidth = dWidth; - m_oCurrentPage.m_dWidth = dWidth; - return S_OK; - } - HRESULT CDocument::get_DpiX(double* dDpiX) - { - *dDpiX = m_dDpiX; - return S_OK; - } - HRESULT CDocument::get_DpiY(double* dDpiY) - { - *dDpiY = m_dDpiY; - return S_OK; - } - //-------- Функции для задания настроек текста ---------------------------------------------- - // pen -------------------------------------------------------------------------------------- - HRESULT CDocument::get_PenColor(LONG* lColor) - { - *lColor = m_oPen.Color; - return S_OK; - } - HRESULT CDocument::put_PenColor(LONG lColor) - { - m_oPen.Color = lColor; - return S_OK; - } - HRESULT CDocument::get_PenAlpha(LONG* lAlpha) - { - *lAlpha = m_oPen.Alpha; - return S_OK; - } - HRESULT CDocument::put_PenAlpha(LONG lAlpha) - { - m_oPen.Alpha = lAlpha; - return S_OK; - } - HRESULT CDocument::get_PenSize(double* dSize) - { - *dSize = m_oPen.Size; - return S_OK; - } - HRESULT CDocument::put_PenSize(double dSize) - { - m_oPen.Size = dSize; - return S_OK; - } - HRESULT CDocument::get_PenDashStyle(BYTE* val) - { - *val = m_oPen.DashStyle; - return S_OK; - } - HRESULT CDocument::put_PenDashStyle(BYTE val) - { - m_oPen.DashStyle = val; - return S_OK; - } - HRESULT CDocument::get_PenLineStartCap(BYTE* val) - { - *val = m_oPen.LineStartCap; - return S_OK; - } - HRESULT CDocument::put_PenLineStartCap(BYTE val) - { - m_oPen.LineStartCap = val; - return S_OK; - } - HRESULT CDocument::get_PenLineEndCap(BYTE* val) - { - *val = m_oPen.LineEndCap; - return S_OK; - } - HRESULT CDocument::put_PenLineEndCap(BYTE val) - { - m_oPen.LineEndCap = val; - return S_OK; - } - HRESULT CDocument::get_PenLineJoin(BYTE* val) - { - *val = m_oPen.LineJoin; - return S_OK; - } - HRESULT CDocument::put_PenLineJoin(BYTE val) - { - m_oPen.LineJoin = val; - return S_OK; - } - HRESULT CDocument::get_PenDashOffset(double* val) - { - *val = m_oPen.DashOffset; - return S_OK; - } - HRESULT CDocument::put_PenDashOffset(double val) - { - m_oPen.DashOffset = val; - return S_OK; - } - HRESULT CDocument::get_PenAlign(LONG* val) - { - *val = m_oPen.Align; - return S_OK; - } - HRESULT CDocument::put_PenAlign(LONG val) - { - m_oPen.Align = val; - return S_OK; - } - HRESULT CDocument::get_PenMiterLimit(double* val) - { - *val = m_oPen.MiterLimit; - return S_OK; - } - HRESULT CDocument::put_PenMiterLimit(double val) - { - m_oPen.MiterLimit = val; - return S_OK; - } - HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount) - { - if (nullptr != pPattern) - { - m_oPen.SetDashPattern(pPattern, lCount); - } - - return S_OK; - } - // brush ------------------------------------------------------------------------------------ - HRESULT CDocument::get_BrushType(LONG* lType) - { - *lType = m_oBrush.Type; - return S_OK; - } - HRESULT CDocument::put_BrushType(LONG lType) - { - m_oBrush.Type = lType; - return S_OK; - } - HRESULT CDocument::get_BrushColor1(LONG* lColor) - { - *lColor = m_oBrush.Color1; - return S_OK; - } - HRESULT CDocument::put_BrushColor1(LONG lColor) - { - m_oBrush.Color1 = lColor; - return S_OK; - } - HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha) - { - *lAlpha = m_oBrush.Alpha1; - return S_OK; - } - HRESULT CDocument::put_BrushAlpha1(LONG lAlpha) - { - m_oBrush.Alpha1 = lAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushColor2(LONG* lColor) - { - *lColor = m_oBrush.Color2; - return S_OK; - } - HRESULT CDocument::put_BrushColor2(LONG lColor) - { - m_oBrush.Color2 = lColor; - return S_OK; - } - HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha) - { - *lAlpha = m_oBrush.Alpha2; - return S_OK; - } - HRESULT CDocument::put_BrushAlpha2(LONG lAlpha) - { - m_oBrush.Alpha2 = lAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath) - { - *sPath = m_oBrush.TexturePath; - return S_OK; - } - HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath) - { - m_oBrush.TexturePath = sPath; - return S_OK; - } - HRESULT CDocument::get_BrushTextureMode(LONG* lMode) - { - *lMode = m_oBrush.TextureMode; - return S_OK; - } - HRESULT CDocument::put_BrushTextureMode(LONG lMode) - { - m_oBrush.TextureMode = lMode; - return S_OK; - } - HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha) - { - *lTxAlpha = m_oBrush.TextureAlpha; - return S_OK; - } - HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha) - { - m_oBrush.TextureAlpha = lTxAlpha; - return S_OK; - } - HRESULT CDocument::get_BrushLinearAngle(double* dAngle) - { - *dAngle = m_oBrush.LinearAngle; - return S_OK; - } - HRESULT CDocument::put_BrushLinearAngle(double dAngle) - { - m_oBrush.LinearAngle = dAngle; - return S_OK; - } - HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height) - { - m_oBrush.Rectable = val ? 1 : 0; - m_oBrush.Rect.X = (float)left; - m_oBrush.Rect.Y = (float)top; - m_oBrush.Rect.Width = (float)width; - m_oBrush.Rect.Height = (float)height; - - return S_OK; - } - // font ------------------------------------------------------------------------------------- - HRESULT CDocument::get_FontName(std::wstring* sName) - { - *sName = m_oFont.Name; - return S_OK; - } - HRESULT CDocument::put_FontName(std::wstring sName) - { - m_oFont.Name = sName; - return S_OK; - } - HRESULT CDocument::get_FontPath(std::wstring* sPath) - { - *sPath = m_oFont.Path; - return S_OK; - } - HRESULT CDocument::put_FontPath(std::wstring sPath) - { - m_oFont.Path = sPath; - return S_OK; - } - HRESULT CDocument::get_FontSize(double* dSize) - { - *dSize = m_oFont.Size; - return S_OK; - } - HRESULT CDocument::put_FontSize(double dSize) - { - m_oFont.Size = dSize; - return S_OK; - } - HRESULT CDocument::get_FontStyle(LONG* lStyle) - { - *lStyle = m_oFont.GetStyle(); - return S_OK; - } - HRESULT CDocument::put_FontStyle(LONG lStyle) - { - m_oFont.SetStyle(lStyle); - return S_OK; - } - HRESULT CDocument::get_FontStringGID(INT* bGID) - { - *bGID = m_oFont.StringGID; - return S_OK; - } - HRESULT CDocument::put_FontStringGID(INT bGID) - { - m_oFont.StringGID = bGID; - return S_OK; - } - HRESULT CDocument::get_FontCharSpace(double* dSpace) - { - *dSpace = m_oFont.CharSpace; - return S_OK; - } - HRESULT CDocument::put_FontCharSpace(double dSpace) - { - m_oFont.CharSpace = dSpace; - return S_OK; - } - HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex) - { - *lFaceIndex = m_oFont.FaceIndex; - return S_OK; - } - HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex) - { - m_oFont.FaceIndex = lFaceIndex; - return S_OK; - } - // shadow ----------------------------------------------------------------------------------- - HRESULT CDocument::get_ShadowDistanceX(double* val) - { - *val = m_oShadow.DistanceX; - return S_OK; - } - HRESULT CDocument::put_ShadowDistanceX(double val) - { - m_oShadow.DistanceX = val; - return S_OK; - } - HRESULT CDocument::get_ShadowDistanceY(double* val) - { - *val = m_oShadow.DistanceY; - return S_OK; - } - HRESULT CDocument::put_ShadowDistanceY(double val) - { - m_oShadow.DistanceY = val; - return S_OK; - } - HRESULT CDocument::get_ShadowBlurSize(double* val) - { - *val = m_oShadow.BlurSize; - return S_OK; - } - HRESULT CDocument::put_ShadowBlurSize(double val) - { - m_oShadow.BlurSize = val; - return S_OK; - } - HRESULT CDocument::get_ShadowColor(LONG* val) - { - *val = m_oShadow.Color; - return S_OK; - } - HRESULT CDocument::put_ShadowColor(LONG val) - { - m_oShadow.Color = val; - return S_OK; - } - HRESULT CDocument::get_ShadowAlpha(LONG* val) - { - *val = m_oShadow.Alpha; - return S_OK; - } - HRESULT CDocument::put_ShadowAlpha(LONG val) - { - m_oShadow.Alpha = val; - return S_OK; - } - HRESULT CDocument::get_ShadowVisible(INT* val) - { - *val = m_oShadow.Visible; - return S_OK; - } - HRESULT CDocument::put_ShadowVisible(INT val) - { - m_oShadow.Visible = val; - return S_OK; - } - // edge ------------------------------------------------------------------------------------- - HRESULT CDocument::get_EdgeVisible(LONG* val) - { - *val = m_oEdge.Visible; - return S_OK; - } - HRESULT CDocument::put_EdgeVisible(LONG val) - { - m_oEdge.Visible = val; - return S_OK; - } - HRESULT CDocument::get_EdgeColor(LONG* val) - { - *val = m_oEdge.Color; - return S_OK; - } - HRESULT CDocument::put_EdgeColor(LONG val) - { - m_oEdge.Color = val; - return S_OK; - } - HRESULT CDocument::get_EdgeAlpha(LONG* val) - { - *val = m_oEdge.Alpha; - return S_OK; - } - HRESULT CDocument::put_EdgeAlpha(LONG val) - { - m_oEdge.Alpha = val; - return S_OK; - } - HRESULT CDocument::get_EdgeDist(double* val) - { - *val = m_oEdge.Dist; - return S_OK; - } - HRESULT CDocument::put_EdgeDist(double val) - { - m_oEdge.Dist = val; - return S_OK; - } - - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, - const double& dX, const double& dY, const double& dW, - const double& dH, const double& dBaseLineOffset) - { - double dAngleMatrix = m_oTransform.z_Rotation(); - if (fabs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0) - { - //note У повернутых символов не приходят координаты. - _SetFont(); - PathCommandEnd(); - BeginCommand(c_nPathType); - m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH); - DrawPath(c_nWindingFillMode); - EndCommand(c_nPathType); - PathCommandEnd(); - return S_OK; - } - - m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer); - return S_OK; - } - - HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) - { - return CommandDrawTextPrivate(&lUnicode, nullptr, 1, dX, dY, dW, dH); - } - HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) - { - return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH); - } - HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) - { - unsigned int nLen = 0; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); - if (nLen == 0) - return S_OK; - CommandDrawTextPrivate((int*)pUnicodes, nullptr, nLen, dX, dY, dW, dH); - delete [] pUnicodes; - return S_OK; - } - HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) - { - unsigned int nLen = 0; - unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); - if (nLen == 0) - return S_OK; - if (nLen != nGidsCount && 0 != nGidsCount) - { - delete [] pUnicodes; - return S_OK; - } + CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : + m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts) + { + m_oSimpleGraphicsConverter.SetRenderer(pRenderer); + + m_oFontManager.m_pFont = &m_oFont; + m_oFontManager.m_pTransform = &m_oTransform; + } + void CDocument::Clear() + { + m_oPen.SetDefaultParams(); + m_oBrush.SetDefaultParams(); + m_oFont.SetDefaultParams(); + m_oShadow.SetDefaultParams(); + m_oEdge.SetDefaultParams(); + + m_oTransform.Reset(); + + m_lClipMode = 0; + + m_lPagesCount = 0; + m_mapXmlString.clear(); + } + + CDocument::~CDocument() { + m_lClipMode = 0; + RELEASEINTERFACE(m_pFontManager); + m_mapXmlString.clear(); + } + + HRESULT CDocument::NewPage() + { + m_oPen.SetDefaultParams(); + m_oBrush.SetDefaultParams(); + m_oFont.SetDefaultParams(); + m_oShadow.SetDefaultParams(); + m_oEdge.SetDefaultParams(); + + m_oTransform.Reset(); + + m_oCurrentPage.Clear(); + + return S_OK; + } + HRESULT CDocument::get_Height(double* dHeight) + { + *dHeight = m_dHeight; + return S_OK; + } + HRESULT CDocument::put_Height(double dHeight) + { + m_dHeight = dHeight; + m_oCurrentPage.m_dHeight = dHeight; + return S_OK; + } + HRESULT CDocument::get_Width(double* dWidth) + { + *dWidth = m_dWidth; + return S_OK; + } + HRESULT CDocument::put_Width(double dWidth) + { + m_dWidth = dWidth; + m_oCurrentPage.m_dWidth = dWidth; + return S_OK; + } + HRESULT CDocument::get_DpiX(double* dDpiX) + { + *dDpiX = m_dDpiX; + return S_OK; + } + HRESULT CDocument::get_DpiY(double* dDpiY) + { + *dDpiY = m_dDpiY; + return S_OK; + } + //-------- Функции для задания настроек текста ---------------------------------------------- + // pen -------------------------------------------------------------------------------------- + HRESULT CDocument::get_PenColor(LONG* lColor) + { + *lColor = m_oPen.Color; + return S_OK; + } + HRESULT CDocument::put_PenColor(LONG lColor) + { + m_oPen.Color = lColor; + return S_OK; + } + HRESULT CDocument::get_PenAlpha(LONG* lAlpha) + { + *lAlpha = m_oPen.Alpha; + return S_OK; + } + HRESULT CDocument::put_PenAlpha(LONG lAlpha) + { + m_oPen.Alpha = lAlpha; + return S_OK; + } + HRESULT CDocument::get_PenSize(double* dSize) + { + *dSize = m_oPen.Size; + return S_OK; + } + HRESULT CDocument::put_PenSize(double dSize) + { + m_oPen.Size = dSize; + return S_OK; + } + HRESULT CDocument::get_PenDashStyle(BYTE* val) + { + *val = m_oPen.DashStyle; + return S_OK; + } + HRESULT CDocument::put_PenDashStyle(BYTE val) + { + m_oPen.DashStyle = val; + return S_OK; + } + HRESULT CDocument::get_PenLineStartCap(BYTE* val) + { + *val = m_oPen.LineStartCap; + return S_OK; + } + HRESULT CDocument::put_PenLineStartCap(BYTE val) + { + m_oPen.LineStartCap = val; + return S_OK; + } + HRESULT CDocument::get_PenLineEndCap(BYTE* val) + { + *val = m_oPen.LineEndCap; + return S_OK; + } + HRESULT CDocument::put_PenLineEndCap(BYTE val) + { + m_oPen.LineEndCap = val; + return S_OK; + } + HRESULT CDocument::get_PenLineJoin(BYTE* val) + { + *val = m_oPen.LineJoin; + return S_OK; + } + HRESULT CDocument::put_PenLineJoin(BYTE val) + { + m_oPen.LineJoin = val; + return S_OK; + } + HRESULT CDocument::get_PenDashOffset(double* val) + { + *val = m_oPen.DashOffset; + return S_OK; + } + HRESULT CDocument::put_PenDashOffset(double val) + { + m_oPen.DashOffset = val; + return S_OK; + } + HRESULT CDocument::get_PenAlign(LONG* val) + { + *val = m_oPen.Align; + return S_OK; + } + HRESULT CDocument::put_PenAlign(LONG val) + { + m_oPen.Align = val; + return S_OK; + } + HRESULT CDocument::get_PenMiterLimit(double* val) + { + *val = m_oPen.MiterLimit; + return S_OK; + } + HRESULT CDocument::put_PenMiterLimit(double val) + { + m_oPen.MiterLimit = val; + return S_OK; + } + HRESULT CDocument::PenDashPattern(double* pPattern, LONG lCount) + { + if (nullptr != pPattern) + { + m_oPen.SetDashPattern(pPattern, lCount); + } + + return S_OK; + } + // brush ------------------------------------------------------------------------------------ + HRESULT CDocument::get_BrushType(LONG* lType) + { + *lType = m_oBrush.Type; + return S_OK; + } + HRESULT CDocument::put_BrushType(LONG lType) + { + m_oBrush.Type = lType; + return S_OK; + } + HRESULT CDocument::get_BrushColor1(LONG* lColor) + { + *lColor = m_oBrush.Color1; + return S_OK; + } + HRESULT CDocument::put_BrushColor1(LONG lColor) + { + m_oBrush.Color1 = lColor; + return S_OK; + } + HRESULT CDocument::get_BrushAlpha1(LONG* lAlpha) + { + *lAlpha = m_oBrush.Alpha1; + return S_OK; + } + HRESULT CDocument::put_BrushAlpha1(LONG lAlpha) + { + m_oBrush.Alpha1 = lAlpha; + return S_OK; + } + HRESULT CDocument::get_BrushColor2(LONG* lColor) + { + *lColor = m_oBrush.Color2; + return S_OK; + } + HRESULT CDocument::put_BrushColor2(LONG lColor) + { + m_oBrush.Color2 = lColor; + return S_OK; + } + HRESULT CDocument::get_BrushAlpha2(LONG* lAlpha) + { + *lAlpha = m_oBrush.Alpha2; + return S_OK; + } + HRESULT CDocument::put_BrushAlpha2(LONG lAlpha) + { + m_oBrush.Alpha2 = lAlpha; + return S_OK; + } + HRESULT CDocument::get_BrushTexturePath(std::wstring* sPath) + { + *sPath = m_oBrush.TexturePath; + return S_OK; + } + HRESULT CDocument::put_BrushTexturePath(const std::wstring& sPath) + { + m_oBrush.TexturePath = sPath; + return S_OK; + } + HRESULT CDocument::get_BrushTextureMode(LONG* lMode) + { + *lMode = m_oBrush.TextureMode; + return S_OK; + } + HRESULT CDocument::put_BrushTextureMode(LONG lMode) + { + m_oBrush.TextureMode = lMode; + return S_OK; + } + HRESULT CDocument::get_BrushTextureAlpha(LONG* lTxAlpha) + { + *lTxAlpha = m_oBrush.TextureAlpha; + return S_OK; + } + HRESULT CDocument::put_BrushTextureAlpha(LONG lTxAlpha) + { + m_oBrush.TextureAlpha = lTxAlpha; + return S_OK; + } + HRESULT CDocument::get_BrushLinearAngle(double* dAngle) + { + *dAngle = m_oBrush.LinearAngle; + return S_OK; + } + HRESULT CDocument::put_BrushLinearAngle(double dAngle) + { + m_oBrush.LinearAngle = dAngle; + return S_OK; + } + HRESULT CDocument::BrushRect(bool val, double left, double top, double width, double height) + { + m_oBrush.Rectable = val ? 1 : 0; + m_oBrush.Rect.X = (float)left; + m_oBrush.Rect.Y = (float)top; + m_oBrush.Rect.Width = (float)width; + m_oBrush.Rect.Height = (float)height; + + return S_OK; + } + // font ------------------------------------------------------------------------------------- + HRESULT CDocument::get_FontName(std::wstring* sName) + { + *sName = m_oFont.Name; + return S_OK; + } + HRESULT CDocument::put_FontName(std::wstring sName) + { + m_oFont.Name = sName; + return S_OK; + } + HRESULT CDocument::get_FontPath(std::wstring* sPath) + { + *sPath = m_oFont.Path; + return S_OK; + } + HRESULT CDocument::put_FontPath(std::wstring sPath) + { + m_oFont.Path = sPath; + return S_OK; + } + HRESULT CDocument::get_FontSize(double* dSize) + { + *dSize = m_oFont.Size; + return S_OK; + } + HRESULT CDocument::put_FontSize(double dSize) + { + m_oFont.Size = dSize; + return S_OK; + } + HRESULT CDocument::get_FontStyle(LONG* lStyle) + { + *lStyle = m_oFont.GetStyle(); + return S_OK; + } + HRESULT CDocument::put_FontStyle(LONG lStyle) + { + m_oFont.SetStyle(lStyle); + return S_OK; + } + HRESULT CDocument::get_FontStringGID(INT* bGID) + { + *bGID = m_oFont.StringGID; + return S_OK; + } + HRESULT CDocument::put_FontStringGID(INT bGID) + { + m_oFont.StringGID = bGID; + return S_OK; + } + HRESULT CDocument::get_FontCharSpace(double* dSpace) + { + *dSpace = m_oFont.CharSpace; + return S_OK; + } + HRESULT CDocument::put_FontCharSpace(double dSpace) + { + m_oFont.CharSpace = dSpace; + return S_OK; + } + HRESULT CDocument::get_FontFaceIndex(int* lFaceIndex) + { + *lFaceIndex = m_oFont.FaceIndex; + return S_OK; + } + HRESULT CDocument::put_FontFaceIndex(const int& lFaceIndex) + { + m_oFont.FaceIndex = lFaceIndex; + return S_OK; + } + // shadow ----------------------------------------------------------------------------------- + HRESULT CDocument::get_ShadowDistanceX(double* val) + { + *val = m_oShadow.DistanceX; + return S_OK; + } + HRESULT CDocument::put_ShadowDistanceX(double val) + { + m_oShadow.DistanceX = val; + return S_OK; + } + HRESULT CDocument::get_ShadowDistanceY(double* val) + { + *val = m_oShadow.DistanceY; + return S_OK; + } + HRESULT CDocument::put_ShadowDistanceY(double val) + { + m_oShadow.DistanceY = val; + return S_OK; + } + HRESULT CDocument::get_ShadowBlurSize(double* val) + { + *val = m_oShadow.BlurSize; + return S_OK; + } + HRESULT CDocument::put_ShadowBlurSize(double val) + { + m_oShadow.BlurSize = val; + return S_OK; + } + HRESULT CDocument::get_ShadowColor(LONG* val) + { + *val = m_oShadow.Color; + return S_OK; + } + HRESULT CDocument::put_ShadowColor(LONG val) + { + m_oShadow.Color = val; + return S_OK; + } + HRESULT CDocument::get_ShadowAlpha(LONG* val) + { + *val = m_oShadow.Alpha; + return S_OK; + } + HRESULT CDocument::put_ShadowAlpha(LONG val) + { + m_oShadow.Alpha = val; + return S_OK; + } + HRESULT CDocument::get_ShadowVisible(INT* val) + { + *val = m_oShadow.Visible; + return S_OK; + } + HRESULT CDocument::put_ShadowVisible(INT val) + { + m_oShadow.Visible = val; + return S_OK; + } + // edge ------------------------------------------------------------------------------------- + HRESULT CDocument::get_EdgeVisible(LONG* val) + { + *val = m_oEdge.Visible; + return S_OK; + } + HRESULT CDocument::put_EdgeVisible(LONG val) + { + m_oEdge.Visible = val; + return S_OK; + } + HRESULT CDocument::get_EdgeColor(LONG* val) + { + *val = m_oEdge.Color; + return S_OK; + } + HRESULT CDocument::put_EdgeColor(LONG val) + { + m_oEdge.Color = val; + return S_OK; + } + HRESULT CDocument::get_EdgeAlpha(LONG* val) + { + *val = m_oEdge.Alpha; + return S_OK; + } + HRESULT CDocument::put_EdgeAlpha(LONG val) + { + m_oEdge.Alpha = val; + return S_OK; + } + HRESULT CDocument::get_EdgeDist(double* val) + { + *val = m_oEdge.Dist; + return S_OK; + } + HRESULT CDocument::put_EdgeDist(double val) + { + m_oEdge.Dist = val; + return S_OK; + } + + //-------- Функции для вывода текста -------------------------------------------------------- + HRESULT CDocument::CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, + const double& dX, const double& dY, const double& dW, + const double& dH, const double& dBaseLineOffset) + { + double dAngleMatrix = m_oTransform.z_Rotation(); + if (fabs(dAngleMatrix) > 1 || m_oTransform.sx() < 0 || m_oTransform.sy() < 0) + { + //note У повернутых символов не приходят координаты. + _SetFont(); + PathCommandEnd(); + BeginCommand(c_nPathType); + m_oSimpleGraphicsConverter.PathCommandText2(pUnicodes, pGids, nCount, m_pFontManager, dX, dY, dW, dH); + DrawPath(c_nWindingFillMode); + EndCommand(c_nPathType); + PathCommandEnd(); + return S_OK; + } + + m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer); + return S_OK; + } + + HRESULT CDocument::CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) + { + return CommandDrawTextPrivate(&lUnicode, nullptr, 1, dX, dY, dW, dH); + } + HRESULT CDocument::CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) + { + return CommandDrawTextPrivate(&lUnicode, &lGid, 1, dX, dY, dW, dH); + } + HRESULT CDocument::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) + { + unsigned int nLen = 0; + unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); + if (nLen == 0) + return S_OK; + CommandDrawTextPrivate((int*)pUnicodes, nullptr, nLen, dX, dY, dW, dH); + delete [] pUnicodes; + return S_OK; + } + HRESULT CDocument::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) + { + unsigned int nLen = 0; + unsigned int* pUnicodes = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeText, nLen); + if (nLen == 0) + return S_OK; + if (nLen != nGidsCount && 0 != nGidsCount) + { + delete [] pUnicodes; + return S_OK; + } CommandDrawTextPrivate((int*)pUnicodes, (0 == nGidsCount) ? nullptr : (int*)pGids, (int)nLen, dX, dY, dW, dH); - delete [] pUnicodes; - return S_OK; - } - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT CDocument::BeginCommand(DWORD lType) - { - if (c_nPageType == lType && m_bIsDisablePageCommand) - return S_OK; - - m_lCurrentCommandType = (LONG)lType; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; - - return S_OK; - } - HRESULT CDocument::EndCommand(DWORD lType) - { - if (c_nPageType == lType && m_bIsDisablePageCommand) - return S_OK; - - m_lCurrentCommandType = -1; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; - - if (c_nPageType == lType) - { - auto pWriter = new NSStringUtils::CStringBuilder(); - pWriter->AddSize(100000); - m_oCurrentPage.ProcessingAndRecordingOfPageData(*pWriter, m_lPagesCount, m_lNumberPages); - m_mapXmlString[m_lPagesCount] = std::move(pWriter); - } - else if (c_nPathType == lType) - { - m_oCurrentPage.End(); - } - - return S_OK; - } - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT CDocument::PathCommandMoveTo(double fX, double fY) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.MoveTo(fX, fY); - } - else - { - m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY); - } - return S_OK; - } - HRESULT CDocument::PathCommandLineTo(double fX, double fY) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.LineTo(fX, fY); - } - else - { - m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY); - } - return S_OK; - } - HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount) - { - m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount); - return S_OK; - } - HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3) - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - else - { - m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); - } - return S_OK; - } - HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount) - { - m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount); - return S_OK; - } - HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle) - { - m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); - return S_OK; - } - HRESULT CDocument::PathCommandClose() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.Close(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandClose(); - } - return S_OK; - } - HRESULT CDocument::PathCommandEnd() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.End(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandEnd(); - } - return S_OK; - } - HRESULT CDocument::DrawPath(long nType) - { - std::shared_ptr pInfo = nullptr; - - if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type)) - { - double x = 0; - double y = 0; - double w = 0; - double h = 0; - pInfo = m_oImageManager.WriteImage(m_oBrush.TexturePath, x, y, w, h); - } - - m_oCurrentPage.DrawPath(nType, pInfo); - return S_OK; - } - HRESULT CDocument::PathCommandStart() - { - if (c_nSimpleGraphicType == m_lCurrentCommandType) - { - m_oCurrentPage.Start(); - } - else - { - m_oSimpleGraphicsConverter.PathCommandStart(); - } - return S_OK; - } - HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY) - { - m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY); - return S_OK; - } - - HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, nullptr, 1, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0); - return S_OK; - } - HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) - { - _SetFont(); - m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH); - return S_OK; - } - - HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) - { - return S_OK; - } - HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) - { - ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags); - return S_OK; - } - //-------- Функции для вывода изображений -------------------------------------------------- - HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight) - { - m_oCurrentPage.WriteImage(m_oImageManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); - return S_OK; - } - HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight) - { - m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); - return S_OK; - } - //------------------------------------------------------------------------------------------ - HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF) - { - ApplyTransform(dA, dB, dC, dD, dE, dF); - return S_OK; - } - HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) - { - return S_OK; - } - HRESULT CDocument::ResetTransform(void) - { - m_oTransform.Reset(); - return S_OK; - } - HRESULT CDocument::get_ClipMode(LONG* plMode) - { - *plMode = m_lClipMode; - return S_OK; - } - HRESULT CDocument::put_ClipMode(LONG lMode) - { - m_lClipMode = lMode; - return S_OK; - } - - void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6) - { - m_oTransform.SetElements(d1, d2, d3, d4, d5, d6); - } - - void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) - { - if ((dWidth <= 1) || (dHeight <= 1)) - lFlags = 0; - - bool bFlipX = (0 != (c_nParamFlipX & lFlags)); - bool bFlipY = (0 != (c_nParamFlipY & lFlags)); - - double m11 = bFlipX ? -1.0 : 1.0; - double m22 = bFlipY ? -1.0 : 1.0; - - Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0); - - if ((0 != dAngle) || (0 != lFlags)) - { - double dCentreX = (dLeft + dWidth / 2.0); - double dCentreY = (dTop + dHeight / 2.0); - - oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend); - - oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend); - oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend); - - oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend); - } - - m_oTransform = oMatrix; - } - - void CDocument::_SetFont() - { - if (nullptr == m_pFontManager) - { - m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts); - } - - double dPix = m_oFont.CharSpace * m_dDpiX / 25.4; - - if (m_oInstalledFont.IsEqual(&m_oFont)) - { - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - return; - } - - m_pFontManager->SetStringGID(m_oFont.StringGID); - if (1 < m_dWidth) - { - m_pFontManager->SetCharSpacing(dPix); - } - - if (m_oFont.Path.empty()) - { - m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY); - } - else - { - m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY); - } - - m_oInstalledFont = m_oFont; - } - - bool CDocument::CreateDocument() - { - CreateTemplate(m_strTempDirectory); - - // Init - Clear(); - - m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager); - - m_oImageManager.NewDocument(); - m_oStyleManager.NewDocument(); - m_oFontManager.Init(); - - // media - m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; - NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); - - return true; - } - - void CDocument::Close() - { - BuildDocumentXml(); - BuildDocumentXmlRels(); - BuildFontTableXml(); - BuildStylesXml(); - } - - void CDocument::BuildDocumentXml() - { - NSFile::CFileBinary oDocumentStream; - - oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); - oDocumentStream.WriteStringUTF8(L"\ - \ - "); - - for (size_t i = 0; i < m_mapXmlString.size(); ++i) - { - oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData()); - } - - oDocumentStream.WriteStringUTF8(L""); - - oDocumentStream.CloseFile(); - } - - void CDocument::BuildDocumentXmlRels() - { - // сохраним rels (images & docs) - NSStringUtils::CStringBuilder oWriter; - - oWriter.WriteString(L"\ - \ - \ - \ - \ - \ - "); - - for (const auto& pImage : m_oImageManager.m_mapImageData) - { - auto pInfo = pImage.second; - - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); - oWriter.WriteString(pInfo->m_strFileName); - oWriter.WriteString(L"\"/>"); - } - - for (const auto& pImage : m_oImageManager.m_mapImagesFile) - { - auto pInfo = pImage.second;; - - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); - oWriter.WriteString(pInfo->m_strFileName); - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L""); - - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData()); - oWriter.ClearNoAttack(); - } - - void CDocument::BuildFontTableXml() - { - NSStringUtils::CStringBuilder oWriter; - // сохраним fontTable - oWriter.WriteString(L"\ - "); - - CFontTable* pFontTable = &m_oFontManager.m_oFontTable; - for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); ++iterFont) - { - CFontTableEntry& oEntry = iterFont->second; - - if (oEntry.m_strFamilyName.empty()) - { - continue; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - if (oEntry.m_bIsFixedWidth) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); - } - - void CDocument::BuildStylesXml() - { - NSStringUtils::CStringBuilder oWriter; - - // сохраним styles - oWriter.WriteString(L"\ - "); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); //отключение проверки орфографии - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - for (size_t i = 0; i < m_oStyleManager.m_arStyles.size(); ++i) - { - m_oStyleManager.m_arStyles[i]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/styles.xml", oWriter.GetData()); - } + delete [] pUnicodes; + return S_OK; + } + //-------- Маркеры для команд --------------------------------------------------------------- + HRESULT CDocument::BeginCommand(DWORD lType) + { + if (c_nPageType == lType && m_bIsDisablePageCommand) + return S_OK; + + m_lCurrentCommandType = (LONG)lType; + m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; + + return S_OK; + } + HRESULT CDocument::EndCommand(DWORD lType) + { + if (c_nPageType == lType && m_bIsDisablePageCommand) + return S_OK; + + m_lCurrentCommandType = -1; + m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; + + if (c_nPageType == lType) + { + auto pWriter = new NSStringUtils::CStringBuilder(); + pWriter->AddSize(100000); + m_oCurrentPage.ProcessingAndRecordingOfPageData(*pWriter, m_lPagesCount, m_lNumberPages); + m_mapXmlString[m_lPagesCount] = std::move(pWriter); + } + else if (c_nPathType == lType) + { + m_oCurrentPage.End(); + } + + return S_OK; + } + //-------- Функции для работы с Graphics Path ----------------------------------------------- + HRESULT CDocument::PathCommandMoveTo(double fX, double fY) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.MoveTo(fX, fY); + } + else + { + m_oSimpleGraphicsConverter.PathCommandMoveTo(fX, fY); + } + return S_OK; + } + HRESULT CDocument::PathCommandLineTo(double fX, double fY) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.LineTo(fX, fY); + } + else + { + m_oSimpleGraphicsConverter.PathCommandLineTo(fX, fY); + } + return S_OK; + } + HRESULT CDocument::PathCommandLinesTo(double* pPoints, LONG lCount) + { + m_oSimpleGraphicsConverter.PathCommandLinesTo(pPoints, lCount); + return S_OK; + } + HRESULT CDocument::PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3) + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.CurveTo(fX1, fY1, fX2, fY2, fX3, fY3); + } + else + { + m_oSimpleGraphicsConverter.PathCommandCurveTo(fX1, fY1, fX2, fY2, fX3, fY3); + } + return S_OK; + } + HRESULT CDocument::PathCommandCurvesTo(double* pPoints, LONG lCount) + { + m_oSimpleGraphicsConverter.PathCommandCurvesTo(pPoints, lCount); + return S_OK; + } + HRESULT CDocument::PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle) + { + m_oSimpleGraphicsConverter.PathCommandArcTo(fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle); + return S_OK; + } + HRESULT CDocument::PathCommandClose() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.Close(); + } + else + { + m_oSimpleGraphicsConverter.PathCommandClose(); + } + return S_OK; + } + HRESULT CDocument::PathCommandEnd() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.End(); + } + else + { + m_oSimpleGraphicsConverter.PathCommandEnd(); + } + return S_OK; + } + HRESULT CDocument::DrawPath(long nType) + { + std::shared_ptr pInfo = nullptr; + + if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type)) + { + double x = 0; + double y = 0; + double w = 0; + double h = 0; + pInfo = m_oImageManager.WriteImage(m_oBrush.TexturePath, x, y, w, h); + } + + m_oCurrentPage.DrawPath(nType, pInfo); + return S_OK; + } + HRESULT CDocument::PathCommandStart() + { + if (c_nSimpleGraphicType == m_lCurrentCommandType) + { + m_oCurrentPage.Start(); + } + else + { + m_oSimpleGraphicsConverter.PathCommandStart(); + } + return S_OK; + } + HRESULT CDocument::PathCommandGetCurrentPoint(double* fX, double* fY) + { + m_oSimpleGraphicsConverter.PathCommandGetCurrentPoint(fX, fY); + return S_OK; + } + + HRESULT CDocument::PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, nullptr, 1, m_pFontManager, dX, dY, dW, dH); + return S_OK; + } + HRESULT CDocument::PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(&lUnicode, &lGid, 1, m_pFontManager, dX, dY, dW, dH); + return S_OK; + } + HRESULT CDocument::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText(wsUnicodeText, m_pFontManager, dX, dY, dW, dH, 0); + return S_OK; + } + HRESULT CDocument::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) + { + _SetFont(); + m_oSimpleGraphicsConverter.PathCommandText2(wsUnicodeText, (const int*)pGids, nGidsCount, m_pFontManager, dX, dY, dW, dH); + return S_OK; + } + + HRESULT CDocument::GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) + { + return S_OK; + } + HRESULT CDocument::SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) + { + ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags); + return S_OK; + } + //-------- Функции для вывода изображений -------------------------------------------------- + HRESULT CDocument::DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight) + { + m_oCurrentPage.WriteImage(m_oImageManager.WriteImage((Aggplus::CImage*)pImage, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); + return S_OK; + } + HRESULT CDocument::DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight) + { + m_oCurrentPage.WriteImage(m_oImageManager.WriteImage(sVal, fX, fY, fWidth, fHeight), fX, fY, fWidth, fHeight); + return S_OK; + } + //------------------------------------------------------------------------------------------ + HRESULT CDocument::SetTransform(double dA, double dB, double dC, double dD, double dE, double dF) + { + ApplyTransform(dA, dB, dC, dD, dE, dF); + return S_OK; + } + HRESULT CDocument::GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) + { + return S_OK; + } + HRESULT CDocument::ResetTransform(void) + { + m_oTransform.Reset(); + return S_OK; + } + HRESULT CDocument::get_ClipMode(LONG* plMode) + { + *plMode = m_lClipMode; + return S_OK; + } + HRESULT CDocument::put_ClipMode(LONG lMode) + { + m_lClipMode = lMode; + return S_OK; + } + + void CDocument::ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6) + { + m_oTransform.SetElements(d1, d2, d3, d4, d5, d6); + } + + void CDocument::ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) + { + if ((dWidth <= 1) || (dHeight <= 1)) + lFlags = 0; + + bool bFlipX = (0 != (c_nParamFlipX & lFlags)); + bool bFlipY = (0 != (c_nParamFlipY & lFlags)); + + double m11 = bFlipX ? -1.0 : 1.0; + double m22 = bFlipY ? -1.0 : 1.0; + + Aggplus::CMatrix oMatrix(1, 0, 0, 1, 0, 0); + + if ((0 != dAngle) || (0 != lFlags)) + { + double dCentreX = (dLeft + dWidth / 2.0); + double dCentreY = (dTop + dHeight / 2.0); + + oMatrix.Translate(-dCentreX, -dCentreY , Aggplus::MatrixOrderAppend); + + oMatrix.Rotate(dAngle , Aggplus::MatrixOrderAppend); + oMatrix.Scale(m11, m22 , Aggplus::MatrixOrderAppend); + + oMatrix.Translate(dCentreX, dCentreY , Aggplus::MatrixOrderAppend); + } + + m_oTransform = oMatrix; + } + + void CDocument::_SetFont() + { + if (nullptr == m_pFontManager) + { + m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts); + } + + double dPix = m_oFont.CharSpace * m_dDpiX / 25.4; + + if (m_oInstalledFont.IsEqual(&m_oFont)) + { + if (1 < m_dWidth) + { + m_pFontManager->SetCharSpacing(dPix); + } + return; + } + + m_pFontManager->SetStringGID(m_oFont.StringGID); + if (1 < m_dWidth) + { + m_pFontManager->SetCharSpacing(dPix); + } + + if (m_oFont.Path.empty()) + { + m_pFontManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle(), m_dDpiX, m_dDpiY); + } + else + { + m_pFontManager->LoadFontFromFile(m_oFont.Path, m_oFont.FaceIndex, (float)m_oFont.Size, m_dDpiX, m_dDpiY); + } + + m_oInstalledFont = m_oFont; + } + + bool CDocument::CreateDocument() + { + CreateTemplate(m_strTempDirectory); + + // Init + Clear(); + + m_lCurrentCommandType = 0; + m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager); + + m_oImageManager.NewDocument(); + m_oStyleManager.NewDocument(); + m_oFontManager.Init(); + + // media + m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; + NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); + + return true; + } + + void CDocument::Close() + { + BuildDocumentXml(); + BuildDocumentXmlRels(); + BuildFontTableXml(); + BuildStylesXml(); + } + + void CDocument::BuildDocumentXml() + { + NSFile::CFileBinary oDocumentStream; + + oDocumentStream.CreateFileW(m_strTempDirectory + L"/word/document.xml"); + oDocumentStream.WriteStringUTF8(L"\ + \ + "); + + for (size_t i = 0; i < m_mapXmlString.size(); ++i) + { + oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData()); + } + + oDocumentStream.WriteStringUTF8(L""); + + oDocumentStream.CloseFile(); + } + + void CDocument::BuildDocumentXmlRels() + { + // сохраним rels (images & docs) + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"\ + \ + \ + \ + \ + \ + "); + + for (const auto& pImage : m_oImageManager.m_mapImageData) + { + auto pInfo = pImage.second; + + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); + oWriter.WriteString(pInfo->m_strFileName); + oWriter.WriteString(L"\"/>"); + } + + for (const auto& pImage : m_oImageManager.m_mapImagesFile) + { + auto pInfo = pImage.second;; + + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); + oWriter.WriteString(pInfo->m_strFileName); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L""); + + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/_rels/document.xml.rels", oWriter.GetData()); + oWriter.ClearNoAttack(); + } + + void CDocument::BuildFontTableXml() + { + NSStringUtils::CStringBuilder oWriter; + // сохраним fontTable + oWriter.WriteString(L"\ + "); + + CFontTable* pFontTable = &m_oFontManager.m_oFontTable; + for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); ++iterFont) + { + CFontTableEntry& oEntry = iterFont->second; + + if (oEntry.m_strFamilyName.empty()) + { + continue; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + if (oEntry.m_bIsFixedWidth) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); + } + + void CDocument::BuildStylesXml() + { + NSStringUtils::CStringBuilder oWriter; + + // сохраним styles + oWriter.WriteString(L"\ + "); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); //отключение проверки орфографии + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + for (size_t i = 0; i < m_oStyleManager.m_arStyles.size(); ++i) + { + m_oStyleManager.m_arStyles[i]->ToXml(oWriter); + } + + oWriter.WriteString(L""); + + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/styles.xml", oWriter.GetData()); + } } diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index 68a98ec05b0..7e333694041 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -7,202 +7,202 @@ namespace NSDocxRenderer { - class CDocument - { - public: - NSFonts::IApplicationFonts* m_pAppFonts; - - NSStructures::CPen m_oPen; - NSStructures::CBrush m_oBrush; - NSStructures::CFont m_oFont; - NSStructures::CShadow m_oShadow; - NSStructures::CEdgeText m_oEdge; - - NSStructures::CFont m_oInstalledFont; - - NSFonts::IFontManager* m_pFontManager {nullptr}; - Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - - Aggplus::CMatrix m_oTransform; - - LONG m_lCurrentCommandType {0}; - - LONG m_lClipMode; - CPage m_oCurrentPage; - - CImageManager m_oImageManager; - CStyleManager m_oStyleManager; - CFontManager m_oFontManager; - - double m_dWidth {0.0}; - double m_dHeight {0.0}; - - double m_dDpiX {72.0}; - double m_dDpiY {72.0}; - - std::wstring m_strTempDirectory {L""}; - std::wstring m_strDstFilePath; - - LONG m_lPagesCount {0}; - LONG m_lNumberPages{0}; - - bool m_bIsNeedPDFTextAnalyzer {false}; - - bool m_bIsDisablePageCommand {false}; // disable commands inside draw function - - std::map m_mapXmlString; - public: - CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); - void Clear(); - - ~CDocument(); - - public: - - HRESULT NewPage(); - HRESULT get_Height(double* dHeight); - HRESULT put_Height(double dHeight); - HRESULT get_Width(double* dWidth); - HRESULT put_Width(double dWidth); - HRESULT get_DpiX(double* dDpiX); - HRESULT get_DpiY(double* dDpiY); - //-------- Функции для задания настроек текста ---------------------------------------------- - // pen -------------------------------------------------------------------------------------- - HRESULT get_PenColor(LONG* lColor); - HRESULT put_PenColor(LONG lColor); - HRESULT get_PenAlpha(LONG* lAlpha); - HRESULT put_PenAlpha(LONG lAlpha); - HRESULT get_PenSize(double* dSize); - HRESULT put_PenSize(double dSize); - HRESULT get_PenDashStyle(BYTE* val); - HRESULT put_PenDashStyle(BYTE val); - HRESULT get_PenLineStartCap(BYTE* val); - HRESULT put_PenLineStartCap(BYTE val); - HRESULT get_PenLineEndCap(BYTE* val); - HRESULT put_PenLineEndCap(BYTE val); - HRESULT get_PenLineJoin(BYTE* val); - HRESULT put_PenLineJoin(BYTE val); - HRESULT get_PenDashOffset(double* val); - HRESULT put_PenDashOffset(double val); - HRESULT get_PenAlign(LONG* val); - HRESULT put_PenAlign(LONG val); - HRESULT get_PenMiterLimit(double* val); - HRESULT put_PenMiterLimit(double val); - HRESULT PenDashPattern(double* pPattern, LONG lCount); - // brush ------------------------------------------------------------------------------------ - HRESULT get_BrushType(LONG* lType); - HRESULT put_BrushType(LONG lType); - HRESULT get_BrushColor1(LONG* lColor); - HRESULT put_BrushColor1(LONG lColor); - HRESULT get_BrushAlpha1(LONG* lAlpha); - HRESULT put_BrushAlpha1(LONG lAlpha); - HRESULT get_BrushColor2(LONG* lColor); - HRESULT put_BrushColor2(LONG lColor); - HRESULT get_BrushAlpha2(LONG* lAlpha); - HRESULT put_BrushAlpha2(LONG lAlpha); - HRESULT get_BrushTexturePath(std::wstring* sPath); - HRESULT put_BrushTexturePath(const std::wstring& sPath); - HRESULT get_BrushTextureMode(LONG* lMode); - HRESULT put_BrushTextureMode(LONG lMode); - HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); - HRESULT put_BrushTextureAlpha(LONG lTxAlpha); - HRESULT get_BrushLinearAngle(double* dAngle); - HRESULT put_BrushLinearAngle(double dAngle); - HRESULT BrushRect(bool val, double left, double top, double width, double height); - // font ------------------------------------------------------------------------------------- - HRESULT get_FontName(std::wstring* sName); - HRESULT put_FontName(std::wstring sName); - HRESULT get_FontPath(std::wstring* sPath); - HRESULT put_FontPath(std::wstring sPath); - HRESULT get_FontSize(double* dSize); - HRESULT put_FontSize(double dSize); - HRESULT get_FontStyle(LONG* lStyle); - HRESULT put_FontStyle(LONG lStyle); - HRESULT get_FontStringGID(INT* bGID); - HRESULT put_FontStringGID(INT bGID); - HRESULT get_FontCharSpace(double* dSpace); - HRESULT put_FontCharSpace(double dSpace); - HRESULT get_FontFaceIndex(int* lFaceIndex); - HRESULT put_FontFaceIndex(const int& lFaceIndex); - // shadow ----------------------------------------------------------------------------------- - HRESULT get_ShadowDistanceX(double* val); - HRESULT put_ShadowDistanceX(double val); - HRESULT get_ShadowDistanceY(double* val); - HRESULT put_ShadowDistanceY(double val); - HRESULT get_ShadowBlurSize(double* val); - HRESULT put_ShadowBlurSize(double val); - HRESULT get_ShadowColor(LONG* val); - HRESULT put_ShadowColor(LONG val); - HRESULT get_ShadowAlpha(LONG* val); - HRESULT put_ShadowAlpha(LONG val); - HRESULT get_ShadowVisible(INT* val); - HRESULT put_ShadowVisible(INT val); - // edge ------------------------------------------------------------------------------------- - HRESULT get_EdgeVisible(LONG* val); - HRESULT put_EdgeVisible(LONG val); - HRESULT get_EdgeColor(LONG* val); - HRESULT put_EdgeColor(LONG val); - HRESULT get_EdgeAlpha(LONG* val); - HRESULT put_EdgeAlpha(LONG val); - HRESULT get_EdgeDist(double* val); - HRESULT put_EdgeDist(double val); - //-------- Функции для вывода текста -------------------------------------------------------- - HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, - const double& dX, const double& dY, const double& dW, - const double& dH, const double& dBaseLineOffset = 0); - HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, - const unsigned int nGidsCount, const double& dX, const double& dY, - const double& dW, const double& dH); - //-------- Маркеры для команд --------------------------------------------------------------- - HRESULT BeginCommand(DWORD lType); - HRESULT EndCommand(DWORD lType); - //-------- Функции для работы с Graphics Path ----------------------------------------------- - HRESULT PathCommandMoveTo(double fX, double fY); - HRESULT PathCommandLineTo(double fX, double fY); - HRESULT PathCommandLinesTo(double* pPoints, LONG lCount); - HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); - HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount); - HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); - HRESULT PathCommandClose(); - HRESULT PathCommandEnd(); - HRESULT DrawPath(long nType); - HRESULT PathCommandStart(); - HRESULT PathCommandGetCurrentPoint(double* fX, double* fY); - - HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - - HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags); - HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); - //-------- Функции для вывода изображений -------------------------------------------------- - HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight); - HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight); - //------------------------------------------------------------------------------------------ - HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF); - HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); - HRESULT ResetTransform(void); - HRESULT get_ClipMode(LONG* plMode); - HRESULT put_ClipMode(LONG lMode); - - protected: - void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); - - void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); - - void _SetFont(); - public: - - bool CreateDocument(); - - void Close(); - void BuildDocumentXml(); - void BuildDocumentXmlRels(); - void BuildFontTableXml(); - void BuildStylesXml(); + class CDocument + { + public: + NSFonts::IApplicationFonts* m_pAppFonts; + + NSStructures::CPen m_oPen; + NSStructures::CBrush m_oBrush; + NSStructures::CFont m_oFont; + NSStructures::CShadow m_oShadow; + NSStructures::CEdgeText m_oEdge; + + NSStructures::CFont m_oInstalledFont; + + NSFonts::IFontManager* m_pFontManager {nullptr}; + Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; + + Aggplus::CMatrix m_oTransform; + + LONG m_lCurrentCommandType {0}; + + LONG m_lClipMode; + CPage m_oCurrentPage; + + CImageManager m_oImageManager; + CStyleManager m_oStyleManager; + CFontManager m_oFontManager; + + double m_dWidth {0.0}; + double m_dHeight {0.0}; + + double m_dDpiX {72.0}; + double m_dDpiY {72.0}; + + std::wstring m_strTempDirectory {L""}; + std::wstring m_strDstFilePath; + + LONG m_lPagesCount {0}; + LONG m_lNumberPages{0}; + + bool m_bIsNeedPDFTextAnalyzer {false}; + + bool m_bIsDisablePageCommand {false}; // disable commands inside draw function + + std::map m_mapXmlString; + public: + CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); + void Clear(); + + ~CDocument(); + + public: + + HRESULT NewPage(); + HRESULT get_Height(double* dHeight); + HRESULT put_Height(double dHeight); + HRESULT get_Width(double* dWidth); + HRESULT put_Width(double dWidth); + HRESULT get_DpiX(double* dDpiX); + HRESULT get_DpiY(double* dDpiY); + //-------- Функции для задания настроек текста ---------------------------------------------- + // pen -------------------------------------------------------------------------------------- + HRESULT get_PenColor(LONG* lColor); + HRESULT put_PenColor(LONG lColor); + HRESULT get_PenAlpha(LONG* lAlpha); + HRESULT put_PenAlpha(LONG lAlpha); + HRESULT get_PenSize(double* dSize); + HRESULT put_PenSize(double dSize); + HRESULT get_PenDashStyle(BYTE* val); + HRESULT put_PenDashStyle(BYTE val); + HRESULT get_PenLineStartCap(BYTE* val); + HRESULT put_PenLineStartCap(BYTE val); + HRESULT get_PenLineEndCap(BYTE* val); + HRESULT put_PenLineEndCap(BYTE val); + HRESULT get_PenLineJoin(BYTE* val); + HRESULT put_PenLineJoin(BYTE val); + HRESULT get_PenDashOffset(double* val); + HRESULT put_PenDashOffset(double val); + HRESULT get_PenAlign(LONG* val); + HRESULT put_PenAlign(LONG val); + HRESULT get_PenMiterLimit(double* val); + HRESULT put_PenMiterLimit(double val); + HRESULT PenDashPattern(double* pPattern, LONG lCount); + // brush ------------------------------------------------------------------------------------ + HRESULT get_BrushType(LONG* lType); + HRESULT put_BrushType(LONG lType); + HRESULT get_BrushColor1(LONG* lColor); + HRESULT put_BrushColor1(LONG lColor); + HRESULT get_BrushAlpha1(LONG* lAlpha); + HRESULT put_BrushAlpha1(LONG lAlpha); + HRESULT get_BrushColor2(LONG* lColor); + HRESULT put_BrushColor2(LONG lColor); + HRESULT get_BrushAlpha2(LONG* lAlpha); + HRESULT put_BrushAlpha2(LONG lAlpha); + HRESULT get_BrushTexturePath(std::wstring* sPath); + HRESULT put_BrushTexturePath(const std::wstring& sPath); + HRESULT get_BrushTextureMode(LONG* lMode); + HRESULT put_BrushTextureMode(LONG lMode); + HRESULT get_BrushTextureAlpha(LONG* lTxAlpha); + HRESULT put_BrushTextureAlpha(LONG lTxAlpha); + HRESULT get_BrushLinearAngle(double* dAngle); + HRESULT put_BrushLinearAngle(double dAngle); + HRESULT BrushRect(bool val, double left, double top, double width, double height); + // font ------------------------------------------------------------------------------------- + HRESULT get_FontName(std::wstring* sName); + HRESULT put_FontName(std::wstring sName); + HRESULT get_FontPath(std::wstring* sPath); + HRESULT put_FontPath(std::wstring sPath); + HRESULT get_FontSize(double* dSize); + HRESULT put_FontSize(double dSize); + HRESULT get_FontStyle(LONG* lStyle); + HRESULT put_FontStyle(LONG lStyle); + HRESULT get_FontStringGID(INT* bGID); + HRESULT put_FontStringGID(INT bGID); + HRESULT get_FontCharSpace(double* dSpace); + HRESULT put_FontCharSpace(double dSpace); + HRESULT get_FontFaceIndex(int* lFaceIndex); + HRESULT put_FontFaceIndex(const int& lFaceIndex); + // shadow ----------------------------------------------------------------------------------- + HRESULT get_ShadowDistanceX(double* val); + HRESULT put_ShadowDistanceX(double val); + HRESULT get_ShadowDistanceY(double* val); + HRESULT put_ShadowDistanceY(double val); + HRESULT get_ShadowBlurSize(double* val); + HRESULT put_ShadowBlurSize(double val); + HRESULT get_ShadowColor(LONG* val); + HRESULT put_ShadowColor(LONG val); + HRESULT get_ShadowAlpha(LONG* val); + HRESULT put_ShadowAlpha(LONG val); + HRESULT get_ShadowVisible(INT* val); + HRESULT put_ShadowVisible(INT val); + // edge ------------------------------------------------------------------------------------- + HRESULT get_EdgeVisible(LONG* val); + HRESULT put_EdgeVisible(LONG val); + HRESULT get_EdgeColor(LONG* val); + HRESULT put_EdgeColor(LONG val); + HRESULT get_EdgeAlpha(LONG* val); + HRESULT put_EdgeAlpha(LONG val); + HRESULT get_EdgeDist(double* val); + HRESULT put_EdgeDist(double val); + //-------- Функции для вывода текста -------------------------------------------------------- + HRESULT CommandDrawTextPrivate(const int* pUnicodes, const int* pGids, int nCount, + const double& dX, const double& dY, const double& dW, + const double& dH, const double& dBaseLineOffset = 0); + HRESULT CommandDrawTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT CommandDrawTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, + const unsigned int nGidsCount, const double& dX, const double& dY, + const double& dW, const double& dH); + //-------- Маркеры для команд --------------------------------------------------------------- + HRESULT BeginCommand(DWORD lType); + HRESULT EndCommand(DWORD lType); + //-------- Функции для работы с Graphics Path ----------------------------------------------- + HRESULT PathCommandMoveTo(double fX, double fY); + HRESULT PathCommandLineTo(double fX, double fY); + HRESULT PathCommandLinesTo(double* pPoints, LONG lCount); + HRESULT PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3); + HRESULT PathCommandCurvesTo(double* pPoints, LONG lCount); + HRESULT PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle); + HRESULT PathCommandClose(); + HRESULT PathCommandEnd(); + HRESULT DrawPath(long nType); + HRESULT PathCommandStart(); + HRESULT PathCommandGetCurrentPoint(double* fX, double* fY); + + HRESULT PathCommandTextCHAR(const int& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandTextExCHAR(const int& lUnicode, const int& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + HRESULT PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags); + HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); + //-------- Функции для вывода изображений -------------------------------------------------- + HRESULT DrawImage(IGrObject* pImage, double fX, double fY, double fWidth, double fHeight); + HRESULT DrawImageFromFile(const std::wstring& sVal, double fX, double fY, double fWidth, double fHeight); + //------------------------------------------------------------------------------------------ + HRESULT SetTransform(double dA, double dB, double dC, double dD, double dE, double dF); + HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF); + HRESULT ResetTransform(void); + HRESULT get_ClipMode(LONG* plMode); + HRESULT put_ClipMode(LONG lMode); + + protected: + void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); + + void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); + + void _SetFont(); + public: + + bool CreateDocument(); + + void Close(); + void BuildDocumentXml(); + void BuildDocumentXmlRels(); + void BuildFontTableXml(); + void BuildStylesXml(); }; } diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 9054ccfa4c8..39fd82e2d77 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -7,1037 +7,1037 @@ namespace NSDocxRenderer { - CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManagerLight(pFonts) - { - } - - void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager) - { - m_pFont = pFont; - m_pPen = pPen; - m_pBrush = pBrush; - m_pShadow = pShadow; - m_pEdgeText = pEdge; - - m_pTransform = pMatrix; - m_pSimpleGraphicsConverter = pSimple; - - m_pStyleManager = pStyleManager; - m_pFontManager = pFontManager; - - m_pCurrentLine = nullptr; - m_pCurrentRow = nullptr; - - CShape::ResetRelativeHeight(); - } - - void CPage::Clear() - { - ClearTextData(); - ClearTextLines(); - ClearOutputObjects(); - ClearShapes(); - ClearImages(); - - ClearTables(); - - m_pCurrentLine = nullptr; - m_pCurrentRow = nullptr; - } - - void CPage::ClearImages() - { - m_arImages.clear(); - } - - void CPage::ClearTextData() - { - m_arDiacriticalSymbol.clear(); - } - - void CPage::ClearTextLines() - { - m_arTextLine.clear(); - } - - void CPage::ClearShapes() - { - m_arShapes.clear(); - } - - void CPage::ClearOutputObjects() - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } - m_arOutputObjects.clear(); - } - - void CPage::ClearTables() - { - m_arPeaks.clear(); - m_arCells.clear(); - m_arRows.clear(); - m_arTables.clear(); - } - - CPage::~CPage() - { - Clear(); - } - - void CPage::DeleteTextClipPage() - { - if (m_bIsDeleteTextClipPage) - { - // удалим все линии, которые выходят за границы страницы - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pLine = m_arTextLine[i]; - - if (pLine->m_dTop >= m_dHeight || pLine->m_dBaselinePos <= 0) - { - pLine->m_bIsNotNecessaryToUse = true; - } - } - } - } - - // image commands - void CPage::WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight) - { - auto pImage = new CShape(pInfo, L""); - pImage->m_eType = CShape::eShapeType::stPicture; - - double dRotation = m_pTransform->z_Rotation(); - - if (fabs(dRotation) < 5.0) - { - double x1 = fX; - double y1 = fY; - double x2 = fX + fWidth; - double y2 = fY + fHeight; - - m_pTransform->TransformPoint(x1, y1); - m_pTransform->TransformPoint(x2, y2); - - if (x1 <= x2) - { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; - } - else - { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; - } - - if (y1 <= y2) - { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; - } - else - { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; - } - - pImage->m_dRotate = 0.0; - } - else - { - double x1 = fX; - double y1 = fY; - double x2 = fX + fWidth; - double y2 = fY + fHeight; - - Aggplus::CMatrix oTemp = *m_pTransform; - - double dCx = (x1 + x2) / 2; - double dCy = (y1 + y2) / 2; - m_pTransform->TransformPoint(dCx, dCy); - oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend); - - oTemp.TransformPoint(x1, y1); - oTemp.TransformPoint(x2, y2); - - if (x1 <= x2) - { - pImage->m_dLeft = x1; - pImage->m_dWidth = x2 - x1; - } - else - { - pImage->m_dLeft = x2; - pImage->m_dWidth = x1 - x2; - } - - if (y1 <= y2) - { - pImage->m_dTop = y1; - pImage->m_dHeight = y2 - y1; - } - else - { - pImage->m_dTop = y2; - pImage->m_dHeight = y1 - y2; - } - - pImage->m_dRotate = dRotation; - } - - pImage->m_dBaselinePos = pImage->m_dTop + pImage->m_dHeight; - pImage->m_dRight = pImage->m_dLeft + pImage->m_dWidth; - - m_arImages.push_back(pImage); - } - - // path commands - void CPage::MoveTo(double& dX, double& dY) - { - m_pTransform->TransformPoint(dX, dY); - m_oVector.MoveTo(dX, dY); - } - - void CPage::LineTo(double& dX, double& dY) - { - m_pTransform->TransformPoint(dX, dY); - m_oVector.LineTo(dX, dY); - } - - void CPage::CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) - { - m_pTransform->TransformPoint(x1, y1); - m_pTransform->TransformPoint(x2, y2); - m_pTransform->TransformPoint(x3, y3); - - m_oVector.CurveTo(x1, y1, x2, y2, x3, y3); - } - - void CPage::Start() - { - } - - void CPage::End() - { - m_oVector.End(); - } - - void CPage::Close() - { - m_oVector.Close(); - } - - void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) - { - if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom)) - { - if (!m_arShapes.empty()) - { - auto pLastShape = m_arShapes.back(); - - if (pLastShape->m_dLeft == m_oVector.m_dLeft && - pLastShape->m_dTop == m_oVector.m_dTop && - pLastShape->m_dWidth == m_oVector.m_dRight - m_oVector.m_dLeft && - pLastShape->m_dHeight == m_oVector.m_dBottom - m_oVector.m_dTop) - { - if (0x00 != (lType & 0x01)) - { - pLastShape->m_bIsNoStroke = false; - pLastShape->m_oPen = *m_pPen; - } - if (0x00 != (lType >> 8)) - { - pLastShape->m_bIsNoFill = false; - pLastShape->m_oBrush = *m_pBrush; - } - return; - } - } - - auto pShape = new CShape(); - - if (pInfo) - { - pShape->m_pImageInfo = pInfo; - pShape->m_eType = CShape::eShapeType::stVectorTexture; - } - else - { - pShape->m_eType = CShape::eShapeType::stVectorGraphics; - } - - if (0x00 != (lType & 0x01)) - { - pShape->m_bIsNoStroke = false; - pShape->m_oPen = *m_pPen; - } - if (0x00 != (lType >> 8)) - { - pShape->m_bIsNoFill = false; - pShape->m_oBrush = *m_pBrush; - } - - if (pShape->m_bIsNoStroke) - { - if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3)) - { - pShape->m_oPen.Color = m_pBrush->Color1; - pShape->m_oPen.Alpha = m_pBrush->Alpha1; - } - } - - pShape->GetDataFromVector(m_oVector); - - m_arShapes.push_back(pShape); - } - } - - void CPage::CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer) - { - if (pUnicodes != nullptr && nCount == 1 && IsSpaceUtf32(*pUnicodes)) - { - //note пробелы не нужны, добавляются при анализе - return; - } - - double dTextX = fX; - double dTextY = fY; - double dTextR = fX + fWidth; - double dTextB = fY + fHeight; - - m_pTransform->TransformPoint(dTextX, dTextY); - m_pTransform->TransformPoint(dTextR, dTextB); - - double dTextW = dTextR - dTextX; - double dTextH = dTextB - dTextY; - - NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); - - if ((pUnicodes != nullptr) && (pGids != nullptr)) - { - for (unsigned int i = 0; i < nCount; ++i) - { - if ( !IsUnicodeSymbol( pUnicodes[i] ) ) - { - oText[i] = ' '; - } - } - } - - bool bIsPath = ((nullptr == pGids) && !bIsPDFAnalyzer) ? false : true; - - m_pFontManager->LoadFont(0, !bIsPath); - - if (!bIsPath) - m_pFontManager->GenerateFontName2(oText); - - if (fabs(dTextW) < 0.01 || (dTextW > 10)) - { - double _x = 0; - double _y = 0; - double _w = 0; - double _h = 0; - - if (nullptr != pGids) - { - m_pFontManager->SetStringGid(1); - m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } - else - { - // такого быть не должно (только из xps) - m_pFontManager->SetStringGid(0); - m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } - - dTextW = _w; - } - - double dBaseLinePos = dTextY + fBaseLineOffset; - dTextH = m_pFontManager->GetFontHeight(); - - auto pCont = new CContText(&m_oFontManagerLight, m_pStyleManager); - - pCont->m_dLeft = dTextX; - pCont->m_dBaselinePos = dBaseLinePos; + CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManagerLight(pFonts) + { + } + + void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, + NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager) + { + m_pFont = pFont; + m_pPen = pPen; + m_pBrush = pBrush; + m_pShadow = pShadow; + m_pEdgeText = pEdge; + + m_pTransform = pMatrix; + m_pSimpleGraphicsConverter = pSimple; + + m_pStyleManager = pStyleManager; + m_pFontManager = pFontManager; + + m_pCurrentLine = nullptr; + m_pCurrentRow = nullptr; + + CShape::ResetRelativeHeight(); + } + + void CPage::Clear() + { + ClearTextData(); + ClearTextLines(); + ClearOutputObjects(); + ClearShapes(); + ClearImages(); + + ClearTables(); + + m_pCurrentLine = nullptr; + m_pCurrentRow = nullptr; + } + + void CPage::ClearImages() + { + m_arImages.clear(); + } + + void CPage::ClearTextData() + { + m_arDiacriticalSymbol.clear(); + } + + void CPage::ClearTextLines() + { + m_arTextLine.clear(); + } + + void CPage::ClearShapes() + { + m_arShapes.clear(); + } + + void CPage::ClearOutputObjects() + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); + } + + void CPage::ClearTables() + { + m_arPeaks.clear(); + m_arCells.clear(); + m_arRows.clear(); + m_arTables.clear(); + } + + CPage::~CPage() + { + Clear(); + } + + void CPage::DeleteTextClipPage() + { + if (m_bIsDeleteTextClipPage) + { + // удалим все линии, которые выходят за границы страницы + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + auto pLine = m_arTextLine[i]; + + if (pLine->m_dTop >= m_dHeight || pLine->m_dBaselinePos <= 0) + { + pLine->m_bIsNotNecessaryToUse = true; + } + } + } + } + + // image commands + void CPage::WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight) + { + auto pImage = new CShape(pInfo, L""); + pImage->m_eType = CShape::eShapeType::stPicture; + + double dRotation = m_pTransform->z_Rotation(); + + if (fabs(dRotation) < 5.0) + { + double x1 = fX; + double y1 = fY; + double x2 = fX + fWidth; + double y2 = fY + fHeight; + + m_pTransform->TransformPoint(x1, y1); + m_pTransform->TransformPoint(x2, y2); + + if (x1 <= x2) + { + pImage->m_dLeft = x1; + pImage->m_dWidth = x2 - x1; + } + else + { + pImage->m_dLeft = x2; + pImage->m_dWidth = x1 - x2; + } + + if (y1 <= y2) + { + pImage->m_dTop = y1; + pImage->m_dHeight = y2 - y1; + } + else + { + pImage->m_dTop = y2; + pImage->m_dHeight = y1 - y2; + } + + pImage->m_dRotate = 0.0; + } + else + { + double x1 = fX; + double y1 = fY; + double x2 = fX + fWidth; + double y2 = fY + fHeight; + + Aggplus::CMatrix oTemp = *m_pTransform; + + double dCx = (x1 + x2) / 2; + double dCy = (y1 + y2) / 2; + m_pTransform->TransformPoint(dCx, dCy); + oTemp.RotateAt(-dRotation, dCx, dCy, Aggplus::MatrixOrderAppend); + + oTemp.TransformPoint(x1, y1); + oTemp.TransformPoint(x2, y2); + + if (x1 <= x2) + { + pImage->m_dLeft = x1; + pImage->m_dWidth = x2 - x1; + } + else + { + pImage->m_dLeft = x2; + pImage->m_dWidth = x1 - x2; + } + + if (y1 <= y2) + { + pImage->m_dTop = y1; + pImage->m_dHeight = y2 - y1; + } + else + { + pImage->m_dTop = y2; + pImage->m_dHeight = y1 - y2; + } + + pImage->m_dRotate = dRotation; + } + + pImage->m_dBaselinePos = pImage->m_dTop + pImage->m_dHeight; + pImage->m_dRight = pImage->m_dLeft + pImage->m_dWidth; + + m_arImages.push_back(pImage); + } + + // path commands + void CPage::MoveTo(double& dX, double& dY) + { + m_pTransform->TransformPoint(dX, dY); + m_oVector.MoveTo(dX, dY); + } + + void CPage::LineTo(double& dX, double& dY) + { + m_pTransform->TransformPoint(dX, dY); + m_oVector.LineTo(dX, dY); + } + + void CPage::CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3) + { + m_pTransform->TransformPoint(x1, y1); + m_pTransform->TransformPoint(x2, y2); + m_pTransform->TransformPoint(x3, y3); + + m_oVector.CurveTo(x1, y1, x2, y2, x3, y3); + } + + void CPage::Start() + { + } + + void CPage::End() + { + m_oVector.End(); + } + + void CPage::Close() + { + m_oVector.Close(); + } + + void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) + { + if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom)) + { + if (!m_arShapes.empty()) + { + auto pLastShape = m_arShapes.back(); + + if (pLastShape->m_dLeft == m_oVector.m_dLeft && + pLastShape->m_dTop == m_oVector.m_dTop && + pLastShape->m_dWidth == m_oVector.m_dRight - m_oVector.m_dLeft && + pLastShape->m_dHeight == m_oVector.m_dBottom - m_oVector.m_dTop) + { + if (0x00 != (lType & 0x01)) + { + pLastShape->m_bIsNoStroke = false; + pLastShape->m_oPen = *m_pPen; + } + if (0x00 != (lType >> 8)) + { + pLastShape->m_bIsNoFill = false; + pLastShape->m_oBrush = *m_pBrush; + } + return; + } + } + + auto pShape = new CShape(); + + if (pInfo) + { + pShape->m_pImageInfo = pInfo; + pShape->m_eType = CShape::eShapeType::stVectorTexture; + } + else + { + pShape->m_eType = CShape::eShapeType::stVectorGraphics; + } + + if (0x00 != (lType & 0x01)) + { + pShape->m_bIsNoStroke = false; + pShape->m_oPen = *m_pPen; + } + if (0x00 != (lType >> 8)) + { + pShape->m_bIsNoFill = false; + pShape->m_oBrush = *m_pBrush; + } + + if (pShape->m_bIsNoStroke) + { + if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3)) + { + pShape->m_oPen.Color = m_pBrush->Color1; + pShape->m_oPen.Alpha = m_pBrush->Alpha1; + } + } + + pShape->GetDataFromVector(m_oVector); + + m_arShapes.push_back(pShape); + } + } + + void CPage::CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, + const double& fX, const double& fY, const double& fWidth, const double& fHeight, + const double& fBaseLineOffset, const bool& bIsPDFAnalyzer) + { + if (pUnicodes != nullptr && nCount == 1 && IsSpaceUtf32(*pUnicodes)) + { + //note пробелы не нужны, добавляются при анализе + return; + } + + double dTextX = fX; + double dTextY = fY; + double dTextR = fX + fWidth; + double dTextB = fY + fHeight; + + m_pTransform->TransformPoint(dTextX, dTextY); + m_pTransform->TransformPoint(dTextR, dTextB); + + double dTextW = dTextR - dTextX; + double dTextH = dTextB - dTextY; + + NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); + + if ((pUnicodes != nullptr) && (pGids != nullptr)) + { + for (unsigned int i = 0; i < nCount; ++i) + { + if ( !IsUnicodeSymbol( pUnicodes[i] ) ) + { + oText[i] = ' '; + } + } + } + + bool bIsPath = ((nullptr == pGids) && !bIsPDFAnalyzer) ? false : true; + + m_pFontManager->LoadFont(0, !bIsPath); + + if (!bIsPath) + m_pFontManager->GenerateFontName2(oText); + + if (fabs(dTextW) < 0.01 || (dTextW > 10)) + { + double _x = 0; + double _y = 0; + double _w = 0; + double _h = 0; + + if (nullptr != pGids) + { + m_pFontManager->SetStringGid(1); + m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + else + { + // такого быть не должно (только из xps) + m_pFontManager->SetStringGid(0); + m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + + dTextW = _w; + } + + double dBaseLinePos = dTextY + fBaseLineOffset; + dTextH = m_pFontManager->GetFontHeight(); + + auto pCont = new CContText(&m_oFontManagerLight, m_pStyleManager); + + pCont->m_dLeft = dTextX; + pCont->m_dBaselinePos = dBaseLinePos; pCont->m_dTop = dBaseLinePos - dTextH - m_pFontManager->m_oFontAdvanced.m_dBaselineOffset; - pCont->m_dWidth = dTextW; - pCont->m_dHeight = dTextH; - pCont->m_dRight = dTextX + dTextW; + pCont->m_dWidth = dTextW; + pCont->m_dHeight = dTextH; + pCont->m_dRight = dTextX + dTextW; - pCont->m_oText = oText; + pCont->m_oText = oText; - //Первичное заполнение стилей + //Первичное заполнение стилей m_pStyleManager->m_pCurrentStyle->m_oFont = m_pFontManager->m_oFontAdvanced.m_oFont; - m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - - if (!bIsPath) - { - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontManager->m_strCurrentPickFont; - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_pFontManager->m_lCurrentPictFontStyle; - } - - //первичное получение стиля для текущего символа - //при дальнейшем анализе может измениться - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - pCont->m_dSpaceWidthMM = m_pFontManager->m_dSpaceWidthMM; - - if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) - { - //собираем отдельно, т.к. такие символы не имею размера m_dWidth - m_arDiacriticalSymbol.push_back(pCont); - } - else - { - //остальные символы сразу добавляем в текстовые линии - AddContToTextLine(pCont); - } - } - - void CPage::AddContToTextLine(CContText *pCont) - { - if (nullptr == m_pCurrentLine) - { - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->AddContent(pCont); - m_arTextLine.push_back(pLine); - return; - } - - if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentLine->AddContent(pCont); - return; - } - - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentLine = m_arTextLine[i]; - m_pCurrentLine->AddContent(pCont); - return; - } - } - - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->AddContent(pCont); - m_arTextLine.push_back(pLine); - } - - void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) - { - AnalyzeCollectedShapes(); - AnalyzeCollectedTextLines(); - ToXml(oWriter); - WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); - } - - void CPage::AnalyzeCollectedShapes() - { - //BuildTables(); - DetermineLinesType(); - } - - void CPage::BuildTables() - { - //Графика таблиц парсится в условные 2 типа: - //1 - С выделение отдельных узлов (peak) в местах пересечения линий - //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки - //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек - - //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа - //Для реализации 2го - нужно сначала создать peak в местах пересечения линий - //Основная причина почему так - нужно удалять все шейпы после парсинга - - //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) - //todo реализовать парсинг таблиц 2-го типа - //todo необходимо в созданные cells добавить содержимое из m_arTextLine по геометрическому признаку (буквы должны находится внутри ячеек) - //todo зетем собрать TextLine и Paragraph для каждой ячейки - //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape - - CollectPeaks(); - CreatCells(); - BuildRows(); - - CTable* pCurrTable = nullptr; - CRow* pFirstRow = nullptr; - - if (!m_arRows.empty()) - { - pCurrTable = new CTable(); - m_arTables.push_back(pCurrTable); - - pFirstRow = m_arRows.front(); - pCurrTable->AddContent(pFirstRow); - } - - for (size_t i = 1; i < m_arRows.size(); ++i) - { - auto pCurrRow = m_arRows[i]; - - eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); - eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); - - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; - bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; - - if (bIf1 && bIf2) - { - pCurrTable->AddContent(pCurrRow); - pFirstRow = pCurrRow; - } - else - { - pCurrTable = new CTable(); - m_arTables.push_back(pCurrTable); - - pFirstRow = pCurrRow; - pCurrTable->AddContent(pFirstRow); - } - } - - for (size_t i = 0; i < m_arTables.size(); ++i) - { - m_arTables[i]->CalculateColumnWidth(); - } - } - - void CPage::CollectPeaks() - { - for (size_t i = 0; i< m_arShapes.size(); ++i) - { - auto pCurrShape = m_arShapes[i]; - - if (pCurrShape->m_bIsNotNecessaryToUse) - { - continue; - } - - //нашли вершину - if (pCurrShape->IsPeak()) - { - CPeak* pCurrPeak = nullptr; - - //ищем стороны - for (size_t j = 0; j < m_arShapes.size(); ++j) - { - auto pNextShape = m_arShapes[j]; - - if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) - { - continue; - } - - eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); - eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); - - //проверяем, подходит ли сторона - bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && - (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); - bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && - (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); - - if (bIf1 || bIf2) - { - if (!pCurrPeak) - { - pCurrPeak = new CPeak(pCurrShape); - pCurrShape->m_bIsNotNecessaryToUse = true; - pCurrShape->m_bIsUseInTable = true; - m_arPeaks.push_back(pCurrPeak); - } - - if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) - { - if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) - { - pCurrPeak->m_pLines[CPeak::dI] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) - { - pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - } - if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) - { - if (eVType == eVerticalCrossingType::vctCurrentAboveNext) - { - pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) - { - pCurrPeak->m_pLines[CPeak::dII] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - } - } - } - } - } - } - - void CPage::CreatCells() - { - //Cells - // II | I - // | - //-----Peak--- - // | - // III | IV - //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку - CCell *pCellI, *pCellII, *pCellIII, *pCellIV; - - for (size_t i = 0; i < m_arPeaks.size(); ++i) - { - CPeak* pPeak = m_arPeaks[i]; - pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; - //Lines from peak - // VI II V - // | - // III <- Peak -> I - // | - // VII IV VIII - - //Corners - //Обозначение углов в ячейке - // IV------III - // | | - // | Cell | - // | | - // I--------II - - bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия - bool bIsII = pPeak->m_pLines[CPeak::dII]; - bool bIsIII = pPeak->m_pLines[CPeak::dIII]; - bool bIsIV = pPeak->m_pLines[CPeak::dIV]; - - //Если ячейки уже есть - //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) - //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются - //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных - for (size_t j = 0; j < m_arCells.size(); ++j) - { - auto pSaveCell = m_arCells[j]; - for (size_t k = 0; k < CCell::cNumCorners; ++k) - { - auto pSavePeak = pSaveCell->m_pPeaks[k]; - if (pSavePeak) - { - if (pPeak->m_pLines[CPeak::dI] && - pSavePeak->m_pLines[CPeak::dIII] && - pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) - { - if (k == CCell::cII) - { - pCellI = pSaveCell; - pCellI->SetParameters(pPeak, CCell::cI); - } - else if (k == CCell::cIII) - { - pCellIV = pSaveCell; - pCellIV->SetParameters(pPeak, CCell::cIV); - } - } - - if (pPeak->m_pLines[CPeak::dII] && - pSavePeak->m_pLines[CPeak::dIV] && - pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) - { - if (k == CCell::cIII) - { - pCellII = pSaveCell; - pCellII->SetParameters(pPeak, CCell::cII); - } - else if (k == CCell::cIV) - { - pCellI = pSaveCell; - pCellI->SetParameters(pPeak, CCell::cI); - } - } - - if (pPeak->m_pLines[CPeak::dIII] && - pSavePeak->m_pLines[CPeak::dI] && - pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) - { - if (k == CCell::cI) - { - pCellII = pSaveCell; - pCellII->SetParameters(pPeak, CCell::cII); - } - else if (k == CCell::cIV) - { - pCellIII = pSaveCell; - pCellIII->SetParameters(pPeak, CCell::cIII); - } - } - - if (pPeak->m_pLines[CPeak::dIV] && - pSavePeak->m_pLines[CPeak::dII] && - pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) - { - if (k == CCell::cI) - { - pCellIV = pSaveCell; - pCellIV->SetParameters(pPeak, CCell::cIV); - } - else if (k == CCell::cII) - { - pCellIII = pSaveCell; - pCellIII->SetParameters(pPeak, CCell::cIII); - } - } - } - } - } - - //Если ячейка еще не построена по заданным углам - создаем ячейку - if (bIsI && bIsII) - { - if (!pCellI) - { - pCellI = new CCell(); - pCellI->SetParameters(pPeak, CCell::cI); - m_arCells.push_back(pCellI); - } - } - if (bIsII && bIsIII) - { - if (!pCellII) - { - pCellII = new CCell(); - pCellII->SetParameters(pPeak, CCell::cII); - m_arCells.push_back(pCellII); - } - } - if (bIsIII && bIsIV) - { - if (!pCellIII) - { - pCellIII = new CCell(); - pCellIII->SetParameters(pPeak, CCell::cIII); - m_arCells.push_back(pCellIII); - } - } - if (bIsIV && bIsI) - { - if (!pCellIV) - { - pCellIV = new CCell(); - pCellIV->SetParameters(pPeak, CCell::cIV); - m_arCells.push_back(pCellIV); - } - } - } - - //удаляем использованные шейпы - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - if (m_arShapes[i]->m_bIsUseInTable) - { - m_arShapes[i]->m_bIsNotNecessaryToUse = true; - } - } - } - - void CPage::BuildRows() - { - //когда созданы все ячейки, собираем их в ряды - for (size_t i = 0; i < m_arCells.size(); ++i) - { - auto pCell = m_arCells[i]; - - if (pCell->m_bIsNotNecessaryToUse) - { - continue; - } - - SelectCurrentRow(pCell); - m_pCurrentRow->AddContent(pCell); - } - - CBaseItem::SortByBaseline(m_arRows); - for (size_t i = 0; i < m_arRows.size(); ++i) - { - CBaseItem::SortByLeft(m_arRows[i]->m_arCells); - } - } - - void CPage::SelectCurrentRow(const CCell *pCell) - { - //логика аналогична AddContToTextLine - //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала - if (nullptr == m_pCurrentRow) - { - auto pRow = new CRow(); - m_pCurrentRow = pRow; - m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; - m_arRows.push_back(pRow); - return; - } - - if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return; - } - - for (size_t i = 0; i < m_arRows.size(); ++i) - { - if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentRow = m_arRows[i]; - return; - } - } - - auto pRow = new CRow(); - m_pCurrentRow = pRow; - m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; - m_arRows.push_back(pRow); - return; - } - - void CPage::DetermineLinesType() - { - //определяются типы только горизонтальных линий. - //Входные данные представляют собой набор прямоугольников на одной линии - //При определении типа линии используется крайний левый шейп, который - //увеличивается в размере на ширину последующих за ним шейпов. - //Последующие шейпы помечаются как m_bIsNotNecessaryToUse - - //todo добавить аналогичное определение для вертикальных линий - //нужно для определения границ таблицы - //note определение типов линий нужно сделать до распознования таблиц, когда линия несплошная - - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - auto pCurrShape = m_arShapes[i]; - - if (pCurrShape->m_bIsNotNecessaryToUse || - pCurrShape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || //рассматриваем только тонкие объекты - (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && - pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) - { - continue; - } - - //Нужно собрать всю графику, которая находится на одной линии - std::vector arCurrShapes; - arCurrShapes.push_back(m_arShapes[i]); - - for (size_t j = i+1; j < m_arShapes.size(); ++j) - { - auto pNextShape = m_arShapes[j]; - if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossingByVertically(pNextShape)) //note значительно ускоряет работу - { - continue; - } - bool bIf1 = pCurrShape->IsCorrelated(pNextShape); - //note довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры - bool bIf2 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); - bool bIf3 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); - //линия должна быть одного размера по высоте - bool bIf4 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; - //все должно быть на одной линии - bool bIf5 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; - - if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) //все должно быть на одной линии - { - arCurrShapes.push_back(pNextShape); - } - } - - if (arCurrShapes.size() > 1) - { - //Отсортируем собранный массив по x - CBaseItem::SortByLeft(arCurrShapes); - pCurrShape = arCurrShapes[0]; - - //сравнение - for (size_t k = 1; k < arCurrShapes.size(); ++k) - { - auto pNextShape = arCurrShapes[k]; - - //note логика работатет только если arCurrShapes отсортирован по m_dLeft - pCurrShape->DetermineLineType(pNextShape, k == arCurrShapes.size() - 1); - - if (pCurrShape->m_bIsNotNecessaryToUse) - { - pCurrShape = pNextShape; - k++; - } - } - } - else if (arCurrShapes.size() == 1) - { - arCurrShapes[0]->DetermineLineType(); - } - - arCurrShapes.clear(); - } - } - - void CPage::AnalyzeCollectedTextLines() - { - //вся логика основана на отсортированных списках объектов - //todo для увеличения производительности можно попробовать использовать другие контейнеры - CBaseItem::SortByBaseline(m_arTextLine); - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); - } - - AnalyzeCollectedConts(); - DetermineStrikeoutsUnderlinesHighlights(); - AddDiacriticalSymbols(); + m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; + + if (!bIsPath) + { + m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontManager->m_strCurrentPickFont; + m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_pFontManager->m_lCurrentPictFontStyle; + } + + //первичное получение стиля для текущего символа + //при дальнейшем анализе может измениться + pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + + pCont->m_dSpaceWidthMM = m_pFontManager->m_dSpaceWidthMM; + + if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) + { + //собираем отдельно, т.к. такие символы не имею размера m_dWidth + m_arDiacriticalSymbol.push_back(pCont); + } + else + { + //остальные символы сразу добавляем в текстовые линии + AddContToTextLine(pCont); + } + } + + void CPage::AddContToTextLine(CContText *pCont) + { + if (nullptr == m_pCurrentLine) + { + auto pLine = new CTextLine(); + m_pCurrentLine = pLine; + m_pCurrentLine->AddContent(pCont); + m_arTextLine.push_back(pLine); + return; + } + + if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine->AddContent(pCont); + return; + } + + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine = m_arTextLine[i]; + m_pCurrentLine->AddContent(pCont); + return; + } + } + + auto pLine = new CTextLine(); + m_pCurrentLine = pLine; + m_pCurrentLine->AddContent(pCont); + m_arTextLine.push_back(pLine); + } + + void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) + { + AnalyzeCollectedShapes(); + AnalyzeCollectedTextLines(); + ToXml(oWriter); + WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); + } + + void CPage::AnalyzeCollectedShapes() + { + //BuildTables(); + DetermineLinesType(); + } + + void CPage::BuildTables() + { + //Графика таблиц парсится в условные 2 типа: + //1 - С выделение отдельных узлов (peak) в местах пересечения линий + //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки + //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек + + //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа + //Для реализации 2го - нужно сначала создать peak в местах пересечения линий + //Основная причина почему так - нужно удалять все шейпы после парсинга + + //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) + //todo реализовать парсинг таблиц 2-го типа + //todo необходимо в созданные cells добавить содержимое из m_arTextLine по геометрическому признаку (буквы должны находится внутри ячеек) + //todo зетем собрать TextLine и Paragraph для каждой ячейки + //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape + + CollectPeaks(); + CreatCells(); + BuildRows(); + + CTable* pCurrTable = nullptr; + CRow* pFirstRow = nullptr; + + if (!m_arRows.empty()) + { + pCurrTable = new CTable(); + m_arTables.push_back(pCurrTable); + + pFirstRow = m_arRows.front(); + pCurrTable->AddContent(pFirstRow); + } + + for (size_t i = 1; i < m_arRows.size(); ++i) + { + auto pCurrRow = m_arRows[i]; + + eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); + eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); + + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; + + if (bIf1 && bIf2) + { + pCurrTable->AddContent(pCurrRow); + pFirstRow = pCurrRow; + } + else + { + pCurrTable = new CTable(); + m_arTables.push_back(pCurrTable); + + pFirstRow = pCurrRow; + pCurrTable->AddContent(pFirstRow); + } + } + + for (size_t i = 0; i < m_arTables.size(); ++i) + { + m_arTables[i]->CalculateColumnWidth(); + } + } + + void CPage::CollectPeaks() + { + for (size_t i = 0; i< m_arShapes.size(); ++i) + { + auto pCurrShape = m_arShapes[i]; + + if (pCurrShape->m_bIsNotNecessaryToUse) + { + continue; + } + + //нашли вершину + if (pCurrShape->IsPeak()) + { + CPeak* pCurrPeak = nullptr; + + //ищем стороны + for (size_t j = 0; j < m_arShapes.size(); ++j) + { + auto pNextShape = m_arShapes[j]; + + if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) + { + continue; + } + + eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); + eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); + + //проверяем, подходит ли сторона + bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && + (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); + bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && + (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); + + if (bIf1 || bIf2) + { + if (!pCurrPeak) + { + pCurrPeak = new CPeak(pCurrShape); + pCurrShape->m_bIsNotNecessaryToUse = true; + pCurrShape->m_bIsUseInTable = true; + m_arPeaks.push_back(pCurrPeak); + } + + if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) + { + if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) + { + pCurrPeak->m_pLines[CPeak::dI] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) + { + pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + } + if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) + { + if (eVType == eVerticalCrossingType::vctCurrentAboveNext) + { + pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) + { + pCurrPeak->m_pLines[CPeak::dII] = pNextShape; + pNextShape->m_bIsUseInTable = true; + } + } + } + } + } + } + } + + void CPage::CreatCells() + { + //Cells + // II | I + // | + //-----Peak--- + // | + // III | IV + //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку + CCell *pCellI, *pCellII, *pCellIII, *pCellIV; + + for (size_t i = 0; i < m_arPeaks.size(); ++i) + { + CPeak* pPeak = m_arPeaks[i]; + pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; + //Lines from peak + // VI II V + // | + // III <- Peak -> I + // | + // VII IV VIII + + //Corners + //Обозначение углов в ячейке + // IV------III + // | | + // | Cell | + // | | + // I--------II + + bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия + bool bIsII = pPeak->m_pLines[CPeak::dII]; + bool bIsIII = pPeak->m_pLines[CPeak::dIII]; + bool bIsIV = pPeak->m_pLines[CPeak::dIV]; + + //Если ячейки уже есть + //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) + //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются + //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных + for (size_t j = 0; j < m_arCells.size(); ++j) + { + auto pSaveCell = m_arCells[j]; + for (size_t k = 0; k < CCell::cNumCorners; ++k) + { + auto pSavePeak = pSaveCell->m_pPeaks[k]; + if (pSavePeak) + { + if (pPeak->m_pLines[CPeak::dI] && + pSavePeak->m_pLines[CPeak::dIII] && + pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) + { + if (k == CCell::cII) + { + pCellI = pSaveCell; + pCellI->SetParameters(pPeak, CCell::cI); + } + else if (k == CCell::cIII) + { + pCellIV = pSaveCell; + pCellIV->SetParameters(pPeak, CCell::cIV); + } + } + + if (pPeak->m_pLines[CPeak::dII] && + pSavePeak->m_pLines[CPeak::dIV] && + pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) + { + if (k == CCell::cIII) + { + pCellII = pSaveCell; + pCellII->SetParameters(pPeak, CCell::cII); + } + else if (k == CCell::cIV) + { + pCellI = pSaveCell; + pCellI->SetParameters(pPeak, CCell::cI); + } + } + + if (pPeak->m_pLines[CPeak::dIII] && + pSavePeak->m_pLines[CPeak::dI] && + pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) + { + if (k == CCell::cI) + { + pCellII = pSaveCell; + pCellII->SetParameters(pPeak, CCell::cII); + } + else if (k == CCell::cIV) + { + pCellIII = pSaveCell; + pCellIII->SetParameters(pPeak, CCell::cIII); + } + } + + if (pPeak->m_pLines[CPeak::dIV] && + pSavePeak->m_pLines[CPeak::dII] && + pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) + { + if (k == CCell::cI) + { + pCellIV = pSaveCell; + pCellIV->SetParameters(pPeak, CCell::cIV); + } + else if (k == CCell::cII) + { + pCellIII = pSaveCell; + pCellIII->SetParameters(pPeak, CCell::cIII); + } + } + } + } + } + + //Если ячейка еще не построена по заданным углам - создаем ячейку + if (bIsI && bIsII) + { + if (!pCellI) + { + pCellI = new CCell(); + pCellI->SetParameters(pPeak, CCell::cI); + m_arCells.push_back(pCellI); + } + } + if (bIsII && bIsIII) + { + if (!pCellII) + { + pCellII = new CCell(); + pCellII->SetParameters(pPeak, CCell::cII); + m_arCells.push_back(pCellII); + } + } + if (bIsIII && bIsIV) + { + if (!pCellIII) + { + pCellIII = new CCell(); + pCellIII->SetParameters(pPeak, CCell::cIII); + m_arCells.push_back(pCellIII); + } + } + if (bIsIV && bIsI) + { + if (!pCellIV) + { + pCellIV = new CCell(); + pCellIV->SetParameters(pPeak, CCell::cIV); + m_arCells.push_back(pCellIV); + } + } + } + + //удаляем использованные шейпы + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + if (m_arShapes[i]->m_bIsUseInTable) + { + m_arShapes[i]->m_bIsNotNecessaryToUse = true; + } + } + } + + void CPage::BuildRows() + { + //когда созданы все ячейки, собираем их в ряды + for (size_t i = 0; i < m_arCells.size(); ++i) + { + auto pCell = m_arCells[i]; + + if (pCell->m_bIsNotNecessaryToUse) + { + continue; + } + + SelectCurrentRow(pCell); + m_pCurrentRow->AddContent(pCell); + } + + CBaseItem::SortByBaseline(m_arRows); + for (size_t i = 0; i < m_arRows.size(); ++i) + { + CBaseItem::SortByLeft(m_arRows[i]->m_arCells); + } + } + + void CPage::SelectCurrentRow(const CCell *pCell) + { + //логика аналогична AddContToTextLine + //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала + if (nullptr == m_pCurrentRow) + { + auto pRow = new CRow(); + m_pCurrentRow = pRow; + m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; + m_arRows.push_back(pRow); + return; + } + + if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return; + } + + for (size_t i = 0; i < m_arRows.size(); ++i) + { + if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentRow = m_arRows[i]; + return; + } + } + + auto pRow = new CRow(); + m_pCurrentRow = pRow; + m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; + m_arRows.push_back(pRow); + return; + } + + void CPage::DetermineLinesType() + { + //определяются типы только горизонтальных линий. + //Входные данные представляют собой набор прямоугольников на одной линии + //При определении типа линии используется крайний левый шейп, который + //увеличивается в размере на ширину последующих за ним шейпов. + //Последующие шейпы помечаются как m_bIsNotNecessaryToUse + + //todo добавить аналогичное определение для вертикальных линий + //нужно для определения границ таблицы + //note определение типов линий нужно сделать до распознования таблиц, когда линия несплошная + + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + auto pCurrShape = m_arShapes[i]; + + if (pCurrShape->m_bIsNotNecessaryToUse || + pCurrShape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || //рассматриваем только тонкие объекты + (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && + pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) + { + continue; + } + + //Нужно собрать всю графику, которая находится на одной линии + std::vector arCurrShapes; + arCurrShapes.push_back(m_arShapes[i]); + + for (size_t j = i+1; j < m_arShapes.size(); ++j) + { + auto pNextShape = m_arShapes[j]; + if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossingByVertically(pNextShape)) //note значительно ускоряет работу + { + continue; + } + bool bIf1 = pCurrShape->IsCorrelated(pNextShape); + //note довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры + bool bIf2 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); + bool bIf3 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); + //линия должна быть одного размера по высоте + bool bIf4 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; + //все должно быть на одной линии + bool bIf5 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; + + if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) //все должно быть на одной линии + { + arCurrShapes.push_back(pNextShape); + } + } + + if (arCurrShapes.size() > 1) + { + //Отсортируем собранный массив по x + CBaseItem::SortByLeft(arCurrShapes); + pCurrShape = arCurrShapes[0]; + + //сравнение + for (size_t k = 1; k < arCurrShapes.size(); ++k) + { + auto pNextShape = arCurrShapes[k]; + + //note логика работатет только если arCurrShapes отсортирован по m_dLeft + pCurrShape->DetermineLineType(pNextShape, k == arCurrShapes.size() - 1); + + if (pCurrShape->m_bIsNotNecessaryToUse) + { + pCurrShape = pNextShape; + k++; + } + } + } + else if (arCurrShapes.size() == 1) + { + arCurrShapes[0]->DetermineLineType(); + } + + arCurrShapes.clear(); + } + } + + void CPage::AnalyzeCollectedTextLines() + { + //вся логика основана на отсортированных списках объектов + //todo для увеличения производительности можно попробовать использовать другие контейнеры + CBaseItem::SortByBaseline(m_arTextLine); + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); + } + + AnalyzeCollectedConts(); + DetermineStrikeoutsUnderlinesHighlights(); + AddDiacriticalSymbols(); MergeLinesByVertAlignType(); - DeleteTextClipPage(); + DeleteTextClipPage(); - //DetermineTextColumns(); + //DetermineTextColumns(); - SingletonInstance().BuildLines(m_arTextLine); - SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, - CBaseItem::ElemType::etParagraph, - m_arTextLine, m_arTables, m_arOutputObjects); - } + SingletonInstance().BuildLines(m_arTextLine); + SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, + CBaseItem::ElemType::etParagraph, + m_arTextLine, m_arTables, m_arOutputObjects); + } - void CPage::AnalyzeCollectedConts() - { + void CPage::AnalyzeCollectedConts() + { // определение различных эффектов на основании взаимного расположения символов // идем по всем текстовым линиям - for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) - { + for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) + { // берем текущую линию - auto pCurrLine = m_arTextLine[uCurrLineIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) - continue; + auto pCurrLine = m_arTextLine[uCurrLineIndex]; + if (pCurrLine->m_bIsNotNecessaryToUse) + continue; // символы в текущей линии - for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) - { + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) + { // берем символ в текущей линии - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - if (pCurrCont->m_bIsNotNecessaryToUse) - continue; + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + if (pCurrCont->m_bIsNotNecessaryToUse) + continue; // берем вторую линию, если символ последний - то начиная со следуюущей, иначе с той же - for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? - uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLine.size(); ++uNextLineIndex) - { - auto pNextLine = m_arTextLine[uNextLineIndex]; + for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? + uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLine.size(); ++uNextLineIndex) + { + auto pNextLine = m_arTextLine[uNextLineIndex]; // значительно ускоряет работу, то есть если никак не перескается - некст if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine)) - continue; + continue; // посимвольно смотрим некст линию - если та же то следующий символ, если другая - то с нуля - for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; - uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) - { + for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; + uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) + { // берем символ во второй линии - auto pNextCont = pNextLine->m_arConts[uNextContIndex]; - if (pNextCont->m_bIsNotNecessaryToUse) - continue; - - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont); - - if (pCurrCont->IsThereAreFontEffects(pNextCont, eVType, eHType)) - { - pCurrLine->CheckLineToNecessaryToUse(); - break; - } - - if (pCurrCont->IsVertAlignTypeBetweenConts(pNextCont, eVType, eHType)) - { - pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); - pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); - if ((pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript && - pNextLine->m_eVertAlignType == eVertAlignType::vatBase) || - (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase && - pNextLine->m_eVertAlignType == eVertAlignType::vatSubscript)) - { - pCurrLine->m_pLine = pNextLine; - } - break; - } - - if (pCurrCont->IsDuplicate(pNextCont, eVType)) - { - break; - } - } - - pNextLine->CheckLineToNecessaryToUse(); - } - } - } - } - - void CPage::DetermineStrikeoutsUnderlinesHighlights() - { - //определение различных эффектов на основании взаимного расположения символов и шейпов - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - auto pShape = m_arShapes[i]; + auto pNextCont = pNextLine->m_arConts[uNextContIndex]; + if (pNextCont->m_bIsNotNecessaryToUse) + continue; + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont); + + if (pCurrCont->IsThereAreFontEffects(pNextCont, eVType, eHType)) + { + pCurrLine->CheckLineToNecessaryToUse(); + break; + } + + if (pCurrCont->IsVertAlignTypeBetweenConts(pNextCont, eVType, eHType)) + { + pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); + pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); + if ((pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript && + pNextLine->m_eVertAlignType == eVertAlignType::vatBase) || + (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase && + pNextLine->m_eVertAlignType == eVertAlignType::vatSubscript)) + { + pCurrLine->m_pLine = pNextLine; + } + break; + } + + if (pCurrCont->IsDuplicate(pNextCont, eVType)) + { + break; + } + } + + pNextLine->CheckLineToNecessaryToUse(); + } + } + } + } + + void CPage::DetermineStrikeoutsUnderlinesHighlights() + { + //определение различных эффектов на основании взаимного расположения символов и шейпов + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + auto pShape = m_arShapes[i]; if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || pShape->m_bIsNotNecessaryToUse) - continue; + continue; - for (size_t j = 0; j < m_arTextLine.size(); ++j) - { - auto pCurrLine = m_arTextLine[j]; + for (size_t j = 0; j < m_arTextLine.size(); ++j) + { + auto pCurrLine = m_arTextLine[j]; - if (pCurrLine->m_bIsNotNecessaryToUse || - (pCurrLine->AreObjectsNoCrossingByVertically(pShape) && - (pCurrLine->m_dTop > pShape->m_dBaselinePos || - pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) - { - continue; - } + if (pCurrLine->m_bIsNotNecessaryToUse || + (pCurrLine->AreObjectsNoCrossingByVertically(pShape) && + (pCurrLine->m_dTop > pShape->m_dBaselinePos || + pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) + { + continue; + } - for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) - { - auto pCurrCont = pCurrLine->m_arConts[k]; + for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) + { + auto pCurrCont = pCurrLine->m_arConts[k]; - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); bool bIsComplicatedFigure = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; bool bIsLineCrossingText = IsLineCrossingText(pShape, pCurrCont, eHType); @@ -1070,590 +1070,590 @@ namespace NSDocxRenderer // проверили - удаляем if (bIsComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) - pShape->m_bIsNotNecessaryToUse = true; + pShape->m_bIsNotNecessaryToUse = true; if (!bIsComplicatedFigure) - { - bool bIf1 = pCurrCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; - bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; - bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; - - if ((bIf1 || bIf2) && bIf3 && (bIf4 || bIf5)) - { - if (!bIf2) - { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCurrCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; - pCurrCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - pCurrCont->m_bIsShadowPresent = true; - pCurrCont->m_bIsOutlinePresent = true; - } - - pShape->m_bIsNotNecessaryToUse = true; - } - } - } - } - } - } - - bool CPage::IsLineCrossingText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) - { + { + bool bIf1 = pCurrCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; + bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; + bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + + if ((bIf1 || bIf2) && bIf3 && (bIf4 || bIf5)) + { + if (!bIf2) + { + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCurrCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; + pCurrCont->m_pFontStyle = m_pStyleManager->GetStyle(); + + pCurrCont->m_bIsShadowPresent = true; + pCurrCont->m_bIsOutlinePresent = true; + } + + pShape->m_bIsNotNecessaryToUse = true; + } + } + } + } + } + } + + bool CPage::IsLineCrossingText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) + { // Height - это максимально возможный размер символа. Больше реального размера. double dTopBorder = pCont->m_dTop + pCont->m_dHeight / 3; - bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle && - pShape->m_eLineType != eLineType::ltUnknown; + bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle && + pShape->m_eLineType != eLineType::ltUnknown; // Условие пересечения по вертикали - bool bIf2 = pShape->m_dTop > dTopBorder && pShape->m_dBaselinePos < pCont->m_dBaselinePos; + bool bIf2 = pShape->m_dTop > dTopBorder && pShape->m_dBaselinePos < pCont->m_dBaselinePos; // Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && + eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; // Условие для размеров по высоте - bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && - pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; + bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && + pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; return bIf1 && bIf2 && bIf3 && bIf4; - } + } - bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) - { - //todo распознавание работает не для всех размеров шрифтов - возможно 0.15 мало или улучшить логику - bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || - pShape->m_eGraphicsType == eGraphicsType::gtCurve) && + bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) + { + //todo распознавание работает не для всех размеров шрифтов - возможно 0.15 мало или улучшить логику + bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || + pShape->m_eGraphicsType == eGraphicsType::gtCurve) && pShape->m_eLineType != eLineType::ltUnknown; - //Условие по вертикали - bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.15; + //Условие по вертикали + bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.15; - //Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + //Условие пересечения по горизонтали + bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && + eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Условие для размеров по высоте - bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && - pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; + //Условие для размеров по высоте + bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && + pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; return bIf1 && bIf2 && bIf3 && bIf4; - } + } - bool CPage::IsItHighlightingBackground(CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) - { - double dSomeBaseLine1 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.75; - double dSomeBaseLine2 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.5; - double dSomeBaseLine3 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.25; + bool CPage::IsItHighlightingBackground(CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) + { + double dSomeBaseLine1 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.75; + double dSomeBaseLine2 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.5; + double dSomeBaseLine3 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.25; - bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle; + bool bIf1 = pShape->m_eGraphicsType == eGraphicsType::gtRectangle; - //Условие пересечения по вертикали - bool bIf2 = (dSomeBaseLine1 > pShape->m_dTop && dSomeBaseLine1 < pShape->m_dBaselinePos && - dSomeBaseLine2 > pShape->m_dTop && dSomeBaseLine2 < pShape->m_dBaselinePos && - dSomeBaseLine3 > pShape->m_dTop && dSomeBaseLine3 < pShape->m_dBaselinePos); + //Условие пересечения по вертикали + bool bIf2 = (dSomeBaseLine1 > pShape->m_dTop && dSomeBaseLine1 < pShape->m_dBaselinePos && + dSomeBaseLine2 > pShape->m_dTop && dSomeBaseLine2 < pShape->m_dBaselinePos && + dSomeBaseLine3 > pShape->m_dTop && dSomeBaseLine3 < pShape->m_dBaselinePos); - //Условие пересечения по горизонтали - bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && - eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + //Условие пересечения по горизонтали + bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && + eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - //Цвета должны быть разными - bool bIf4 = pCont->m_pFontStyle->m_oBrush.Color1 != pShape->m_oBrush.Color1; - bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; - bool bIf6 = pShape->m_bIsNoFill == false; - bool bIf7 = pShape->m_bIsNoStroke == true; + //Цвета должны быть разными + bool bIf4 = pCont->m_pFontStyle->m_oBrush.Color1 != pShape->m_oBrush.Color1; + bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; + bool bIf6 = pShape->m_bIsNoFill == false; + bool bIf7 = pShape->m_bIsNoStroke == true; return bIf1 && bIf2 && bIf3 && bIf4 && !bIf5 && bIf6 && bIf7; - } - - void CPage::AddDiacriticalSymbols() - { - if (m_arDiacriticalSymbol.empty()) - { - return; - } - - for (size_t i = 0; i < m_arDiacriticalSymbol.size(); ++i) - { - auto pDiacriticalCont = m_arDiacriticalSymbol[i]; - if (pDiacriticalCont->m_bIsNotNecessaryToUse) - { - continue; - } - - bool isBreak = false; - - for (size_t j = 0; j < m_arTextLine.size(); ++j) - { - auto pCurrLine = m_arTextLine[j]; - - if (pCurrLine->m_bIsNotNecessaryToUse || - pCurrLine->AreObjectsNoCrossingByVertically(pDiacriticalCont)) - { - continue; - } - - for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) - { - auto pCurrCont = pCurrLine->m_arConts[k]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pDiacriticalCont); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pDiacriticalCont); - - if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && - eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; - bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; - bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; - bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; - - bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || - eVType == eVerticalCrossingType::vctCurrentAboveNext; - bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; - bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; - - if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) - { - pCurrCont->m_oText += pDiacriticalCont->m_oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; - isBreak = true; - break; - } - else if (bIf3 && bIf7) - { - NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); - oText += pCurrCont->m_oText; - pCurrCont->m_oText = oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; - isBreak = true; - break; - } - } - } - if (isBreak) - { - break; - } - } - } - } - - void CPage::MergeLinesByVertAlignType() - { - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pCurrLine = m_arTextLine[i]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript) - { - auto pBaseLine = pCurrLine->m_pLine; - if (pBaseLine) - { - double dFontSize = 0; - - for (size_t j = 0; j < pBaseLine->m_arConts.size(); ++j) - { - auto pCont = pBaseLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) - { - continue; - } - - dFontSize = pCont->m_pFontStyle->m_oFont.Size; - break; - } - - for (auto pCont : pCurrLine->m_arConts) - { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - if (pBaseLine->m_dLeft > pCont->m_dLeft) - { - pBaseLine->m_dLeft = pCont->m_dLeft; - } - if (pBaseLine->m_dRight < pCont->m_dRight) - { - pBaseLine->m_dRight = pCont->m_dRight; - } - - pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; - - pBaseLine->m_arConts.push_back(std::move(pCont)); - } - CBaseItem::SortByLeft(pBaseLine->m_arConts); - pCurrLine->m_bIsNotNecessaryToUse = true; - } - } - else if (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase) - { - auto pSubLine = pCurrLine->m_pLine; - if (pSubLine) - { - double dFontSize = 0; - - for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) - { - auto pCont = pCurrLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) - { - continue; - } - - dFontSize = pCont->m_pFontStyle->m_oFont.Size; - break; - } - - for (auto pCont : pSubLine->m_arConts) - { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - - if (pCurrLine->m_dLeft > pCont->m_dLeft) - { - pCurrLine->m_dLeft = pCont->m_dLeft; - } - if (pCurrLine->m_dRight < pCont->m_dRight) - { - pCurrLine->m_dRight = pCont->m_dRight; - } - - pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; - - pCurrLine->m_arConts.push_back(std::move(pCont)); - } - CBaseItem::SortByLeft(pCurrLine->m_arConts); - pSubLine->m_bIsNotNecessaryToUse = true; - } - } - } - } - - void CPage::DetermineTextColumns() - { - std::vector keys; - std::vector arConts; - CTable* pTable = nullptr; - - //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу - //Выбирается первая строка и относительно нее проверяются все последующие строки - - //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, - //то добавляем uFirstContIndex в keys. - //Todo улучшить локигу определения keys - for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLine.size(); ++uFirstLineIndex) - { - auto pFirstLine = m_arTextLine[uFirstLineIndex]; - - if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLine.size() - 1) - { - continue; - } - - CTextLine* pFlagLine = nullptr; - - //первоначальное определение индексов pFirstLine, где могут присутствовать колонки - for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) - { - auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; - - if (pFirtsCont->m_bIsNotNecessaryToUse) - { - continue; - } - - for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) - { - auto pCurrLine = m_arTextLine[uCurrLineIndex]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - auto pPrevLine = m_arTextLine[uCurrLineIndex-1]; - - if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) - { - //Нашли линию, до которой будет таблица/ряд - pFlagLine = pCurrLine; - break; - } - - size_t numConts = arConts.size(); - - for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) - { - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); - - if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || - eHType == eHorizontalCrossingType::hctLeftBorderMatch) - { - //Добавили Cont-ориентир - arConts.push_back(pCurrCont); - break; - } - } - - if (numConts == arConts.size()) - { - //не было добавления Cont, значит дальше можно не проверять - break; - } - } - - if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) - { - keys.push_back(uFirstContIndex); - arConts.clear(); - } - } - - size_t uLastLineIndexInCell = 0; - - //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то - //начинаем распределять символы из всех строк до pFlagLine по высоте и - //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) - //Повторяем это действие, пока не пробежимся по всем keys - if (keys.size() > 1) - { - auto pRow = new CRow(); - - for (size_t i = 0; i < keys.size(); ++i) - { - auto pCell = new CCell(); - - for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLine.size(); ++uLineIndex) - { - auto pCurrLine = m_arTextLine[uLineIndex]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pFlagLine == pCurrLine) - { - uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); - break; - } - - CTextLine* pCellLine = nullptr; - CContText* pFlagCont = nullptr; - CContText* pFirstCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i]]; - - if (i < keys.size() - 1) - { - pFlagCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i+1]]; - } - - for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) - { - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); - - if (pFlagCont) - { - eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); - if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && - eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - if (!pCellLine) - { - pCellLine = new CTextLine(); - } - pCellLine->AddContent(new CContText(*pCurrCont)); - pCurrCont->m_bIsNotNecessaryToUse = true; - } - else - { - break; - } - } - else - { - if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - if (!pCellLine) - { - pCellLine = new CTextLine(); - } - pCellLine->AddContent(new CContText(*pCurrCont)); - pCurrCont->m_bIsNotNecessaryToUse = true; - } - } - } - - if (pCellLine) - { - pCell->AddContent(pCellLine); - } - - if (i >= keys.size() - 1) - { - pCurrLine->CheckLineToNecessaryToUse(); - } - } - - SingletonInstance().BuildLines(pCell->m_arTextLine); - SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etCell, - pCell->m_arTextLine, pCell->m_arOutputObjects); - - pRow->AddContent(pCell); - } - - if (pFlagLine) - { - uFirstLineIndex = uLastLineIndexInCell; - } - - //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы - if (!pTable) - { - pTable = new CTable(); - m_arTables.push_back(pTable); - } - - pTable->AddContent(pRow); - pTable->CalculateColumnWidth(); - } - - keys.clear(); - arConts.clear(); - } - } - - void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - bool bIsTextShapePresent = false; - - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - if (m_arOutputObjects[i]->m_eType == CBaseItem::ElemType::etShape) - { - bIsTextShapePresent = true; - break; - } - } - - bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); - - if (bIsNeedWP) - { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); - } - - for (size_t i = 0; i < m_arImages.size(); ++i) - { - m_arImages[i]->ToXml(oWriter); - } - - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - m_arShapes[i]->ToXml(oWriter); - } - - if (bIsTextShapePresent) - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } - } - } - - if (bIsNeedWP) - { - oWriter.WriteString(L""); - } - - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } - } - } - - void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) - { - // section - int lWidthDx = (int)(m_dWidth * c_dMMToDx); - int lHeightDx = (int)(m_dHeight * c_dMMToDx); - - if (!bLastPage) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - - oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); - oWriter.WriteString(L"\"/>"); - - if (!bLastPage) - oWriter.WriteString(L""); - else - oWriter.WriteString(L""); - } + } + + void CPage::AddDiacriticalSymbols() + { + if (m_arDiacriticalSymbol.empty()) + { + return; + } + + for (size_t i = 0; i < m_arDiacriticalSymbol.size(); ++i) + { + auto pDiacriticalCont = m_arDiacriticalSymbol[i]; + if (pDiacriticalCont->m_bIsNotNecessaryToUse) + { + continue; + } + + bool isBreak = false; + + for (size_t j = 0; j < m_arTextLine.size(); ++j) + { + auto pCurrLine = m_arTextLine[j]; + + if (pCurrLine->m_bIsNotNecessaryToUse || + pCurrLine->AreObjectsNoCrossingByVertically(pDiacriticalCont)) + { + continue; + } + + for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) + { + auto pCurrCont = pCurrLine->m_arConts[k]; + + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pDiacriticalCont); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pDiacriticalCont); + + if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + bool bIf1 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; + bool bIf2 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; + bool bIf4 = eHType == eHorizontalCrossingType::hctDublicate; + bool bIf5 = eHType == eHorizontalCrossingType::hctRightBorderMatch; + + bool bIf6 = eVType == eVerticalCrossingType::vctCurrentBelowNext || + eVType == eVerticalCrossingType::vctCurrentAboveNext; + bool bIf7 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch; + bool bIf8 = eVType == eVerticalCrossingType::vctDublicate; + + if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) + { + pCurrCont->m_oText += pDiacriticalCont->m_oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + isBreak = true; + break; + } + else if (bIf3 && bIf7) + { + NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); + oText += pCurrCont->m_oText; + pCurrCont->m_oText = oText; + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + isBreak = true; + break; + } + } + } + if (isBreak) + { + break; + } + } + } + } + + void CPage::MergeLinesByVertAlignType() + { + for (size_t i = 0; i < m_arTextLine.size(); ++i) + { + auto pCurrLine = m_arTextLine[i]; + + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript) + { + auto pBaseLine = pCurrLine->m_pLine; + if (pBaseLine) + { + double dFontSize = 0; + + for (size_t j = 0; j < pBaseLine->m_arConts.size(); ++j) + { + auto pCont = pBaseLine->m_arConts[j]; + if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) + { + continue; + } + + dFontSize = pCont->m_pFontStyle->m_oFont.Size; + break; + } + + for (auto pCont : pCurrLine->m_arConts) + { + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; + pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + + if (pBaseLine->m_dLeft > pCont->m_dLeft) + { + pBaseLine->m_dLeft = pCont->m_dLeft; + } + if (pBaseLine->m_dRight < pCont->m_dRight) + { + pBaseLine->m_dRight = pCont->m_dRight; + } + + pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; + + pBaseLine->m_arConts.push_back(std::move(pCont)); + } + CBaseItem::SortByLeft(pBaseLine->m_arConts); + pCurrLine->m_bIsNotNecessaryToUse = true; + } + } + else if (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase) + { + auto pSubLine = pCurrLine->m_pLine; + if (pSubLine) + { + double dFontSize = 0; + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto pCont = pCurrLine->m_arConts[j]; + if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) + { + continue; + } + + dFontSize = pCont->m_pFontStyle->m_oFont.Size; + break; + } + + for (auto pCont : pSubLine->m_arConts) + { + m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); + m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; + pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + + if (pCurrLine->m_dLeft > pCont->m_dLeft) + { + pCurrLine->m_dLeft = pCont->m_dLeft; + } + if (pCurrLine->m_dRight < pCont->m_dRight) + { + pCurrLine->m_dRight = pCont->m_dRight; + } + + pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; + + pCurrLine->m_arConts.push_back(std::move(pCont)); + } + CBaseItem::SortByLeft(pCurrLine->m_arConts); + pSubLine->m_bIsNotNecessaryToUse = true; + } + } + } + } + + void CPage::DetermineTextColumns() + { + std::vector keys; + std::vector arConts; + CTable* pTable = nullptr; + + //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу + //Выбирается первая строка и относительно нее проверяются все последующие строки - + //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, + //то добавляем uFirstContIndex в keys. + //Todo улучшить локигу определения keys + for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLine.size(); ++uFirstLineIndex) + { + auto pFirstLine = m_arTextLine[uFirstLineIndex]; + + if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLine.size() - 1) + { + continue; + } + + CTextLine* pFlagLine = nullptr; + + //первоначальное определение индексов pFirstLine, где могут присутствовать колонки + for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) + { + auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; + + if (pFirtsCont->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) + { + auto pCurrLine = m_arTextLine[uCurrLineIndex]; + + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + auto pPrevLine = m_arTextLine[uCurrLineIndex-1]; + + if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) + { + //Нашли линию, до которой будет таблица/ряд + pFlagLine = pCurrLine; + break; + } + + size_t numConts = arConts.size(); + + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) + { + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); + + if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || + eHType == eHorizontalCrossingType::hctLeftBorderMatch) + { + //Добавили Cont-ориентир + arConts.push_back(pCurrCont); + break; + } + } + + if (numConts == arConts.size()) + { + //не было добавления Cont, значит дальше можно не проверять + break; + } + } + + if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) + { + keys.push_back(uFirstContIndex); + arConts.clear(); + } + } + + size_t uLastLineIndexInCell = 0; + + //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то + //начинаем распределять символы из всех строк до pFlagLine по высоте и + //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) + //Повторяем это действие, пока не пробежимся по всем keys + if (keys.size() > 1) + { + auto pRow = new CRow(); + + for (size_t i = 0; i < keys.size(); ++i) + { + auto pCell = new CCell(); + + for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLine.size(); ++uLineIndex) + { + auto pCurrLine = m_arTextLine[uLineIndex]; + + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pFlagLine == pCurrLine) + { + uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); + break; + } + + CTextLine* pCellLine = nullptr; + CContText* pFlagCont = nullptr; + CContText* pFirstCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i]]; + + if (i < keys.size() - 1) + { + pFlagCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i+1]]; + } + + for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) + { + auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); + + if (pFlagCont) + { + eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); + if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && + eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + if (!pCellLine) + { + pCellLine = new CTextLine(); + } + pCellLine->AddContent(new CContText(*pCurrCont)); + pCurrCont->m_bIsNotNecessaryToUse = true; + } + else + { + break; + } + } + else + { + if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + if (!pCellLine) + { + pCellLine = new CTextLine(); + } + pCellLine->AddContent(new CContText(*pCurrCont)); + pCurrCont->m_bIsNotNecessaryToUse = true; + } + } + } + + if (pCellLine) + { + pCell->AddContent(pCellLine); + } + + if (i >= keys.size() - 1) + { + pCurrLine->CheckLineToNecessaryToUse(); + } + } + + SingletonInstance().BuildLines(pCell->m_arTextLine); + SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etCell, + pCell->m_arTextLine, pCell->m_arOutputObjects); + + pRow->AddContent(pCell); + } + + if (pFlagLine) + { + uFirstLineIndex = uLastLineIndexInCell; + } + + //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы + if (!pTable) + { + pTable = new CTable(); + m_arTables.push_back(pTable); + } + + pTable->AddContent(pRow); + pTable->CalculateColumnWidth(); + } + + keys.clear(); + arConts.clear(); + } + } + + void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + bool bIsTextShapePresent = false; + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + if (m_arOutputObjects[i]->m_eType == CBaseItem::ElemType::etShape) + { + bIsTextShapePresent = true; + break; + } + } + + bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); + + if (bIsNeedWP) + { + oWriter.WriteString(L""); + //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст + oWriter.WriteString(L""); + } + + for (size_t i = 0; i < m_arImages.size(); ++i) + { + m_arImages[i]->ToXml(oWriter); + } + + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + m_arShapes[i]->ToXml(oWriter); + } + + if (bIsTextShapePresent) + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } + } + } + + if (bIsNeedWP) + { + oWriter.WriteString(L""); + } + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } + } + } + + void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) + { + // section + int lWidthDx = (int)(m_dWidth * c_dMMToDx); + int lHeightDx = (int)(m_dHeight * c_dMMToDx); + + if (!bLastPage) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + + oWriter.WriteString(L"= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); + oWriter.WriteString(L"\"/>"); + + if (!bLastPage) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index f54039c0692..429ad44fbbe 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -8,112 +8,112 @@ namespace NSDocxRenderer { - class CPage - { - public: - NSStructures::CFont* m_pFont {nullptr}; - NSStructures::CPen* m_pPen {nullptr}; - NSStructures::CBrush* m_pBrush {nullptr}; - NSStructures::CShadow* m_pShadow {nullptr}; - NSStructures::CEdgeText* m_pEdgeText {nullptr}; - - Aggplus::CMatrix* m_pTransform {nullptr}; - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; - - CStyleManager* m_pStyleManager {nullptr}; - CFontManager* m_pFontManager {nullptr}; - CVectorGraphics m_oVector; - - double m_dWidth {0.0}; - double m_dHeight {0.0}; - - LONG m_lCurrentCommand {0}; - - std::vector m_arImages; - std::vector m_arDiacriticalSymbol; - std::vector m_arTextLine; - std::vector m_arShapes; - - std::vector m_arOutputObjects; - - std::vector m_arPeaks; - std::vector m_arCells; - std::vector m_arRows; - std::vector m_arTables; - - CTextLine* m_pCurrentLine {nullptr}; - CRow* m_pCurrentRow {nullptr}; - - CFontManagerLight m_oFontManagerLight; - - eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; - - bool m_bIsDeleteTextClipPage {true}; - - public: - CPage(NSFonts::IApplicationFonts* pFonts); - ~CPage(); - void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager* pFontManager); - - void Clear(); - void ClearImages(); - void ClearTextData(); - void ClearTextLines(); - void ClearShapes(); - void ClearOutputObjects(); - - void ClearTables(); - - //удаляем то, что выходит за границы страницы - void DeleteTextClipPage(); - - // image commands - //набивается содержимым вектор m_arImages - void WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight); - - // path commands - void MoveTo(double& dX, double& dY); - void LineTo(double& dX, double& dY); - void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3); - void Start(); - void End(); - void Close(); - //набивается содержимым вектор m_arShapes - void DrawPath(LONG lType, const std::shared_ptr pInfo); - - //набивается содержимым вектор m_arTextData - void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); - void AddContToTextLine(CContText *pCont); - - void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); - - void AnalyzeCollectedShapes(); - void BuildTables(); - void CollectPeaks(); - void CreatCells(); - void BuildRows(); - void SelectCurrentRow(const CCell *pCell); - void DetermineLinesType(); - - //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить - void AnalyzeCollectedTextLines(); - void AnalyzeCollectedConts(); - void DetermineStrikeoutsUnderlinesHighlights(); - bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - void AddDiacriticalSymbols(); - void MergeLinesByVertAlignType(); - void DetermineTextColumns(); - void DetermineDominantGraphics(); - - //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку - void ToXml(NSStringUtils::CStringBuilder& oWriter); - - void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); - }; + class CPage + { + public: + NSStructures::CFont* m_pFont {nullptr}; + NSStructures::CPen* m_pPen {nullptr}; + NSStructures::CBrush* m_pBrush {nullptr}; + NSStructures::CShadow* m_pShadow {nullptr}; + NSStructures::CEdgeText* m_pEdgeText {nullptr}; + + Aggplus::CMatrix* m_pTransform {nullptr}; + Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; + + CStyleManager* m_pStyleManager {nullptr}; + CFontManager* m_pFontManager {nullptr}; + CVectorGraphics m_oVector; + + double m_dWidth {0.0}; + double m_dHeight {0.0}; + + LONG m_lCurrentCommand {0}; + + std::vector m_arImages; + std::vector m_arDiacriticalSymbol; + std::vector m_arTextLine; + std::vector m_arShapes; + + std::vector m_arOutputObjects; + + std::vector m_arPeaks; + std::vector m_arCells; + std::vector m_arRows; + std::vector m_arTables; + + CTextLine* m_pCurrentLine {nullptr}; + CRow* m_pCurrentRow {nullptr}; + + CFontManagerLight m_oFontManagerLight; + + eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; + + bool m_bIsDeleteTextClipPage {true}; + + public: + CPage(NSFonts::IApplicationFonts* pFonts); + ~CPage(); + void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, + NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager* pFontManager); + + void Clear(); + void ClearImages(); + void ClearTextData(); + void ClearTextLines(); + void ClearShapes(); + void ClearOutputObjects(); + + void ClearTables(); + + //удаляем то, что выходит за границы страницы + void DeleteTextClipPage(); + + // image commands + //набивается содержимым вектор m_arImages + void WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight); + + // path commands + void MoveTo(double& dX, double& dY); + void LineTo(double& dX, double& dY); + void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3); + void Start(); + void End(); + void Close(); + //набивается содержимым вектор m_arShapes + void DrawPath(LONG lType, const std::shared_ptr pInfo); + + //набивается содержимым вектор m_arTextData + void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, + const double& fX, const double& fY, const double& fWidth, const double& fHeight, + const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); + void AddContToTextLine(CContText *pCont); + + void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); + + void AnalyzeCollectedShapes(); + void BuildTables(); + void CollectPeaks(); + void CreatCells(); + void BuildRows(); + void SelectCurrentRow(const CCell *pCell); + void DetermineLinesType(); + + //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить + void AnalyzeCollectedTextLines(); + void AnalyzeCollectedConts(); + void DetermineStrikeoutsUnderlinesHighlights(); + bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + void AddDiacriticalSymbols(); + void MergeLinesByVertAlignType(); + void DetermineTextColumns(); + void DetermineDominantGraphics(); + + //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); + }; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index cb0707ea032..98759fb889e 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -4,189 +4,189 @@ namespace NSDocxRenderer { - CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - - m_dLeft = oSrc.m_dLeft; - m_dTop = oSrc.m_dTop; - m_dWidth = oSrc.m_dWidth; - m_dHeight = oSrc.m_dHeight; - m_dBaselinePos = oSrc.m_dBaselinePos; - m_dRight = oSrc.m_dRight; - - return *this; - } - - void CBaseItem::AddContent(CBaseItem* pObj) - { - m_dBaselinePos = std::max(m_dBaselinePos, pObj->m_dBaselinePos); - - if ((pObj->m_dLeft < m_dLeft) || (pObj->m_dLeft > 0 && m_dLeft == 0.0)) - { - m_dLeft = pObj->m_dLeft; - } - - if ((pObj->m_dRight > m_dRight) || (pObj->m_dRight > 0 && m_dRight == 0.0)) - { - m_dRight = pObj->m_dRight; - } - - if (m_dTop > pObj->m_dTop || m_dTop == 0.0) - { - m_dTop = pObj->m_dTop; - } - - m_dWidth = m_dRight - m_dLeft; - m_dHeight = m_dBaselinePos - m_dTop; - } - - eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) - { - if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentInsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctCurrentOutsideNext; - } - else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && - (m_dBaselinePos >= oSrc->m_dTop || fabs(m_dBaselinePos - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) - { - return eVerticalCrossingType::vctCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && - (m_dTop <= oSrc->m_dBaselinePos || fabs(m_dTop - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) - { - return eVerticalCrossingType::vctCurrentBelowNext; - } - else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && - m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) - { - return eVerticalCrossingType::vctDublicate; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && - fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopAndBottomBordersMatch; - } - else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctTopBorderMatch; - } - else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eVerticalCrossingType::vctBottomBorderMatch; - } - else if (m_dBaselinePos < oSrc->m_dTop) - { - return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; - } - else if (m_dTop > oSrc->m_dBaselinePos) - { - return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - } - else - { - return eVerticalCrossingType::vctUnknown; - } - } - - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) - { - if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentInsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctCurrentOutsideNext; - } - else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && - (m_dRight >= oSrc->m_dLeft || fabs(m_dRight - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) - { - return eHorizontalCrossingType::hctCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && - (m_dLeft <= oSrc->m_dRight || fabs(m_dLeft - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) - { - return eHorizontalCrossingType::hctCurrentRightOfNext; - } - else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && - m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) - { - return eHorizontalCrossingType::hctDublicate; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM && - fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftAndRightBordersMatch; - } - else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctLeftBorderMatch; - } - else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return eHorizontalCrossingType::hctRightBorderMatch; - } - else if (m_dRight < oSrc->m_dLeft) - { - return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; - } - else if (m_dLeft > oSrc->m_dRight) - { - return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; - } - else - { - return eHorizontalCrossingType::hctUnknown; - } - } - - bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) - { - eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); - - if (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - return true; - } - return false; - } - - bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) - { - eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); - - if (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - return true; - } - return false; - } - - double CBaseItem::CalculateBeforeSpacing(double dPreviousBaseline) - { - return m_dTop - dPreviousBaseline; - } - - bool CBaseItem::IsCurrentLeftOfNext(const CBaseItem* oSrc) - { - return m_dLeft < oSrc->m_dLeft; - } - - bool CBaseItem::IsCurrentAboveOfNext(const CBaseItem* oSrc) - { - return m_dBaselinePos < oSrc->m_dBaselinePos; - } + CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_eType = oSrc.m_eType; + m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; + + m_dLeft = oSrc.m_dLeft; + m_dTop = oSrc.m_dTop; + m_dWidth = oSrc.m_dWidth; + m_dHeight = oSrc.m_dHeight; + m_dBaselinePos = oSrc.m_dBaselinePos; + m_dRight = oSrc.m_dRight; + + return *this; + } + + void CBaseItem::AddContent(CBaseItem* pObj) + { + m_dBaselinePos = std::max(m_dBaselinePos, pObj->m_dBaselinePos); + + if ((pObj->m_dLeft < m_dLeft) || (pObj->m_dLeft > 0 && m_dLeft == 0.0)) + { + m_dLeft = pObj->m_dLeft; + } + + if ((pObj->m_dRight > m_dRight) || (pObj->m_dRight > 0 && m_dRight == 0.0)) + { + m_dRight = pObj->m_dRight; + } + + if (m_dTop > pObj->m_dTop || m_dTop == 0.0) + { + m_dTop = pObj->m_dTop; + } + + m_dWidth = m_dRight - m_dLeft; + m_dHeight = m_dBaselinePos - m_dTop; + } + + eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) + { + if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentInsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctCurrentOutsideNext; + } + else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && + (m_dBaselinePos >= oSrc->m_dTop || fabs(m_dBaselinePos - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && + (m_dTop <= oSrc->m_dBaselinePos || fabs(m_dTop - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eVerticalCrossingType::vctCurrentBelowNext; + } + else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos && + m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight) + { + return eVerticalCrossingType::vctDublicate; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + } + else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctTopBorderMatch; + } + else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eVerticalCrossingType::vctBottomBorderMatch; + } + else if (m_dBaselinePos < oSrc->m_dTop) + { + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + } + else if (m_dTop > oSrc->m_dBaselinePos) + { + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + } + else + { + return eVerticalCrossingType::vctUnknown; + } + } + + eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) + { + if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentInsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctCurrentOutsideNext; + } + else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && + (m_dRight >= oSrc->m_dLeft || fabs(m_dRight - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && + (m_dLeft <= oSrc->m_dRight || fabs(m_dLeft - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + { + return eHorizontalCrossingType::hctCurrentRightOfNext; + } + else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight && + m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos) + { + return eHorizontalCrossingType::hctDublicate; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftAndRightBordersMatch; + } + else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctLeftBorderMatch; + } + else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + return eHorizontalCrossingType::hctRightBorderMatch; + } + else if (m_dRight < oSrc->m_dLeft) + { + return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext; + } + else if (m_dLeft > oSrc->m_dRight) + { + return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; + } + else + { + return eHorizontalCrossingType::hctUnknown; + } + } + + bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) + { + eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); + + if (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + return true; + } + return false; + } + + bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) + { + eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); + + if (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) + { + return true; + } + return false; + } + + double CBaseItem::CalculateBeforeSpacing(double dPreviousBaseline) + { + return m_dTop - dPreviousBaseline; + } + + bool CBaseItem::IsCurrentLeftOfNext(const CBaseItem* oSrc) + { + return m_dLeft < oSrc->m_dLeft; + } + + bool CBaseItem::IsCurrentAboveOfNext(const CBaseItem* oSrc) + { + return m_dBaselinePos < oSrc->m_dBaselinePos; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index ce5a31568b4..5e1a78bb20d 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -4,101 +4,101 @@ namespace NSDocxRenderer { - enum class eVerticalCrossingType - { - vctUnknown, - vctCurrentInsideNext, - vctCurrentOutsideNext, - vctCurrentAboveNext, - vctCurrentBelowNext, - vctDublicate, - vctTopAndBottomBordersMatch, - vctTopBorderMatch, - vctBottomBorderMatch, - vctNoCrossingCurrentAboveNext, - vctNoCrossingCurrentBelowNext - }; - - enum class eHorizontalCrossingType - { - hctUnknown, - hctCurrentInsideNext, - hctCurrentOutsideNext, - hctCurrentLeftOfNext, - hctCurrentRightOfNext, - hctDublicate, - hctLeftAndRightBordersMatch, - hctLeftBorderMatch, - hctRightBorderMatch, - hctNoCrossingCurrentLeftOfNext, - hctNoCrossingCurrentRightOfNext - }; - - class CBaseItem - { - public: - enum class ElemType - { - etContText = 0, - etTextLine = 1, - etParagraph = 2, - etImage = 3, - etShape = 4, - etCell = 5, - etRow = 6, - etTable = 7, - }; - - ElemType m_eType; - - bool m_bIsNotNecessaryToUse {false}; - - //General - double m_dLeft {0.0}; - double m_dTop {0.0}; - double m_dWidth {0.0}; - double m_dHeight {0.0}; - - //Secondary - double m_dBaselinePos {0.0}; - double m_dRight {0.0}; - - public: - CBaseItem(const ElemType& eType): m_eType(eType) {} - virtual ~CBaseItem() {} - virtual void Clear() = 0; - - CBaseItem& operator=(const CBaseItem& oSrc); - - virtual void AddContent(CBaseItem* pObj); - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - - eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); - - bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj); - bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj); - - double CalculateBeforeSpacing(double dPreviousBaseline); - - template - static void SortByLeft(std::vector& oArray) - { - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return a->IsCurrentLeftOfNext(a); - }); - } - - template - static void SortByBaseline(std::vector& oArray) - { - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return a->IsCurrentAboveOfNext(b); - }); - } - - private: - bool IsCurrentLeftOfNext(const CBaseItem* oSrc); - bool IsCurrentAboveOfNext(const CBaseItem* oSrc); - }; + enum class eVerticalCrossingType + { + vctUnknown, + vctCurrentInsideNext, + vctCurrentOutsideNext, + vctCurrentAboveNext, + vctCurrentBelowNext, + vctDublicate, + vctTopAndBottomBordersMatch, + vctTopBorderMatch, + vctBottomBorderMatch, + vctNoCrossingCurrentAboveNext, + vctNoCrossingCurrentBelowNext + }; + + enum class eHorizontalCrossingType + { + hctUnknown, + hctCurrentInsideNext, + hctCurrentOutsideNext, + hctCurrentLeftOfNext, + hctCurrentRightOfNext, + hctDublicate, + hctLeftAndRightBordersMatch, + hctLeftBorderMatch, + hctRightBorderMatch, + hctNoCrossingCurrentLeftOfNext, + hctNoCrossingCurrentRightOfNext + }; + + class CBaseItem + { + public: + enum class ElemType + { + etContText = 0, + etTextLine = 1, + etParagraph = 2, + etImage = 3, + etShape = 4, + etCell = 5, + etRow = 6, + etTable = 7, + }; + + ElemType m_eType; + + bool m_bIsNotNecessaryToUse {false}; + + //General + double m_dLeft {0.0}; + double m_dTop {0.0}; + double m_dWidth {0.0}; + double m_dHeight {0.0}; + + //Secondary + double m_dBaselinePos {0.0}; + double m_dRight {0.0}; + + public: + CBaseItem(const ElemType& eType): m_eType(eType) {} + virtual ~CBaseItem() {} + virtual void Clear() = 0; + + CBaseItem& operator=(const CBaseItem& oSrc); + + virtual void AddContent(CBaseItem* pObj); + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; + + eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); + eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); + + bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj); + bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj); + + double CalculateBeforeSpacing(double dPreviousBaseline); + + template + static void SortByLeft(std::vector& oArray) + { + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + return a->IsCurrentLeftOfNext(a); + }); + } + + template + static void SortByBaseline(std::vector& oArray) + { + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + return a->IsCurrentAboveOfNext(b); + }); + } + + private: + bool IsCurrentLeftOfNext(const CBaseItem* oSrc); + bool IsCurrentAboveOfNext(const CBaseItem* oSrc); + }; } diff --git a/DocxRenderer/src/logic/elements/Cell.cpp b/DocxRenderer/src/logic/elements/Cell.cpp index 3d976e8b210..2f739b8bdd6 100644 --- a/DocxRenderer/src/logic/elements/Cell.cpp +++ b/DocxRenderer/src/logic/elements/Cell.cpp @@ -3,212 +3,212 @@ namespace NSDocxRenderer { - CCell::CCell() : CBaseItem(ElemType::etCell) - { - } - - CCell::~CCell() - { - Clear(); - } - - void CCell::Clear() - { - m_arTextLine.clear(); - - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } - m_arOutputObjects.clear(); - } - - void CCell::AddContent(CBaseItem* pObj) - { - CBaseItem::AddContent(pObj); - - m_arTextLine.push_back(dynamic_cast(pObj)); - } - - void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"dxa\"/>"); - - if (m_bIsvMergeStart) - { - oWriter.WriteString(L""); - } - else if (m_bIsvMerge) - { - oWriter.WriteString(L""); - } - - if (m_uGridSpan > 1) - { - oWriter.WriteString(L""); - } - if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || - !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) - { - oWriter.WriteString(L""); - if (!m_bIsTopBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsLeftBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsBottomBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsRightBorder) - { - oWriter.WriteString(L""); - } - if (m_bIsDiagonalDownBorder) - { - oWriter.WriteString(L""); - } - if (m_bIsDiagonalUpBorder) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - if (m_arOutputObjects.empty()) - { - oWriter.WriteString(L""); - } - else - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } - } - } - - oWriter.WriteString(L""); - } - - void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) - { - m_pPeaks[eCorner] = pPeak; - - switch (eCorner) - { - case cI: - if (pPeak->m_pLines[CPeak::dI]) - { - m_bIsLeftBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dII]) - { - m_bIsBottomBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cII: - if (pPeak->m_pLines[CPeak::dII]) - { - m_bIsRightBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dIII]) - { - m_bIsBottomBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cIII: - if (pPeak->m_pLines[CPeak::dIV]) - { - m_bIsRightBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dIII]) - { - m_bIsTopBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cIV: - if (pPeak->m_pLines[CPeak::dIV]) - { - m_bIsLeftBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dI]) - { - m_bIsTopBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - default: - break; - } - - if (m_dLeft != 0 && m_dRight != 0) - { - m_dWidth = m_dRight - m_dLeft; - } - - if (m_dTop != 0 && m_dBaselinePos != 0) - { - m_dHeight = m_dBaselinePos - m_dTop; - } - } + CCell::CCell() : CBaseItem(ElemType::etCell) + { + } + + CCell::~CCell() + { + Clear(); + } + + void CCell::Clear() + { + m_arTextLine.clear(); + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); + } + + void CCell::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arTextLine.push_back(dynamic_cast(pObj)); + } + + void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"dxa\"/>"); + + if (m_bIsvMergeStart) + { + oWriter.WriteString(L""); + } + else if (m_bIsvMerge) + { + oWriter.WriteString(L""); + } + + if (m_uGridSpan > 1) + { + oWriter.WriteString(L""); + } + if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || + !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) + { + oWriter.WriteString(L""); + if (!m_bIsTopBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsLeftBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsBottomBorder) + { + oWriter.WriteString(L""); + } + if (!m_bIsRightBorder) + { + oWriter.WriteString(L""); + } + if (m_bIsDiagonalDownBorder) + { + oWriter.WriteString(L""); + } + if (m_bIsDiagonalUpBorder) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + + if (m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); + } + else + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } + } + } + + oWriter.WriteString(L""); + } + + void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) + { + m_pPeaks[eCorner] = pPeak; + + switch (eCorner) + { + case cI: + if (pPeak->m_pLines[CPeak::dI]) + { + m_bIsLeftBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dII]) + { + m_bIsBottomBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cII: + if (pPeak->m_pLines[CPeak::dII]) + { + m_bIsRightBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dIII]) + { + m_bIsBottomBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; + m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cIII: + if (pPeak->m_pLines[CPeak::dIV]) + { + m_bIsRightBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dIII]) + { + m_bIsTopBorder = true; + + m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + case cIV: + if (pPeak->m_pLines[CPeak::dIV]) + { + m_bIsLeftBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + if (pPeak->m_pLines[CPeak::dI]) + { + m_bIsTopBorder = true; + + m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; + m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; + } + break; + default: + break; + } + + if (m_dLeft != 0 && m_dRight != 0) + { + m_dWidth = m_dRight - m_dLeft; + } + + if (m_dTop != 0 && m_dBaselinePos != 0) + { + m_dHeight = m_dBaselinePos - m_dTop; + } + } } diff --git a/DocxRenderer/src/logic/elements/Cell.h b/DocxRenderer/src/logic/elements/Cell.h index fbcdba89148..c47f8d8e7d3 100644 --- a/DocxRenderer/src/logic/elements/Cell.h +++ b/DocxRenderer/src/logic/elements/Cell.h @@ -3,85 +3,85 @@ namespace NSDocxRenderer { - class CPeak - { - public: - // - // VI II V - // | - // III <- Peak -> I - // | - // VII IV VIII - //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) - enum eDirections - { - dI = 0, - dII = 1, - dIII = 2, - dIV = 3, - dV = 4, - dVI = 5, - dVII = 6, - dVIII = 7, - dNumDirections = 8 - }; + class CPeak + { + public: + // + // VI II V + // | + // III <- Peak -> I + // | + // VII IV VIII + //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) + enum eDirections + { + dI = 0, + dII = 1, + dIII = 2, + dIV = 3, + dV = 4, + dVI = 5, + dVII = 6, + dVIII = 7, + dNumDirections = 8 + }; - public: - CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak - CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон + public: + CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak + CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон - public: - CPeak(CShape* pPeak) : m_pPeak(pPeak) {} - }; + public: + CPeak(CShape* pPeak) : m_pPeak(pPeak) {} + }; - class CCell : public CBaseItem - { - public: - //Corners - // IV------III - // | | - // | Cell | - // | | - // I--------II - //У каждой ячейки может быть только 4 угла ) - enum eCorners - { - cI = 0, - cII = 1, - cIII = 2, - cIV = 3, - cNumCorners = 4 - }; - public: - bool m_bIsvMergeStart {false}; - bool m_bIsvMerge {false}; + class CCell : public CBaseItem + { + public: + //Corners + // IV------III + // | | + // | Cell | + // | | + // I--------II + //У каждой ячейки может быть только 4 угла ) + enum eCorners + { + cI = 0, + cII = 1, + cIII = 2, + cIV = 3, + cNumCorners = 4 + }; + public: + bool m_bIsvMergeStart {false}; + bool m_bIsvMerge {false}; - bool m_bIsTopBorder {false}; - bool m_bIsLeftBorder {false}; - bool m_bIsBottomBorder {false}; - bool m_bIsRightBorder {false}; + bool m_bIsTopBorder {false}; + bool m_bIsLeftBorder {false}; + bool m_bIsBottomBorder {false}; + bool m_bIsRightBorder {false}; - bool m_bIsDiagonalDownBorder {false}; - bool m_bIsDiagonalUpBorder {false}; + bool m_bIsDiagonalDownBorder {false}; + bool m_bIsDiagonalUpBorder {false}; - UINT m_uGridSpan {1}; + UINT m_uGridSpan {1}; - CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки + CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки - //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами - //- дополнительное выделение памяти. Возможно нужно просто делать move. - std::vector m_arTextLine; - //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. - //Возможно подойдет вывод из CShape::BuildPictureProperties - std::vector m_arOutputObjects; + //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами + //- дополнительное выделение памяти. Возможно нужно просто делать move. + std::vector m_arTextLine; + //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. + //Возможно подойдет вывод из CShape::BuildPictureProperties + std::vector m_arOutputObjects; - public: - CCell(); - virtual ~CCell(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + public: + CCell(); + virtual ~CCell(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void SetParameters(CPeak *pPeak, eCorners eCorner); - }; + void SetParameters(CPeak *pPeak, eCorners eCorner); + }; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 2051d21a53b..a31b59729d5 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,512 +5,512 @@ namespace NSDocxRenderer { - CContText::CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager): - CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight), m_pStyleManager(pStyleManager) - { - } + CContText::CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager): + CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight), m_pStyleManager(pStyleManager) + { + } - CContText::CContText(const CContText& rCont): - CBaseItem(ElemType::etContText) - { - *this = rCont; - } + CContText::CContText(const CContText& rCont): + CBaseItem(ElemType::etContText) + { + *this = rCont; + } - CContText::~CContText() - { - Clear(); - } - - void CContText::Clear() - { - m_pFontStyle = nullptr; - } - - CContText& CContText::operator= (const CContText& rCont) - { - if (this == &rCont) - { - return *this; - } - - CBaseItem::operator=(rCont); - - m_pFontStyle = rCont.m_pFontStyle; - - m_bIsStrikeoutPresent = rCont.m_bIsStrikeoutPresent; - m_bIsDoubleStrikeout = rCont.m_bIsDoubleStrikeout; - - m_bIsHighlightPresent = rCont.m_bIsHighlightPresent; - m_lHighlightColor = rCont.m_lHighlightColor; - - m_bIsUnderlinePresent = rCont.m_bIsUnderlinePresent; - m_eUnderlineType = rCont.m_eUnderlineType; - m_lUnderlineColor = rCont.m_lUnderlineColor; - - m_bIsShadowPresent = rCont.m_bIsShadowPresent; - m_bIsOutlinePresent = rCont.m_bIsOutlinePresent; - m_bIsEmbossPresent = rCont.m_bIsEmbossPresent; - m_bIsEngravePresent = rCont.m_bIsEngravePresent; - - m_oText =rCont.m_oText; - - m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; - m_bSpaceIsNotNeeded = rCont.m_bSpaceIsNotNeeded; - - m_eVertAlignType = rCont.m_eVertAlignType; - - m_pManagerLight = rCont.m_pManagerLight; - m_pStyleManager = rCont.m_pStyleManager; - - m_pShape = rCont.m_pShape; - m_pCont = rCont.m_pCont; - - m_iNumDuplicates = rCont.m_iNumDuplicates; - - return *this; - } - - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L"GetStyleId()); - oWriter.WriteString(L"\"/>"); - - LONG lCalculatedSpacing = 0; - - if (!m_pFontStyle->m_strPickFontName.empty() && !m_oText.empty()) - { - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - // нужно перемерять... - m_pManagerLight->LoadFont(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, false); - double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); - - double dSpacing = (m_dWidth - dWidth) / (m_oText.length()); - dSpacing *= c_dMMToDx; - - lCalculatedSpacing = static_cast(dSpacing); - } - } - - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - //note 1 -> 0.5pt - lCalculatedSpacing -= 1; - - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L""); - } - } - - if (m_bIsStrikeoutPresent) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_bIsUnderlinePresent) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent) - { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L""); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L"GetStyleId()); - oWriter.WriteString(L"\"/>"); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (!m_pFontStyle->m_strPickFontName.empty()) - { - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (m_bIsEmbossPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - } - - if (m_bIsStrikeoutPresent && bIsNeedSaveFormat) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_bIsUnderlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L" "); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - bool CContText::IsEqual(const CContText *pCont) - { - bool bIf1 = m_pFontStyle->GetStyleId() == pCont->m_pFontStyle->GetStyleId(); - bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; - bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; - bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; - bool bIf5 = m_lHighlightColor == pCont->m_lHighlightColor; - bool bIf6 = m_bIsUnderlinePresent == pCont->m_bIsUnderlinePresent; - bool bIf7 = m_eUnderlineType == pCont->m_eUnderlineType; - bool bIf8 = m_lUnderlineColor == pCont->m_lUnderlineColor; - bool bIf9 = m_bIsShadowPresent == pCont->m_bIsShadowPresent; - bool bIf10 = m_bIsOutlinePresent == pCont->m_bIsOutlinePresent; - bool bIf11 = m_bIsEmbossPresent == pCont->m_bIsEmbossPresent; - bool bIf12 = m_bIsEngravePresent == pCont->m_bIsEngravePresent; - bool bIf13 = m_eVertAlignType == pCont->m_eVertAlignType; - bool bIf14 = m_eVertAlignType == eVertAlignType::vatUnknown && pCont->m_eVertAlignType == eVertAlignType::vatBase; - bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && - bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) - { - return true; - } - return false; - } - - UINT CContText::GetNumberOfFeatures() - { - UINT ret = 0; - - if (m_pFontStyle->m_oFont.Bold) - { - ret++; - } - if (m_pFontStyle->m_oFont.Italic) - { - ret++; - } - if (m_bIsStrikeoutPresent) - { - ret++; - } - if (m_bIsDoubleStrikeout) - { - ret++; - } - if (m_bIsHighlightPresent) - { - ret++; - } - if (m_bIsUnderlinePresent) - { - ret++; - } - if (m_eVertAlignType != eVertAlignType::vatUnknown) - { - ret++; - } - - return ret; - } - - bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) - { - if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) - { - pCont->m_bIsNotNecessaryToUse = true; - m_iNumDuplicates++; - return true; - } - return false; - } - - bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже - - //Условие пересечения по горизонтали - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее - - //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_pFontStyle->m_oFont.Size == pCont->m_pFontStyle->m_oFont.Size; - bool bIf6 = m_oText == pCont->m_oText; - - //Цвет тени должен быть серым - bool bIf7 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; - - //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами - //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. - //todo существует проблема неправильного определением FontEffects с физически пересекаемыми строчками - файл generaltest.pdf p.14 - if (bIf5 && bIf6) - { - if (m_bIsEmbossPresent && bIf12) - { - if (bIf1 && bIf3) - { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - } - - if (m_bIsEngravePresent && bIf10) - { - if (bIf1 && bIf3) - { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - } - - //Shadow - if (bIf1 && bIf3 && bIf8) - { - m_bIsShadowPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - else if (bIf2 && bIf4 && bIf7) - { - pCont->m_bIsShadowPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - - //Emboss - //Первый проход - //c_iBlackColor -> c_iBlackColor -> c_iGreyColor2 - else if (bIf1 && bIf3 && bIf9) - { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - //Engrave - else if (bIf1 && bIf3 && bIf11) - { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - return false; - } - - bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || - eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; - //Условие пересечения по горизонтали - bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && - fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; - bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || - eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && - fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; - //Размеры шрифта должны бать разными - bool bIf5 = m_pFontStyle->m_oFont.Size * 0.7 > pCont->m_pFontStyle->m_oFont.Size; - bool bIf6 = m_pFontStyle->m_oFont.Size < pCont->m_pFontStyle->m_oFont.Size * 0.7; - - if (bIf3 || bIf4) - { - if (bIf1 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf2 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf1 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - else if (bIf2 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSubscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - } - return false; - } - - double CContText::CalculateWideSpace() - { - //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 4; - } - - double CContText::CalculateThinSpace() - { - //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.7; - } + CContText::~CContText() + { + Clear(); + } + + void CContText::Clear() + { + m_pFontStyle = nullptr; + } + + CContText& CContText::operator= (const CContText& rCont) + { + if (this == &rCont) + { + return *this; + } + + CBaseItem::operator=(rCont); + + m_pFontStyle = rCont.m_pFontStyle; + + m_bIsStrikeoutPresent = rCont.m_bIsStrikeoutPresent; + m_bIsDoubleStrikeout = rCont.m_bIsDoubleStrikeout; + + m_bIsHighlightPresent = rCont.m_bIsHighlightPresent; + m_lHighlightColor = rCont.m_lHighlightColor; + + m_bIsUnderlinePresent = rCont.m_bIsUnderlinePresent; + m_eUnderlineType = rCont.m_eUnderlineType; + m_lUnderlineColor = rCont.m_lUnderlineColor; + + m_bIsShadowPresent = rCont.m_bIsShadowPresent; + m_bIsOutlinePresent = rCont.m_bIsOutlinePresent; + m_bIsEmbossPresent = rCont.m_bIsEmbossPresent; + m_bIsEngravePresent = rCont.m_bIsEngravePresent; + + m_oText =rCont.m_oText; + + m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; + m_bSpaceIsNotNeeded = rCont.m_bSpaceIsNotNeeded; + + m_eVertAlignType = rCont.m_eVertAlignType; + + m_pManagerLight = rCont.m_pManagerLight; + m_pStyleManager = rCont.m_pStyleManager; + + m_pShape = rCont.m_pShape; + m_pCont = rCont.m_pCont; + + m_iNumDuplicates = rCont.m_iNumDuplicates; + + return *this; + } + + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L"GetStyleId()); + oWriter.WriteString(L"\"/>"); + + LONG lCalculatedSpacing = 0; + + if (!m_pFontStyle->m_strPickFontName.empty() && !m_oText.empty()) + { + if (m_eVertAlignType != eVertAlignType::vatSubscript && + m_eVertAlignType != eVertAlignType::vatSuperscript) + { + // нужно перемерять... + m_pManagerLight->LoadFont(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, false); + double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); + + double dSpacing = (m_dWidth - dWidth) / (m_oText.length()); + dSpacing *= c_dMMToDx; + + lCalculatedSpacing = static_cast(dSpacing); + } + } + + //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + //note 1 -> 0.5pt + lCalculatedSpacing -= 1; + + if (lCalculatedSpacing != 0) + { + oWriter.WriteString(L""); + } + + if (m_bIsEmbossPresent) + { + oWriter.WriteString(L""); + } + else if (m_bIsEngravePresent) + { + oWriter.WriteString(L""); + } + else + { + if (m_bIsOutlinePresent) + { + oWriter.WriteString(L""); + } + if (m_bIsShadowPresent) + { + oWriter.WriteString(L""); + } + } + + if (m_bIsStrikeoutPresent) + { + if (m_bIsDoubleStrikeout) + { + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L""); + } + } + + if (m_bIsUnderlinePresent) + { + oWriter.WriteString(L""); + } + + if (m_bIsHighlightPresent) + { + //note В (); + if (colorTable.IsStandardColor(m_lHighlightColor)) + { + oWriter.WriteString(L""); + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + { + oWriter.WriteString(L""); + } + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + void CContText::AddWideSpaceToXml(double dSpacingMM, + NSStringUtils::CStringBuilder& oWriter, + bool bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + + oWriter.WriteString(L"GetStyleId()); + oWriter.WriteString(L"\"/>"); + + double dSpaceMMSize = m_dSpaceWidthMM; + if (!m_pFontStyle->m_strPickFontName.empty()) + { + dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); + } + + LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); + //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + lCalculatedSpacing -= 1; + if (lCalculatedSpacing != 0) + { + oWriter.WriteString(L""); + } + + if (m_bIsEmbossPresent && bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + } + else if (m_bIsEngravePresent && bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + } + else + { + if (m_bIsOutlinePresent && bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + } + if (m_bIsShadowPresent && bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + } + } + + if (m_bIsStrikeoutPresent && bIsNeedSaveFormat) + { + if (m_bIsDoubleStrikeout) + { + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L""); + } + } + + if (m_bIsUnderlinePresent && bIsNeedSaveFormat) + { + oWriter.WriteString(L""); + } + + if (m_bIsHighlightPresent && bIsNeedSaveFormat) + { + //note В (); + if (colorTable.IsStandardColor(m_lHighlightColor)) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L" "); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + bool CContText::IsEqual(const CContText *pCont) + { + bool bIf1 = m_pFontStyle->GetStyleId() == pCont->m_pFontStyle->GetStyleId(); + bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; + bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; + bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; + bool bIf5 = m_lHighlightColor == pCont->m_lHighlightColor; + bool bIf6 = m_bIsUnderlinePresent == pCont->m_bIsUnderlinePresent; + bool bIf7 = m_eUnderlineType == pCont->m_eUnderlineType; + bool bIf8 = m_lUnderlineColor == pCont->m_lUnderlineColor; + bool bIf9 = m_bIsShadowPresent == pCont->m_bIsShadowPresent; + bool bIf10 = m_bIsOutlinePresent == pCont->m_bIsOutlinePresent; + bool bIf11 = m_bIsEmbossPresent == pCont->m_bIsEmbossPresent; + bool bIf12 = m_bIsEngravePresent == pCont->m_bIsEngravePresent; + bool bIf13 = m_eVertAlignType == pCont->m_eVertAlignType; + bool bIf14 = m_eVertAlignType == eVertAlignType::vatUnknown && pCont->m_eVertAlignType == eVertAlignType::vatBase; + bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; + + if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && + bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) + { + return true; + } + return false; + } + + UINT CContText::GetNumberOfFeatures() + { + UINT ret = 0; + + if (m_pFontStyle->m_oFont.Bold) + { + ret++; + } + if (m_pFontStyle->m_oFont.Italic) + { + ret++; + } + if (m_bIsStrikeoutPresent) + { + ret++; + } + if (m_bIsDoubleStrikeout) + { + ret++; + } + if (m_bIsHighlightPresent) + { + ret++; + } + if (m_bIsUnderlinePresent) + { + ret++; + } + if (m_eVertAlignType != eVertAlignType::vatUnknown) + { + ret++; + } + + return ret; + } + + bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) + { + if (eVType == eVerticalCrossingType::vctDublicate && + m_oText == pCont->m_oText) + { + pCont->m_bIsNotNecessaryToUse = true; + m_iNumDuplicates++; + return true; + } + return false; + } + + bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) + { + //Условие пересечения по вертикали + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже + + //Условие пересечения по горизонтали + bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее + bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее + + //Размеры шрифта и текст должны бать одинаковыми + bool bIf5 = m_pFontStyle->m_oFont.Size == pCont->m_pFontStyle->m_oFont.Size; + bool bIf6 = m_oText == pCont->m_oText; + + //Цвет тени должен быть серым + bool bIf7 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; + bool bIf8 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; + bool bIf9 = m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; + bool bIf10 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; + bool bIf11 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; + bool bIf12 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; + + //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами + //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. + //todo существует проблема неправильного определением FontEffects с физически пересекаемыми строчками - файл generaltest.pdf p.14 + if (bIf5 && bIf6) + { + if (m_bIsEmbossPresent && bIf12) + { + if (bIf1 && bIf3) + { + m_bIsEmbossPresent = true; + pCont->m_bIsNotNecessaryToUse = true; + return true; + } + } + + if (m_bIsEngravePresent && bIf10) + { + if (bIf1 && bIf3) + { + m_bIsEngravePresent = true; + pCont->m_bIsNotNecessaryToUse = true; + return true; + } + } + + //Shadow + if (bIf1 && bIf3 && bIf8) + { + m_bIsShadowPresent = true; + pCont->m_bIsNotNecessaryToUse = true; + return true; + } + else if (bIf2 && bIf4 && bIf7) + { + pCont->m_bIsShadowPresent = true; + m_bIsNotNecessaryToUse = true; + return true; + } + + //Emboss + //Первый проход + //c_iBlackColor -> c_iBlackColor -> c_iGreyColor2 + else if (bIf1 && bIf3 && bIf9) + { + pCont->m_bIsEmbossPresent = true; + m_bIsNotNecessaryToUse = true; + return true; + } + //Engrave + else if (bIf1 && bIf3 && bIf11) + { + pCont->m_bIsEngravePresent = true; + m_bIsNotNecessaryToUse = true; + return true; + } + } + return false; + } + + bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) + { + //Условие пересечения по вертикали + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || + eVType == eVerticalCrossingType::vctCurrentInsideNext; + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; + //Условие пересечения по горизонтали + bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && + fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; + bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || + eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && + fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; + //Размеры шрифта должны бать разными + bool bIf5 = m_pFontStyle->m_oFont.Size * 0.7 > pCont->m_pFontStyle->m_oFont.Size; + bool bIf6 = m_pFontStyle->m_oFont.Size < pCont->m_pFontStyle->m_oFont.Size * 0.7; + + if (bIf3 || bIf4) + { + if (bIf1 && bIf5) + { + pCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pCont->m_pCont = this; + m_eVertAlignType = eVertAlignType::vatBase; + m_pCont = pCont; + return true; + } + else if (bIf2 && bIf5) + { + pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pCont->m_pCont = this; + m_eVertAlignType = eVertAlignType::vatBase; + m_pCont = pCont; + return true; + } + else if (bIf1 && bIf6) + { + m_eVertAlignType = eVertAlignType::vatSuperscript; + m_pCont = pCont; + pCont->m_eVertAlignType = eVertAlignType::vatBase; + pCont->m_pCont = this; + return true; + } + else if (bIf2 && bIf6) + { + m_eVertAlignType = eVertAlignType::vatSubscript; + m_pCont = pCont; + pCont->m_eVertAlignType = eVertAlignType::vatBase; + pCont->m_pCont = this; + return true; + } + } + return false; + } + + double CContText::CalculateWideSpace() + { + //note подобранное условие - не везде хорошо работает + return m_dSpaceWidthMM * 4; + } + + double CContText::CalculateThinSpace() + { + //note подобранное условие - не везде хорошо работает + return m_dSpaceWidthMM * 0.7; + } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index a410a596dd9..cc3654ce7fd 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -9,71 +9,71 @@ namespace NSDocxRenderer { - class CShape; + class CShape; - enum class eVertAlignType - { - vatUnknown, - vatBase, - vatSubscript, - vatSuperscript - }; + enum class eVertAlignType + { + vatUnknown, + vatBase, + vatSubscript, + vatSuperscript + }; - class CContText : public CBaseItem - { - public: - std::shared_ptr m_pFontStyle {nullptr}; + class CContText : public CBaseItem + { + public: + std::shared_ptr m_pFontStyle {nullptr}; - bool m_bIsStrikeoutPresent {false}; - bool m_bIsDoubleStrikeout {false}; + bool m_bIsStrikeoutPresent {false}; + bool m_bIsDoubleStrikeout {false}; - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; + bool m_bIsHighlightPresent {false}; + LONG m_lHighlightColor {c_iBlackColor}; - bool m_bIsUnderlinePresent {false}; - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; + bool m_bIsUnderlinePresent {false}; + eLineType m_eUnderlineType {eLineType::ltUnknown}; + LONG m_lUnderlineColor {c_iBlackColor}; - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; + bool m_bIsShadowPresent {false}; + bool m_bIsOutlinePresent {false}; + bool m_bIsEmbossPresent {false}; + bool m_bIsEngravePresent {false}; - NSStringUtils::CStringUTF32 m_oText; + NSStringUtils::CStringUTF32 m_oText; - double m_dSpaceWidthMM {0}; - bool m_bSpaceIsNotNeeded {false}; + double m_dSpaceWidthMM {0}; + bool m_bSpaceIsNotNeeded {false}; - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CFontManagerLight* m_pManagerLight {nullptr}; - CStyleManager* m_pStyleManager {nullptr}; + CFontManagerLight* m_pManagerLight {nullptr}; + CStyleManager* m_pStyleManager {nullptr}; - CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. + const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - UINT m_iNumDuplicates {0}; + UINT m_iNumDuplicates {0}; - public: - CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); - CContText(const CContText& rCont); - virtual ~CContText(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final {}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + public: + CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); + CContText(const CContText& rCont); + virtual ~CContText(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final {}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - CContText& operator= (const CContText& rCont); + CContText& operator= (const CContText& rCont); - void AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat = false); - bool IsEqual(const CContText* pCont); - UINT GetNumberOfFeatures(); - bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); - bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); + void AddWideSpaceToXml(double dSpacingMM, + NSStringUtils::CStringBuilder& oWriter, + bool bIsNeedSaveFormat = false); + bool IsEqual(const CContText* pCont); + UINT GetNumberOfFeatures(); + bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); + bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); + bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - double CalculateWideSpace(); - double CalculateThinSpace(); - }; + double CalculateWideSpace(); + double CalculateThinSpace(); + }; } diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 60ed6de3f98..95b7c227a9b 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -4,744 +4,744 @@ namespace NSDocxRenderer { - //общая функция для сборки строк в любом текстовом объекте - void CConverter::BuildLines(std::vector& rTextLines) - { - for (size_t i = 0; i < rTextLines.size(); ++i) - { - auto pCurrLine = rTextLines[i]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) - { - auto pCurrCont = pCurrLine->m_arConts[j]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pCurrCont->m_iNumDuplicates > 0) - { - pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); - } - } - - pCurrLine->MergeConts(); - } - - DetermineDominantGraphics(rTextLines); - } - - void CConverter::DetermineDominantGraphics(std::vector& rTextLines) - { - CShape* pDominantShape = nullptr; - - for (size_t i = 0; i < rTextLines.size(); ++i) - { - auto pLine = rTextLines[i]; - if (pLine->m_bIsNotNecessaryToUse) - { - continue; - } - - for (size_t j = 0; j < pLine->m_arConts.size(); ++j) - { - auto pCont = pLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pCont->m_pShape && pCont->m_pShape != pDominantShape) - { - if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && - pCont->m_pShape->m_dRight > pCont->m_dRight) - { - if (!pDominantShape || - (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && - pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) - { - pDominantShape = pCont->m_pShape; - } - } - } - } - - pLine->m_pDominantShape = pDominantShape; - pDominantShape = nullptr; - } - } - - void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, - std::vector& rTextLines, - std::vector& rOutputObjects) - { - std::vector oStubVector; //просто объект-заглушка - BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects); - } - - // eBaseType == etCell или etParagraph - // eType == 2 - 5 из eTextAssociationType - void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects) - { - CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; - double dBeforeSpacingWithShapes = 0; - //note Все параграфы были сдвинуты на данное значение от верхнего края страницы - double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; - eVerticalCrossingType eCrossingType; - - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; - bool bIsNeedParagraphToShape = eType == eTextAssociationType::tatParagraphToShape && eBaseType == CBaseItem::ElemType::etParagraph; - - CTable* pCurrTable = nullptr; - size_t nTableIndex = 0; - - size_t nIndexForCheking = c_nAntiZero; - - if (!rTables.empty()) - { - CBaseItem::SortByBaseline(rTables); - pCurrTable = rTables.front(); - nTableIndex = 0; - - //Если линий нет, то добавлем сразу - if (rTextLines.empty()) - { - for (size_t i = 0; i < rTables.size(); ++i) - { - if (bIsNeedParagraphToShape) - { - CreateShapeFormTable(pCurrTable, rOutputObjects); - } - else - { - rOutputObjects.push_back(rTables[i]); - } - } - } - } - - CBaseItem::SortByBaseline(rTextLines); - - for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) - { - pCurrLine = rTextLines[nIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - if (eType == eTextAssociationType::tatShapeLine) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - continue; - } - - - while (pCurrTable) - { - eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); - - //добавляем таблицу в общий массив, если она идет после текущей строки - if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - if (bIsNeedParagraphToShape) - { - CreateShapeFormTable(pCurrTable, rOutputObjects); - } - else - { - rOutputObjects.push_back(pCurrTable); - } - dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); - pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - if (eType != eTextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) - { - pCurrTable->m_bIsNeedSpacing = true; - } - dPreviousStringBaseline = pCurrTable->m_dBaselinePos; - pCurrTable = nullptr; - //таблицы отсортированы, можно сразу взять следующую для проверки - for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) - { - pCurrTable = rTables[i]; - } - } - else - { - break; - } - } - - dPrevBeforeSpacing = dCurrBeforeSpacing; - if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) - { - dCurrBeforeSpacing = 0; - } - else - { - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - } - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - - //Если у текущей линии есть дубликаты, то создаем из них шейпы - if (pCurrLine->m_iNumDuplicates > 0) - { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; - - auto iNumDuplicates = pCurrLine->m_iNumDuplicates; - CreateSingleLineShape(pCurrLine, rOutputObjects); - while (iNumDuplicates > 0) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - iNumDuplicates--; - } - continue; - } - - if (eType == eTextAssociationType::tatPlainLine) - { - CreateSingleLineParagraph(pCurrLine, dPageWidth, &dCurrBeforeSpacing, rOutputObjects); - continue; - } - - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - if (bIsNeedParagraphToShape) - { - pPrevLine = GetPrevTextLine(nIndex, rTextLines); - } - - //Если две линии пересекаются, то создаем из них шейпы - if (pNextLine) - { - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bool bIsPassed = false; - double dCurrentAdditive = 0.0; - - switch (eCrossingType) - { - case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; - dPreviousStringBaseline = pNextLine->m_dBaselinePos; - bIsPassed = true; - break; - case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: - case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; - bIsPassed = true; - break; - default: - break; - } - - if (bIsPassed) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - CreateSingleLineShape(pNextLine, rOutputObjects); - - dBeforeSpacingWithShapes += dCurrentAdditive; - - nIndex++; - continue; - } - } - - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; - - bool bIsSingleLineParagraph = false; - - //Логика определения параметров для DetermineTextAlignmentType - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - - //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; - //расстрояние между строк тоже одинаково - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - //или - bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; - //нет отступа - bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - //есть отступ - bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; - //совпадают правые границы - bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - size_t nNextIndex = nIndex+1; - pNextNextLine = GetNextTextLine(nNextIndex, rTextLines); - - bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && - (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); - - if (pNextNextLine) - { - double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - - if (bIf1 && (bIf2 || bIf3)) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - pNextNextLine = nullptr; - } - } - else - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - if (dNextBeforeSpacing < dNextNextBeforeSpacing) - { - pNextNextLine = nullptr; - } - else - { - bIsSingleLineParagraph = true; - } - } - else - { - pNextNextLine = nullptr; - } - } - } - } - } - - bool bIsUseNextNextLine = true; - CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( - pCurrLine, pNextLine, pNextNextLine, dPageWidth, bIsUseNextNextLine, bIsSingleLineParagraph); - - auto pParagraph = new CParagraph(); - pParagraph->m_eTextAlignmentType = eTextAlignmentType; - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) - { - pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) - { - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - } - } - else - { - pParagraph->m_dLeft = pCurrLine->m_dLeft; - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; - pParagraph->m_dRight = pCurrLine->m_dRight; - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pCurrLine->m_dWidth; - - pParagraph->m_bIsNeedFirstLineIndent = false; - pParagraph->m_dFirstLine = 0; - } - - pParagraph->m_dTop = pCurrLine->m_dTop; - pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - pParagraph->m_dHeight = pCurrLine->m_dHeight; - - //размер строк во всем параграфе - pParagraph->m_dLineHeight= pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - - pParagraph->m_arLines.push_back(pCurrLine); - pParagraph->m_nNumLines++; - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - if (pCurrLine->IsShadingPresent(pNextLine)) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - double dCorrectionBeforeSpacing = dCurrBeforeSpacing; - - if (bIsUseNextNextLine) - { - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; - - if (!pCurrLine->IsShadingPresent(pNextLine)) - { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале - - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - } - } - - if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - CreateSingleLineShape(pNextLine, rOutputObjects); - nIndex++; - } - - //коррекция - pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; - pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); - - pParagraph->RemoveHighlightColor(); - pParagraph->MergeLines(); - } - else - { - if (pCurrLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - } - - if (bIsNeedParagraphToShape) - { - bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText, dPageWidth, rOutputObjects); - } - else - { - rOutputObjects.push_back(pParagraph); - } - - if (nIndexForCheking != c_nAntiZero) - { - nIndex = nIndexForCheking - 1; - nIndexForCheking = c_nAntiZero; - } - } - - if (bIsNeedParagraphToShape) - { - CorrectionObjectesInShapes(rOutputObjects, dPageWidth); - } - - std::sort(rOutputObjects.begin(), rOutputObjects.end(), [](CBaseItem* a, CBaseItem* b) { - return a->m_dBaselinePos < b->m_dBaselinePos; - }); - } - - void CConverter::CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, - const double *pBeforeSpacing, std::vector& rOutputObjects) - { - auto pParagraph = new CParagraph(); - pParagraph->m_arLines.push_back(pLine); - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dTop; - pParagraph->m_dFirstLine = 0; - pParagraph->m_dRight = pLine->m_dRight; - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dHeight; - if (*pBeforeSpacing < 0) - { - pParagraph->m_dHeight += *pBeforeSpacing; - } - - pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - rOutputObjects.push_back(pParagraph); - } - - void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector &rOutputObjects) - { - auto pParagraph = new CParagraph(); - pParagraph->m_arLines.push_back(pLine); - pParagraph->m_dRightBorder = 0; - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - auto pShape = new CShape(); - pShape->m_arOutputObjects.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dTop; - pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; - pShape->m_bIsBehindDoc = false; - - rOutputObjects.push_back(pShape); - } - - void CConverter::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText, double dPageWidth, - std::vector &rOutputObjects) - { - if (!pParagraph) - { - return; - } - - bool bIsShapesPresent = false; - CShape* pBackShape = nullptr; - - for (size_t i = 0; i < rOutputObjects.size(); ++i) - { - if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) - { - continue; - } - bIsShapesPresent = true; - pBackShape = dynamic_cast(rOutputObjects[i]); - } - - CShape* pShape; - - if (bIsSameTypeText && bIsShapesPresent) - { - pShape = pBackShape; - pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; - } - else - { - pShape = new CShape(); - pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines; - } - - pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; - pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; - pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; - pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; - pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); - - pParagraph->m_dLeftBorder = 0; - pParagraph->m_dRightBorder = 0; - - pShape->m_arOutputObjects.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_bIsBehindDoc = false; - - if (!bIsSameTypeText) - { - rOutputObjects.push_back(pShape); - } - } - - void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) - { - if (!pTable) - { - return; - } - - CShape* pShape; - - pShape = new CShape(); - pShape->m_dHeight = pTable->m_dHeight; - pShape->m_dLeft = pTable->m_dLeft; - pShape->m_dTop =pTable->m_dTop; - pShape->m_dRight = pTable->m_dRight; - pShape->m_dBaselinePos = pTable->m_dBaselinePos; - pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); - - pShape->m_arOutputObjects.push_back(pTable); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_bIsBehindDoc = false; - - rOutputObjects.push_back(pShape); - } - - void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) - { - for (size_t i = 0; i < rOutputObjects.size(); ++i) - { - if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) - { - continue; - } - - auto pShape = dynamic_cast(rOutputObjects[i]); - - if (pShape->m_bIsNotNecessaryToUse || - pShape->m_eType != CShape::eShapeType::stTextBox || - pShape->m_arOutputObjects.empty()) - { - continue; - } - - for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) - { - auto pObj = pShape->m_arOutputObjects[j]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - { - auto pParagraph = dynamic_cast(pObj); - - if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) - { - pParagraph->m_bIsNeedFirstLineIndent = true; - pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; - pParagraph->m_dLeft = 0; - } - - pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; - pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; - } - break; - case CBaseItem::ElemType::etTable: - { - auto pTable = dynamic_cast(pObj); - //todo - } - break; - default: - break; - } - - } - } - } - - CTextLine* CConverter::GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking) - { - CTextLine* pLine = nullptr; - - for (size_t nIndex = nCurrentIndex + 1; nIndex < rTextLines.size(); ++nIndex) - { - pLine = rTextLines[nIndex]; - bool bIf1 = pLine->m_bIsNotNecessaryToUse; - bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; - - if (bIf1 || bIf2) - { - if (bIf2) - { - if (*pIndexForCheking == c_nAntiZero) - { - *pIndexForCheking = nIndex; - } - } - - nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки - pLine = nullptr; - continue; - } - else - { - break; - } - } - return pLine; - } - - CTextLine* CConverter::GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines) - { - CTextLine* pLine = nullptr; - - if (nCurrentIndex) - { - for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) - { - pLine = rTextLines[nIndex]; - - if (pLine->m_bIsNotNecessaryToUse) - { - pLine = nullptr; - continue; - } - else - { - break; - } - } - } - return pLine; - } + //общая функция для сборки строк в любом текстовом объекте + void CConverter::BuildLines(std::vector& rTextLines) + { + for (size_t i = 0; i < rTextLines.size(); ++i) + { + auto pCurrLine = rTextLines[i]; + + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto pCurrCont = pCurrLine->m_arConts[j]; + + if (pCurrCont->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCurrCont->m_iNumDuplicates > 0) + { + pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); + } + } + + pCurrLine->MergeConts(); + } + + DetermineDominantGraphics(rTextLines); + } + + void CConverter::DetermineDominantGraphics(std::vector& rTextLines) + { + CShape* pDominantShape = nullptr; + + for (size_t i = 0; i < rTextLines.size(); ++i) + { + auto pLine = rTextLines[i]; + if (pLine->m_bIsNotNecessaryToUse) + { + continue; + } + + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto pCont = pLine->m_arConts[j]; + if (pCont->m_bIsNotNecessaryToUse) + { + continue; + } + + if (pCont->m_pShape && pCont->m_pShape != pDominantShape) + { + if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && + pCont->m_pShape->m_dRight > pCont->m_dRight) + { + if (!pDominantShape || + (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && + pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) + { + pDominantShape = pCont->m_pShape; + } + } + } + } + + pLine->m_pDominantShape = pDominantShape; + pDominantShape = nullptr; + } + } + + void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, + std::vector& rTextLines, + std::vector& rOutputObjects) + { + std::vector oStubVector; //просто объект-заглушка + BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects); + } + + // eBaseType == etCell или etParagraph + // eType == 2 - 5 из eTextAssociationType + void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector &rOutputObjects) + { + CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; + double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; + double dBeforeSpacingWithShapes = 0; + //note Все параграфы были сдвинуты на данное значение от верхнего края страницы + double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; + eVerticalCrossingType eCrossingType; + + bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; + bool bIsNeedParagraphToShape = eType == eTextAssociationType::tatParagraphToShape && eBaseType == CBaseItem::ElemType::etParagraph; + + CTable* pCurrTable = nullptr; + size_t nTableIndex = 0; + + size_t nIndexForCheking = c_nAntiZero; + + if (!rTables.empty()) + { + CBaseItem::SortByBaseline(rTables); + pCurrTable = rTables.front(); + nTableIndex = 0; + + //Если линий нет, то добавлем сразу + if (rTextLines.empty()) + { + for (size_t i = 0; i < rTables.size(); ++i) + { + if (bIsNeedParagraphToShape) + { + CreateShapeFormTable(pCurrTable, rOutputObjects); + } + else + { + rOutputObjects.push_back(rTables[i]); + } + } + } + } + + CBaseItem::SortByBaseline(rTextLines); + + for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) + { + pCurrLine = rTextLines[nIndex]; + if (pCurrLine->m_bIsNotNecessaryToUse) + { + continue; + } + + if (eType == eTextAssociationType::tatShapeLine) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + continue; + } + + + while (pCurrTable) + { + eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); + + //добавляем таблицу в общий массив, если она идет после текущей строки + if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + if (bIsNeedParagraphToShape) + { + CreateShapeFormTable(pCurrTable, rOutputObjects); + } + else + { + rOutputObjects.push_back(pCurrTable); + } + dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); + pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + if (eType != eTextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) + { + pCurrTable->m_bIsNeedSpacing = true; + } + dPreviousStringBaseline = pCurrTable->m_dBaselinePos; + pCurrTable = nullptr; + //таблицы отсортированы, можно сразу взять следующую для проверки + for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) + { + pCurrTable = rTables[i]; + } + } + else + { + break; + } + } + + dPrevBeforeSpacing = dCurrBeforeSpacing; + if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) + { + dCurrBeforeSpacing = 0; + } + else + { + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + } + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + + //Если у текущей линии есть дубликаты, то создаем из них шейпы + if (pCurrLine->m_iNumDuplicates > 0) + { + dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; + + auto iNumDuplicates = pCurrLine->m_iNumDuplicates; + CreateSingleLineShape(pCurrLine, rOutputObjects); + while (iNumDuplicates > 0) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + iNumDuplicates--; + } + continue; + } + + if (eType == eTextAssociationType::tatPlainLine) + { + CreateSingleLineParagraph(pCurrLine, dPageWidth, &dCurrBeforeSpacing, rOutputObjects); + continue; + } + + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + if (bIsNeedParagraphToShape) + { + pPrevLine = GetPrevTextLine(nIndex, rTextLines); + } + + //Если две линии пересекаются, то создаем из них шейпы + if (pNextLine) + { + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + bool bIsPassed = false; + double dCurrentAdditive = 0.0; + + switch (eCrossingType) + { + case eVerticalCrossingType::vctCurrentInsideNext: + case eVerticalCrossingType::vctCurrentBelowNext: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; + dPreviousStringBaseline = pNextLine->m_dBaselinePos; + bIsPassed = true; + break; + case eVerticalCrossingType::vctCurrentOutsideNext: + case eVerticalCrossingType::vctCurrentAboveNext: + case eVerticalCrossingType::vctDublicate: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; + bIsPassed = true; + break; + default: + break; + } + + if (bIsPassed) + { + CreateSingleLineShape(pCurrLine, rOutputObjects); + CreateSingleLineShape(pNextLine, rOutputObjects); + + dBeforeSpacingWithShapes += dCurrentAdditive; + + nIndex++; + continue; + } + } + + dCurrBeforeSpacing += dBeforeSpacingWithShapes; + dBeforeSpacingWithShapes = 0; + + bool bIsSingleLineParagraph = false; + + //Логика определения параметров для DetermineTextAlignmentType + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + + //Высота строк должна быть примерно одинаковой + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + //расстрояние между строк тоже одинаково + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + //или + bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; + //нет отступа + bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + //есть отступ + bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; + //совпадают правые границы + bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + size_t nNextIndex = nIndex+1; + pNextNextLine = GetNextTextLine(nNextIndex, rTextLines); + + bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && + (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); + + if (pNextNextLine) + { + double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + + if (bIf1 && (bIf2 || bIf3)) + { + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + pNextNextLine = nullptr; + } + } + else + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + if (dNextBeforeSpacing < dNextNextBeforeSpacing) + { + pNextNextLine = nullptr; + } + else + { + bIsSingleLineParagraph = true; + } + } + else + { + pNextNextLine = nullptr; + } + } + } + } + } + + bool bIsUseNextNextLine = true; + CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( + pCurrLine, pNextLine, pNextNextLine, dPageWidth, bIsUseNextNextLine, bIsSingleLineParagraph); + + auto pParagraph = new CParagraph(); + pParagraph->m_eTextAlignmentType = eTextAlignmentType; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) + { + pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) + { + pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; + pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; + } + } + else + { + pParagraph->m_dLeft = pCurrLine->m_dLeft; + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = pCurrLine->m_dRight; + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pCurrLine->m_dWidth; + + pParagraph->m_bIsNeedFirstLineIndent = false; + pParagraph->m_dFirstLine = 0; + } + + pParagraph->m_dTop = pCurrLine->m_dTop; + pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; + pParagraph->m_dHeight = pCurrLine->m_dHeight; + + //размер строк во всем параграфе + pParagraph->m_dLineHeight= pCurrLine->m_dHeight; + pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + + pParagraph->m_arLines.push_back(pCurrLine); + pParagraph->m_nNumLines++; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + if (pCurrLine->IsShadingPresent(pNextLine)) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + double dCorrectionBeforeSpacing = dCurrBeforeSpacing; + + if (bIsUseNextNextLine) + { + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + + //проверим, подходят ли следующие строчки для текущего pParagraph + while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; + + if (!pCurrLine->IsShadingPresent(pNextLine)) + { + pParagraph->m_bIsShadingPresent = false; + pParagraph->m_lColorOfShadingFill = c_iWhiteColor; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале + + if (pNextLine) + { + dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + } + } + + if (eCrossingType != eVerticalCrossingType::vctUnknown && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + CreateSingleLineShape(pNextLine, rOutputObjects); + nIndex++; + } + + //коррекция + pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; + pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); + + pParagraph->RemoveHighlightColor(); + pParagraph->MergeLines(); + } + else + { + if (pCurrLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + } + + if (bIsNeedParagraphToShape) + { + bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText, dPageWidth, rOutputObjects); + } + else + { + rOutputObjects.push_back(pParagraph); + } + + if (nIndexForCheking != c_nAntiZero) + { + nIndex = nIndexForCheking - 1; + nIndexForCheking = c_nAntiZero; + } + } + + if (bIsNeedParagraphToShape) + { + CorrectionObjectesInShapes(rOutputObjects, dPageWidth); + } + + std::sort(rOutputObjects.begin(), rOutputObjects.end(), [](CBaseItem* a, CBaseItem* b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + } + + void CConverter::CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, + const double *pBeforeSpacing, std::vector& rOutputObjects) + { + auto pParagraph = new CParagraph(); + pParagraph->m_arLines.push_back(pLine); + + pParagraph->m_dLeft = pLine->m_dLeft; + pParagraph->m_dTop = pLine->m_dTop; + pParagraph->m_dFirstLine = 0; + pParagraph->m_dRight = pLine->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pLine->m_dWidth; + pParagraph->m_dHeight = pLine->m_dHeight; + if (*pBeforeSpacing < 0) + { + pParagraph->m_dHeight += *pBeforeSpacing; + } + + pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + rOutputObjects.push_back(pParagraph); + } + + void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector &rOutputObjects) + { + auto pParagraph = new CParagraph(); + pParagraph->m_arLines.push_back(pLine); + pParagraph->m_dRightBorder = 0; + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + auto pShape = new CShape(); + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_dLeft = pLine->m_dLeft; + pShape->m_dTop = pLine->m_dTop; + pShape->m_dWidth = pLine->m_dWidth; + pShape->m_dHeight = pLine->m_dHeight; + pShape->m_bIsBehindDoc = false; + + rOutputObjects.push_back(pShape); + } + + void CConverter::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText, double dPageWidth, + std::vector &rOutputObjects) + { + if (!pParagraph) + { + return; + } + + bool bIsShapesPresent = false; + CShape* pBackShape = nullptr; + + for (size_t i = 0; i < rOutputObjects.size(); ++i) + { + if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + { + continue; + } + bIsShapesPresent = true; + pBackShape = dynamic_cast(rOutputObjects[i]); + } + + CShape* pShape; + + if (bIsSameTypeText && bIsShapesPresent) + { + pShape = pBackShape; + pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + } + else + { + pShape = new CShape(); + pParagraph->m_dSpaceBefore = 0; + pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines; + } + + pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; + pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; + pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; + pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; + pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + + pParagraph->m_dLeftBorder = 0; + pParagraph->m_dRightBorder = 0; + + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + if (!bIsSameTypeText) + { + rOutputObjects.push_back(pShape); + } + } + + void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) + { + if (!pTable) + { + return; + } + + CShape* pShape; + + pShape = new CShape(); + pShape->m_dHeight = pTable->m_dHeight; + pShape->m_dLeft = pTable->m_dLeft; + pShape->m_dTop =pTable->m_dTop; + pShape->m_dRight = pTable->m_dRight; + pShape->m_dBaselinePos = pTable->m_dBaselinePos; + pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + + pShape->m_arOutputObjects.push_back(pTable); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + rOutputObjects.push_back(pShape); + } + + void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) + { + for (size_t i = 0; i < rOutputObjects.size(); ++i) + { + if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + { + continue; + } + + auto pShape = dynamic_cast(rOutputObjects[i]); + + if (pShape->m_bIsNotNecessaryToUse || + pShape->m_eType != CShape::eShapeType::stTextBox || + pShape->m_arOutputObjects.empty()) + { + continue; + } + + for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) + { + auto pObj = pShape->m_arOutputObjects[j]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + { + auto pParagraph = dynamic_cast(pObj); + + if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) + { + pParagraph->m_bIsNeedFirstLineIndent = true; + pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; + pParagraph->m_dLeft = 0; + } + + pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; + pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; + } + break; + case CBaseItem::ElemType::etTable: + { + auto pTable = dynamic_cast(pObj); + //todo + } + break; + default: + break; + } + + } + } + } + + CTextLine* CConverter::GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking) + { + CTextLine* pLine = nullptr; + + for (size_t nIndex = nCurrentIndex + 1; nIndex < rTextLines.size(); ++nIndex) + { + pLine = rTextLines[nIndex]; + bool bIf1 = pLine->m_bIsNotNecessaryToUse; + bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; + + if (bIf1 || bIf2) + { + if (bIf2) + { + if (*pIndexForCheking == c_nAntiZero) + { + *pIndexForCheking = nIndex; + } + } + + nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки + pLine = nullptr; + continue; + } + else + { + break; + } + } + return pLine; + } + + CTextLine* CConverter::GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines) + { + CTextLine* pLine = nullptr; + + if (nCurrentIndex) + { + for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) + { + pLine = rTextLines[nIndex]; + + if (pLine->m_bIsNotNecessaryToUse) + { + pLine = nullptr; + continue; + } + else + { + break; + } + } + } + return pLine; + } } diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h index 8733e8872d1..2f3e8ac6741 100644 --- a/DocxRenderer/src/logic/elements/Converter.h +++ b/DocxRenderer/src/logic/elements/Converter.h @@ -3,28 +3,28 @@ namespace NSDocxRenderer { - class CConverter - { - public: - void BuildLines(std::vector& rTextLines); - void DetermineDominantGraphics(std::vector& rTextLines); + class CConverter + { + public: + void BuildLines(std::vector& rTextLines); + void DetermineDominantGraphics(std::vector& rTextLines); - void BuildParagraphes(double dPageWidth, eTextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector &rOutputObjects); - void BuildParagraphes(double dPageWidth, eTextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects); + void BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector &rOutputObjects); + void BuildParagraphes(double dPageWidth, eTextAssociationType eType, + CBaseItem::ElemType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector &rOutputObjects); - void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector &rOutputObjects); - void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); - void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector &rOutputObjects); - void CreateShapeFormTable(CTable* pParagraph, std::vector &rOutputObjects); - void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); + void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector &rOutputObjects); + void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); + void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector &rOutputObjects); + void CreateShapeFormTable(CTable* pParagraph, std::vector &rOutputObjects); + void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); - private: - CTextLine* GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking = nullptr); - CTextLine* GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines); - }; + private: + CTextLine* GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking = nullptr); + CTextLine* GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines); + }; } diff --git a/DocxRenderer/src/logic/elements/Image.cpp b/DocxRenderer/src/logic/elements/Image.cpp index 43e90af5a65..7137ee2c49d 100644 --- a/DocxRenderer/src/logic/elements/Image.cpp +++ b/DocxRenderer/src/logic/elements/Image.cpp @@ -4,47 +4,47 @@ namespace NSDocxRenderer { - CImage::CImage() : CBaseItem(ElemType::etImage) - { - } - CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etImage), - m_oImageInfo(oInfo), m_strPath(strDstMedia) - { - } - void CImage::Clear(){} - - void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L"rotation:"); - oWriter.AddInt((int)m_dRotate); - oWriter.AddCharSafe(';'); - } - - oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page\" filled=\"f\">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } + CImage::CImage() : CBaseItem(ElemType::etImage) + { + } + CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etImage), + m_oImageInfo(oInfo), m_strPath(strDstMedia) + { + } + void CImage::Clear(){} + + void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L" 0.01) + { + oWriter.WriteString(L"rotation:"); + oWriter.AddInt((int)m_dRotate); + oWriter.AddCharSafe(';'); + } + + oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-position-vertical-relative:page\" filled=\"f\">"); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } } diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index fe7e2eb8f66..ac2cc28ab18 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -4,25 +4,25 @@ namespace NSDocxRenderer { - class CImage : public CBaseItem + class CImage : public CBaseItem { public: - CImageInfo m_oImageInfo; + CImageInfo m_oImageInfo; - std::wstring m_strPath {L""}; + std::wstring m_strPath {L""}; - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; + bool m_bIsNoFill {true}; + bool m_bIsNoStroke {true}; + bool m_bIsBehindDoc {true}; - double m_dRotate {0.0}; + double m_dRotate {0.0}; public: - CImage(); - CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); - void Clear() override final; - void AddContent(CBaseItem* pObj) override final{}; + CImage(); + CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); + void Clear() override final; + void AddContent(CBaseItem* pObj) override final{}; - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; }; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index e8df40e7397..99f215f7f1d 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -4,296 +4,296 @@ namespace NSDocxRenderer { - CParagraph::CParagraph(): CBaseItem(ElemType::etParagraph) - { - } - - CParagraph::~CParagraph() - { - Clear(); - } - - void CParagraph::Clear() - { - m_arLines.clear(); - } - - void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L" 0) - { - oWriter.WriteString(L" w:before=\""); - oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dSpaceAfter > 0) - { - oWriter.WriteString(L" w:after=\""); - oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dLineHeight > 0) - { - oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки - } - - oWriter.WriteString(L"/>"); //конец w:spacing - - oWriter.WriteString(L" 0) - { - oWriter.WriteString(L" w:left=\""); - oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - if (m_dRightBorder > 0) - { - oWriter.WriteString(L" w:right=\""); - oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края - oWriter.WriteString(L"\""); - } - if (m_bIsNeedFirstLineIndent) - { - oWriter.WriteString(L" w:firstLine=\""); - oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); //конец w:ind - - switch (m_eTextAlignmentType) - { - case tatByCenter: - oWriter.WriteString(L""); - break; - case tatByRightEdge: - oWriter.WriteString(L""); - break; - case tatByWidth: - oWriter.WriteString(L""); - break; - case tatByLeftEdge: - oWriter.WriteString(L""); - break; - case tatUnknown: - default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять - break; - } - - if (m_bIsShadingPresent) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - for(size_t i = 0; i < m_arLines.size(); ++i) - { - m_arLines[i]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - void CParagraph::RemoveHighlightColor() - { - if (!m_bIsShadingPresent) - { - return; - } - - - for(size_t i = 0; i < m_arLines.size(); ++i) - { - auto pLine = m_arLines[i]; - if (pLine->m_pDominantShape) - { - for (size_t j = 0; j < pLine->m_arConts.size(); ++j) - { - auto pCont = pLine->m_arConts[j]; - if (m_lColorOfShadingFill == pCont->m_lHighlightColor) - { - pCont->m_bIsHighlightPresent = false; - } - } - } - } - } - - void CParagraph::MergeLines() - { - auto pLine = m_arLines.front(); - - for(size_t i = 1; i < m_arLines.size(); ++i) - { - auto pLastCont = pLine->m_arConts.back(); - size_t iNumConts = pLine->m_arConts.size() - 1; - - while (pLastCont->m_bIsNotNecessaryToUse) - { - pLastCont = pLine->m_arConts[--iNumConts]; - } - - //Добавляем пробел в конец каждой строки - pLastCont->m_oText += L" "; - pLastCont->m_bSpaceIsNotNeeded = true; - pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthMM; - - auto pNext = m_arLines[i]; - - auto pCont = pNext->m_arConts.front(); - - if (pLastCont->IsEqual(pCont)) - { - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth += pCont->m_dWidth; - pLastCont->m_dRight = pCont->m_dRight; - - pLastCont->m_bSpaceIsNotNeeded = false; - - pCont->m_bIsNotNecessaryToUse = true; - } - - for (size_t j = 0; j < pNext->m_arConts.size(); ++j) - { - auto pCont = pNext->m_arConts[j]; - if (!pCont->m_bIsNotNecessaryToUse) - { - pLine->m_arConts.push_back(pCont); - } - } - - pNext->m_bIsNotNecessaryToUse = true; - } - } - - CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) - { - if (!pCurrentLine || !pNextLine) - { - return tatUnknown; - } - - double dCurrLeft = pCurrentLine->m_dLeft; - double dNextLeft = pNextLine->m_dLeft; - double dNextNextLeft = pNextNextLine ? pNextNextLine->m_dLeft : 0; - - double dCurrRight = pCurrentLine->m_dRight; - double dNextRight = pNextLine->m_dRight; - double dNextNextRight = pNextNextLine ? pNextNextLine->m_dRight : 0; - - bool bIf1 = fabs(dCurrLeft - dNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf2 = pNextNextLine && fabs(dNextLeft - dNextNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf3 = dCurrLeft != dNextLeft && dCurrLeft > dNextLeft; - - bool bIf4 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf5 = fabs(dNextRight - dNextNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - bool bIf6 = fabs(dCurrLeft + pCurrentLine->m_dWidth/2 - dNextLeft - pNextLine->m_dWidth/2) < 0.5; - bool bIf7 = pNextNextLine && fabs(dNextLeft + pNextLine->m_dWidth/2 - dNextNextLeft - pNextNextLine->m_dWidth/2) < 0.5; - - if (pNextNextLine) - { - if (bIf1 && bIf2) - { - if (bIf4) - { - return tatByWidth; - } - else - { - return tatByLeftEdge; - } - } - else if (bIf3 && bIf2) - { - if (bIf4) - { - return tatByWidth; - } - else - { - return tatByLeftEdge; - } - } - else if (bIf4 && bIf5 && !(bIf1 && !bIf2 && dNextLeft > dNextNextLeft)) - { - return tatByRightEdge; - } - else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) - { - bIsUseNextNextLine = false; - return tatByWidth; - } - else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) - { - bIsSingleLineParagraph = true; - return tatByWidth; - } - else if (!bIf1 && !bIf2 && !bIf4 && !bIf5 && bIf6 && bIf7) - { - return tatByCenter; - } - else - { - return tatByWidth; - } - } - else - { - if (bIf4) - { - if (bIf1) - { - return tatByWidth; - } - else if (bIf3 && dCurrLeft < dNextLeft) - { - return tatByRightEdge; - } - else - { - return tatByWidth; - } - } - else if (dCurrRight > dNextRight) - { - if (bIf1 || bIf3) - { - return tatByWidth; - } - else - { - return tatByCenter; - } - } - else if (dCurrRight < dNextRight) - { - if (bIf1) - { - return tatByLeftEdge; - } - else if (bIf3 && bIf6) - { - return tatByCenter; - } - } - } - - return tatUnknown; - } + CParagraph::CParagraph(): CBaseItem(ElemType::etParagraph) + { + } + + CParagraph::~CParagraph() + { + Clear(); + } + + void CParagraph::Clear() + { + m_arLines.clear(); + } + + void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L" 0) + { + oWriter.WriteString(L" w:before=\""); + oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dSpaceAfter > 0) + { + oWriter.WriteString(L" w:after=\""); + oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dLineHeight > 0) + { + oWriter.WriteString(L" w:line=\""); + oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + } + + oWriter.WriteString(L"/>"); //конец w:spacing + + oWriter.WriteString(L" 0) + { + oWriter.WriteString(L" w:left=\""); + oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + if (m_dRightBorder > 0) + { + oWriter.WriteString(L" w:right=\""); + oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края + oWriter.WriteString(L"\""); + } + if (m_bIsNeedFirstLineIndent) + { + oWriter.WriteString(L" w:firstLine=\""); + oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L"/>"); //конец w:ind + + switch (m_eTextAlignmentType) + { + case tatByCenter: + oWriter.WriteString(L""); + break; + case tatByRightEdge: + oWriter.WriteString(L""); + break; + case tatByWidth: + oWriter.WriteString(L""); + break; + case tatByLeftEdge: + oWriter.WriteString(L""); + break; + case tatUnknown: + default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять + break; + } + + if (m_bIsShadingPresent) + { + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + + for(size_t i = 0; i < m_arLines.size(); ++i) + { + m_arLines[i]->ToXml(oWriter); + } + + oWriter.WriteString(L""); + } + + void CParagraph::RemoveHighlightColor() + { + if (!m_bIsShadingPresent) + { + return; + } + + + for(size_t i = 0; i < m_arLines.size(); ++i) + { + auto pLine = m_arLines[i]; + if (pLine->m_pDominantShape) + { + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto pCont = pLine->m_arConts[j]; + if (m_lColorOfShadingFill == pCont->m_lHighlightColor) + { + pCont->m_bIsHighlightPresent = false; + } + } + } + } + } + + void CParagraph::MergeLines() + { + auto pLine = m_arLines.front(); + + for(size_t i = 1; i < m_arLines.size(); ++i) + { + auto pLastCont = pLine->m_arConts.back(); + size_t iNumConts = pLine->m_arConts.size() - 1; + + while (pLastCont->m_bIsNotNecessaryToUse) + { + pLastCont = pLine->m_arConts[--iNumConts]; + } + + //Добавляем пробел в конец каждой строки + pLastCont->m_oText += L" "; + pLastCont->m_bSpaceIsNotNeeded = true; + pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthMM; + + auto pNext = m_arLines[i]; + + auto pCont = pNext->m_arConts.front(); + + if (pLastCont->IsEqual(pCont)) + { + pLastCont->m_oText += pCont->m_oText; + pLastCont->m_dWidth += pCont->m_dWidth; + pLastCont->m_dRight = pCont->m_dRight; + + pLastCont->m_bSpaceIsNotNeeded = false; + + pCont->m_bIsNotNecessaryToUse = true; + } + + for (size_t j = 0; j < pNext->m_arConts.size(); ++j) + { + auto pCont = pNext->m_arConts[j]; + if (!pCont->m_bIsNotNecessaryToUse) + { + pLine->m_arConts.push_back(pCont); + } + } + + pNext->m_bIsNotNecessaryToUse = true; + } + } + + CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) + { + if (!pCurrentLine || !pNextLine) + { + return tatUnknown; + } + + double dCurrLeft = pCurrentLine->m_dLeft; + double dNextLeft = pNextLine->m_dLeft; + double dNextNextLeft = pNextNextLine ? pNextNextLine->m_dLeft : 0; + + double dCurrRight = pCurrentLine->m_dRight; + double dNextRight = pNextLine->m_dRight; + double dNextNextRight = pNextNextLine ? pNextNextLine->m_dRight : 0; + + bool bIf1 = fabs(dCurrLeft - dNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf2 = pNextNextLine && fabs(dNextLeft - dNextNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf3 = dCurrLeft != dNextLeft && dCurrLeft > dNextLeft; + + bool bIf4 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + bool bIf5 = fabs(dNextRight - dNextNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + bool bIf6 = fabs(dCurrLeft + pCurrentLine->m_dWidth/2 - dNextLeft - pNextLine->m_dWidth/2) < 0.5; + bool bIf7 = pNextNextLine && fabs(dNextLeft + pNextLine->m_dWidth/2 - dNextNextLeft - pNextNextLine->m_dWidth/2) < 0.5; + + if (pNextNextLine) + { + if (bIf1 && bIf2) + { + if (bIf4) + { + return tatByWidth; + } + else + { + return tatByLeftEdge; + } + } + else if (bIf3 && bIf2) + { + if (bIf4) + { + return tatByWidth; + } + else + { + return tatByLeftEdge; + } + } + else if (bIf4 && bIf5 && !(bIf1 && !bIf2 && dNextLeft > dNextNextLeft)) + { + return tatByRightEdge; + } + else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) + { + bIsUseNextNextLine = false; + return tatByWidth; + } + else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) + { + bIsSingleLineParagraph = true; + return tatByWidth; + } + else if (!bIf1 && !bIf2 && !bIf4 && !bIf5 && bIf6 && bIf7) + { + return tatByCenter; + } + else + { + return tatByWidth; + } + } + else + { + if (bIf4) + { + if (bIf1) + { + return tatByWidth; + } + else if (bIf3 && dCurrLeft < dNextLeft) + { + return tatByRightEdge; + } + else + { + return tatByWidth; + } + } + else if (dCurrRight > dNextRight) + { + if (bIf1 || bIf3) + { + return tatByWidth; + } + else + { + return tatByCenter; + } + } + else if (dCurrRight < dNextRight) + { + if (bIf1) + { + return tatByLeftEdge; + } + else if (bIf3 && bIf6) + { + return tatByCenter; + } + } + } + + return tatUnknown; + } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index bf8c2e00d54..39910abb9b9 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -4,60 +4,60 @@ namespace NSDocxRenderer { - enum class eTextAssociationType - { - tatBlockChar = 0, // Каждый символ во фрейме - tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. - tatPlainLine = 2, // Каждая линия - параграф обычный - tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. - tatPlainParagraph = 4, // Все линии объединяются в параграфы - tatParagraphToShape = 5 // Параграфы записываем в шейпы - }; - - class CParagraph : public CBaseItem - { - public: - enum TextAlignmentType - { - tatUnknown, - tatByLeftEdge, - tatByCenter, - tatByRightEdge, - tatByWidth - }; - - // text frame properties - bool m_bIsNeedFirstLineIndent {false}; - bool m_bIsShadingPresent {false}; - LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR - TextAlignmentType m_eTextAlignmentType {tatUnknown}; - - // geometry paragraph - double m_dLeftBorder {0.0}; //сдвиг относительно левого края страницы/шейпа/таблицы - double m_dRightBorder {0.0}; //сдвиг относительно правого края страницы/шейпа/таблицы - double m_dFirstLine {0.0}; //сдвиг относительно m_dLeftBorder - - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dLineHeight {0.0}; - - std::vector m_arLines; - - size_t m_nNumLines {0}; - - public: - CParagraph(); - virtual ~CParagraph(); - virtual void Clear() override final; - - virtual void AddContent(CBaseItem* pObj) override final{}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void RemoveHighlightColor(); - - void MergeLines(); - - static TextAlignmentType DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, - double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph); - }; + enum class eTextAssociationType + { + tatBlockChar = 0, // Каждый символ во фрейме + tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. + tatPlainLine = 2, // Каждая линия - параграф обычный + tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. + tatPlainParagraph = 4, // Все линии объединяются в параграфы + tatParagraphToShape = 5 // Параграфы записываем в шейпы + }; + + class CParagraph : public CBaseItem + { + public: + enum TextAlignmentType + { + tatUnknown, + tatByLeftEdge, + tatByCenter, + tatByRightEdge, + tatByWidth + }; + + // text frame properties + bool m_bIsNeedFirstLineIndent {false}; + bool m_bIsShadingPresent {false}; + LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR + TextAlignmentType m_eTextAlignmentType {tatUnknown}; + + // geometry paragraph + double m_dLeftBorder {0.0}; //сдвиг относительно левого края страницы/шейпа/таблицы + double m_dRightBorder {0.0}; //сдвиг относительно правого края страницы/шейпа/таблицы + double m_dFirstLine {0.0}; //сдвиг относительно m_dLeftBorder + + double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dLineHeight {0.0}; + + std::vector m_arLines; + + size_t m_nNumLines {0}; + + public: + CParagraph(); + virtual ~CParagraph(); + virtual void Clear() override final; + + virtual void AddContent(CBaseItem* pObj) override final{}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + + void RemoveHighlightColor(); + + void MergeLines(); + + static TextAlignmentType DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, + double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph); + }; } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 671dbfe3447..734e040f15f 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -6,994 +6,994 @@ namespace NSDocxRenderer { - UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; - - CShape::CShape() : CBaseItem(ElemType::etShape) - { - m_nRelativeHeight = m_gRelativeHeight; - m_gRelativeHeight += c_iStandartRelativeHeight; - } - - CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etShape), - m_strPath(strDstMedia), m_pImageInfo(pInfo) - { - m_nRelativeHeight = m_gRelativeHeight; - m_gRelativeHeight += c_iStandartRelativeHeight; - } - - CShape::~CShape() - { - Clear(); - } - - void CShape::Clear() - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } - m_arOutputObjects.clear(); - } - - UINT CShape::GenerateShapeId() - { - static UINT iId = 0; - iId++; - return iId; - } - - void CShape::ResetRelativeHeight() - { - m_gRelativeHeight = c_iStandartRelativeHeight; - } - - void CShape::GetDataFromVector(const CVectorGraphics& oVector) - { - m_dLeft = oVector.m_dLeft; - m_dTop = oVector.m_dTop; - m_dWidth = oVector.m_dRight - m_dLeft; - m_dHeight = oVector.m_dBottom - m_dTop; - - if (m_dWidth < 0.0001) - m_dWidth = 0.0001; - if (m_dHeight < 0.0001) - m_dHeight = 0.0001; - - m_dBaselinePos = m_dTop + m_dHeight; - m_dRight = m_dLeft + m_dWidth; - - WritePath(oVector); - } - - void CShape::WritePath(const CVectorGraphics& oVector) - { - size_t nCount = oVector.GetCurSize(); - double *pData = oVector.m_pData; - - double dWidth = oVector.m_dRight - oVector.m_dLeft; - double dHeight = oVector.m_dBottom - oVector.m_dTop; - - NSStringUtils::CStringBuilder oWriter; - - oWriter.WriteString(L"(dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" h=\""); - oWriter.AddInt(static_cast(dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\">"); - - size_t nPeacks = 0; - size_t nCurves = 0; - - while (nCount > 0) - { - CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast((*pData - m_dLeft) * c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtLine: - { - LONG lX = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY1 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX2 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY2 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX3 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY3 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L""); - - oWriter.WriteString(L"(lX1)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY1)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX2)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY2)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX3)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY3)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); - - nCurves++; - nCount -= 7; - break; - } - case CVectorGraphics::vgtClose: - default: - --nCount; - break; - } - } - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - m_strPath = oWriter.GetData(); - - DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves); - - oWriter.ClearNoAttack(); - } - - void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) - { - //note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста. - if ((m_bIsNoStroke && m_bIsNoFill) || - (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor)) - { - m_eGraphicsType = eGraphicsType::gtNoGraphics; - } - else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks - { - m_eGraphicsType = eGraphicsType::gtRectangle; - - if (dHeight < 0.7) - { - if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman - { - m_eSimpleLineType = eSimpleLineType::sltHLongDash; - } - else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash - { - m_eSimpleLineType = eSimpleLineType::sltHDash; - } - else //максимальна точка - 0.5mm - { - m_eSimpleLineType = eSimpleLineType::sltHDot; - } - } - else if (dWidth < 0.7) - { - if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman - { - m_eSimpleLineType = eSimpleLineType::sltVLongDash; - } - else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash - { - m_eSimpleLineType = eSimpleLineType::sltVDash; - } - else //максимальна точка - 0.5mm - { - m_eSimpleLineType = eSimpleLineType::sltVDot; - } - } - } - else if (nCurves > 0 && nPeacks <= 1) //1 move - { - m_eGraphicsType = eGraphicsType::gtCurve; - if (dHeight < dWidth) - { - m_eSimpleLineType = eSimpleLineType::sltHWave; - } - else - { - m_eSimpleLineType = eSimpleLineType::sltVWave; - } - } - else if (nCurves > 0 && nPeacks > 1) - { - m_eGraphicsType = eGraphicsType::gtComplicatedFigure; - } - } - - bool CShape::IsItFitLine() - { - return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) || - (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave); - } - - bool CShape::IsCorrelated(const CShape *pShape) - { - return m_eGraphicsType == pShape->m_eGraphicsType; - } - - void CShape::ChangeGeometryOfDesiredShape(CShape *pShape) - { - if (!pShape) - { - return; - } - - CShape* pModObject; - CShape* pDataObject; - - if (pShape->m_bIsNotNecessaryToUse) - { - pModObject = this; - pDataObject = pShape; - } - else if (m_bIsNotNecessaryToUse) - { - pModObject = pShape; - pDataObject = this; - } - else - { - return; - } - - double dModRight = pModObject->m_dLeft + pModObject->m_dWidth; - double dDataRight = pDataObject->m_dLeft + pDataObject->m_dWidth; - double dModBottom = pModObject->m_dTop + pModObject->m_dHeight; - double dDataBottom = pDataObject->m_dTop + pDataObject->m_dHeight; - - if (pModObject->m_dTop == pDataObject->m_dTop || - (pModObject->m_dTop < pDataObject->m_dTop && pModObject->m_dHeight > pDataObject->m_dHeight) || - (pModObject->m_dTop > pDataObject->m_dTop && pModObject->m_dHeight < pDataObject->m_dHeight)) - { - pModObject->m_dHeight = std::max(pModObject->m_dHeight, pDataObject->m_dHeight); - } - else if (pModObject->m_dTop < pDataObject->m_dTop) - { - pModObject->m_dHeight += pDataObject->m_dHeight + pDataObject->m_dTop - dModBottom; - } - else - { - pModObject->m_dHeight += pDataObject->m_dHeight + dDataBottom - pModObject->m_dTop; - } - - if (pModObject->m_dLeft == pDataObject->m_dLeft || - (pModObject->m_dLeft < pDataObject->m_dLeft && dModRight > dDataRight) || - (pModObject->m_dLeft > pDataObject->m_dLeft && dModRight < dDataRight)) - { - pModObject->m_dWidth = std::max(pModObject->m_dWidth, pDataObject->m_dWidth); - } - else if (pModObject->m_dLeft < pDataObject->m_dLeft) - { - pModObject->m_dWidth += pDataObject->m_dWidth + pDataObject->m_dLeft - dModRight; - } - else - { - pModObject->m_dWidth += pDataObject->m_dWidth + dDataRight - pModObject->m_dLeft; - } - - //note m_dWidth иногда меняет знак на "-" - pModObject->m_dHeight = fabs(pModObject->m_dHeight); - pModObject->m_dWidth = fabs(pModObject->m_dWidth); - pModObject->m_dLeft = std::min(pModObject->m_dLeft, pDataObject->m_dLeft); - pModObject->m_dTop = std::min(pModObject->m_dTop, pDataObject->m_dTop); - pModObject->m_dBaselinePos = pModObject->m_dTop + pModObject->m_dHeight; - pModObject->m_dRight = pModObject->m_dLeft + pModObject->m_dWidth; - } - - bool CShape::IsPeak() - { - return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; - } - - bool CShape::IsSide() - { - return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; - } - - void CShape::DetermineLineType(CShape *pShape, bool bIsLast) - { - if (!pShape) - { - //Если нашелся один шейп в линии - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - return; - } - - if (!IsItFitLine() || !pShape->IsItFitLine() || !IsCorrelated(pShape) || - fabs(m_dHeight - pShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) //линия должна быть одного размера по высоте - { - return; - } - - //Проверка на двойную линию - if (m_eLineType == eLineType::ltDouble || m_eLineType == eLineType::ltWavyDouble) - { - if (m_eLineType == eLineType::ltDouble) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - else if (m_eLineType == eLineType::ltWavyDouble) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - return; - } - else if (fabs(m_dTop - pShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && - fabs(m_dWidth - pShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(m_dLeft - pShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - //Условие первого определения - if (m_eSimpleLineType == eSimpleLineType::sltHLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - else if (m_eSimpleLineType == eSimpleLineType::sltHWave && pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) - { - if (m_dTop < pShape->m_dTop) - { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - else - { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - return; - } - else if (fabs(m_dTop - pShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) - { - //все должно быть на одной линии - return; - } - - //Теперь считаем, что графика находится на одной линии - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) - { - //расстояние между объектами на одной линии должно быть небольшим - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - return; - } - - if (bIsLast) - { - //note Если имеем всего 2 шейпа в линии, то нужно специально определять тип - if (m_eLineType == eLineType::ltUnknown) - { - switch (m_eSimpleLineType) - { - case eSimpleLineType::sltHDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - } - break; - - case eSimpleLineType::sltHDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - } - break; - - case eSimpleLineType::sltHLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - } - break; - - case eSimpleLineType::sltHWave: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } - break; - default: - break; - } - } - - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - return; - } - - bool bIsConditionPassed = false; - - switch (m_eSimpleLineType) - { - case eSimpleLineType::sltHDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted || - m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy || - m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; - } - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) - { - if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltHDash; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltHDash; - bIsConditionPassed = true; - } - } - break; - case eSimpleLineType::sltHDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash || - m_eLineType == eLineType::ltDashedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - bIsConditionPassed = true; - } - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash || - m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; - } - } - break; - - case eSimpleLineType::sltHLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7 || - m_eLineType == eLineType::ltThick || m_eLineType == eLineType::ltSingle) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - bIsConditionPassed = true; - } - else if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDashLong || - m_eLineType == eLineType::ltDashLongHeavy) && pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - bIsConditionPassed = true; - } - break; - - case eSimpleLineType::sltHWave: - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave || - m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) && - pShape->m_eLineType == eLineType::ltUnknown) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - bIsConditionPassed = true; - } - break; - default: - break; - } - - if (bIsConditionPassed) - { - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); - } - } - - void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) - { - //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст - //todo добавить все возможные параметры/атрибуты - - if (m_bIsNotNecessaryToUse) - { - return; - } - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //отключение проверки орфографии - - oWriter.WriteString(L""); - - BuildGeneralProperties(oWriter); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"(m_bIsBehindDoc)); - oWriter.WriteString(L"\""); - oWriter.WriteString(L" locked=\"0\""); //true/1 Указывает, что местоположение привязки для этого объекта не должно быть изменено во время выполнения, когда приложение редактирует содержимое этого документа. - oWriter.WriteString(L" layoutInCell=\"0\""); //объект будет позиционирован, как указано, но таблица будет изменена в размерах и/или перемещена в документе, как это необходимо для размещения объекта. - oWriter.WriteString(L" allowOverlap=\"1\""); //разрешается перекрывать содержимое другого объекта - oWriter.WriteString(L" hidden=\"0\""); //Определяет, будет ли отображаться данный плавающий объект DrawingML. - oWriter.WriteString(L">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.AddInt(static_cast(m_dLeft * c_dMMToEMU)); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - //координаты конца границы шейпа - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML - - oWriter.WriteString(L""); - - m_nShapeId = GenerateShapeId(); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - BuildSpecificProperties(oWriter); - - oWriter.WriteString(L""); - } - - void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - switch (m_eType) - { - case eShapeType::stPicture: - case eShapeType::stVectorTexture: - BuildPictureProperties(oWriter); - break; - case eShapeType::stCanvas: - BuildCanvasProperties(oWriter); - break; - case eShapeType::stGroup: - BuildGroupProperties(oWriter); - break; - case eShapeType::stTextBox: - case eShapeType::stVectorGraphics: - default: - BuildShapeProperties(oWriter); - break; - } - - oWriter.WriteString(L""); - } - - void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php - - oWriter.WriteString(L""); //shape properties. http://officeopenxml.com/drwSp-SpPr.php - - //не работает - //oWriter.WriteString(L""); //shape styles. http://officeopenxml.com/drwSp-styles.php - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L""); - - BuildTextBox(oWriter); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\" name=\"Picture "); - oWriter.AddUInt(m_pImageInfo->m_nId); - oWriter.WriteString(L"\""); - //oWriter.WriteString(L" descr=\"Alt Text!\""); //Коммент к картинке - oWriter.WriteString(L"/>"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L"m_nId); - oWriter.WriteString(L"\">"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - BuildGraphicProperties(oWriter); - oWriter.WriteString(L""); - - //todo довабить любое количество элементов в группе - BuildPictureProperties(oWriter); - BuildShapeProperties(oWriter); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - - void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) - { - //todo добавить реализацию - oWriter.WriteString(L""); - } - - void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) - { - //отвечает за размеры прямоугольного фрейма шейпа - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L" rot=\""); - oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L">"); - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L""); - - //Если просто текст без графики - if (m_strPath.empty()) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - //Рисуем сложный путь - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(m_strPath); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - - if (m_bIsNoFill) - { - //Нет заливки - oWriter.WriteString(L""); - } - else - { - //Есть заливка - oWriter.WriteString(L""); - oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oBrush.Color1))); - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"\">(m_oBrush.TextureAlpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - oWriter.WriteString(L""); - } - - if (m_bIsNoStroke) - { - oWriter.WriteString(L""); // w - width по умолчанию 0.75pt = 9525 - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L"(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм - oWriter.WriteString(L"\">"); - - oWriter.WriteString(L""); - - oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"\">(m_oPen.Alpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - - void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) - { - if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) - { - oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php - oWriter.WriteString(L""); - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } - } - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L"1) - oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). - oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. - oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top - oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. - oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. - oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. - oWriter.WriteString(L">"); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } + UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; + + CShape::CShape() : CBaseItem(ElemType::etShape) + { + m_nRelativeHeight = m_gRelativeHeight; + m_gRelativeHeight += c_iStandartRelativeHeight; + } + + CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etShape), + m_strPath(strDstMedia), m_pImageInfo(pInfo) + { + m_nRelativeHeight = m_gRelativeHeight; + m_gRelativeHeight += c_iStandartRelativeHeight; + } + + CShape::~CShape() + { + Clear(); + } + + void CShape::Clear() + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->Clear(); + break; + case CBaseItem::ElemType::etShape: + dynamic_cast(pObj)->Clear(); + break; + default: + pObj->Clear(); + break; + } + } + m_arOutputObjects.clear(); + } + + UINT CShape::GenerateShapeId() + { + static UINT iId = 0; + iId++; + return iId; + } + + void CShape::ResetRelativeHeight() + { + m_gRelativeHeight = c_iStandartRelativeHeight; + } + + void CShape::GetDataFromVector(const CVectorGraphics& oVector) + { + m_dLeft = oVector.m_dLeft; + m_dTop = oVector.m_dTop; + m_dWidth = oVector.m_dRight - m_dLeft; + m_dHeight = oVector.m_dBottom - m_dTop; + + if (m_dWidth < 0.0001) + m_dWidth = 0.0001; + if (m_dHeight < 0.0001) + m_dHeight = 0.0001; + + m_dBaselinePos = m_dTop + m_dHeight; + m_dRight = m_dLeft + m_dWidth; + + WritePath(oVector); + } + + void CShape::WritePath(const CVectorGraphics& oVector) + { + size_t nCount = oVector.GetCurSize(); + double *pData = oVector.m_pData; + + double dWidth = oVector.m_dRight - oVector.m_dLeft; + double dHeight = oVector.m_dBottom - oVector.m_dTop; + + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"(dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" h=\""); + oWriter.AddInt(static_cast(dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\">"); + + size_t nPeacks = 0; + size_t nCurves = 0; + + while (nCount > 0) + { + CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); + + switch (eType) + { + case CVectorGraphics::vgtMove: + { + LONG lX = static_cast((*pData - m_dLeft) * c_dMMToEMU); + ++pData; + LONG lY = static_cast((*pData - m_dTop) * c_dMMToEMU); + ++pData; + + oWriter.WriteString(L"(lX)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY)); + oWriter.WriteString(L"\"/>"); + + nPeacks++; + nCount -= 3; + break; + } + case CVectorGraphics::vgtLine: + { + LONG lX = static_cast((*pData - m_dLeft)* c_dMMToEMU); + ++pData; + LONG lY = static_cast((*pData - m_dTop)* c_dMMToEMU); + ++pData; + + oWriter.WriteString(L"(lX)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY)); + oWriter.WriteString(L"\"/>"); + + nPeacks++; + nCount -= 3; + break; + } + case CVectorGraphics::vgtCurve: + { + LONG lX1 = static_cast((*pData - m_dLeft)* c_dMMToEMU); + ++pData; + LONG lY1 = static_cast((*pData - m_dTop)* c_dMMToEMU); + ++pData; + LONG lX2 = static_cast((*pData - m_dLeft)* c_dMMToEMU); + ++pData; + LONG lY2 = static_cast((*pData - m_dTop)* c_dMMToEMU); + ++pData; + LONG lX3 = static_cast((*pData - m_dLeft)* c_dMMToEMU); + ++pData; + LONG lY3 = static_cast((*pData - m_dTop)* c_dMMToEMU); + ++pData; + + oWriter.WriteString(L""); + + oWriter.WriteString(L"(lX1)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY1)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"(lX2)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY2)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"(lX3)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(lY3)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); + + nCurves++; + nCount -= 7; + break; + } + case CVectorGraphics::vgtClose: + default: + --nCount; + break; + } + } + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + m_strPath = oWriter.GetData(); + + DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves); + + oWriter.ClearNoAttack(); + } + + void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) + { + //note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста. + if ((m_bIsNoStroke && m_bIsNoFill) || + (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor)) + { + m_eGraphicsType = eGraphicsType::gtNoGraphics; + } + else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks + { + m_eGraphicsType = eGraphicsType::gtRectangle; + + if (dHeight < 0.7) + { + if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltHLongDash; + } + else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltHDash; + } + else //максимальна точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltHDot; + } + } + else if (dWidth < 0.7) + { + if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltVLongDash; + } + else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltVDash; + } + else //максимальна точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltVDot; + } + } + } + else if (nCurves > 0 && nPeacks <= 1) //1 move + { + m_eGraphicsType = eGraphicsType::gtCurve; + if (dHeight < dWidth) + { + m_eSimpleLineType = eSimpleLineType::sltHWave; + } + else + { + m_eSimpleLineType = eSimpleLineType::sltVWave; + } + } + else if (nCurves > 0 && nPeacks > 1) + { + m_eGraphicsType = eGraphicsType::gtComplicatedFigure; + } + } + + bool CShape::IsItFitLine() + { + return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) || + (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave); + } + + bool CShape::IsCorrelated(const CShape *pShape) + { + return m_eGraphicsType == pShape->m_eGraphicsType; + } + + void CShape::ChangeGeometryOfDesiredShape(CShape *pShape) + { + if (!pShape) + { + return; + } + + CShape* pModObject; + CShape* pDataObject; + + if (pShape->m_bIsNotNecessaryToUse) + { + pModObject = this; + pDataObject = pShape; + } + else if (m_bIsNotNecessaryToUse) + { + pModObject = pShape; + pDataObject = this; + } + else + { + return; + } + + double dModRight = pModObject->m_dLeft + pModObject->m_dWidth; + double dDataRight = pDataObject->m_dLeft + pDataObject->m_dWidth; + double dModBottom = pModObject->m_dTop + pModObject->m_dHeight; + double dDataBottom = pDataObject->m_dTop + pDataObject->m_dHeight; + + if (pModObject->m_dTop == pDataObject->m_dTop || + (pModObject->m_dTop < pDataObject->m_dTop && pModObject->m_dHeight > pDataObject->m_dHeight) || + (pModObject->m_dTop > pDataObject->m_dTop && pModObject->m_dHeight < pDataObject->m_dHeight)) + { + pModObject->m_dHeight = std::max(pModObject->m_dHeight, pDataObject->m_dHeight); + } + else if (pModObject->m_dTop < pDataObject->m_dTop) + { + pModObject->m_dHeight += pDataObject->m_dHeight + pDataObject->m_dTop - dModBottom; + } + else + { + pModObject->m_dHeight += pDataObject->m_dHeight + dDataBottom - pModObject->m_dTop; + } + + if (pModObject->m_dLeft == pDataObject->m_dLeft || + (pModObject->m_dLeft < pDataObject->m_dLeft && dModRight > dDataRight) || + (pModObject->m_dLeft > pDataObject->m_dLeft && dModRight < dDataRight)) + { + pModObject->m_dWidth = std::max(pModObject->m_dWidth, pDataObject->m_dWidth); + } + else if (pModObject->m_dLeft < pDataObject->m_dLeft) + { + pModObject->m_dWidth += pDataObject->m_dWidth + pDataObject->m_dLeft - dModRight; + } + else + { + pModObject->m_dWidth += pDataObject->m_dWidth + dDataRight - pModObject->m_dLeft; + } + + //note m_dWidth иногда меняет знак на "-" + pModObject->m_dHeight = fabs(pModObject->m_dHeight); + pModObject->m_dWidth = fabs(pModObject->m_dWidth); + pModObject->m_dLeft = std::min(pModObject->m_dLeft, pDataObject->m_dLeft); + pModObject->m_dTop = std::min(pModObject->m_dTop, pDataObject->m_dTop); + pModObject->m_dBaselinePos = pModObject->m_dTop + pModObject->m_dHeight; + pModObject->m_dRight = pModObject->m_dLeft + pModObject->m_dWidth; + } + + bool CShape::IsPeak() + { + return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; + } + + bool CShape::IsSide() + { + return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; + } + + void CShape::DetermineLineType(CShape *pShape, bool bIsLast) + { + if (!pShape) + { + //Если нашелся один шейп в линии + if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + } + else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) + { + m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + } + return; + } + + if (!IsItFitLine() || !pShape->IsItFitLine() || !IsCorrelated(pShape) || + fabs(m_dHeight - pShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) //линия должна быть одного размера по высоте + { + return; + } + + //Проверка на двойную линию + if (m_eLineType == eLineType::ltDouble || m_eLineType == eLineType::ltWavyDouble) + { + if (m_eLineType == eLineType::ltDouble) + { + if (m_dTop < pShape->m_dTop) + { + m_eLineType = eLineType::ltDouble; + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + else + { + pShape->m_eLineType = eLineType::ltDouble; + m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + } + else if (m_eLineType == eLineType::ltWavyDouble) + { + if (m_dTop < pShape->m_dTop) + { + m_eLineType = eLineType::ltWavyDouble; + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + else + { + pShape->m_eLineType = eLineType::ltWavyDouble; + m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + } + return; + } + else if (fabs(m_dTop - pShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && + fabs(m_dWidth - pShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(m_dLeft - pShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) + { + //Условие первого определения + if (m_eSimpleLineType == eSimpleLineType::sltHLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + { + if (m_dTop < pShape->m_dTop) + { + m_eLineType = eLineType::ltDouble; + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + else + { + pShape->m_eLineType = eLineType::ltDouble; + m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + } + else if (m_eSimpleLineType == eSimpleLineType::sltHWave && pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + { + if (m_dTop < pShape->m_dTop) + { + m_eLineType = eLineType::ltWavyDouble; + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + else + { + pShape->m_eLineType = eLineType::ltWavyDouble; + m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + } + return; + } + else if (fabs(m_dTop - pShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) + { + //все должно быть на одной линии + return; + } + + //Теперь считаем, что графика находится на одной линии + if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) + { + //расстояние между объектами на одной линии должно быть небольшим + if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + } + else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) + { + m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + } + return; + } + + if (bIsLast) + { + //note Если имеем всего 2 шейпа в линии, то нужно специально определять тип + if (m_eLineType == eLineType::ltUnknown) + { + switch (m_eSimpleLineType) + { + case eSimpleLineType::sltHDot: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + } + break; + + case eSimpleLineType::sltHDash: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + } + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + } + break; + + case eSimpleLineType::sltHLongDash: + if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + } + else + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + } + break; + + case eSimpleLineType::sltHWave: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + { + m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + } + break; + default: + break; + } + } + + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + return; + } + + bool bIsConditionPassed = false; + + switch (m_eSimpleLineType) + { + case eSimpleLineType::sltHDot: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted || + m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + bIsConditionPassed = true; + } + else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy || + m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && + pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; + m_eSimpleLineType = eSimpleLineType::sltHDot; + bIsConditionPassed = true; + } + } + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + { + if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && + pShape->m_eLineType == eLineType::ltUnknown) + { + m_eSimpleLineType = eSimpleLineType::sltHDash; + bIsConditionPassed = true; + } + else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && + pShape->m_eLineType == eLineType::ltUnknown) + { + m_eSimpleLineType = eSimpleLineType::sltHDash; + bIsConditionPassed = true; + } + } + break; + case eSimpleLineType::sltHDash: + if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + { + if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash || + m_eLineType == eLineType::ltDashedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + bIsConditionPassed = true; + } + else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && + pShape->m_eLineType == eLineType::ltUnknown) + { + bIsConditionPassed = true; + } + } + else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + { + if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash || + m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + m_eSimpleLineType = eSimpleLineType::sltHDot; + bIsConditionPassed = true; + } + else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && + pShape->m_eLineType == eLineType::ltUnknown) + { + m_eSimpleLineType = eSimpleLineType::sltHDot; + bIsConditionPassed = true; + } + } + break; + + case eSimpleLineType::sltHLongDash: + if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7 || + m_eLineType == eLineType::ltThick || m_eLineType == eLineType::ltSingle) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + bIsConditionPassed = true; + } + else if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDashLong || + m_eLineType == eLineType::ltDashLongHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + bIsConditionPassed = true; + } + break; + + case eSimpleLineType::sltHWave: + if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave || + m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) && + pShape->m_eLineType == eLineType::ltUnknown) + { + m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + bIsConditionPassed = true; + } + break; + default: + break; + } + + if (bIsConditionPassed) + { + pShape->m_bIsNotNecessaryToUse = true; + ChangeGeometryOfDesiredShape(pShape); + } + } + + void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) + { + //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст + //todo добавить все возможные параметры/атрибуты + + if (m_bIsNotNecessaryToUse) + { + return; + } + oWriter.WriteString(L""); + + oWriter.WriteString(L""); //отключение проверки орфографии + + oWriter.WriteString(L""); + + BuildGeneralProperties(oWriter); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) + { + oWriter.WriteString(L"(m_bIsBehindDoc)); + oWriter.WriteString(L"\""); + oWriter.WriteString(L" locked=\"0\""); //true/1 Указывает, что местоположение привязки для этого объекта не должно быть изменено во время выполнения, когда приложение редактирует содержимое этого документа. + oWriter.WriteString(L" layoutInCell=\"0\""); //объект будет позиционирован, как указано, но таблица будет изменена в размерах и/или перемещена в документе, как это необходимо для размещения объекта. + oWriter.WriteString(L" allowOverlap=\"1\""); //разрешается перекрывать содержимое другого объекта + oWriter.WriteString(L" hidden=\"0\""); //Определяет, будет ли отображаться данный плавающий объект DrawingML. + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.AddInt(static_cast(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + //координаты конца границы шейпа + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML + + oWriter.WriteString(L""); + + m_nShapeId = GenerateShapeId(); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + BuildSpecificProperties(oWriter); + + oWriter.WriteString(L""); + } + + void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) + { + oWriter.WriteString(L""); + + switch (m_eType) + { + case eShapeType::stPicture: + case eShapeType::stVectorTexture: + BuildPictureProperties(oWriter); + break; + case eShapeType::stCanvas: + BuildCanvasProperties(oWriter); + break; + case eShapeType::stGroup: + BuildGroupProperties(oWriter); + break; + case eShapeType::stTextBox: + case eShapeType::stVectorGraphics: + default: + BuildShapeProperties(oWriter); + break; + } + + oWriter.WriteString(L""); + } + + void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php + + oWriter.WriteString(L""); //shape properties. http://officeopenxml.com/drwSp-SpPr.php + + //не работает + //oWriter.WriteString(L""); //shape styles. http://officeopenxml.com/drwSp-styles.php + + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L""); + + BuildTextBox(oWriter); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) + { + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" name=\"Picture "); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\""); + //oWriter.WriteString(L" descr=\"Alt Text!\""); //Коммент к картинке + oWriter.WriteString(L"/>"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\">"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } + + void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L""); + + //todo довабить любое количество элементов в группе + BuildPictureProperties(oWriter); + BuildShapeProperties(oWriter); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) + { + //todo добавить реализацию + oWriter.WriteString(L""); + } + + void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) + { + //отвечает за размеры прямоугольного фрейма шейпа + oWriter.WriteString(L" 0.01) + { + oWriter.WriteString(L" rot=\""); + oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + //Если просто текст без графики + if (m_strPath.empty()) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + else + { + //Рисуем сложный путь + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(m_strPath); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + if (m_bIsNoFill) + { + //Нет заливки + oWriter.WriteString(L""); + } + else + { + //Есть заливка + oWriter.WriteString(L""); + oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oBrush.Color1))); + if (0xFF != m_oBrush.TextureAlpha) + { + oWriter.WriteString(L"\">(m_oBrush.TextureAlpha / 255.0 * 100.0)); + oWriter.WriteString(L"%\"/>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + oWriter.WriteString(L""); + } + + if (m_bIsNoStroke) + { + oWriter.WriteString(L""); // w - width по умолчанию 0.75pt = 9525 + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L"(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L""); + + oWriter.WriteString(L"(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" + if (0xFF != m_oPen.Alpha) + { + oWriter.WriteString(L"\">(m_oPen.Alpha / 255.0 * 100.0)); + oWriter.WriteString(L"%\"/>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + } + + void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) + { + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); //text within the shape. http://officeopenxml.com/drwSp-text.php + oWriter.WriteString(L""); + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + + switch(pObj->m_eType) + { + case CBaseItem::ElemType::etParagraph: + dynamic_cast(pObj)->ToXml(oWriter); + break; + case CBaseItem::ElemType::etTable: + dynamic_cast(pObj)->ToXml(oWriter); + break; + default: + break; + } + } + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L"1) + oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). + oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. + oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top + oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. + oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. + oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L""); + } + } }; // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index ee887ad4b67..4dd186c6c92 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -6,87 +6,87 @@ namespace NSDocxRenderer { - enum class eGraphicsType - { - gtUnknown, - gtRectangle, - gtCurve, - gtComplicatedFigure, - gtNoGraphics, - }; - - class CShape : public CBaseItem - { - public: - enum class eShapeType - { - stUnknown, - stTextBox, - stPicture, - stVectorGraphics, - stVectorTexture, - stGroup, - stCanvas, - }; - - public: - eShapeType m_eType {eShapeType::stUnknown}; - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - double m_dRotate {0.0}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; - - bool m_bIsUseInTable {false}; - - eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; - eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; - eLineType m_eLineType {eLineType::ltUnknown}; - - std::vector m_arOutputObjects; - - std::shared_ptr m_pImageInfo {nullptr}; - - private: - UINT m_nShapeId {0}; - UINT m_nRelativeHeight {0}; - - static UINT m_gRelativeHeight; - - public: - CShape(); - CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); - virtual ~CShape(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final{}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void GetDataFromVector(const CVectorGraphics& oVector); - void WritePath(const CVectorGraphics& oVector); - void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); - bool IsItFitLine(); - bool IsCorrelated(const CShape* pShape); - void ChangeGeometryOfDesiredShape(CShape* pShape); - - bool IsPeak(); - bool IsSide(); - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - - void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); - - static void ResetRelativeHeight(); - - private: - UINT GenerateShapeId(); - }; + enum class eGraphicsType + { + gtUnknown, + gtRectangle, + gtCurve, + gtComplicatedFigure, + gtNoGraphics, + }; + + class CShape : public CBaseItem + { + public: + enum class eShapeType + { + stUnknown, + stTextBox, + stPicture, + stVectorGraphics, + stVectorTexture, + stGroup, + stCanvas, + }; + + public: + eShapeType m_eType {eShapeType::stUnknown}; + std::wstring m_strPath {L""}; + NSStructures::CBrush m_oBrush; + NSStructures::CPen m_oPen; + double m_dRotate {0.0}; + + bool m_bIsNoFill {true}; + bool m_bIsNoStroke {true}; + bool m_bIsBehindDoc {true}; + + bool m_bIsUseInTable {false}; + + eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; + eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; + eLineType m_eLineType {eLineType::ltUnknown}; + + std::vector m_arOutputObjects; + + std::shared_ptr m_pImageInfo {nullptr}; + + private: + UINT m_nShapeId {0}; + UINT m_nRelativeHeight {0}; + + static UINT m_gRelativeHeight; + + public: + CShape(); + CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); + virtual ~CShape(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final{}; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + + void GetDataFromVector(const CVectorGraphics& oVector); + void WritePath(const CVectorGraphics& oVector); + void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); + bool IsItFitLine(); + bool IsCorrelated(const CShape* pShape); + void ChangeGeometryOfDesiredShape(CShape* pShape); + + bool IsPeak(); + bool IsSide(); + void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); + + void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); + void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); + + static void ResetRelativeHeight(); + + private: + UINT GenerateShapeId(); + }; } diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp index 55ab2c035fd..a43e625148e 100644 --- a/DocxRenderer/src/logic/elements/Table.cpp +++ b/DocxRenderer/src/logic/elements/Table.cpp @@ -2,219 +2,219 @@ namespace NSDocxRenderer { - CRow::CRow() : CBaseItem(ElemType::etTable) - { - } - - CRow::~CRow() - { - Clear(); - } - - void CRow::Clear() - { - m_arCells.clear(); - } - - void CRow::AddContent(CBaseItem* pObj) - { - CBaseItem::AddContent(pObj); - - m_arCells.push_back(dynamic_cast(pObj)); - } - - CTable::CTable() : CBaseItem(ElemType::etTable) - { - - } - - CTable::~CTable() - { - Clear(); - } - - void CTable::Clear() - { - m_arRows.clear(); - } - - void CTable::AddContent(CBaseItem* pObj) - { - CBaseItem::AddContent(pObj); - - m_arRows.push_back(dynamic_cast(pObj)); - } - - void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - if (m_bIsNeedSpacing) - { - oWriter.WriteString(L" 0) - { - oWriter.WriteString(L" w:before=\""); - oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dSpaceAfter > 0) - { - oWriter.WriteString(L" w:after=\""); - oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dLineHeight > 0) - { - oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки - } - oWriter.WriteString(L"/>"); //конец w:spacing - - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"dxa\"/>"); - } - else - { - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\" w:tblpY=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"auto\"/>"); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - for (size_t i = 0; i < m_arColumnWidths.size(); ++i) - { - oWriter.WriteString(L""); - } - oWriter.WriteString(L""); - - for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) - { - auto pRow = m_arRows[nRow]; - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L"m_dHeight * c_dMMToDx); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L""); - - for (size_t j = 0; j < pRow->m_arCells.size(); ++j) - { - pRow->m_arCells[j]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } - - //note: для полной таблицы, составляющей в сумме ячеек прямоугольник - void CTable::CalculateColumnWidth() - { - m_arColumnWidths.clear(); - - if (m_arRows.empty()) - { - return; - } - - //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают - //if (m_arRows.size() == 1) - { - for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) - { - m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); - } - return; - } - - double dMinWidth = 0; - double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы - CCell* pCurrCellWithMinWidth = nullptr; - - //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать - //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы - while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! - { - //находим минимальный width после текущей dCurrLeftBorder - for (size_t i = 0; i < m_arRows.size(); ++i) - { - for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) - { - auto pCell = m_arRows[i]->m_arCells[j]; - - if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) - { - if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) - { - dMinWidth = pCell->m_dRight - dCurrLeftBorder; - pCurrCellWithMinWidth = pCell; - } - break; - } - } - } - - m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); - - //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки - for (size_t i = 0; i < m_arRows.size(); ++i) - { - for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) - { - auto pCell = m_arRows[i]->m_arCells[j]; - - if (dCurrLeftBorder < pCell->m_dRight && - fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && - pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && - fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) - { - ++pCell->m_uGridSpan; - break; - } - } - } - - //сдвигаем dCurrLeftBorder - dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; - } - } + CRow::CRow() : CBaseItem(ElemType::etTable) + { + } + + CRow::~CRow() + { + Clear(); + } + + void CRow::Clear() + { + m_arCells.clear(); + } + + void CRow::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arCells.push_back(dynamic_cast(pObj)); + } + + CTable::CTable() : CBaseItem(ElemType::etTable) + { + + } + + CTable::~CTable() + { + Clear(); + } + + void CTable::Clear() + { + m_arRows.clear(); + } + + void CTable::AddContent(CBaseItem* pObj) + { + CBaseItem::AddContent(pObj); + + m_arRows.push_back(dynamic_cast(pObj)); + } + + void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + if (m_bIsNeedSpacing) + { + oWriter.WriteString(L" 0) + { + oWriter.WriteString(L" w:before=\""); + oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dSpaceAfter > 0) + { + oWriter.WriteString(L" w:after=\""); + oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dLineHeight > 0) + { + oWriter.WriteString(L" w:line=\""); + oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + } + oWriter.WriteString(L"/>"); //конец w:spacing + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"dxa\"/>"); + } + else + { + oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); + oWriter.WriteString(L"\" w:tblpY=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\" w:type=\"auto\"/>"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + for (size_t i = 0; i < m_arColumnWidths.size(); ++i) + { + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + + for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) + { + auto pRow = m_arRows[nRow]; + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"m_dHeight * c_dMMToDx); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + for (size_t j = 0; j < pRow->m_arCells.size(); ++j) + { + pRow->m_arCells[j]->ToXml(oWriter); + } + + oWriter.WriteString(L""); + } + + oWriter.WriteString(L""); + } + + //note: для полной таблицы, составляющей в сумме ячеек прямоугольник + void CTable::CalculateColumnWidth() + { + m_arColumnWidths.clear(); + + if (m_arRows.empty()) + { + return; + } + + //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают + //if (m_arRows.size() == 1) + { + for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) + { + m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); + } + return; + } + + double dMinWidth = 0; + double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы + CCell* pCurrCellWithMinWidth = nullptr; + + //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать + //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы + while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! + { + //находим минимальный width после текущей dCurrLeftBorder + for (size_t i = 0; i < m_arRows.size(); ++i) + { + for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) + { + auto pCell = m_arRows[i]->m_arCells[j]; + + if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) + { + if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) + { + dMinWidth = pCell->m_dRight - dCurrLeftBorder; + pCurrCellWithMinWidth = pCell; + } + break; + } + } + } + + m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); + + //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки + for (size_t i = 0; i < m_arRows.size(); ++i) + { + for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) + { + auto pCell = m_arRows[i]->m_arCells[j]; + + if (dCurrLeftBorder < pCell->m_dRight && + fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && + pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && + fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) + { + ++pCell->m_uGridSpan; + break; + } + } + } + + //сдвигаем dCurrLeftBorder + dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; + } + } } diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h index 1c7819e8c49..d660274e6f8 100644 --- a/DocxRenderer/src/logic/elements/Table.h +++ b/DocxRenderer/src/logic/elements/Table.h @@ -3,41 +3,41 @@ namespace NSDocxRenderer { - class CRow : public CBaseItem - { - public: - std::vector m_arCells; + class CRow : public CBaseItem + { + public: + std::vector m_arCells; - public: - CRow(); - virtual ~CRow(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final {} - }; + public: + CRow(); + virtual ~CRow(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final {} + }; - class CTable : public CBaseItem - { - public: - std::vector m_arColumnWidths; //общее количество колонок в таблице - std::vector m_arRows; + class CTable : public CBaseItem + { + public: + std::vector m_arColumnWidths; //общее количество колонок в таблице + std::vector m_arRows; - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dLineHeight {0.0}; - bool m_bIsNeedSpacing {false}; + double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dLineHeight {0.0}; + bool m_bIsNeedSpacing {false}; - public: - CTable(); - virtual ~CTable(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + public: + CTable(); + virtual ~CTable(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - double CalculateBeforeSpacing(double dPreviousStringBaseline) - { - return m_dTop - dPreviousStringBaseline; - } - void CalculateColumnWidth(); - }; + double CalculateBeforeSpacing(double dPreviousStringBaseline) + { + return m_dTop - dPreviousStringBaseline; + } + void CalculateColumnWidth(); + }; } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 9a153478e16..6a98a7c8123 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -5,192 +5,192 @@ namespace NSDocxRenderer { - CTextLine::CTextLine() : CBaseItem(ElemType::etTextLine) - { - } - - void CTextLine::Clear() - { - m_arConts.clear(); - } - - CTextLine::~CTextLine() - { - Clear(); - } - - void CTextLine::AddContent(CBaseItem *pObj) - { - CBaseItem::AddContent(pObj); - - if (dynamic_cast(pObj)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) - { - m_eVertAlignType = dynamic_cast(pObj)->m_eVertAlignType; - } - - m_arConts.push_back(dynamic_cast(pObj)); - } - - void CTextLine::CheckLineToNecessaryToUse() - { - for (size_t i = 0; i < m_arConts.size(); ++i) - { - if (!m_arConts[i]->m_bIsNotNecessaryToUse) - { - return; - } - } - m_bIsNotNecessaryToUse = true; - } - - void CTextLine::MergeConts() - { - if (m_arConts.empty()) - return; - - auto pFirst = m_arConts.front(); - - for (size_t i = 1; i < m_arConts.size(); ++i) - { - auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { - continue; - } - - //todo возможно стоит доработать логику - bool bIsEqual = pFirst->IsEqual(pCurrent); - bool bIsBigDelta = ((pFirst->m_dRight < pCurrent->m_dLeft) && ((pCurrent->m_dLeft - pFirst->m_dRight) < pCurrent->m_dSpaceWidthMM)) || - fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace(); - bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); - - if (bIsVeryBigDelta) - { - pFirst->m_bSpaceIsNotNeeded = false; - pFirst = pCurrent; - - } - else if (bIsEqual) - { - if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) - { - pFirst->m_oText += pCurrent->m_oText; - } - else if (bIsBigDelta) - { - pFirst->m_oText += uint32_t(' '); - pFirst->m_oText += pCurrent->m_oText; - } - - pFirst->m_dWidth = pCurrent->m_dRight - pFirst->m_dLeft; - pFirst->m_dRight = pCurrent->m_dRight; - - if (!pFirst->m_pCont) - { - pFirst->m_pCont = pCurrent->m_pCont; - pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; - } - - pFirst->m_bSpaceIsNotNeeded = true; - pCurrent->m_bIsNotNecessaryToUse = true; - } - else - { - if (bIsBigDelta) - { - if (!IsSpaceUtf32(pFirst->m_oText[pFirst->m_oText.length()-1]) && - !IsSpaceUtf32(pCurrent->m_oText[0])) - { - if (pFirst->GetNumberOfFeatures() <= pCurrent->GetNumberOfFeatures()) - { - pFirst->m_oText += L" "; - pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; - } - else - { - NSStringUtils::CStringUTF32 oNewText = L" "; - oNewText += pCurrent->m_oText; - pCurrent->m_oText = oNewText; - pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM; - } - } - - pFirst->m_bSpaceIsNotNeeded = true; - } - else - { - pFirst->m_bSpaceIsNotNeeded = false; - } - pFirst = pCurrent; - } - } - } - - void CTextLine::SetVertAlignType(const eVertAlignType& oType) - { - m_eVertAlignType = oType; - for (size_t i = 0; i < m_arConts.size(); ++i) - { - m_arConts[i]->m_eVertAlignType = oType; - } - } - - bool CTextLine::IsShadingPresent(const CTextLine *pLine) - { - if (m_pDominantShape && pLine->m_pDominantShape && - m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && - fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - return true; - } - - return false; - } - - void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - size_t nCountConts = m_arConts.size(); - - if (0 == nCountConts) - return; - - auto pPrev = m_arConts[0]; - double dDelta = 0; - - for (size_t i = 1; i < nCountConts; ++i) - { - auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { - continue; - } - - dDelta = pCurrent->m_dLeft - pPrev->m_dRight; - - if (dDelta < pPrev->CalculateWideSpace() || - pPrev->m_bSpaceIsNotNeeded) - { - // просто текст на тексте или сменились настройки (font/brush) - pPrev->ToXml(oWriter); - pPrev = pCurrent; - } - else - { - // расстояние слишком большое. нужно сделать большой пробел - pPrev->ToXml(oWriter); - pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); - pPrev = pCurrent; - } - } - - pPrev->ToXml(oWriter); - } + CTextLine::CTextLine() : CBaseItem(ElemType::etTextLine) + { + } + + void CTextLine::Clear() + { + m_arConts.clear(); + } + + CTextLine::~CTextLine() + { + Clear(); + } + + void CTextLine::AddContent(CBaseItem *pObj) + { + CBaseItem::AddContent(pObj); + + if (dynamic_cast(pObj)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) + { + m_eVertAlignType = dynamic_cast(pObj)->m_eVertAlignType; + } + + m_arConts.push_back(dynamic_cast(pObj)); + } + + void CTextLine::CheckLineToNecessaryToUse() + { + for (size_t i = 0; i < m_arConts.size(); ++i) + { + if (!m_arConts[i]->m_bIsNotNecessaryToUse) + { + return; + } + } + m_bIsNotNecessaryToUse = true; + } + + void CTextLine::MergeConts() + { + if (m_arConts.empty()) + return; + + auto pFirst = m_arConts.front(); + + for (size_t i = 1; i < m_arConts.size(); ++i) + { + auto pCurrent = m_arConts[i]; + + if (pCurrent->m_bIsNotNecessaryToUse) + { + continue; + } + + //todo возможно стоит доработать логику + bool bIsEqual = pFirst->IsEqual(pCurrent); + bool bIsBigDelta = ((pFirst->m_dRight < pCurrent->m_dLeft) && ((pCurrent->m_dLeft - pFirst->m_dRight) < pCurrent->m_dSpaceWidthMM)) || + fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace(); + bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); + + if (bIsVeryBigDelta) + { + pFirst->m_bSpaceIsNotNeeded = false; + pFirst = pCurrent; + + } + else if (bIsEqual) + { + if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) + { + pFirst->m_oText += pCurrent->m_oText; + } + else if (bIsBigDelta) + { + pFirst->m_oText += uint32_t(' '); + pFirst->m_oText += pCurrent->m_oText; + } + + pFirst->m_dWidth = pCurrent->m_dRight - pFirst->m_dLeft; + pFirst->m_dRight = pCurrent->m_dRight; + + if (!pFirst->m_pCont) + { + pFirst->m_pCont = pCurrent->m_pCont; + pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; + } + + pFirst->m_bSpaceIsNotNeeded = true; + pCurrent->m_bIsNotNecessaryToUse = true; + } + else + { + if (bIsBigDelta) + { + if (!IsSpaceUtf32(pFirst->m_oText[pFirst->m_oText.length()-1]) && + !IsSpaceUtf32(pCurrent->m_oText[0])) + { + if (pFirst->GetNumberOfFeatures() <= pCurrent->GetNumberOfFeatures()) + { + pFirst->m_oText += L" "; + pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; + } + else + { + NSStringUtils::CStringUTF32 oNewText = L" "; + oNewText += pCurrent->m_oText; + pCurrent->m_oText = oNewText; + pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM; + } + } + + pFirst->m_bSpaceIsNotNeeded = true; + } + else + { + pFirst->m_bSpaceIsNotNeeded = false; + } + pFirst = pCurrent; + } + } + } + + void CTextLine::SetVertAlignType(const eVertAlignType& oType) + { + m_eVertAlignType = oType; + for (size_t i = 0; i < m_arConts.size(); ++i) + { + m_arConts[i]->m_eVertAlignType = oType; + } + } + + bool CTextLine::IsShadingPresent(const CTextLine *pLine) + { + if (m_pDominantShape && pLine->m_pDominantShape && + m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && + fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) + { + return true; + } + + return false; + } + + void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + size_t nCountConts = m_arConts.size(); + + if (0 == nCountConts) + return; + + auto pPrev = m_arConts[0]; + double dDelta = 0; + + for (size_t i = 1; i < nCountConts; ++i) + { + auto pCurrent = m_arConts[i]; + + if (pCurrent->m_bIsNotNecessaryToUse) + { + continue; + } + + dDelta = pCurrent->m_dLeft - pPrev->m_dRight; + + if (dDelta < pPrev->CalculateWideSpace() || + pPrev->m_bSpaceIsNotNeeded) + { + // просто текст на тексте или сменились настройки (font/brush) + pPrev->ToXml(oWriter); + pPrev = pCurrent; + } + else + { + // расстояние слишком большое. нужно сделать большой пробел + pPrev->ToXml(oWriter); + pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); + pPrev = pCurrent; + } + } + + pPrev->ToXml(oWriter); + } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index dd70a3c29b2..471981ce55f 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -3,39 +3,39 @@ namespace NSDocxRenderer { - class CTextLine : public CBaseItem - { - public: - enum AssumedTextAlignmentType - { - atatUnknown, - atatByLeftEdge, - atatByCenter, - atatByRightEdge, - atatByWidth - }; - - std::vector m_arConts; - - AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - - CShape* m_pDominantShape {nullptr}; - - UINT m_iNumDuplicates {0}; - public: - CTextLine(); - virtual ~CTextLine(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void CheckLineToNecessaryToUse(); - void MergeConts(); - void SetVertAlignType(const eVertAlignType& oType); - bool IsShadingPresent(const CTextLine* pLine); - }; + class CTextLine : public CBaseItem + { + public: + enum AssumedTextAlignmentType + { + atatUnknown, + atatByLeftEdge, + atatByCenter, + atatByRightEdge, + atatByWidth + }; + + std::vector m_arConts; + + AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; + + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + + CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + + CShape* m_pDominantShape {nullptr}; + + UINT m_iNumDuplicates {0}; + public: + CTextLine(); + virtual ~CTextLine(); + virtual void Clear() override final; + virtual void AddContent(CBaseItem* pObj) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + + void CheckLineToNecessaryToUse(); + void MergeConts(); + void SetVertAlignType(const eVertAlignType& oType); + bool IsShadingPresent(const CTextLine* pLine); + }; } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 5a8fcff0e8b..508bb753a2f 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -3,42 +3,42 @@ namespace NSDocxRenderer { - CFontTableEntry::CFontTableEntry(const CFontTableEntry& oSrc) - { - *this = oSrc; - } - - CFontTableEntry& CFontTableEntry::operator =(const CFontTableEntry& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - - return *this; - } - - CFontManager::CFontManager(NSFonts::IApplicationFonts* pFonts) : CFontManagerBase(pFonts) - { - } - - void CFontManager::Init() - { - m_oFontTable.m_mapTable.clear(); - ClearPickUps(); - } - - void CFontManager::AddFontToMap() - { + CFontTableEntry::CFontTableEntry(const CFontTableEntry& oSrc) + { + *this = oSrc; + } + + CFontTableEntry& CFontTableEntry::operator =(const CFontTableEntry& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_strFamilyName = oSrc.m_strFamilyName; + m_strPANOSE = oSrc.m_strPANOSE; + m_lStyle = oSrc.m_lStyle; + m_arSignature = oSrc.m_arSignature; + m_bIsFixedWidth = oSrc.m_bIsFixedWidth; + + return *this; + } + + CFontManager::CFontManager(NSFonts::IApplicationFonts* pFonts) : CFontManagerBase(pFonts) + { + } + + void CFontManager::Init() + { + m_oFontTable.m_mapTable.clear(); + ClearPickUps(); + } + + void CFontManager::AddFontToMap() + { if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_oFontAdvanced.m_strFamilyName)) - { - CFontTableEntry oEntry; + { + CFontTableEntry oEntry; oEntry.m_strFamilyName = m_oFontAdvanced.m_strFamilyName; oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; @@ -46,213 +46,213 @@ namespace NSDocxRenderer oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); - } - } + } + } - void CFontManager::LoadFont(long lFaceIndex, bool bNeedAddToMap) - { - if (nullptr == m_pManager) - return; + void CFontManager::LoadFont(long lFaceIndex, bool bNeedAddToMap) + { + if (nullptr == m_pManager) + return; - double dSize = m_pFont->Size; - double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); + double dSize = m_pFont->Size; + double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); - double dPix = m_pFont->CharSpace / c_dPixToMM; + double dPix = m_pFont->CharSpace / c_dPixToMM; - m_pFont->Size = dSizeFont; + m_pFont->Size = dSizeFont; if (m_pFont->IsEqual2(&m_oFontAdvanced.m_oFont)) - { - m_pFont->Size = dSize; - m_pManager->SetCharSpacing(dPix); - return; - } + { + m_pFont->Size = dSize; + m_pManager->SetCharSpacing(dPix); + return; + } m_oFontAdvanced.m_oFont = *m_pFont; - m_pFont->Size = dSize; + m_pFont->Size = dSize; - if (m_pFont->Path.empty()) - { + if (m_pFont->Path.empty()) + { CFontManagerBase::LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); - } - else - { + } + else + { CFontManagerBase::LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex); m_pFont->SetStyle(m_oFontAdvanced.m_lStyle); m_oFontAdvanced.m_oFont.SetStyle(m_oFontAdvanced.m_lStyle); - } - - int bIsGID = m_pManager->GetStringGID(); - m_pManager->SetStringGID(FALSE); - - m_pManager->LoadString2(L" ", 0, 0); - TBBox bbox = m_pManager->MeasureString2(); - - m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - if (0 >= m_dSpaceWidthMM) - { - m_dSpaceWidthMM = 1.0; - } - - m_pManager->SetStringGID(bIsGID); - - if (bNeedAddToMap) - AddFontToMap(); - } - - void CFontManager::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - LoadFont(); - - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (nullptr == m_pManager) - return; - - m_pManager->LoadString1(sText, (float)x, (float)y); - - TBBox bbox; - if (mtGlyph == measureType) - { - bbox = m_pManager->MeasureString(); - } - else if (mtPosition == measureType) - { - bbox = m_pManager->MeasureString2(); - } - - dBoxX = (double)bbox.fMinX; - dBoxY = (double)bbox.fMinY; - dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); - dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - } - - void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) - { - LoadFont(); - - dBoxX = 0; - dBoxY = 0; - dBoxWidth = 0; - dBoxHeight = 0; - - if (nullptr == m_pManager) - return; - - m_pManager->LoadString1(pGids, count, (float)x, (float)y); - - TBBox bbox; - if (mtGlyph == measureType) - { - bbox = m_pManager->MeasureString(); - } - else if (mtPosition == measureType) - { - bbox = m_pManager->MeasureString2(); - } - - dBoxX = (double)bbox.fMinX; - dBoxY = (double)bbox.fMinY; - dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); - dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); - - // переводим в миллиметры - dBoxX *= c_dPixToMM; - dBoxY *= c_dPixToMM; - dBoxWidth *= c_dPixToMM; - dBoxHeight *= c_dPixToMM; - } - - double CFontManager::GetBaseLineOffset() - { - LoadFont(); + } + + int bIsGID = m_pManager->GetStringGID(); + m_pManager->SetStringGID(FALSE); + + m_pManager->LoadString2(L" ", 0, 0); + TBBox bbox = m_pManager->MeasureString2(); + + m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + if (0 >= m_dSpaceWidthMM) + { + m_dSpaceWidthMM = 1.0; + } + + m_pManager->SetStringGID(bIsGID); + + if (bNeedAddToMap) + AddFontToMap(); + } + + void CFontManager::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) + { + LoadFont(); + + dBoxX = 0; + dBoxY = 0; + dBoxWidth = 0; + dBoxHeight = 0; + + if (nullptr == m_pManager) + return; + + m_pManager->LoadString1(sText, (float)x, (float)y); + + TBBox bbox; + if (mtGlyph == measureType) + { + bbox = m_pManager->MeasureString(); + } + else if (mtPosition == measureType) + { + bbox = m_pManager->MeasureString2(); + } + + dBoxX = (double)bbox.fMinX; + dBoxY = (double)bbox.fMinY; + dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); + dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); + + // переводим в миллиметры + dBoxX *= c_dPixToMM; + dBoxY *= c_dPixToMM; + dBoxWidth *= c_dPixToMM; + dBoxHeight *= c_dPixToMM; + } + + void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) + { + LoadFont(); + + dBoxX = 0; + dBoxY = 0; + dBoxWidth = 0; + dBoxHeight = 0; + + if (nullptr == m_pManager) + return; + + m_pManager->LoadString1(pGids, count, (float)x, (float)y); + + TBBox bbox; + if (mtGlyph == measureType) + { + bbox = m_pManager->MeasureString(); + } + else if (mtPosition == measureType) + { + bbox = m_pManager->MeasureString2(); + } + + dBoxX = (double)bbox.fMinX; + dBoxY = (double)bbox.fMinY; + dBoxWidth = (double)(bbox.fMaxX - bbox.fMinX); + dBoxHeight = (double)(bbox.fMaxY - bbox.fMinY); + + // переводим в миллиметры + dBoxX *= c_dPixToMM; + dBoxY *= c_dPixToMM; + dBoxWidth *= c_dPixToMM; + dBoxHeight *= c_dPixToMM; + } + + double CFontManager::GetBaseLineOffset() + { + LoadFont(); double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; - d1 /= 2.0; + d1 /= 2.0; d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - return d1; - } + return d1; + } - double CFontManager::GetFontHeight() - { + double CFontManager::GetFontHeight() + { return c_dPtToMM * (m_oFontAdvanced.m_dLineSpacing * m_oFontAdvanced.m_oFont.Size ) / m_oFontAdvanced.m_dEmHeight; - } - - void CFontManager::SetStringGid(const LONG& lGid) - { - if (nullptr != m_pManager) - m_pManager->SetStringGID(lGid); - } - - void CFontManager::GenerateFontName2(NSStringUtils::CStringUTF32& oText) - { - bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText); - - if (bIsNeedAddToMap) - { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_strCurrentPickFont)) - { - CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_strCurrentPickFont; + } + + void CFontManager::SetStringGid(const LONG& lGid) + { + if (nullptr != m_pManager) + m_pManager->SetStringGID(lGid); + } + + void CFontManager::GenerateFontName2(NSStringUtils::CStringUTF32& oText) + { + bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText); + + if (bIsNeedAddToMap) + { + if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_strCurrentPickFont)) + { + CFontTableEntry oEntry; + oEntry.m_strFamilyName = m_strCurrentPickFont; oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; oEntry.m_bIsFixedWidth = m_oFontAdvanced.m_bIsFixedWidth; oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); - } - } - } - - CFontManagerLight::CFontManagerLight(NSFonts::IApplicationFonts* pFonts) - { - m_pManager = NSFontManager::CreateFontManager(pFonts); - } - - CFontManagerLight::~CFontManagerLight() - { - RELEASEINTERFACE(m_pManager); - } - - double CFontManagerLight::GetSpaceWidth() - { - return m_dSpaceWidth; - } - - void CFontManagerLight::LoadFont(std::wstring& strFontName, LONG& lStyle, const double& dSize, const bool& bIsGID) - { - if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize)) - { - m_pManager->SetStringGID(bIsGID); - return; - } - - m_strFontName = strFontName; - m_lFontStyle = lStyle; - m_dSize = dSize; - - m_pManager->LoadFontByName(strFontName, m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY); - m_dSpaceWidth = MeasureStringWidth(L" "); - - m_pManager->SetStringGID(bIsGID); - } - - double CFontManagerLight::MeasureStringWidth(const std::wstring& sText) - { - m_pManager->LoadString2(sText, (float)0, (float)0); - TBBox bbox = m_pManager->MeasureString2(); - - return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - } + } + } + } + + CFontManagerLight::CFontManagerLight(NSFonts::IApplicationFonts* pFonts) + { + m_pManager = NSFontManager::CreateFontManager(pFonts); + } + + CFontManagerLight::~CFontManagerLight() + { + RELEASEINTERFACE(m_pManager); + } + + double CFontManagerLight::GetSpaceWidth() + { + return m_dSpaceWidth; + } + + void CFontManagerLight::LoadFont(std::wstring& strFontName, LONG& lStyle, const double& dSize, const bool& bIsGID) + { + if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize)) + { + m_pManager->SetStringGID(bIsGID); + return; + } + + m_strFontName = strFontName; + m_lFontStyle = lStyle; + m_dSize = dSize; + + m_pManager->LoadFontByName(strFontName, m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY); + m_dSpaceWidth = MeasureStringWidth(L" "); + + m_pManager->SetStringGID(bIsGID); + } + + double CFontManagerLight::MeasureStringWidth(const std::wstring& sText) + { + m_pManager->LoadString2(sText, (float)0, (float)0); + TBBox bbox = m_pManager->MeasureString2(); + + return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + } } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 322375ad665..43f3fa3d412 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -4,93 +4,93 @@ namespace NSDocxRenderer { - using namespace NSFontManager; + using namespace NSFontManager; - class CFontTableEntry - { - public: - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; + class CFontTableEntry + { + public: + std::wstring m_strFamilyName {L""}; + std::wstring m_strPANOSE {L""}; + LONG m_lStyle {0}; + std::vector m_arSignature; + bool m_bIsFixedWidth {false}; - public: - CFontTableEntry(){} - virtual ~CFontTableEntry(){} + public: + CFontTableEntry(){} + virtual ~CFontTableEntry(){} - CFontTableEntry(const CFontTableEntry& oSrc); + CFontTableEntry(const CFontTableEntry& oSrc); - CFontTableEntry& operator =(const CFontTableEntry& oSrc); - }; + CFontTableEntry& operator =(const CFontTableEntry& oSrc); + }; - class CFontTable - { - public: - std::map m_mapTable; + class CFontTable + { + public: + std::map m_mapTable; - public: - CFontTable() : m_mapTable(){} - }; + public: + CFontTable() : m_mapTable(){} + }; - class CFontManager : public CFontManagerBase - { - public: - NSStructures::CFont* m_pFont {nullptr}; - Aggplus::CMatrix* m_pTransform {nullptr}; - double m_dSpaceWidthMM {0.0}; + class CFontManager : public CFontManagerBase + { + public: + NSStructures::CFont* m_pFont {nullptr}; + Aggplus::CMatrix* m_pTransform {nullptr}; + double m_dSpaceWidthMM {0.0}; - public: - CFontTable m_oFontTable; + public: + CFontTable m_oFontTable; - public: - CFontManager(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManager(){} + public: + CFontManager(NSFonts::IApplicationFonts* pFonts); + virtual ~CFontManager(){} - public: - void Init(); + public: + void Init(); - void AddFontToMap(); + void AddFontToMap(); - public: - virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true); + public: + virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true); - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType); + virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, + double& dBoxWidth, double& dBoxHeight, MeasureType measureType); - void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, - double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); + void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, + double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); - double GetBaseLineOffset(); + double GetBaseLineOffset(); - double GetFontHeight(); + double GetFontHeight(); - void SetStringGid(const LONG& lGid); + void SetStringGid(const LONG& lGid); - void GenerateFontName2(NSStringUtils::CStringUTF32& oText); - }; + void GenerateFontName2(NSStringUtils::CStringUTF32& oText); + }; - class CFontManagerLight - { - private: - std::wstring m_strFontName {L""}; - LONG m_lFontStyle {0}; - double m_dSize {0.0}; + class CFontManagerLight + { + private: + std::wstring m_strFontName {L""}; + LONG m_lFontStyle {0}; + double m_dSize {0.0}; - double m_dSpaceWidth {0.0}; + double m_dSpaceWidth {0.0}; - NSFonts::IFontManager* m_pManager {nullptr}; + NSFonts::IFontManager* m_pManager {nullptr}; - public: - CFontManagerLight(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerLight(); + public: + CFontManagerLight(NSFonts::IApplicationFonts* pFonts); + virtual ~CFontManagerLight(); - double GetSpaceWidth(); + double GetSpaceWidth(); - public: - void LoadFont(std::wstring& strFontName, LONG& lStyle, const double &dSize, const bool& bIsGID); + public: + void LoadFont(std::wstring& strFontName, LONG& lStyle, const double &dSize, const bool& bIsGID); - double MeasureStringWidth(const std::wstring& sText); - }; + double MeasureStringWidth(const std::wstring& sText); + }; } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp index ee89f1db8d5..d23b8ff7949 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ b/DocxRenderer/src/logic/managers/FontManagerBase.cpp @@ -5,546 +5,546 @@ namespace NSFontManager { - CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, - const BYTE& _range, const BYTE& _rangenum): - RangeNum(_rangenum), Range(_range), Start(_start), End(_end) - { - } - - CUnicodeRanges::CUnicodeRanges() - { - // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur - - m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin - m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement - m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A - m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B - m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions - m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement - m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters - m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters - m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks - m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement - m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic - m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic - m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic - m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement - m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A - m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B - m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian - m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew - m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai - m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic - m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement - m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo - m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari - m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali - m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi - m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati - m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya - m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil - m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu - m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada - m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam - m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai - m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao - m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian - m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement - m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese - m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo - m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional - m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C - m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D - m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended - m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation - m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation - - m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts - m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols - m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols - m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols - m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms - m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows - m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A - m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B - m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows - m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A - m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B - m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical - m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures - m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition - m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics - m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing - m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements - m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes - m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols - m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats - m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation - m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana - m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana - m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo - m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended - m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo - m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa - m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months - m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility - m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables - m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 - m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician - m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs - m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement - m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals - m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters - m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A - m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun - m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B - m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) - m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes - m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs - m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement - m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms - m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A - - m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks - m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms - m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms - m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants - m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B - m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms - m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials - m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan - m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac - m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana - m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala - m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar - m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic - m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement - m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended - m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee - m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics - m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham - m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic - m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer - m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols - m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian - m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns - m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables - m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals - m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog - m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo - m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid - m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa - m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic - m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic - m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret - m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation - m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols - m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) - m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) - m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors - m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement - m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags - m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu - m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le - m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue - - m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese - m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic - m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh - m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols - m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri - m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary - m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms - m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers - m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers - m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic - m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian - m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian - m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya - m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary - m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi - m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols - m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform - m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation - m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals - m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese - m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha - m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki - m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra - m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li - m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang - m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham - m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols - m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc - m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian - m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian - m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian - m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles - m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles - // 27: "Reserved for process-internal usage" - // 28: "Reserved for process-internal usage" - // 29: "Reserved for process-internal usage" - // 30: "Reserved for process-internal usage" - // 31: "Reserved for process-internal usage" - } - - void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) - { - // определяем range и двигаем его в начало. - std::list::iterator iter = m_arRanges.begin(); - while (iter != m_arRanges.end()) - { - CUnicodeRange& range = *iter; - if (symbol >= range.Start && symbol <= range.End) - { - Range = range.Range; - RangeNum = range.RangeNum; - - m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); - return; - } - iter++; - } - } - - void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) - { - BYTE nRange = 0xFF; - BYTE nRangeNum = 0xFF; - CheckRange(symbol, nRange, nRangeNum); - - switch (nRangeNum) - { - case 0: Range1 |= (1 << nRange); break; - case 1: Range2 |= (1 << nRange); break; - case 2: Range3 |= (1 << nRange); break; - case 3: Range4 |= (1 << nRange); break; - default: - break; - } - } - - CFontAdvanced::CFontAdvanced() - { - m_oFont.SetDefaultParams(); - m_arSignature.clear(); - } - - CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) - { - *this = oSrc; - } - - CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - - m_dAscent = oSrc.m_dAscent; - m_dDescent = oSrc.m_dDescent; - m_dLineSpacing = oSrc.m_dLineSpacing; - m_dEmHeight = oSrc.m_dEmHeight; - - m_dBaselineOffset = oSrc.m_dBaselineOffset; - - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - m_lAvgWidth = oSrc.m_lAvgWidth; - - return *this; - } - - CFontPickUp::CFontPickUp() : m_oFont() - { - } - - CFontPickUp::CFontPickUp(const CFontPickUp& oSrc) - { - *this = oSrc; - } - - CFontPickUp& CFontPickUp::operator=(const CFontPickUp& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - m_lRange = oSrc.m_lRange; - m_lRangeNum = oSrc.m_lRangeNum; - m_strPickFont = oSrc.m_strPickFont; - m_lPickStyle = oSrc.m_lPickStyle; - - return *this; - } - - CFontManagerBase::CFontManagerBase(NSFonts::IApplicationFonts* pFonts) - { - m_pManager = NSFontManager::CreateFontManager(pFonts); - - SetDefaultFont(L"Arial"); - - ClearPickUps(); - } - - CFontManagerBase::~CFontManagerBase() - { - RELEASEINTERFACE(m_pManager); - } - - void CFontManagerBase::ClearPickUps() - { - m_arListPicUps.clear(); - m_strCurrentPickFont = L""; - m_lCurrentPictFontStyle = 0; - } - - void CFontManagerBase::SetDefaultFont(const std::wstring& strName) - { - m_strDefaultFont = strName; - } - - std::wstring CFontManagerBase::GetDefaultFont() - { - return m_strDefaultFont; - } - - void CFontManagerBase::LoadFont(long lFaceIndex, bool bIsNeedAddToMap) - { - } - - void CFontManagerBase::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) - { - m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); - m_pManager->AfterLoad(); - - LoadFontMetrics(); - LoadFontParams(); + CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, + const BYTE& _range, const BYTE& _rangenum): + RangeNum(_rangenum), Range(_range), Start(_start), End(_end) + { + } + + CUnicodeRanges::CUnicodeRanges() + { + // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur + + m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin + m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement + m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A + m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B + m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions + m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement + m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters + m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters + m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks + m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement + m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic + m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic + m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic + m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement + m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A + m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B + m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian + m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew + m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai + m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic + m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement + m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo + m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari + m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali + m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi + m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati + m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya + m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil + m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu + m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada + m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam + m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai + m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao + m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian + m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement + m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese + m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo + m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional + m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C + m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D + m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended + m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation + m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation + + m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts + m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols + m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols + m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols + m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms + m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows + m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A + m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B + m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows + m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A + m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B + m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical + m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures + m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition + m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics + m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing + m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements + m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes + m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols + m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats + m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation + m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana + m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana + m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo + m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended + m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo + m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa + m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months + m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility + m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables + m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 + m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician + m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs + m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement + m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals + m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters + m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A + m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun + m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B + m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) + m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes + m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs + m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement + m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms + m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A + + m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks + m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms + m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms + m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants + m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B + m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms + m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials + m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan + m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac + m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana + m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala + m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar + m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic + m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement + m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended + m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee + m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics + m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham + m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic + m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer + m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols + m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian + m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns + m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables + m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals + m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog + m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo + m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid + m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa + m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic + m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic + m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret + m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation + m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols + m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) + m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) + m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors + m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement + m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags + m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu + m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le + m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue + + m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese + m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic + m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh + m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols + m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri + m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary + m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms + m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers + m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers + m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic + m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian + m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian + m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya + m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary + m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi + m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols + m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform + m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation + m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals + m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese + m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha + m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki + m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra + m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li + m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang + m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham + m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols + m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc + m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian + m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian + m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian + m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles + m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles + // 27: "Reserved for process-internal usage" + // 28: "Reserved for process-internal usage" + // 29: "Reserved for process-internal usage" + // 30: "Reserved for process-internal usage" + // 31: "Reserved for process-internal usage" + } + + void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) + { + // определяем range и двигаем его в начало. + std::list::iterator iter = m_arRanges.begin(); + while (iter != m_arRanges.end()) + { + CUnicodeRange& range = *iter; + if (symbol >= range.Start && symbol <= range.End) + { + Range = range.Range; + RangeNum = range.RangeNum; + + m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); + return; + } + iter++; + } + } + + void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) + { + BYTE nRange = 0xFF; + BYTE nRangeNum = 0xFF; + CheckRange(symbol, nRange, nRangeNum); + + switch (nRangeNum) + { + case 0: Range1 |= (1 << nRange); break; + case 1: Range2 |= (1 << nRange); break; + case 2: Range3 |= (1 << nRange); break; + case 3: Range4 |= (1 << nRange); break; + default: + break; + } + } + + CFontAdvanced::CFontAdvanced() + { + m_oFont.SetDefaultParams(); + m_arSignature.clear(); + } + + CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) + { + *this = oSrc; + } + + CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_oFont = oSrc.m_oFont; + + m_dAscent = oSrc.m_dAscent; + m_dDescent = oSrc.m_dDescent; + m_dLineSpacing = oSrc.m_dLineSpacing; + m_dEmHeight = oSrc.m_dEmHeight; + + m_dBaselineOffset = oSrc.m_dBaselineOffset; + + m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; + + m_strFamilyName = oSrc.m_strFamilyName; + m_strPANOSE = oSrc.m_strPANOSE; + m_lStyle = oSrc.m_lStyle; + m_arSignature = oSrc.m_arSignature; + m_bIsFixedWidth = oSrc.m_bIsFixedWidth; + m_lAvgWidth = oSrc.m_lAvgWidth; + + return *this; + } + + CFontPickUp::CFontPickUp() : m_oFont() + { + } + + CFontPickUp::CFontPickUp(const CFontPickUp& oSrc) + { + *this = oSrc; + } + + CFontPickUp& CFontPickUp::operator=(const CFontPickUp& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_oFont = oSrc.m_oFont; + m_lRange = oSrc.m_lRange; + m_lRangeNum = oSrc.m_lRangeNum; + m_strPickFont = oSrc.m_strPickFont; + m_lPickStyle = oSrc.m_lPickStyle; + + return *this; + } + + CFontManagerBase::CFontManagerBase(NSFonts::IApplicationFonts* pFonts) + { + m_pManager = NSFontManager::CreateFontManager(pFonts); + + SetDefaultFont(L"Arial"); + + ClearPickUps(); + } + + CFontManagerBase::~CFontManagerBase() + { + RELEASEINTERFACE(m_pManager); + } + + void CFontManagerBase::ClearPickUps() + { + m_arListPicUps.clear(); + m_strCurrentPickFont = L""; + m_lCurrentPictFontStyle = 0; + } + + void CFontManagerBase::SetDefaultFont(const std::wstring& strName) + { + m_strDefaultFont = strName; + } + + std::wstring CFontManagerBase::GetDefaultFont() + { + return m_strDefaultFont; + } + + void CFontManagerBase::LoadFont(long lFaceIndex, bool bIsNeedAddToMap) + { + } + + void CFontManagerBase::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) + { + m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontParams(); m_oFontAdvanced.m_lAvgWidth = -1; - } + } - void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); - m_pManager->AfterLoad(); + void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) + { + m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); + m_pManager->AfterLoad(); - LoadFontMetrics(); - LoadFontParams(); + LoadFontMetrics(); + LoadFontParams(); m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; m_oFontAdvanced.m_lAvgWidth = -1; - bool bIsCID = false; - std::wstring sFileExt = NSFile::GetFileExtention(strPath); - if (std::wstring::npos != sFileExt.find(L"cid")) - bIsCID = true; - - std::wstring sFileName = NSFile::GetFileName(strPath); - std::wstring::size_type pos = sFileName.rfind('.'); - if (std::wstring::npos != pos) - sFileName = sFileName.substr(0, pos); - std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; - - XmlUtils::CXmlNode oMainNode; - oMainNode.FromXmlFile(sEncFilePath); - - if (L"PDF-resources" == oMainNode.GetName()) - { - if (bIsCID) - { - XmlUtils::CXmlNode oType0Node; - if ( oMainNode.GetNode( L"Type0", oType0Node ) ) - { - XmlUtils::CXmlNode oNode; - if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) - { - XmlUtils::CXmlNode oDescNode; - if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { + bool bIsCID = false; + std::wstring sFileExt = NSFile::GetFileExtention(strPath); + if (std::wstring::npos != sFileExt.find(L"cid")) + bIsCID = true; + + std::wstring sFileName = NSFile::GetFileName(strPath); + std::wstring::size_type pos = sFileName.rfind('.'); + if (std::wstring::npos != pos) + sFileName = sFileName.substr(0, pos); + std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; + + XmlUtils::CXmlNode oMainNode; + oMainNode.FromXmlFile(sEncFilePath); + + if (L"PDF-resources" == oMainNode.GetName()) + { + if (bIsCID) + { + XmlUtils::CXmlNode oType0Node; + if ( oMainNode.GetNode( L"Type0", oType0Node ) ) + { + XmlUtils::CXmlNode oNode; + if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) + { + XmlUtils::CXmlNode oDescNode; + if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } - else - { - XmlUtils::CXmlNode oNode; - if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { + } catch (std::invalid_argument &) {} + } + } + } + } + } + else + { + XmlUtils::CXmlNode oNode; + if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } + } catch (std::invalid_argument &) {} + } + } + } + } + } - void CFontManagerBase::CalculateBaselineOffset() - { - LoadFont(); + void CFontManagerBase::CalculateBaselineOffset() + { + LoadFont(); double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; - d1 /= 2.0; + d1 /= 2.0; d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); m_oFontAdvanced.m_dBaselineOffset = d1; - } + } - void CFontManagerBase::LoadFontMetrics() - { + void CFontManagerBase::LoadFontMetrics() + { m_oFontAdvanced.m_dAscent = m_pManager->GetAscender(); m_oFontAdvanced.m_dDescent = m_pManager->GetDescender(); m_oFontAdvanced.m_dLineSpacing = m_pManager->GetLineHeight(); m_oFontAdvanced.m_dEmHeight = m_pManager->GetUnitsPerEm(); m_oFontAdvanced.m_dBaselineOffset = (c_dPtToMM * m_oFontAdvanced.m_dDescent * m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - } - - std::wstring CFontManagerBase::ToHexString( BYTE uc ) - { - std::wstring sRet = L""; - char c1 = (char)(uc >> 4); - char c2 = (char)(uc & 0x0F); - sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); - sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); - return sRet; - } - - BYTE CFontManagerBase::FromHexString( wchar_t c1, wchar_t c2 ) - { - BYTE res = 0; - res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0')); - res <<= 4; - res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0')); - return res; - } - - void CFontManagerBase::LoadFontParams(bool bIsPath) - { - // читаем и выставляем все настройки шрифта - if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) - return; + } + + std::wstring CFontManagerBase::ToHexString( BYTE uc ) + { + std::wstring sRet = L""; + char c1 = (char)(uc >> 4); + char c2 = (char)(uc & 0x0F); + sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); + sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); + return sRet; + } + + BYTE CFontManagerBase::FromHexString( wchar_t c1, wchar_t c2 ) + { + BYTE res = 0; + res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0')); + res <<= 4; + res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0')); + return res; + } + + void CFontManagerBase::LoadFontParams(bool bIsPath) + { + // читаем и выставляем все настройки шрифта + if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) + return; m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; m_oFontAdvanced.m_lStyle = 0x00; - if (m_pManager->GetFile()->IsBold()) - { + if (m_pManager->GetFile()->IsBold()) + { m_oFontAdvanced.m_lStyle |= 0x01; - } - if (m_pManager->GetFile()->IsItalic()) - { + } + if (m_pManager->GetFile()->IsItalic()) + { m_oFontAdvanced.m_lStyle |= 0x02; - } + } - // PANOSE - BYTE pPanose[10]; - m_pManager->GetFile()->GetPanose(pPanose); + // PANOSE + BYTE pPanose[10]; + m_pManager->GetFile()->GetPanose(pPanose); m_oFontAdvanced.m_strPANOSE.clear(); - for ( int i = 0; i < 10; ++i ) - { + for ( int i = 0; i < 10; ++i ) + { m_oFontAdvanced.m_strPANOSE += ToHexString(pPanose[i]); - } + } - // IsFixed + // IsFixed m_oFontAdvanced.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); - // Signature + // Signature m_oFontAdvanced.m_arSignature.clear(); - for ( unsigned int i = 0; i < 6; ++i ) - { - DWORD value = 0; + for ( unsigned int i = 0; i < 6; ++i ) + { + DWORD value = 0; - for ( unsigned long bit = 0; bit < 32; ++bit ) - { - if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) - { - value |= ( 1 << bit ); - } - } + for ( unsigned long bit = 0; bit < 32; ++bit ) + { + if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) + { + value |= ( 1 << bit ); + } + } m_oFontAdvanced.m_arSignature.push_back(value); - } - } - - void CFontManagerBase::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - - bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText) - { + } + } + + void CFontManagerBase::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) + { + if (0 == lRangeNum) + lRange1 |= 1 << lRange; + else if (1 == lRangeNum) + lRange2 |= 1 << lRange; + else if (2 == lRangeNum) + lRange3 |= 1 << lRange; + else + lRange4 |= 1 << lRange; + } + + bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText) + { if (m_oFontAdvanced.m_oFont.Path.empty() || oText.empty()) - { + { m_strCurrentPickFont = m_oFontAdvanced.m_strFamilyName; m_lCurrentPictFontStyle = m_oFontAdvanced.m_lStyle; - return false; - } + return false; + } - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; + BYTE lRangeNum = 0xFF; + BYTE lRange = 0xFF; - m_oRanges.CheckRange(oText[0], lRange, lRangeNum); - std::list::iterator posStart, pos; - posStart = pos = m_arListPicUps.begin(); + m_oRanges.CheckRange(oText[0], lRange, lRangeNum); + std::list::iterator posStart, pos; + posStart = pos = m_arListPicUps.begin(); - while (m_arListPicUps.end() != pos) - { - std::list::iterator posOld = pos; - CFontPickUp& oPick = *(pos++); + while (m_arListPicUps.end() != pos) + { + std::list::iterator posOld = pos; + CFontPickUp& oPick = *(pos++); if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) - { - // нашли! ничего подбирать не нужно - // нужно просто выкинуть этот шрифт наверх - m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - return false; - } - } - - // не нашли... - CFontPickUp oPick; - oPick.m_lRangeNum = lRangeNum; - oPick.m_lRange = lRange; + { + // нашли! ничего подбирать не нужно + // нужно просто выкинуть этот шрифт наверх + m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); + m_strCurrentPickFont = oPick.m_strPickFont; + m_lCurrentPictFontStyle = oPick.m_lPickStyle; + return false; + } + } + + // не нашли... + CFontPickUp oPick; + oPick.m_lRangeNum = lRangeNum; + oPick.m_lRange = lRange; oPick.m_oFont = m_oFontAdvanced; oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; @@ -553,148 +553,148 @@ namespace NSFontManager UINT dwR2 = m_oFontAdvanced.m_arSignature[1]; UINT dwR3 = m_oFontAdvanced.m_arSignature[2]; UINT dwR4 = m_oFontAdvanced.m_arSignature[3]; - UINT dwCodePage1 = 0; - UINT dwCodePage2 = 0; - - if ((lRangeNum == 1) && (lRange == 28)) - { - dwCodePage1 = 0x80000000; - //strText = (WCHAR)(strText[0] - 0xF000); - } - else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) - { - // арабский язык!!! - dwR1 = 1 << 13; - dwR2 = 1 << 31; - dwR3 = 1 << 3; - } - else - { - CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); - } - - NSFonts::CFontSelectFormat oFormat; - - std::wstring sFontNameSelect = L""; + UINT dwCodePage1 = 0; + UINT dwCodePage2 = 0; + + if ((lRangeNum == 1) && (lRange == 28)) + { + dwCodePage1 = 0x80000000; + //strText = (WCHAR)(strText[0] - 0xF000); + } + else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) + { + // арабский язык!!! + dwR1 = 1 << 13; + dwR2 = 1 << 31; + dwR3 = 1 << 3; + } + else + { + CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); + } + + NSFonts::CFontSelectFormat oFormat; + + std::wstring sFontNameSelect = L""; if (m_oFontAdvanced.m_strFamilyName.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) - sFontNameSelect = m_strDefaultFont; - else + sFontNameSelect = m_strDefaultFont; + else sFontNameSelect = m_oFontAdvanced.m_strFamilyName; - bool bSelectBold = false; - bool bSelectItalic = false; - CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); + bool bSelectBold = false; + bool bSelectItalic = false; + CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - oFormat.wsName = new std::wstring(sFontNameSelect); + oFormat.wsName = new std::wstring(sFontNameSelect); if (!m_oFontAdvanced.m_strPANOSE.empty()) - { - oFormat.pPanose = new BYTE[10]; + { + oFormat.pPanose = new BYTE[10]; const wchar_t* pPanoseStr = m_oFontAdvanced.m_strPANOSE.c_str(); - for (int i = 0; i < 10; ++i) - { - oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]); - pPanoseStr += 2; - } - } + for (int i = 0; i < 10; ++i) + { + oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]); + pPanoseStr += 2; + } + } oFormat.bBold = new INT(((m_oFontAdvanced.m_lStyle & 0x01) == 0x01) ? 1 : 0); oFormat.bItalic = new INT(((m_oFontAdvanced.m_lStyle & 0x02) == 0x02) ? 1 : 0); oFormat.bFixedWidth = new INT(m_oFontAdvanced.m_bIsFixedWidth ? 1 : 0); if (-1 != m_oFontAdvanced.m_lAvgWidth) oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFontAdvanced.m_lAvgWidth); - oFormat.ulRange1 = new UINT(dwR1); - oFormat.ulRange2 = new UINT(dwR2); - oFormat.ulRange3 = new UINT(dwR3); - oFormat.ulRange4 = new UINT(dwR4); - oFormat.ulCodeRange1 = new UINT(dwCodePage1); - oFormat.ulCodeRange2 = new UINT(dwCodePage2); - - if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) - oFormat.pPanose[2] = 7; - - oFormat.wsDefaultName = new std::wstring(L"Arial"); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - - oPick.m_strPickFont = pInfo->m_wsFontName; - oPick.m_lPickStyle = 0; - if (pInfo->m_bBold) - oPick.m_lPickStyle |= 0x01; - if (pInfo->m_bItalic) - oPick.m_lPickStyle |= 0x02; - - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - - m_arListPicUps.push_front(oPick); - return true; - } - - bool CFontManagerBase::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) - { - size_t nPos = 0; - size_t nLenReplace = sStyle.length(); - bool bRet = false; - - std::wstring sName2 = sName; - NSStringExt::ToLower(sName2); - - while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) - { - size_t nOffset = 0; - if ((nPos > 0) && sName2.at(nPos - 1) == '-') - { - --nPos; - ++nOffset; - } - - bRet = true; - sName.erase(nPos, nLenReplace + nOffset); - sName2.erase(nPos, nLenReplace + nOffset); - } - return bRet; - } - - void CFontManagerBase::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) - { - if (sName.length() > 7 && sName.at(6) == '+') - { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - wchar_t nChar = sName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } - } - if (bIsRemove) - { - sName.erase(0, 7); - } - } - - CheckFontNameStyle(sName, L"regular"); - CheckFontNameStyle(sName, L"condensed"); - CheckFontNameStyle(sName, L"condensedlight"); - //CheckFontNameStyle(sName, L"light"); - - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); - if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; - - if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - - if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } - } + oFormat.ulRange1 = new UINT(dwR1); + oFormat.ulRange2 = new UINT(dwR2); + oFormat.ulRange3 = new UINT(dwR3); + oFormat.ulRange4 = new UINT(dwR4); + oFormat.ulCodeRange1 = new UINT(dwCodePage1); + oFormat.ulCodeRange2 = new UINT(dwCodePage2); + + if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) + oFormat.pPanose[2] = 7; + + oFormat.wsDefaultName = new std::wstring(L"Arial"); + + NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); + + oPick.m_strPickFont = pInfo->m_wsFontName; + oPick.m_lPickStyle = 0; + if (pInfo->m_bBold) + oPick.m_lPickStyle |= 0x01; + if (pInfo->m_bItalic) + oPick.m_lPickStyle |= 0x02; + + m_strCurrentPickFont = oPick.m_strPickFont; + m_lCurrentPictFontStyle = oPick.m_lPickStyle; + + m_arListPicUps.push_front(oPick); + return true; + } + + bool CFontManagerBase::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) + { + size_t nPos = 0; + size_t nLenReplace = sStyle.length(); + bool bRet = false; + + std::wstring sName2 = sName; + NSStringExt::ToLower(sName2); + + while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) + { + size_t nOffset = 0; + if ((nPos > 0) && sName2.at(nPos - 1) == '-') + { + --nPos; + ++nOffset; + } + + bRet = true; + sName.erase(nPos, nLenReplace + nOffset); + sName2.erase(nPos, nLenReplace + nOffset); + } + return bRet; + } + + void CFontManagerBase::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) + { + if (sName.length() > 7 && sName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; ++nIndex) + { + wchar_t nChar = sName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + { + sName.erase(0, 7); + } + } + + CheckFontNameStyle(sName, L"regular"); + CheckFontNameStyle(sName, L"condensed"); + CheckFontNameStyle(sName, L"condensedlight"); + //CheckFontNameStyle(sName, L"light"); + + CheckFontNameStyle(sName, L"condensedbold"); + CheckFontNameStyle(sName, L"semibold"); + if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; + if (CheckFontNameStyle(sName, L"bold")) bBold = true; + + if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; + if (CheckFontNameStyle(sName, L"italic")) bItalic = true; + if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; + + if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } + } } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.h b/DocxRenderer/src/logic/managers/FontManagerBase.h index 64f14dfebc0..6c95e42bf8e 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.h +++ b/DocxRenderer/src/logic/managers/FontManagerBase.h @@ -6,150 +6,150 @@ namespace NSFontManager { - static NSFonts::IFontManager* CreateFontManager(NSFonts::IApplicationFonts* pApplication) - { - NSFonts::IFontManager* pManager = pApplication->GenerateFontManager(); - pManager->CreateOwnerCache(8); - return pManager; - } - - class CUnicodeRange - { - public: - BYTE RangeNum {0}; - BYTE Range {0}; - - int Start {0}; - int End {0}; - - CUnicodeRange(const int& _start = 0, - const int& _end = 0, - const BYTE& _range = 0, - const BYTE& _rangenum = 0); - }; + static NSFonts::IFontManager* CreateFontManager(NSFonts::IApplicationFonts* pApplication) + { + NSFonts::IFontManager* pManager = pApplication->GenerateFontManager(); + pManager->CreateOwnerCache(8); + return pManager; + } + + class CUnicodeRange + { + public: + BYTE RangeNum {0}; + BYTE Range {0}; + + int Start {0}; + int End {0}; + + CUnicodeRange(const int& _start = 0, + const int& _end = 0, + const BYTE& _range = 0, + const BYTE& _rangenum = 0); + }; - // класс для проставления Ranges для подбора шрифта по символу - class CUnicodeRanges - { - public: - std::list m_arRanges; - - public: - CUnicodeRanges(); + // класс для проставления Ranges для подбора шрифта по символу + class CUnicodeRanges + { + public: + std::list m_arRanges; + + public: + CUnicodeRanges(); - void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); + void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); - void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); - }; + void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); + }; - class CFontAdvanced - { - public: - NSStructures::CFont m_oFont; + class CFontAdvanced + { + public: + NSStructures::CFont m_oFont; - // font metrics - double m_dAscent {0.0}; - double m_dDescent {0.0}; - double m_dLineSpacing {0.0}; - double m_dEmHeight {0.0}; + // font metrics + double m_dAscent {0.0}; + double m_dDescent {0.0}; + double m_dLineSpacing {0.0}; + double m_dEmHeight {0.0}; - double m_dBaselineOffset {0.0}; + double m_dBaselineOffset {0.0}; - double m_dSpaceWidthMM {0.0}; + double m_dSpaceWidthMM {0.0}; - // font params - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; - SHORT m_lAvgWidth {-1}; + // font params + std::wstring m_strFamilyName {L""}; + std::wstring m_strPANOSE {L""}; + LONG m_lStyle {0}; + std::vector m_arSignature; + bool m_bIsFixedWidth {false}; + SHORT m_lAvgWidth {-1}; - public: - CFontAdvanced(); + public: + CFontAdvanced(); - CFontAdvanced(const CFontAdvanced& oSrc); + CFontAdvanced(const CFontAdvanced& oSrc); - CFontAdvanced& operator=(const CFontAdvanced& oSrc); - }; + CFontAdvanced& operator=(const CFontAdvanced& oSrc); + }; - class CFontPickUp - { - public: - CFontAdvanced m_oFont; - BYTE m_lRangeNum {0xFF}; - BYTE m_lRange {0xFF}; - std::wstring m_strPickFont {L""}; - LONG m_lPickStyle {0}; + class CFontPickUp + { + public: + CFontAdvanced m_oFont; + BYTE m_lRangeNum {0xFF}; + BYTE m_lRange {0xFF}; + std::wstring m_strPickFont {L""}; + LONG m_lPickStyle {0}; - public: - CFontPickUp(); - CFontPickUp(const CFontPickUp& oSrc); - CFontPickUp& operator=(const CFontPickUp& oSrc); - }; + public: + CFontPickUp(); + CFontPickUp(const CFontPickUp& oSrc); + CFontPickUp& operator=(const CFontPickUp& oSrc); + }; - class CFontManagerBase - { - public: - enum MeasureType - { - mtGlyph = 0, - mtPosition = 1 - }; + class CFontManagerBase + { + public: + enum MeasureType + { + mtGlyph = 0, + mtPosition = 1 + }; - protected: - NSFonts::IFontManager* m_pManager; - std::wstring m_strDefaultFont; + protected: + NSFonts::IFontManager* m_pManager; + std::wstring m_strDefaultFont; - public: + public: - CFontAdvanced m_oFontAdvanced; + CFontAdvanced m_oFontAdvanced; - //для подбора шрифтов - CUnicodeRanges m_oRanges; + //для подбора шрифтов + CUnicodeRanges m_oRanges; - std::list m_arListPicUps; - std::wstring m_strCurrentPickFont; - LONG m_lCurrentPictFontStyle; + std::list m_arListPicUps; + std::wstring m_strCurrentPickFont; + LONG m_lCurrentPictFontStyle; - public: - CFontManagerBase(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerBase(); + public: + CFontManagerBase(NSFonts::IApplicationFonts* pFonts); + virtual ~CFontManagerBase(); - void ClearPickUps(); + void ClearPickUps(); - public: - void SetDefaultFont(const std::wstring& strName); - std::wstring GetDefaultFont(); + public: + void SetDefaultFont(const std::wstring& strName); + std::wstring GetDefaultFont(); - virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true); + virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true); - void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); + void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); - void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); + void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - public: - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType) = 0; - virtual void CalculateBaselineOffset(); + public: + virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, + double& dBoxWidth, double& dBoxHeight, MeasureType measureType) = 0; + virtual void CalculateBaselineOffset(); - public: - void LoadFontMetrics(); + public: + void LoadFontMetrics(); - std::wstring ToHexString( BYTE uc ); + std::wstring ToHexString( BYTE uc ); - BYTE FromHexString( wchar_t c1, wchar_t c2 ); + BYTE FromHexString( wchar_t c1, wchar_t c2 ); - void LoadFontParams(bool bIsPath = true); + void LoadFontParams(bool bIsPath = true); - private: - void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); + private: + void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); - public: - bool GenerateFontName(NSStringUtils::CStringUTF32& oText); + public: + bool GenerateFontName(NSStringUtils::CStringUTF32& oText); - bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); + bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); - void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); - }; + void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); + }; } diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index 2d5470d2b79..fbdfc0a012d 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -3,207 +3,207 @@ namespace NSDocxRenderer { - void CImageManager::NewDocument() - { - m_strDstMedia = L""; - m_lMaxSizeImage = 1200; - m_lNextIDImage = 0; - - m_mapImageData.clear(); - m_mapImagesFile.clear(); - } - - std::shared_ptr CImageManager::WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height) - { - if (height < 0) - { - FlipY(pImage); - height = -height; - y -= height; - } - - return GenerateImageID(pImage); - } - - std::shared_ptr CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height) - { - return GenerateImageID(strFile); - } - - void CImageManager::CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst) - { - NSFile::CFileBinary::Copy(strFileSrc, strFileDst); - } - - void CImageManager::SaveImage(const std::wstring& strFileSrc, std::shared_ptr pInfo) - { - Aggplus::CImage oFrame(strFileSrc); - if (nullptr != oFrame.GetData()) - return SaveImage(&oFrame, pInfo); - } - - void CImageManager::SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo) - { - if (nullptr == pImage) - return; - - int w = pImage->GetWidth(); - int h = pImage->GetHeight(); - - pInfo->m_eType = GetImageType(pImage); - - UINT format = (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4; - pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId); - pInfo->m_strFileName += ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); - - std::wstring sSavedFile = m_strDstMedia + L"/" + pInfo->m_strFileName; - - if (w <= m_lMaxSizeImage && h <= m_lMaxSizeImage) - { - pImage->SaveFile(sSavedFile, format); - } - else - { - int lW = 0; - int lH = 0; - double dAspect = (double)w / h; - - if (w >= h) - { - lW = m_lMaxSizeImage; - lH = (int)((double)lW / dAspect); - } - else - { - lH = m_lMaxSizeImage; - lW = (LONG)(dAspect * lH); - } - - // TODO: resize - pImage->SaveFile(sSavedFile, format); - } - } - - std::shared_ptr CImageManager::GenerateImageID(Aggplus::CImage* pImage) - { - BYTE* pData = pImage->GetData(); - int nSize = pImage->GetStride() * pImage->GetHeight(); - if (nSize < 0) - nSize = -nSize; - - DWORD dwSum = m_oCRC.Calc(pData, nSize); - - auto find = m_mapImageData.find(dwSum); - if (find != m_mapImageData.end()) - return find->second; - - ++m_lNextIDImage; - auto pInfo = std::make_shared(); - pInfo->m_nId = m_lNextIDImage; - SaveImage(pImage, pInfo); - m_mapImageData.insert(std::pair>(dwSum, pInfo)); - - return pInfo; - } - - std::shared_ptr CImageManager::GenerateImageID(const std::wstring& strFileName) - { - auto find = m_mapImagesFile.find(strFileName); - if (find != m_mapImagesFile.end()) - return find->second; - - ++m_lNextIDImage; - auto pInfo = std::make_shared(); - pInfo->m_nId = m_lNextIDImage; - SaveImage(strFileName, pInfo); - m_mapImagesFile.insert(std::pair>(strFileName, pInfo)); - - return pInfo; - } - - CImageInfo::ImageType CImageManager::GetImageType(Aggplus::CImage* pFrame) - { - int w = pFrame->GetWidth(); - int h = pFrame->GetHeight(); - BYTE* pBuffer = pFrame->GetData(); - - BYTE* pBufferMem = pBuffer + 3; - LONG lCountPix = w * h; - - for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4) - { - if (255 != *pBufferMem) - return CImageInfo::itPNG; - } - return CImageInfo::itJPG; - } - - void CImageManager::FlipY(Aggplus::CImage* pImage) - { - if (nullptr == pImage) - return; - - int w = pImage->GetWidth(); - int h = pImage->GetHeight(); - BYTE* pBuffer = pImage->GetData(); - int stride = pImage->GetStride(); - - if (stride < 0) - stride = -stride; - - if ((w * 4) != stride) - return; - - BYTE* pBufferMem = new BYTE[stride]; - - BYTE* pBufferEnd = pBuffer + stride * (h - 1); - - LONG lCountV = h / 2; - - for (LONG lIndexV = 0; lIndexV < lCountV; ++lIndexV) - { - memcpy(pBufferMem, pBuffer, stride); - memcpy(pBuffer, pBufferEnd, stride); - memcpy(pBufferEnd, pBufferMem, stride); - - pBuffer += stride; - pBufferEnd -= stride; - } - - RELEASEARRAYOBJECTS(pBufferMem); - } - - void CImageManager::FlipX(CBgraFrame* pImage) - { - if (nullptr == pImage) - return; - - int w = pImage->get_Width(); - int h = pImage->get_Height(); - BYTE* pBuffer = pImage->get_Data(); - int stride = pImage->get_Stride(); - - if (stride < 0) - stride = -stride; - - if ((w * 4) != stride) - return; - - DWORD* pBufferDWORD = (DWORD*)pBuffer; - - LONG lW2 = w / 2; - for (LONG lIndexV = 0; lIndexV < h; ++lIndexV) - { - DWORD* pMem1 = pBufferDWORD; - DWORD* pMem2 = pBufferDWORD + w - 1; - - LONG lI = 0; - while (lI < lW2) - { - DWORD dwMem = *pMem1; - *pMem1++ = *pMem2; - *pMem2-- = dwMem; - } - } - } + void CImageManager::NewDocument() + { + m_strDstMedia = L""; + m_lMaxSizeImage = 1200; + m_lNextIDImage = 0; + + m_mapImageData.clear(); + m_mapImagesFile.clear(); + } + + std::shared_ptr CImageManager::WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height) + { + if (height < 0) + { + FlipY(pImage); + height = -height; + y -= height; + } + + return GenerateImageID(pImage); + } + + std::shared_ptr CImageManager::WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height) + { + return GenerateImageID(strFile); + } + + void CImageManager::CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst) + { + NSFile::CFileBinary::Copy(strFileSrc, strFileDst); + } + + void CImageManager::SaveImage(const std::wstring& strFileSrc, std::shared_ptr pInfo) + { + Aggplus::CImage oFrame(strFileSrc); + if (nullptr != oFrame.GetData()) + return SaveImage(&oFrame, pInfo); + } + + void CImageManager::SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo) + { + if (nullptr == pImage) + return; + + int w = pImage->GetWidth(); + int h = pImage->GetHeight(); + + pInfo->m_eType = GetImageType(pImage); + + UINT format = (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4; + pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId); + pInfo->m_strFileName += ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); + + std::wstring sSavedFile = m_strDstMedia + L"/" + pInfo->m_strFileName; + + if (w <= m_lMaxSizeImage && h <= m_lMaxSizeImage) + { + pImage->SaveFile(sSavedFile, format); + } + else + { + int lW = 0; + int lH = 0; + double dAspect = (double)w / h; + + if (w >= h) + { + lW = m_lMaxSizeImage; + lH = (int)((double)lW / dAspect); + } + else + { + lH = m_lMaxSizeImage; + lW = (LONG)(dAspect * lH); + } + + // TODO: resize + pImage->SaveFile(sSavedFile, format); + } + } + + std::shared_ptr CImageManager::GenerateImageID(Aggplus::CImage* pImage) + { + BYTE* pData = pImage->GetData(); + int nSize = pImage->GetStride() * pImage->GetHeight(); + if (nSize < 0) + nSize = -nSize; + + DWORD dwSum = m_oCRC.Calc(pData, nSize); + + auto find = m_mapImageData.find(dwSum); + if (find != m_mapImageData.end()) + return find->second; + + ++m_lNextIDImage; + auto pInfo = std::make_shared(); + pInfo->m_nId = m_lNextIDImage; + SaveImage(pImage, pInfo); + m_mapImageData.insert(std::pair>(dwSum, pInfo)); + + return pInfo; + } + + std::shared_ptr CImageManager::GenerateImageID(const std::wstring& strFileName) + { + auto find = m_mapImagesFile.find(strFileName); + if (find != m_mapImagesFile.end()) + return find->second; + + ++m_lNextIDImage; + auto pInfo = std::make_shared(); + pInfo->m_nId = m_lNextIDImage; + SaveImage(strFileName, pInfo); + m_mapImagesFile.insert(std::pair>(strFileName, pInfo)); + + return pInfo; + } + + CImageInfo::ImageType CImageManager::GetImageType(Aggplus::CImage* pFrame) + { + int w = pFrame->GetWidth(); + int h = pFrame->GetHeight(); + BYTE* pBuffer = pFrame->GetData(); + + BYTE* pBufferMem = pBuffer + 3; + LONG lCountPix = w * h; + + for (LONG i = 0; i < lCountPix; ++i, pBufferMem += 4) + { + if (255 != *pBufferMem) + return CImageInfo::itPNG; + } + return CImageInfo::itJPG; + } + + void CImageManager::FlipY(Aggplus::CImage* pImage) + { + if (nullptr == pImage) + return; + + int w = pImage->GetWidth(); + int h = pImage->GetHeight(); + BYTE* pBuffer = pImage->GetData(); + int stride = pImage->GetStride(); + + if (stride < 0) + stride = -stride; + + if ((w * 4) != stride) + return; + + BYTE* pBufferMem = new BYTE[stride]; + + BYTE* pBufferEnd = pBuffer + stride * (h - 1); + + LONG lCountV = h / 2; + + for (LONG lIndexV = 0; lIndexV < lCountV; ++lIndexV) + { + memcpy(pBufferMem, pBuffer, stride); + memcpy(pBuffer, pBufferEnd, stride); + memcpy(pBufferEnd, pBufferMem, stride); + + pBuffer += stride; + pBufferEnd -= stride; + } + + RELEASEARRAYOBJECTS(pBufferMem); + } + + void CImageManager::FlipX(CBgraFrame* pImage) + { + if (nullptr == pImage) + return; + + int w = pImage->get_Width(); + int h = pImage->get_Height(); + BYTE* pBuffer = pImage->get_Data(); + int stride = pImage->get_Stride(); + + if (stride < 0) + stride = -stride; + + if ((w * 4) != stride) + return; + + DWORD* pBufferDWORD = (DWORD*)pBuffer; + + LONG lW2 = w / 2; + for (LONG lIndexV = 0; lIndexV < h; ++lIndexV) + { + DWORD* pMem1 = pBufferDWORD; + DWORD* pMem2 = pBufferDWORD + w - 1; + + LONG lI = 0; + while (lI < lW2) + { + DWORD dwMem = *pMem1; + *pMem1++ = *pMem2; + *pMem2-- = dwMem; + } + } + } } diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index ff36d1e4a09..8e63e12344c 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -7,45 +7,45 @@ namespace NSDocxRenderer { - class CImageManager - { - public: - std::map> m_mapImagesFile; - std::map> m_mapImageData; + class CImageManager + { + public: + std::map> m_mapImagesFile; + std::map> m_mapImageData; - std::wstring m_strDstMedia {L""}; + std::wstring m_strDstMedia {L""}; - int m_lMaxSizeImage {1200}; - int m_lNextIDImage {0}; + int m_lMaxSizeImage {1200}; + int m_lNextIDImage {0}; - CCalculatorCRC32 m_oCRC; + CCalculatorCRC32 m_oCRC; - public: + public: - CImageManager(){}; + CImageManager(){}; - void NewDocument(); + void NewDocument(); - public: - std::shared_ptr WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); + public: + std::shared_ptr WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); - std::shared_ptr WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); + std::shared_ptr WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); - protected: - void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); + protected: + void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); - void SaveImage(const std::wstring& strFileSrc, std::shared_ptr pInfo); + void SaveImage(const std::wstring& strFileSrc, std::shared_ptr pInfo); - void SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo); + void SaveImage(Aggplus::CImage* pImage, std::shared_ptr pInfo); - std::shared_ptr GenerateImageID(Aggplus::CImage* pImage); + std::shared_ptr GenerateImageID(Aggplus::CImage* pImage); - std::shared_ptr GenerateImageID(const std::wstring& strFileName); + std::shared_ptr GenerateImageID(const std::wstring& strFileName); - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); + CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - void FlipY(Aggplus::CImage* pImage); + void FlipY(Aggplus::CImage* pImage); - void FlipX(CBgraFrame* pImage); - }; + void FlipX(CBgraFrame* pImage); + }; } diff --git a/DocxRenderer/src/logic/managers/StyleManager.cpp b/DocxRenderer/src/logic/managers/StyleManager.cpp index e6d9e7977f2..f621ebcc5c9 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.cpp +++ b/DocxRenderer/src/logic/managers/StyleManager.cpp @@ -3,42 +3,42 @@ namespace NSDocxRenderer { - CStyleManager::CStyleManager() - { - m_pCurrentStyle = std::make_shared(); - } - - CStyleManager::~CStyleManager() - { - Clear(); - } - - void CStyleManager::Clear() - { - m_arStyles.clear(); - } - - void CStyleManager::NewDocument() - { - Clear(); - } - - std::shared_ptr CStyleManager::GetStyle() - { - for (size_t i = 0; i < m_arStyles.size(); ++i) - { - if (m_arStyles[i]->IsEqual(m_pCurrentStyle)) - { - return m_arStyles[i]; - } - } - - m_arStyles.push_back(m_pCurrentStyle); - - auto pStyle = m_pCurrentStyle; - - m_pCurrentStyle = std::make_shared(); - - return pStyle; - } + CStyleManager::CStyleManager() + { + m_pCurrentStyle = std::make_shared(); + } + + CStyleManager::~CStyleManager() + { + Clear(); + } + + void CStyleManager::Clear() + { + m_arStyles.clear(); + } + + void CStyleManager::NewDocument() + { + Clear(); + } + + std::shared_ptr CStyleManager::GetStyle() + { + for (size_t i = 0; i < m_arStyles.size(); ++i) + { + if (m_arStyles[i]->IsEqual(m_pCurrentStyle)) + { + return m_arStyles[i]; + } + } + + m_arStyles.push_back(m_pCurrentStyle); + + auto pStyle = m_pCurrentStyle; + + m_pCurrentStyle = std::make_shared(); + + return pStyle; + } } diff --git a/DocxRenderer/src/logic/managers/StyleManager.h b/DocxRenderer/src/logic/managers/StyleManager.h index 29115298b9e..0bf366191ff 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.h +++ b/DocxRenderer/src/logic/managers/StyleManager.h @@ -3,22 +3,22 @@ namespace NSDocxRenderer { - class CStyleManager - { - public: - std::vector> m_arStyles; + class CStyleManager + { + public: + std::vector> m_arStyles; - std::shared_ptr m_pCurrentStyle; + std::shared_ptr m_pCurrentStyle; - public: - CStyleManager(); - virtual ~CStyleManager(); + public: + CStyleManager(); + virtual ~CStyleManager(); - void Clear(); + void Clear(); - void NewDocument(); + void NewDocument(); - std::shared_ptr GetStyle(); - }; + std::shared_ptr GetStyle(); + }; } diff --git a/DocxRenderer/src/logic/styles/BaseStyle.h b/DocxRenderer/src/logic/styles/BaseStyle.h index e329daf06b2..2a8e977a7f3 100644 --- a/DocxRenderer/src/logic/styles/BaseStyle.h +++ b/DocxRenderer/src/logic/styles/BaseStyle.h @@ -3,43 +3,43 @@ namespace NSDocxRenderer { - class CBaseStyle - { - protected: - enum class eStyleType - { - stUnknown, - stParagraph, - stCharacter, - stTable, - stNumbering - }; - - public: - CBaseStyle(const eStyleType& eType): m_eType(eType) {} - virtual ~CBaseStyle() {} - - CBaseStyle& operator=(const CBaseStyle& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - - return *this; - } - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - - private: - eStyleType m_eType {eStyleType::stUnknown}; - - public: - bool m_bIsNotNecessaryToUse {false}; - }; + class CBaseStyle + { + protected: + enum class eStyleType + { + stUnknown, + stParagraph, + stCharacter, + stTable, + stNumbering + }; + + public: + CBaseStyle(const eStyleType& eType): m_eType(eType) {} + virtual ~CBaseStyle() {} + + CBaseStyle& operator=(const CBaseStyle& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_eType = oSrc.m_eType; + m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; + + return *this; + } + + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; + + private: + eStyleType m_eType {eStyleType::stUnknown}; + + public: + bool m_bIsNotNecessaryToUse {false}; + }; } diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index da1d6c778ff..e466b11ef29 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -4,169 +4,169 @@ namespace NSDocxRenderer { - CFontStyle::CFontStyle() : CBaseStyle(CBaseStyle::eStyleType::stCharacter) - { - static UINT iId = 0; - iId++; - if (iId < 10) - { - m_strStyleId = L"fontstyle0" + std::to_wstring(iId); - } - else - { - m_strStyleId = L"fontstyle" + std::to_wstring(iId); - } - } - - CFontStyle& CFontStyle::operator=(const CFontStyle& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - CBaseStyle::operator=(oSrc); - - m_strStyleId = oSrc.m_strStyleId; - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - - return *this; - } - - void CFontStyle::CopyFormat(const CFontStyle& oSrc) - { - if (this == &oSrc) - { - return; - } - - CBaseStyle::operator=(oSrc); - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - } - - bool CFontStyle::IsEqual(std::shared_ptr oSrc) - { - //note Бывают fonts только с разными path => новый стиль => m_oFont.IsEqual не берем - //todo проверить FaceIndex StringGID - bool bIf1 = m_oFont.Name == oSrc->m_oFont.Name; - bool bIf2 = m_oFont.Size == oSrc->m_oFont.Size; - bool bIf3 = m_oFont.Bold == oSrc->m_oFont.Bold; - bool bIf4 = m_oFont.Italic == oSrc->m_oFont.Italic; - bool bIf5 = m_oFont.Underline == oSrc->m_oFont.Underline; - bool bIf6 = m_oFont.Strikeout == oSrc->m_oFont.Strikeout; - - bool bIf7 = m_oBrush.Type == oSrc->m_oBrush.Type; - bool bIf8 = m_oBrush.Color1 == oSrc->m_oBrush.Color1; - bool bIf9 = m_oBrush.Color2 == oSrc->m_oBrush.Color2; - bool bIf10 = m_oBrush.Alpha1 == oSrc->m_oBrush.Alpha1; - bool bIf11 = m_oBrush.Alpha2 == oSrc->m_oBrush.Alpha2; - bool bIf12 = m_oBrush.LinearAngle == oSrc->m_oBrush.LinearAngle; - - //todo - // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && - // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); - //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); - - bool bIf13 = m_strPickFontName == oSrc->m_strPickFontName; - bool bIf14 = m_lPickFontStyle == oSrc->m_lPickFontStyle; - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && - bIf7 && bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && - bIf13 && bIf14) - { - return true; - } - return false; - } - \ - void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - //oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (m_oFont.Italic) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (0x02 == (0x02 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) - { - oWriter.WriteString(L""); - } - - int lSize = static_cast(2 * m_oFont.Size); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } + CFontStyle::CFontStyle() : CBaseStyle(CBaseStyle::eStyleType::stCharacter) + { + static UINT iId = 0; + iId++; + if (iId < 10) + { + m_strStyleId = L"fontstyle0" + std::to_wstring(iId); + } + else + { + m_strStyleId = L"fontstyle" + std::to_wstring(iId); + } + } + + CFontStyle& CFontStyle::operator=(const CFontStyle& oSrc) + { + if (this == &oSrc) + { + return *this; + } + + CBaseStyle::operator=(oSrc); + + m_strStyleId = oSrc.m_strStyleId; + + m_oFont = oSrc.m_oFont; + m_oBrush = oSrc.m_oBrush; + + m_strPickFontName = oSrc.m_strPickFontName; + m_lPickFontStyle = oSrc.m_lPickFontStyle; + + return *this; + } + + void CFontStyle::CopyFormat(const CFontStyle& oSrc) + { + if (this == &oSrc) + { + return; + } + + CBaseStyle::operator=(oSrc); + + m_oFont = oSrc.m_oFont; + m_oBrush = oSrc.m_oBrush; + + m_strPickFontName = oSrc.m_strPickFontName; + m_lPickFontStyle = oSrc.m_lPickFontStyle; + } + + bool CFontStyle::IsEqual(std::shared_ptr oSrc) + { + //note Бывают fonts только с разными path => новый стиль => m_oFont.IsEqual не берем + //todo проверить FaceIndex StringGID + bool bIf1 = m_oFont.Name == oSrc->m_oFont.Name; + bool bIf2 = m_oFont.Size == oSrc->m_oFont.Size; + bool bIf3 = m_oFont.Bold == oSrc->m_oFont.Bold; + bool bIf4 = m_oFont.Italic == oSrc->m_oFont.Italic; + bool bIf5 = m_oFont.Underline == oSrc->m_oFont.Underline; + bool bIf6 = m_oFont.Strikeout == oSrc->m_oFont.Strikeout; + + bool bIf7 = m_oBrush.Type == oSrc->m_oBrush.Type; + bool bIf8 = m_oBrush.Color1 == oSrc->m_oBrush.Color1; + bool bIf9 = m_oBrush.Color2 == oSrc->m_oBrush.Color2; + bool bIf10 = m_oBrush.Alpha1 == oSrc->m_oBrush.Alpha1; + bool bIf11 = m_oBrush.Alpha2 == oSrc->m_oBrush.Alpha2; + bool bIf12 = m_oBrush.LinearAngle == oSrc->m_oBrush.LinearAngle; + + //todo + // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && + // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); + //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); + + bool bIf13 = m_strPickFontName == oSrc->m_strPickFontName; + bool bIf14 = m_lPickFontStyle == oSrc->m_lPickFontStyle; + + if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && + bIf7 && bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && + bIf13 && bIf14) + { + return true; + } + return false; + } + \ + void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + //oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; + oWriter.WriteString(L""); + + if (m_strPickFontName.empty()) + { + if (m_oFont.Bold) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (m_oFont.Italic) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + } + else + { + if (0x01 == (0x01 & m_lPickFontStyle)) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (0x02 == (0x02 & m_lPickFontStyle)) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + } + + if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L""); + } + + int lSize = static_cast(2 * m_oFont.Size); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } } diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 89539e0b591..1a02656ff22 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -6,31 +6,31 @@ namespace NSDocxRenderer { - class CFontStyle : public CBaseStyle - { - public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; + class CFontStyle : public CBaseStyle + { + public: + NSStructures::CFont m_oFont; + NSStructures::CBrush m_oBrush; - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; + std::wstring m_strPickFontName {L""}; + LONG m_lPickFontStyle {0}; - private: - std::wstring m_strStyleId {L""}; + private: + std::wstring m_strStyleId {L""}; - public: - CFontStyle(); - ~CFontStyle(){} + public: + CFontStyle(); + ~CFontStyle(){} - CFontStyle& operator=(const CFontStyle& oSrc); - void CopyFormat(const CFontStyle& oSrc); + CFontStyle& operator=(const CFontStyle& oSrc); + void CopyFormat(const CFontStyle& oSrc); - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - bool IsEqual(std::shared_ptr oSrc); + bool IsEqual(std::shared_ptr oSrc); - std::wstring GetStyleId() {return m_strStyleId;} - }; + std::wstring GetStyleId() {return m_strStyleId;} + }; } diff --git a/DocxRenderer/src/resources/ColorTable.h b/DocxRenderer/src/resources/ColorTable.h index 6df05c6faed..8ec2dc81e7c 100644 --- a/DocxRenderer/src/resources/ColorTable.h +++ b/DocxRenderer/src/resources/ColorTable.h @@ -5,61 +5,61 @@ class ColorTable { - public: - ColorTable () - { - InitClrTable (); - } +public: + ColorTable () + { + InitClrTable (); + } - inline std::wstring ConverColorToString(const unsigned int& sKey) - { - auto iter = m_Table.find(sKey); - if (iter == m_Table.end()) - { - //note если не нашли стандартный цвет, отсылаем что есть - return L"none"; - } - else - { - return iter->second; - } - } + inline std::wstring ConverColorToString(const unsigned int& sKey) + { + auto iter = m_Table.find(sKey); + if (iter == m_Table.end()) + { + //note если не нашли стандартный цвет, отсылаем что есть + return L"none"; + } + else + { + return iter->second; + } + } - inline bool IsStandardColor(const unsigned int& sKey) - { - auto iter = m_Table.find(sKey); - return iter == m_Table.end() ? false : true; - } + inline bool IsStandardColor(const unsigned int& sKey) + { + auto iter = m_Table.find(sKey); + return iter == m_Table.end() ? false : true; + } - private: - std::map m_Table; +private: + std::map m_Table; - private: - void InitClrTable() - { - if (m_Table.size()) - return; +private: + void InitClrTable() + { + if (m_Table.size()) + return; - //ECMA-376-1:2016 17.18.40 ST_HighlightColor (Text Highlight Colors) - m_Table.insert({0x000000, L"black" }); - m_Table.insert({0x0000FF, L"blue" }); - m_Table.insert({0x00FFFF, L"cyan" }); - m_Table.insert({0x00008B, L"darkBlue" }); - m_Table.insert({0x008B8B, L"darkCyan" }); - m_Table.insert({0xA9A9A9, L"darkGray" }); - m_Table.insert({0x006400, L"darkGreen" }); - m_Table.insert({0x800080, L"darkMagenta" }); - m_Table.insert({0x8B0000, L"darkRed" }); - m_Table.insert({0x808000, L"darkYellow" }); - m_Table.insert({0x00FF00, L"green" }); - m_Table.insert({0xD3D3D3, L"lightGray" }); - m_Table.insert({0xFF00FF, L"magenta" }); - m_Table.insert({0xFF0000, L"red" }); - m_Table.insert({0xFFFFFF, L"white" }); - m_Table.insert({0xFFFF00, L"yellow" }); + //ECMA-376-1:2016 17.18.40 ST_HighlightColor (Text Highlight Colors) + m_Table.insert({0x000000, L"black" }); + m_Table.insert({0x0000FF, L"blue" }); + m_Table.insert({0x00FFFF, L"cyan" }); + m_Table.insert({0x00008B, L"darkBlue" }); + m_Table.insert({0x008B8B, L"darkCyan" }); + m_Table.insert({0xA9A9A9, L"darkGray" }); + m_Table.insert({0x006400, L"darkGreen" }); + m_Table.insert({0x800080, L"darkMagenta" }); + m_Table.insert({0x8B0000, L"darkRed" }); + m_Table.insert({0x808000, L"darkYellow" }); + m_Table.insert({0x00FF00, L"green" }); + m_Table.insert({0xD3D3D3, L"lightGray" }); + m_Table.insert({0xFF00FF, L"magenta" }); + m_Table.insert({0xFF0000, L"red" }); + m_Table.insert({0xFFFFFF, L"white" }); + m_Table.insert({0xFFFF00, L"yellow" }); - //note Больше цветов здесь - //core\Common\3dParty\html\css\src\ConstValues.h - //core\DesktopEditor\agg-2.4\svg\agg_svg_color_parser.cpp - } + //note Больше цветов здесь + //core\Common\3dParty\html\css\src\ConstValues.h + //core\DesktopEditor\agg-2.4\svg\agg_svg_color_parser.cpp + } }; diff --git a/DocxRenderer/src/resources/ImageInfo.h b/DocxRenderer/src/resources/ImageInfo.h index 6fa00e408c1..4425ebe2c22 100644 --- a/DocxRenderer/src/resources/ImageInfo.h +++ b/DocxRenderer/src/resources/ImageInfo.h @@ -4,41 +4,41 @@ namespace NSDocxRenderer { - class CImageInfo - { - public: - enum ImageType - { - itPNG = 0, - itJPG = 1 - }; - - public: - ImageType m_eType {itPNG}; - UINT m_nId {0}; - std::wstring m_strFileName {L""}; - - public: - CImageInfo(){} - - CImageInfo(const CImageInfo &oSrc) - { - *this = oSrc; - } - - CImageInfo& operator=(const CImageInfo &oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_nId = oSrc.m_nId; - m_strFileName = oSrc.m_strFileName; - - return *this; - } - - }; + class CImageInfo + { + public: + enum ImageType + { + itPNG = 0, + itJPG = 1 + }; + + public: + ImageType m_eType {itPNG}; + UINT m_nId {0}; + std::wstring m_strFileName {L""}; + + public: + CImageInfo(){} + + CImageInfo(const CImageInfo &oSrc) + { + *this = oSrc; + } + + CImageInfo& operator=(const CImageInfo &oSrc) + { + if (this == &oSrc) + { + return *this; + } + + m_eType = oSrc.m_eType; + m_nId = oSrc.m_nId; + m_strFileName = oSrc.m_strFileName; + + return *this; + } + + }; } diff --git a/DocxRenderer/src/resources/LinesTable.h b/DocxRenderer/src/resources/LinesTable.h index 2535f1e58d5..a09083a3c2d 100644 --- a/DocxRenderer/src/resources/LinesTable.h +++ b/DocxRenderer/src/resources/LinesTable.h @@ -5,82 +5,82 @@ enum class eSimpleLineType { - sltUnknown, - sltHDot, //Horizontal - sltVDot, //Vertical - sltHDash, - sltVDash, - sltHLongDash, - sltVLongDash, - sltHWave, - sltVWave + sltUnknown, + sltHDot, //Horizontal + sltVDot, //Vertical + sltHDash, + sltVDash, + sltHLongDash, + sltVLongDash, + sltHWave, + sltVWave }; enum class eLineType { - ltUnknown, - ltSingle, - ltDouble, - ltThick, - ltDotted, - ltDottedHeavy, - ltDash, - ltDashedHeavy, - ltDashLong, - ltDashLongHeavy, - ltDotDash, - ltDashDotHeavy, - ltDotDotDash, - ltDashDotDotHeavy, - ltWave, - ltWavyHeavy, - ltWavyDouble, - ltWords, - ltNone + ltUnknown, + ltSingle, + ltDouble, + ltThick, + ltDotted, + ltDottedHeavy, + ltDash, + ltDashedHeavy, + ltDashLong, + ltDashLongHeavy, + ltDotDash, + ltDashDotHeavy, + ltDotDotDash, + ltDashDotDotHeavy, + ltWave, + ltWavyHeavy, + ltWavyDouble, + ltWords, + ltNone }; class LinesTable { - public: - LinesTable () - { - InitLinesTable (); - } +public: + LinesTable () + { + InitLinesTable (); + } - inline std::wstring ConverLineToString(const eLineType& sKey) - { - auto iter = m_Table.find(sKey); - return iter == m_Table.end() ? L"\"none\"" : iter->second; - } + inline std::wstring ConverLineToString(const eLineType& sKey) + { + auto iter = m_Table.find(sKey); + return iter == m_Table.end() ? L"\"none\"" : iter->second; + } - private: - std::map m_Table; +private: + std::map m_Table; - private: - void InitLinesTable() - { - if (m_Table.size()) - return; +private: + void InitLinesTable() + { + if (m_Table.size()) + return; - //ECMA-376 Part 1 17.18.99 ST_Underline (Underline Patterns) - m_Table.insert({eLineType::ltSingle, L"\"single\""}); - m_Table.insert({eLineType::ltDouble, L"\"double\"" }); - m_Table.insert({eLineType::ltThick, L"\"thick\"" }); - m_Table.insert({eLineType::ltDotted, L"\"dotted\"" }); - m_Table.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); - m_Table.insert({eLineType::ltDash, L"\"dash\"" }); - m_Table.insert({eLineType::ltDashedHeavy, L"\"dashedHeavy\"" }); - m_Table.insert({eLineType::ltDashLong, L"\"dashLong\"" }); - m_Table.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); - m_Table.insert({eLineType::ltDotDash, L"\"dotDash\"" }); - m_Table.insert({eLineType::ltDashDotHeavy, L"\"dashDotHeavy\"" }); - m_Table.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); - m_Table.insert({eLineType::ltDashDotDotHeavy, L"\"dashDotDotHeavy\"" }); - m_Table.insert({eLineType::ltWave, L"\"wave\"" }); - m_Table.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); - m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" }); - m_Table.insert({eLineType::ltWords, L"\"words\"" }); - m_Table.insert({eLineType::ltNone, L"\"none\"" }); - } + //ECMA-376 Part 1 17.18.99 ST_Underline (Underline Patterns) + m_Table.insert({eLineType::ltSingle, L"\"single\""}); + m_Table.insert({eLineType::ltDouble, L"\"double\"" }); + m_Table.insert({eLineType::ltThick, L"\"thick\"" }); + m_Table.insert({eLineType::ltDotted, L"\"dotted\"" }); + m_Table.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); + m_Table.insert({eLineType::ltDash, L"\"dash\"" }); + m_Table.insert({eLineType::ltDashedHeavy, L"\"dashedHeavy\"" }); + m_Table.insert({eLineType::ltDashLong, L"\"dashLong\"" }); + m_Table.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); + m_Table.insert({eLineType::ltDotDash, L"\"dotDash\"" }); + m_Table.insert({eLineType::ltDashDotHeavy, L"\"dashDotHeavy\"" }); + m_Table.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); + m_Table.insert({eLineType::ltDashDotDotHeavy, L"\"dashDotDotHeavy\"" }); + m_Table.insert({eLineType::ltWave, L"\"wave\"" }); + m_Table.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); + m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" }); + m_Table.insert({eLineType::ltWords, L"\"words\"" }); + m_Table.insert({eLineType::ltNone, L"\"none\"" }); + } }; diff --git a/DocxRenderer/src/resources/SingletonTemplate.h b/DocxRenderer/src/resources/SingletonTemplate.h index bb589adee57..ba038f04c85 100644 --- a/DocxRenderer/src/resources/SingletonTemplate.h +++ b/DocxRenderer/src/resources/SingletonTemplate.h @@ -3,20 +3,20 @@ template class SingletonTemplate{ public: - static T& GetInstance() - { - static T instance; - return instance; - } + static T& GetInstance() + { + static T instance; + return instance; + } protected: - SingletonTemplate(){} - SingletonTemplate(const SingletonTemplate&) = delete; - SingletonTemplate& operator=(const SingletonTemplate&) = delete; - virtual ~SingletonTemplate() {} + SingletonTemplate(){} + SingletonTemplate(const SingletonTemplate&) = delete; + SingletonTemplate& operator=(const SingletonTemplate&) = delete; + virtual ~SingletonTemplate() {} }; template inline T& SingletonInstance() { - return SingletonTemplate::GetInstance(); + return SingletonTemplate::GetInstance(); } diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 5195fe42660..5e1c09d810b 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -5,171 +5,171 @@ namespace NSDocxRenderer { - CVectorGraphics::CVectorGraphics() - { - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - - End(); - } - - CVectorGraphics::~CVectorGraphics() - { - RELEASEMEM(m_pData); - } - - void CVectorGraphics::AddSize(size_t nSize) - { - if (nullptr == m_pData) - { - m_lSize = std::max(nSize, (size_t)500); - m_pData = (double *)malloc(m_lSize * sizeof(double)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - { - m_lSize *= 2; - } - - double *pRealloc = (double *)realloc(m_pData, m_lSize * sizeof(double)); - if (nullptr != pRealloc) - { - // реаллок сработал - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - double *pMalloc = (double *)malloc(m_lSize * sizeof(double)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } - - void CVectorGraphics::MoveTo(const double &x1, const double &y1) - { - AddSize(3); - *m_pDataCur = vgtMove; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; - - CheckPoint(x1, y1); - } - - void CVectorGraphics::LineTo(const double &x1, const double &y1) - { - AddSize(3); - *m_pDataCur = vgtLine; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; - - CheckPoint(x1, y1); - } - - void CVectorGraphics::CurveTo(const double &x1, const double &y1, - const double &x2, const double &y2, - const double &x3, const double &y3) - { - AddSize(7); - *m_pDataCur = vgtCurve; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - *m_pDataCur = x2; - ++m_pDataCur; - *m_pDataCur = y2; - ++m_pDataCur; - *m_pDataCur = x3; - ++m_pDataCur; - *m_pDataCur = y3; - ++m_pDataCur; - - m_lSizeCur += 7; - - CheckPoint(x1, y1); - CheckPoint(x2, y2); - CheckPoint(x3, y3); - } - - void CVectorGraphics::Close() - { - AddSize(1); - *m_pDataCur = vgtClose; - ++m_pDataCur; - - m_lSizeCur += 1; - } - - size_t CVectorGraphics::GetCurSize() const - { - return m_lSizeCur; - } - - void CVectorGraphics::Clear() - { - RELEASEMEM(m_pData); - - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - void CVectorGraphics::ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - void CVectorGraphics::End() - { - ClearNoAttack(); - - //todo - m_dLeft = 0xFFFFFF; - m_dTop = 0xFFFFFF; - m_dRight = -0xFFFFFF; - m_dBottom = -0xFFFFFF; - } - - void CVectorGraphics::CheckPoint(const double &x, const double &y) - { - if (m_dLeft > x) - m_dLeft = x; - if (m_dRight < x) - m_dRight = x; - if (m_dTop > y) - m_dTop = y; - if (m_dBottom < y) - m_dBottom = y; - } + CVectorGraphics::CVectorGraphics() + { + m_pData = nullptr; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + + End(); + } + + CVectorGraphics::~CVectorGraphics() + { + RELEASEMEM(m_pData); + } + + void CVectorGraphics::AddSize(size_t nSize) + { + if (nullptr == m_pData) + { + m_lSize = std::max(nSize, (size_t)500); + m_pData = (double *)malloc(m_lSize * sizeof(double)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + { + m_lSize *= 2; + } + + double *pRealloc = (double *)realloc(m_pData, m_lSize * sizeof(double)); + if (nullptr != pRealloc) + { + // реаллок сработал + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + double *pMalloc = (double *)malloc(m_lSize * sizeof(double)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + void CVectorGraphics::MoveTo(const double &x1, const double &y1) + { + AddSize(3); + *m_pDataCur = vgtMove; + ++m_pDataCur; + + *m_pDataCur = x1; + ++m_pDataCur; + *m_pDataCur = y1; + ++m_pDataCur; + + m_lSizeCur += 3; + + CheckPoint(x1, y1); + } + + void CVectorGraphics::LineTo(const double &x1, const double &y1) + { + AddSize(3); + *m_pDataCur = vgtLine; + ++m_pDataCur; + + *m_pDataCur = x1; + ++m_pDataCur; + *m_pDataCur = y1; + ++m_pDataCur; + + m_lSizeCur += 3; + + CheckPoint(x1, y1); + } + + void CVectorGraphics::CurveTo(const double &x1, const double &y1, + const double &x2, const double &y2, + const double &x3, const double &y3) + { + AddSize(7); + *m_pDataCur = vgtCurve; + ++m_pDataCur; + + *m_pDataCur = x1; + ++m_pDataCur; + *m_pDataCur = y1; + ++m_pDataCur; + *m_pDataCur = x2; + ++m_pDataCur; + *m_pDataCur = y2; + ++m_pDataCur; + *m_pDataCur = x3; + ++m_pDataCur; + *m_pDataCur = y3; + ++m_pDataCur; + + m_lSizeCur += 7; + + CheckPoint(x1, y1); + CheckPoint(x2, y2); + CheckPoint(x3, y3); + } + + void CVectorGraphics::Close() + { + AddSize(1); + *m_pDataCur = vgtClose; + ++m_pDataCur; + + m_lSizeCur += 1; + } + + size_t CVectorGraphics::GetCurSize() const + { + return m_lSizeCur; + } + + void CVectorGraphics::Clear() + { + RELEASEMEM(m_pData); + + m_pData = nullptr; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + + void CVectorGraphics::ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + + void CVectorGraphics::End() + { + ClearNoAttack(); + + //todo + m_dLeft = 0xFFFFFF; + m_dTop = 0xFFFFFF; + m_dRight = -0xFFFFFF; + m_dBottom = -0xFFFFFF; + } + + void CVectorGraphics::CheckPoint(const double &x, const double &y) + { + if (m_dLeft > x) + m_dLeft = x; + if (m_dRight < x) + m_dRight = x; + if (m_dTop > y) + m_dTop = y; + if (m_dBottom < y) + m_dBottom = y; + } } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index ff09addc5db..2a6eaba922c 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -2,49 +2,49 @@ namespace NSDocxRenderer { - class CVectorGraphics - { - public: - enum VectorGraphicsType - { - vgtMove = 0, - vgtLine = 1, - vgtCurve = 2, - vgtClose = 3 - }; - - public: - double* m_pData; - size_t m_lSize; - - double* m_pDataCur; - size_t m_lSizeCur; - - public: - double m_dLeft; - double m_dTop; - double m_dRight; - double m_dBottom; - - public: - CVectorGraphics(); - ~CVectorGraphics(); - - inline void AddSize(size_t nSize); - - public: - void MoveTo(const double& x1, const double& y1); - void LineTo(const double& x1, const double& y1); - void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); - void Close(); - - size_t GetCurSize() const; - - void Clear(); - void ClearNoAttack(); - - void End(); - - void CheckPoint(const double& x, const double& y); - }; + class CVectorGraphics + { + public: + enum VectorGraphicsType + { + vgtMove = 0, + vgtLine = 1, + vgtCurve = 2, + vgtClose = 3 + }; + + public: + double* m_pData; + size_t m_lSize; + + double* m_pDataCur; + size_t m_lSizeCur; + + public: + double m_dLeft; + double m_dTop; + double m_dRight; + double m_dBottom; + + public: + CVectorGraphics(); + ~CVectorGraphics(); + + inline void AddSize(size_t nSize); + + public: + void MoveTo(const double& x1, const double& y1); + void LineTo(const double& x1, const double& y1); + void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); + void Close(); + + size_t GetCurSize() const; + + void Clear(); + void ClearNoAttack(); + + void End(); + + void CheckPoint(const double& x, const double& y); + }; } diff --git a/DocxRenderer/src/resources/resources.cpp b/DocxRenderer/src/resources/resources.cpp index c22ff541ff1..93b7e3db505 100644 --- a/DocxRenderer/src/resources/resources.cpp +++ b/DocxRenderer/src/resources/resources.cpp @@ -10,58 +10,58 @@ bool WriteXmlUTF8(const std::wstring& strFile, const std::string& sContent) { - bool bRes = false; - NSFile::CFileBinary oFileBinary; - if (oFileBinary.CreateFileW(strFile)) - { - oFileBinary.WriteFile((BYTE*)sContent.c_str(), (DWORD)sContent.length()); - oFileBinary.CloseFile(); - } - return bRes; + bool bRes = false; + NSFile::CFileBinary oFileBinary; + if (oFileBinary.CreateFileW(strFile)) + { + oFileBinary.WriteFile((BYTE*)sContent.c_str(), (DWORD)sContent.length()); + oFileBinary.CloseFile(); + } + return bRes; } bool CreateTemplate(const std::wstring& strDirectory) { - if (NSDirectory::Exists(strDirectory)) - NSDirectory::CreateDirectory(strDirectory); + if (NSDirectory::Exists(strDirectory)) + NSDirectory::CreateDirectory(strDirectory); - std::string str_resource_app = "1100ONLYOFFICE011falsefalse0falsefalse"; - std::string str_resource_contenttypes = "\n"; - std::string str_resource_core = "1"; - std::string str_resource_rels = ""; - std::string str_resource_settings = ""; - std::string str_resource_theme = ""; - std::string str_resource_websettings = ""; + std::string str_resource_app = "1100ONLYOFFICE011falsefalse0falsefalse"; + std::string str_resource_contenttypes = "\n"; + std::string str_resource_core = "1"; + std::string str_resource_rels = ""; + std::string str_resource_settings = ""; + std::string str_resource_theme = ""; + std::string str_resource_websettings = ""; - std::wstring str_resource_app_replace = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (str_resource_app_replace.empty()) - str_resource_app_replace = NSSystemUtils::gc_EnvApplicationNameDefault; + std::wstring str_resource_app_replace = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (str_resource_app_replace.empty()) + str_resource_app_replace = NSSystemUtils::gc_EnvApplicationNameDefault; #if defined(INTVER) - std::string s = VALUE2STR(INTVER); - str_resource_app_replace += (L"/" + UTF8_TO_U(s)); + std::string s = VALUE2STR(INTVER); + str_resource_app_replace += (L"/" + UTF8_TO_U(s)); #endif - std::string str_resource_app_replace_a = "" + U_TO_UTF8(str_resource_app_replace) + ""; - NSStringUtils::string_replaceA(str_resource_app, "ONLYOFFICE", str_resource_app_replace_a); + std::string str_resource_app_replace_a = "" + U_TO_UTF8(str_resource_app_replace) + ""; + NSStringUtils::string_replaceA(str_resource_app, "ONLYOFFICE", str_resource_app_replace_a); - NSDirectory::CreateDirectory(strDirectory + L"/_rels"); - WriteXmlUTF8(strDirectory + L"/_rels/.rels", str_resource_rels); + NSDirectory::CreateDirectory(strDirectory + L"/_rels"); + WriteXmlUTF8(strDirectory + L"/_rels/.rels", str_resource_rels); - NSDirectory::CreateDirectory(strDirectory + L"/docProps"); - WriteXmlUTF8(strDirectory + L"/docProps/app.xml", str_resource_app); - WriteXmlUTF8(strDirectory + L"/docProps/core.xml", str_resource_core); + NSDirectory::CreateDirectory(strDirectory + L"/docProps"); + WriteXmlUTF8(strDirectory + L"/docProps/app.xml", str_resource_app); + WriteXmlUTF8(strDirectory + L"/docProps/core.xml", str_resource_core); - WriteXmlUTF8(strDirectory + L"/[Content_Types].xml", str_resource_contenttypes); + WriteXmlUTF8(strDirectory + L"/[Content_Types].xml", str_resource_contenttypes); - NSDirectory::CreateDirectory(strDirectory + L"/word"); - WriteXmlUTF8(strDirectory + L"/word/settings.xml", str_resource_settings); - WriteXmlUTF8(strDirectory + L"/word/webSettings.xml", str_resource_websettings); + NSDirectory::CreateDirectory(strDirectory + L"/word"); + WriteXmlUTF8(strDirectory + L"/word/settings.xml", str_resource_settings); + WriteXmlUTF8(strDirectory + L"/word/webSettings.xml", str_resource_websettings); - NSDirectory::CreateDirectory(strDirectory + L"/word/theme"); - WriteXmlUTF8(strDirectory + L"/word/theme/theme.xml", str_resource_theme); + NSDirectory::CreateDirectory(strDirectory + L"/word/theme"); + WriteXmlUTF8(strDirectory + L"/word/theme/theme.xml", str_resource_theme); - NSDirectory::CreateDirectory(strDirectory + L"/word/_rels"); - return true; + NSDirectory::CreateDirectory(strDirectory + L"/word/_rels"); + return true; } diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index afe0cd02acb..f933971a161 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -4,48 +4,48 @@ inline LONG ConvertColorBGRToRGB(LONG lBGR) { - return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); + return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); } inline bool IsSpaceUtf32(const uint32_t& c) { - return (0x20 == c || //пробел - 0xA0 == c || //неразрывный пробел - 0x2003 == c //Em пробел - ) ? true : false; + return (0x20 == c || //пробел + 0xA0 == c || //неразрывный пробел + 0x2003 == c //Em пробел + ) ? true : false; } inline bool IsSpaceUtf32(const NSStringUtils::CStringUTF32& oText) { - if (1 != oText.length()) - return false; - return IsSpaceUtf32(oText.ToStdWString()[0]); + if (1 != oText.length()) + return false; + return IsSpaceUtf32(oText.ToStdWString()[0]); } inline bool IsUnicodeSymbol(const int& symbol ) { - if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) || - ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) || - ( ( 0x10000 <= symbol ) && symbol ) ) - { - return true; - } - return false; + if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) || + ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) || + ( ( 0x10000 <= symbol ) && symbol ) ) + { + return true; + } + return false; } inline bool IsDiacriticalMark(const int& symbol ) { - if ( 0x0300 <= symbol && 0x036F >= symbol ) - { - return true; - } - return false; + if ( 0x0300 <= symbol && 0x036F >= symbol ) + { + return true; + } + return false; } // 2-byte number inline short little_endian_2_big_endian( short s ) { - return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 ); + return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 ); } /*========================================================================================================*/ @@ -53,5 +53,5 @@ inline short little_endian_2_big_endian( short s ) // 4-byte number inline int little_endian_2_big_endian( int i ) { - return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); + return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 61745fc1e35..0bc683fd047 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = L""; - std::wstring sTempDirOut = L""; + std::wstring sTempDir = L"C:\\Work\\TestDocxR\\temp"; + std::wstring sTempDirOut = L"C:\\Work\\TestDocxR\\temp\\output"; if (!NSDirectory::Exists(sTempDir)) NSDirectory::CreateDirectory(sTempDir); @@ -91,9 +91,9 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - sSourceFiles.push_back(L""); + sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\test_underline.pdf"); - std::wstring sTextDirOut = L""; + std::wstring sTextDirOut = L"C:\\Work\\TestDocxR\\text"; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); @@ -166,10 +166,10 @@ int main(int argc, char *argv[]) // проверить все режимы NSDocxRenderer::eTextAssociationType taType; - //taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; - //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; - //taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; - taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; + taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; + //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; + //taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; + //taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; oDocxRenderer.SetTextAssociationType(taType); oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); From 53bbeb0cdccf509d4cfe716b024c592e829b3c0c Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 27 Feb 2023 15:46:54 +0300 Subject: [PATCH 011/794] Refactoring + VectrosGraphics update --- DocxRenderer/src/logic/Page.cpp | 17 +- DocxRenderer/src/logic/elements/Shape.cpp | 108 ++++------- DocxRenderer/src/resources/VectorGraphics.cpp | 181 ++++++------------ DocxRenderer/src/resources/VectorGraphics.h | 45 +++-- DocxRenderer/test/main.cpp | 8 +- 5 files changed, 140 insertions(+), 219 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 39fd82e2d77..71e58464c69 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -250,16 +250,21 @@ namespace NSDocxRenderer void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) { - if ((m_oVector.m_dLeft <= m_oVector.m_dRight) && (m_oVector.m_dTop <= m_oVector.m_dBottom)) + double left, right, top, bottom; + left = m_oVector.GetLeft(); + right = m_oVector.GetRight(); + top = m_oVector.GetTop(); + bottom = m_oVector.GetBottom(); + if ((left <= right) && (top <= bottom)) { if (!m_arShapes.empty()) { auto pLastShape = m_arShapes.back(); - if (pLastShape->m_dLeft == m_oVector.m_dLeft && - pLastShape->m_dTop == m_oVector.m_dTop && - pLastShape->m_dWidth == m_oVector.m_dRight - m_oVector.m_dLeft && - pLastShape->m_dHeight == m_oVector.m_dBottom - m_oVector.m_dTop) + if (pLastShape->m_dLeft == left && + pLastShape->m_dTop == top && + pLastShape->m_dWidth == right - left && + pLastShape->m_dHeight == bottom - top) { if (0x00 != (lType & 0x01)) { @@ -300,7 +305,7 @@ namespace NSDocxRenderer if (pShape->m_bIsNoStroke) { - if ((fabs(m_oVector.m_dLeft - m_oVector.m_dRight) < 0.3) || (fabs(m_oVector.m_dTop - m_oVector.m_dBottom) < 0.3)) + if ((fabs(left - right) < 0.3) || (fabs(top - bottom) < 0.3)) { pShape->m_oPen.Color = m_pBrush->Color1; pShape->m_oPen.Alpha = m_pBrush->Alpha1; diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 734e040f15f..0120e32e659 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -65,10 +65,10 @@ namespace NSDocxRenderer void CShape::GetDataFromVector(const CVectorGraphics& oVector) { - m_dLeft = oVector.m_dLeft; - m_dTop = oVector.m_dTop; - m_dWidth = oVector.m_dRight - m_dLeft; - m_dHeight = oVector.m_dBottom - m_dTop; + m_dLeft = oVector.GetLeft(); + m_dTop = oVector.GetTop(); + m_dWidth = oVector.GetRight() - m_dLeft; + m_dHeight = oVector.GetBottom() - m_dTop; if (m_dWidth < 0.0001) m_dWidth = 0.0001; @@ -83,11 +83,10 @@ namespace NSDocxRenderer void CShape::WritePath(const CVectorGraphics& oVector) { - size_t nCount = oVector.GetCurSize(); - double *pData = oVector.m_pData; + auto arData = oVector.GetData(); - double dWidth = oVector.m_dRight - oVector.m_dLeft; - double dHeight = oVector.m_dBottom - oVector.m_dTop; + double dWidth = oVector.GetRight() - oVector.GetLeft(); + double dHeight = oVector.GetBottom() - oVector.GetTop(); NSStringUtils::CStringBuilder oWriter; @@ -100,98 +99,67 @@ namespace NSDocxRenderer size_t nPeacks = 0; size_t nCurves = 0; - while (nCount > 0) + for(auto& path_command : arData) { - CVectorGraphics::VectorGraphicsType eType = static_cast((int)(0.5 + *pData++)); - - switch (eType) + switch (path_command.type) { case CVectorGraphics::vgtMove: - { - LONG lX = static_cast((*pData - m_dLeft) * c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop) * c_dMMToEMU); - ++pData; + oWriter.WriteString(L""); + break; - oWriter.WriteString(L"(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); + case CVectorGraphics::vgtLine: + oWriter.WriteString(L""); + break; - nPeacks++; - nCount -= 3; + case CVectorGraphics::vgtCurve: + oWriter.WriteString(L""); + break; + + case CVectorGraphics::vgtClose: + default: break; } - case CVectorGraphics::vgtLine: + + for(auto& point : path_command.points) { - LONG lX = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; + LONG lX = static_cast((point.x - m_dLeft) * c_dMMToEMU); + LONG lY = static_cast((point.y - m_dTop) * c_dMMToEMU); - oWriter.WriteString(L"(lX)); oWriter.WriteString(L"\" y=\""); oWriter.AddInt(static_cast(lY)); - oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"\"/>"); + } + switch (path_command.type) + { + case CVectorGraphics::vgtMove: + oWriter.WriteString(L""); nPeacks++; - nCount -= 3; break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY1 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX2 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY2 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX3 = static_cast((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY3 = static_cast((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L""); - oWriter.WriteString(L"(lX1)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY1)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX2)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY2)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"(lX3)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(lY3)); - oWriter.WriteString(L"\"/>"); + case CVectorGraphics::vgtLine: + oWriter.WriteString(L""); + nPeacks++; + break; + case CVectorGraphics::vgtCurve: oWriter.WriteString(L""); - nCurves++; - nCount -= 7; break; - } + case CVectorGraphics::vgtClose: default: - --nCount; break; } + } oWriter.WriteString(L""); oWriter.WriteString(L""); m_strPath = oWriter.GetData(); - DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves); - oWriter.ClearNoAttack(); } diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 5e1c09d810b..8f53e257847 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -1,175 +1,110 @@ #include +#include +#include + #include "VectorGraphics.h" #include "../DesktopEditor/common/Types.h" -#include + namespace NSDocxRenderer { CVectorGraphics::CVectorGraphics() { - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - - End(); + ResetBorders(); } CVectorGraphics::~CVectorGraphics() { - RELEASEMEM(m_pData); + m_arData.clear(); } - void CVectorGraphics::AddSize(size_t nSize) + void CVectorGraphics::ResetBorders() { - if (nullptr == m_pData) - { - m_lSize = std::max(nSize, (size_t)500); - m_pData = (double *)malloc(m_lSize * sizeof(double)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - { - m_lSize *= 2; - } + m_dLeft = std::numeric_limits().max(); + m_dTop = std::numeric_limits().max(); + m_dRight = std::numeric_limits().min(); + m_dBottom = std::numeric_limits().min(); + } - double *pRealloc = (double *)realloc(m_pData, m_lSize * sizeof(double)); - if (nullptr != pRealloc) - { - // реаллок сработал - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - double *pMalloc = (double *)malloc(m_lSize * sizeof(double)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(double)); + double CVectorGraphics::GetLeft() const noexcept + { + return m_dLeft; + } + double CVectorGraphics::GetTop() const noexcept + { + return m_dTop; + } + double CVectorGraphics::GetRight() const noexcept + { + return m_dRight; + } + double CVectorGraphics::GetBottom() const noexcept + { + return m_dBottom; + } - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } + std::vector CVectorGraphics::GetData() const + { + return m_arData; } void CVectorGraphics::MoveTo(const double &x1, const double &y1) { - AddSize(3); - *m_pDataCur = vgtMove; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; + Point point = {x1, y1}; + VectorGraphicsType type = vgtMove; + m_arData.push_back({type, {point}}); - CheckPoint(x1, y1); + CheckPoint(point); } void CVectorGraphics::LineTo(const double &x1, const double &y1) { - AddSize(3); - *m_pDataCur = vgtLine; - ++m_pDataCur; - - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - - m_lSizeCur += 3; + Point point = {x1, y1}; + VectorGraphicsType type = vgtLine; + m_arData.push_back({type, {point}}); - CheckPoint(x1, y1); + CheckPoint(point); } void CVectorGraphics::CurveTo(const double &x1, const double &y1, const double &x2, const double &y2, const double &x3, const double &y3) { - AddSize(7); - *m_pDataCur = vgtCurve; - ++m_pDataCur; + std::vector points = {{x1, y1}, {x2, y2}, {x3, y3}}; + VectorGraphicsType type = vgtCurve; + m_arData.push_back({type, points}); - *m_pDataCur = x1; - ++m_pDataCur; - *m_pDataCur = y1; - ++m_pDataCur; - *m_pDataCur = x2; - ++m_pDataCur; - *m_pDataCur = y2; - ++m_pDataCur; - *m_pDataCur = x3; - ++m_pDataCur; - *m_pDataCur = y3; - ++m_pDataCur; - - m_lSizeCur += 7; - - CheckPoint(x1, y1); - CheckPoint(x2, y2); - CheckPoint(x3, y3); + for(auto& point : points) + CheckPoint(point); } void CVectorGraphics::Close() { - AddSize(1); - *m_pDataCur = vgtClose; - ++m_pDataCur; - - m_lSizeCur += 1; - } - - size_t CVectorGraphics::GetCurSize() const - { - return m_lSizeCur; + VectorGraphicsType type = vgtCurve; + m_arData.push_back({type, {}}); } void CVectorGraphics::Clear() { - RELEASEMEM(m_pData); - - m_pData = nullptr; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; + m_arData.clear(); } - void CVectorGraphics::ClearNoAttack() + void CVectorGraphics::End() { - m_pDataCur = m_pData; - m_lSizeCur = 0; + Clear(); + ResetBorders(); } - void CVectorGraphics::End() + void CVectorGraphics::CheckPoint(const Point& point) { - ClearNoAttack(); - - //todo - m_dLeft = 0xFFFFFF; - m_dTop = 0xFFFFFF; - m_dRight = -0xFFFFFF; - m_dBottom = -0xFFFFFF; + if (m_dLeft > point.x) m_dLeft = point.x; + if (m_dRight < point.x) m_dRight = point.x; + if (m_dTop > point.y) m_dTop = point.y; + if (m_dBottom < point.y) m_dBottom = point.y; } - - void CVectorGraphics::CheckPoint(const double &x, const double &y) + void CVectorGraphics::CheckPoint(const double& x, const double& y) { - if (m_dLeft > x) - m_dLeft = x; - if (m_dRight < x) - m_dRight = x; - if (m_dTop > y) - m_dTop = y; - if (m_dBottom < y) - m_dBottom = y; + Point point = {x, y}; + CheckPoint(point); } } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 2a6eaba922c..68ac8004ad6 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -1,4 +1,5 @@ #pragma once +#include namespace NSDocxRenderer { @@ -13,38 +14,50 @@ namespace NSDocxRenderer vgtClose = 3 }; - public: - double* m_pData; - size_t m_lSize; + struct Point + { + double x = 0; + double y = 0; + }; - double* m_pDataCur; - size_t m_lSizeCur; + struct PathCommand + { + VectorGraphicsType type; + std::vector points; + }; public: - double m_dLeft; - double m_dTop; - double m_dRight; - double m_dBottom; + std::vector GetData() const; + + public: + double GetLeft() const noexcept; + double GetTop() const noexcept; + double GetRight() const noexcept; + double GetBottom() const noexcept; public: CVectorGraphics(); ~CVectorGraphics(); - inline void AddSize(size_t nSize); - public: void MoveTo(const double& x1, const double& y1); void LineTo(const double& x1, const double& y1); void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); void Close(); - - size_t GetCurSize() const; + void End(); void Clear(); - void ClearNoAttack(); + void CheckPoint(const Point& point); + void CheckPoint(const double& x, const double& y); - void End(); + private: + std::vector m_arData; - void CheckPoint(const double& x, const double& y); + double m_dLeft; + double m_dTop; + double m_dRight; + double m_dBottom; + + void ResetBorders(); }; } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 0bc683fd047..d3bce163819 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = L"C:\\Work\\TestDocxR\\temp"; - std::wstring sTempDirOut = L"C:\\Work\\TestDocxR\\temp\\output"; + std::wstring sTempDir = L""; + std::wstring sTempDirOut = L""; if (!NSDirectory::Exists(sTempDir)) NSDirectory::CreateDirectory(sTempDir); @@ -91,9 +91,9 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\test_underline.pdf"); + sSourceFiles.push_back(L""); - std::wstring sTextDirOut = L"C:\\Work\\TestDocxR\\text"; + std::wstring sTextDirOut = L""; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); From 66050307ce2afa1a3f6652c153b481c142882cd7 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 2 Mar 2023 16:48:47 +0300 Subject: [PATCH 012/794] Refactoring CStyleManager* in conttext is useless --- DocxRenderer/src/logic/Page.cpp | 2 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 16 ++++------------ DocxRenderer/src/logic/elements/BaseItem.h | 2 ++ DocxRenderer/src/logic/elements/ContText.cpp | 13 ++++--------- DocxRenderer/src/logic/elements/ContText.h | 3 +-- DocxRenderer/src/logic/elements/Shape.cpp | 19 +------------------ .../src/logic/managers/FontManagerBase.cpp | 1 + .../src/logic/managers/StyleManager.cpp | 6 ------ .../src/logic/managers/StyleManager.h | 3 --- DocxRenderer/src/logic/styles/FontStyle.cpp | 10 +++------- DocxRenderer/src/logic/styles/FontStyle.h | 4 +--- DocxRenderer/src/resources/VectorGraphics.cpp | 2 +- DocxRenderer/src/resources/VectorGraphics.h | 9 ++++----- 13 files changed, 23 insertions(+), 67 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 71e58464c69..613ede2b14d 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -384,7 +384,7 @@ namespace NSDocxRenderer double dBaseLinePos = dTextY + fBaseLineOffset; dTextH = m_pFontManager->GetFontHeight(); - auto pCont = new CContText(&m_oFontManagerLight, m_pStyleManager); + auto pCont = new CContText(&m_oFontManagerLight); pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 98759fb889e..ed61cd34a4f 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -155,24 +155,16 @@ namespace NSDocxRenderer { eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); - if (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - return true; - } - return false; + return (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); } bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) { eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); - if (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - return true; - } - return false; + return (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext); } double CBaseItem::CalculateBeforeSpacing(double dPreviousBaseline) diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 5e1a78bb20d..e4371aae30a 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -4,6 +4,7 @@ namespace NSDocxRenderer { + // взаимное расположение по вертикали со следующим объектом enum class eVerticalCrossingType { vctUnknown, @@ -19,6 +20,7 @@ namespace NSDocxRenderer vctNoCrossingCurrentBelowNext }; + // взаимное расположение по горизонтали со следующим объектом enum class eHorizontalCrossingType { hctUnknown, diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index a31b59729d5..604ce0d0973 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,8 +5,8 @@ namespace NSDocxRenderer { - CContText::CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager): - CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight), m_pStyleManager(pStyleManager) + CContText::CContText(CFontManagerLight* pManagerLight): + CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight) { } @@ -60,7 +60,6 @@ namespace NSDocxRenderer m_eVertAlignType = rCont.m_eVertAlignType; m_pManagerLight = rCont.m_pManagerLight; - m_pStyleManager = rCont.m_pStyleManager; m_pShape = rCont.m_pShape; m_pCont = rCont.m_pCont; @@ -310,12 +309,8 @@ namespace NSDocxRenderer bool bIf14 = m_eVertAlignType == eVertAlignType::vatUnknown && pCont->m_eVertAlignType == eVertAlignType::vatBase; bool bIf15 = m_eVertAlignType == eVertAlignType::vatBase && pCont->m_eVertAlignType == eVertAlignType::vatUnknown; - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && - bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)) - { - return true; - } - return false; + return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && + bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)); } UINT CContText::GetNumberOfFeatures() diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index cc3654ce7fd..7f0ccebaf3d 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -47,7 +47,6 @@ namespace NSDocxRenderer eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; CFontManagerLight* m_pManagerLight {nullptr}; - CStyleManager* m_pStyleManager {nullptr}; CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; @@ -55,7 +54,7 @@ namespace NSDocxRenderer UINT m_iNumDuplicates {0}; public: - CContText(CFontManagerLight* pManagerLight, CStyleManager* pStyleManager); + CContText(CFontManagerLight* pManagerLight); CContText(const CContText& rCont); virtual ~CContText(); virtual void Clear() override final; diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 0120e32e659..3a95efdd74c 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -29,25 +29,8 @@ namespace NSDocxRenderer void CShape::Clear() { for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; + m_arOutputObjects[i]->Clear(); - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } m_arOutputObjects.clear(); } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp index d23b8ff7949..81e0a9d6844 100644 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ b/DocxRenderer/src/logic/managers/FontManagerBase.cpp @@ -611,6 +611,7 @@ namespace NSFontManager oFormat.ulCodeRange1 = new UINT(dwCodePage1); oFormat.ulCodeRange2 = new UINT(dwCodePage2); + // ??? if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) oFormat.pPanose[2] = 7; diff --git a/DocxRenderer/src/logic/managers/StyleManager.cpp b/DocxRenderer/src/logic/managers/StyleManager.cpp index f621ebcc5c9..3680c95224b 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.cpp +++ b/DocxRenderer/src/logic/managers/StyleManager.cpp @@ -26,17 +26,11 @@ namespace NSDocxRenderer std::shared_ptr CStyleManager::GetStyle() { for (size_t i = 0; i < m_arStyles.size(); ++i) - { if (m_arStyles[i]->IsEqual(m_pCurrentStyle)) - { return m_arStyles[i]; - } - } m_arStyles.push_back(m_pCurrentStyle); - auto pStyle = m_pCurrentStyle; - m_pCurrentStyle = std::make_shared(); return pStyle; diff --git a/DocxRenderer/src/logic/managers/StyleManager.h b/DocxRenderer/src/logic/managers/StyleManager.h index 0bf366191ff..a9be808e885 100644 --- a/DocxRenderer/src/logic/managers/StyleManager.h +++ b/DocxRenderer/src/logic/managers/StyleManager.h @@ -7,7 +7,6 @@ namespace NSDocxRenderer { public: std::vector> m_arStyles; - std::shared_ptr m_pCurrentStyle; public: @@ -15,9 +14,7 @@ namespace NSDocxRenderer virtual ~CStyleManager(); void Clear(); - void NewDocument(); - std::shared_ptr GetStyle(); }; } diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index e466b11ef29..ef271a9bace 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -80,15 +80,11 @@ namespace NSDocxRenderer bool bIf13 = m_strPickFontName == oSrc->m_strPickFontName; bool bIf14 = m_lPickFontStyle == oSrc->m_lPickFontStyle; - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && + return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && - bIf13 && bIf14) - { - return true; - } - return false; + bIf13 && bIf14); } - \ + void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) { if (m_bIsNotNecessaryToUse) diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 1a02656ff22..45d122087fb 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -23,12 +23,10 @@ namespace NSDocxRenderer ~CFontStyle(){} CFontStyle& operator=(const CFontStyle& oSrc); - void CopyFormat(const CFontStyle& oSrc); + void CopyFormat(const CFontStyle& oSrc); void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - bool IsEqual(std::shared_ptr oSrc); - std::wstring GetStyleId() {return m_strStyleId;} }; } diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 8f53e257847..0d9c3bce64f 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -43,7 +43,7 @@ namespace NSDocxRenderer return m_dBottom; } - std::vector CVectorGraphics::GetData() const + const std::vector& CVectorGraphics::GetData() const { return m_arData; } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 68ac8004ad6..fd07e43b0a1 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -27,18 +27,17 @@ namespace NSDocxRenderer }; public: - std::vector GetData() const; + CVectorGraphics(); + ~CVectorGraphics(); public: + const std::vector& GetData() const; + double GetLeft() const noexcept; double GetTop() const noexcept; double GetRight() const noexcept; double GetBottom() const noexcept; - public: - CVectorGraphics(); - ~CVectorGraphics(); - public: void MoveTo(const double& x1, const double& y1); void LineTo(const double& x1, const double& y1); From 0d062162151d368ae7da126c9b5dcf7fbe613d0c Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 5 Mar 2023 13:06:18 +0300 Subject: [PATCH 013/794] Refactoring --- DocxRenderer/src/logic/Page.cpp | 14 +++----------- DocxRenderer/src/logic/elements/Shape.cpp | 2 +- DocxRenderer/src/logic/elements/TextLine.cpp | 12 +++--------- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 613ede2b14d..14239e75271 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1182,11 +1182,6 @@ namespace NSDocxRenderer void CPage::AddDiacriticalSymbols() { - if (m_arDiacriticalSymbol.empty()) - { - return; - } - for (size_t i = 0; i < m_arDiacriticalSymbol.size(); ++i) { auto pDiacriticalCont = m_arDiacriticalSymbol[i]; @@ -1238,19 +1233,16 @@ namespace NSDocxRenderer if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) { pCurrCont->m_oText += pDiacriticalCont->m_oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; - isBreak = true; - break; } else if (bIf3 && bIf7) { NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); oText += pCurrCont->m_oText; pCurrCont->m_oText = oText; - pDiacriticalCont->m_bIsNotNecessaryToUse = true; - isBreak = true; - break; } + pDiacriticalCont->m_bIsNotNecessaryToUse = true; + isBreak = true; + break; } } if (isBreak) diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 3a95efdd74c..ed6b580c716 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -168,7 +168,7 @@ namespace NSDocxRenderer { m_eSimpleLineType = eSimpleLineType::sltHDash; } - else //максимальна точка - 0.5mm + else //максимальная точка - 0.5mm { m_eSimpleLineType = eSimpleLineType::sltHDot; } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 6a98a7c8123..2936cbfd5e5 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -138,15 +138,10 @@ namespace NSDocxRenderer bool CTextLine::IsShadingPresent(const CTextLine *pLine) { - if (m_pDominantShape && pLine->m_pDominantShape && + return (m_pDominantShape && pLine->m_pDominantShape && m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && fabs(m_pDominantShape->m_dLeft - pLine->m_pDominantShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM) - { - return true; - } - - return false; + fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM); } void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) @@ -180,15 +175,14 @@ namespace NSDocxRenderer { // просто текст на тексте или сменились настройки (font/brush) pPrev->ToXml(oWriter); - pPrev = pCurrent; } else { // расстояние слишком большое. нужно сделать большой пробел pPrev->ToXml(oWriter); pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); - pPrev = pCurrent; } + pPrev = pCurrent; } pPrev->ToXml(oWriter); From 118783c7162a37f462dfc835bf0b8965b9cdde7e Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 5 Mar 2023 13:27:15 +0300 Subject: [PATCH 014/794] Fix bug --- DocxRenderer/src/resources/VectorGraphics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 0d9c3bce64f..d7dd4b99782 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -80,19 +80,19 @@ namespace NSDocxRenderer void CVectorGraphics::Close() { - VectorGraphicsType type = vgtCurve; + VectorGraphicsType type = vgtClose; m_arData.push_back({type, {}}); } void CVectorGraphics::Clear() { m_arData.clear(); + ResetBorders(); } void CVectorGraphics::End() { Clear(); - ResetBorders(); } void CVectorGraphics::CheckPoint(const Point& point) From 2ab9f0649387e01e61930a45af9ff211209b9b94 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 14 Mar 2023 18:10:33 +0300 Subject: [PATCH 015/794] Refactoring --- DocxRenderer/DocxRenderer.pro | 2 - DocxRenderer/src/logic/Document.cpp | 7 +- DocxRenderer/src/logic/Page.cpp | 67 +- DocxRenderer/src/logic/Page.h | 1 - DocxRenderer/src/logic/elements/ContText.cpp | 21 +- DocxRenderer/src/logic/elements/ContText.h | 4 +- .../src/logic/managers/FontManager.cpp | 673 ++++++++++++++--- DocxRenderer/src/logic/managers/FontManager.h | 129 ++-- .../src/logic/managers/FontManagerBase.cpp | 701 ------------------ .../src/logic/managers/FontManagerBase.h | 155 ---- DocxRenderer/test/main.cpp | 12 +- 11 files changed, 694 insertions(+), 1078 deletions(-) delete mode 100644 DocxRenderer/src/logic/managers/FontManagerBase.cpp delete mode 100644 DocxRenderer/src/logic/managers/FontManagerBase.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 3a6af0ca05c..8d35adfdec7 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -37,7 +37,6 @@ HEADERS += \ src/logic/elements/TextLine.h \ src/logic/managers/ImageManager.h \ src/logic/managers/FontManager.h \ - src/logic/managers/FontManagerBase.h \ src/logic/managers/StyleManager.h \ src/logic/styles/BaseStyle.h \ src/logic/styles/FontStyle.h \ @@ -64,7 +63,6 @@ SOURCES += \ src/logic/elements/Table.cpp \ src/logic/elements/TextLine.cpp \ src/logic/managers/FontManager.cpp \ - src/logic/managers/FontManagerBase.cpp \ src/logic/managers/ImageManager.cpp \ src/logic/managers/StyleManager.cpp \ src/logic/styles/FontStyle.cpp \ diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 856cbc4ebcb..1b6f1dcce9e 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -6,9 +6,6 @@ namespace NSDocxRenderer m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts) { m_oSimpleGraphicsConverter.SetRenderer(pRenderer); - - m_oFontManager.m_pFont = &m_oFont; - m_oFontManager.m_pTransform = &m_oTransform; } void CDocument::Clear() { @@ -773,7 +770,8 @@ namespace NSDocxRenderer { if (nullptr == m_pFontManager) { - m_pFontManager = NSFontManager::CreateFontManager(m_pAppFonts); + m_pFontManager = m_pAppFonts->GenerateFontManager(); + m_pFontManager->CreateOwnerCache(8); } double dPix = m_oFont.CharSpace * m_dDpiX / 25.4; @@ -817,7 +815,6 @@ namespace NSDocxRenderer m_oImageManager.NewDocument(); m_oStyleManager.NewDocument(); - m_oFontManager.Init(); // media m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 14239e75271..62720b22cee 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -7,7 +7,7 @@ namespace NSDocxRenderer { - CPage::CPage(NSFonts::IApplicationFonts* pFonts) : m_oFontManagerLight(pFonts) + CPage::CPage(NSFonts::IApplicationFonts* pFonts) { } @@ -250,21 +250,21 @@ namespace NSDocxRenderer void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) { - double left, right, top, bottom; - left = m_oVector.GetLeft(); - right = m_oVector.GetRight(); - top = m_oVector.GetTop(); - bottom = m_oVector.GetBottom(); - if ((left <= right) && (top <= bottom)) + double dLeft, dRight, dTop, dBottom; + dLeft = m_oVector.GetLeft(); + dRight = m_oVector.GetRight(); + dTop = m_oVector.GetTop(); + dBottom = m_oVector.GetBottom(); + if ((dLeft <= dRight) && (dTop <= dBottom)) { if (!m_arShapes.empty()) { auto pLastShape = m_arShapes.back(); - if (pLastShape->m_dLeft == left && - pLastShape->m_dTop == top && - pLastShape->m_dWidth == right - left && - pLastShape->m_dHeight == bottom - top) + if (pLastShape->m_dLeft == dLeft && + pLastShape->m_dTop == dTop && + pLastShape->m_dWidth == dRight - dLeft && + pLastShape->m_dHeight == dBottom - dTop) { if (0x00 != (lType & 0x01)) { @@ -305,7 +305,7 @@ namespace NSDocxRenderer if (pShape->m_bIsNoStroke) { - if ((fabs(left - right) < 0.3) || (fabs(top - bottom) < 0.3)) + if ((fabs(dLeft - dRight) < 0.3) || (fabs(dTop - dBottom) < 0.3)) { pShape->m_oPen.Color = m_pBrush->Color1; pShape->m_oPen.Alpha = m_pBrush->Alpha1; @@ -342,22 +342,16 @@ namespace NSDocxRenderer NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); if ((pUnicodes != nullptr) && (pGids != nullptr)) - { for (unsigned int i = 0; i < nCount; ++i) - { - if ( !IsUnicodeSymbol( pUnicodes[i] ) ) - { + if (!IsUnicodeSymbol( pUnicodes[i])) oText[i] = ' '; - } - } - } - bool bIsPath = ((nullptr == pGids) && !bIsPDFAnalyzer) ? false : true; - m_pFontManager->LoadFont(0, !bIsPath); + m_pFontManager->SetFont(*m_pFont); + m_pFontManager->SetTransform(m_pTransform); - if (!bIsPath) - m_pFontManager->GenerateFontName2(oText); + m_pFontManager->LoadFont(); + m_pFontManager->GenerateFontName(oText); if (fabs(dTextW) < 0.01 || (dTextW > 10)) { @@ -384,12 +378,14 @@ namespace NSDocxRenderer double dBaseLinePos = dTextY + fBaseLineOffset; dTextH = m_pFontManager->GetFontHeight(); - auto pCont = new CContText(&m_oFontManagerLight); + auto pCont = new CContText(m_pFontManager); pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dTop = dBaseLinePos - dTextH - m_pFontManager->m_oFontAdvanced.m_dBaselineOffset; + CFontAdvanced oFontAdvanced = m_pFontManager->GetFontAdvanced(); + + pCont->m_dTop = dBaseLinePos - dTextH - oFontAdvanced.m_dBaselineOffset; pCont->m_dWidth = dTextW; pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; @@ -397,31 +393,24 @@ namespace NSDocxRenderer pCont->m_oText = oText; //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = m_pFontManager->m_oFontAdvanced.m_oFont; + m_pStyleManager->m_pCurrentStyle->m_oFont = oFontAdvanced.m_oFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - if (!bIsPath) - { - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontManager->m_strCurrentPickFont; - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = m_pFontManager->m_lCurrentPictFontStyle; - } + m_pStyleManager->m_pCurrentStyle->m_strPickFontName = oFontAdvanced.m_strFamilyName; + m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = oFontAdvanced.m_oFont.GetStyle2(); //первичное получение стиля для текущего символа //при дальнейшем анализе может измениться pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + pCont->m_dSpaceWidthMM = oFontAdvanced.m_dSpaceWidthMM; - pCont->m_dSpaceWidthMM = m_pFontManager->m_dSpaceWidthMM; - + // собираем отдельно, т.к. такие символы не имею размера m_dWidth if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) - { - //собираем отдельно, т.к. такие символы не имею размера m_dWidth m_arDiacriticalSymbol.push_back(pCont); - } + + // остальные символы сразу добавляем в текстовые линии else - { - //остальные символы сразу добавляем в текстовые линии AddContToTextLine(pCont); - } } void CPage::AddContToTextLine(CContText *pCont) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 429ad44fbbe..a24d52b19d8 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -44,7 +44,6 @@ namespace NSDocxRenderer CTextLine* m_pCurrentLine {nullptr}; CRow* m_pCurrentRow {nullptr}; - CFontManagerLight m_oFontManagerLight; eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 604ce0d0973..6db00cbab57 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,8 +5,8 @@ namespace NSDocxRenderer { - CContText::CContText(CFontManagerLight* pManagerLight): - CBaseItem(ElemType::etContText), m_pManagerLight(pManagerLight) + CContText::CContText(CFontManager* pManager): + CBaseItem(ElemType::etContText), m_pManager(pManager) { } @@ -59,7 +59,7 @@ namespace NSDocxRenderer m_eVertAlignType = rCont.m_eVertAlignType; - m_pManagerLight = rCont.m_pManagerLight; + m_pManager = rCont.m_pManager; m_pShape = rCont.m_pShape; m_pCont = rCont.m_pCont; @@ -91,10 +91,17 @@ namespace NSDocxRenderer m_eVertAlignType != eVertAlignType::vatSuperscript) { // нужно перемерять... - m_pManagerLight->LoadFont(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, false); - double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); + m_pManager->LoadFontByName(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, + c_dDpiX, c_dDpiY); + m_pManager->GenerateFontName(m_oText); - double dSpacing = (m_dWidth - dWidth) / (m_oText.length()); + double dBoxX; + double dBoxY; + double dBoxWidth; + double dBoxHeight; + m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); + + double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); dSpacing *= c_dMMToDx; lCalculatedSpacing = static_cast(dSpacing); @@ -206,7 +213,7 @@ namespace NSDocxRenderer double dSpaceMMSize = m_dSpaceWidthMM; if (!m_pFontStyle->m_strPickFontName.empty()) { - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); + dSpaceMMSize = m_pManager->GetFontAdvanced().m_dSpaceWidthMM; } LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 7f0ccebaf3d..17c89eab334 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -46,7 +46,7 @@ namespace NSDocxRenderer eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CFontManagerLight* m_pManagerLight {nullptr}; + CFontManager* m_pManager {nullptr}; CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; @@ -54,7 +54,7 @@ namespace NSDocxRenderer UINT m_iNumDuplicates {0}; public: - CContText(CFontManagerLight* pManagerLight); + CContText(CFontManager* m_pManager); CContText(const CContText& rCont); virtual ~CContText(); virtual void Clear() override final; diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 508bb753a2f..5c871d600ca 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -1,87 +1,317 @@ #include "FontManager.h" #include "../../resources/Constants.h" +#include "../DesktopEditor/xml/include/xmlutils.h" +#include "../DesktopEditor/common/Directory.h" namespace NSDocxRenderer { - CFontTableEntry::CFontTableEntry(const CFontTableEntry& oSrc) + CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, + const BYTE& _range, const BYTE& _rangenum): + RangeNum(_rangenum), Range(_range), Start(_start), End(_end) + { + } + + CUnicodeRanges::CUnicodeRanges() + { + // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur + + m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin + m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement + m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A + m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B + m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions + m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement + m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters + m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters + m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks + m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement + m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic + m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic + m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic + m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement + m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A + m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B + m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian + m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew + m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai + m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic + m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement + m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo + m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari + m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali + m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi + m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati + m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya + m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil + m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu + m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada + m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam + m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai + m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao + m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian + m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement + m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese + m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo + m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional + m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C + m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D + m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended + m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation + m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation + + m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts + m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols + m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols + m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols + m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms + m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows + m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A + m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B + m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows + m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators + m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A + m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B + m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical + m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures + m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition + m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics + m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing + m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements + m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes + m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols + m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats + m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation + m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana + m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana + m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions + m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo + m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended + m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo + m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa + m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months + m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility + m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables + m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 + m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician + m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs + m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement + m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals + m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters + m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A + m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun + m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B + m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) + m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes + m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs + m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement + m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms + m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A + + m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks + m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms + m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms + m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants + m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B + m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms + m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials + m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan + m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac + m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana + m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala + m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar + m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic + m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement + m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended + m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee + m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics + m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham + m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic + m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer + m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols + m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian + m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns + m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables + m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals + m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog + m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo + m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid + m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa + m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic + m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic + m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret + m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols + m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation + m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols + m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) + m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) + m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors + m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement + m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags + m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu + m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le + m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue + + m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese + m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic + m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh + m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols + m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri + m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary + m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms + m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers + m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers + m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic + m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian + m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian + m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya + m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary + m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi + m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols + m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform + m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation + m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals + m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese + m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha + m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki + m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra + m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li + m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang + m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham + m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols + m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc + m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian + m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian + m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian + m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles + m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles + // 27: "Reserved for process-internal usage" + // 28: "Reserved for process-internal usage" + // 29: "Reserved for process-internal usage" + // 30: "Reserved for process-internal usage" + // 31: "Reserved for process-internal usage" + } + + void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) + { + // определяем range и двигаем его в начало. + std::list::iterator iter = m_arRanges.begin(); + while (iter != m_arRanges.end()) + { + CUnicodeRange& range = *iter; + if (symbol >= range.Start && symbol <= range.End) + { + Range = range.Range; + RangeNum = range.RangeNum; + + m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); + return; + } + iter++; + } + } + + void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) + { + BYTE nRange = 0xFF; + BYTE nRangeNum = 0xFF; + CheckRange(symbol, nRange, nRangeNum); + + switch (nRangeNum) + { + case 0: Range1 |= (1 << nRange); break; + case 1: Range2 |= (1 << nRange); break; + case 2: Range3 |= (1 << nRange); break; + case 3: Range4 |= (1 << nRange); break; + default: + break; + } + } + + CFontAdvanced::CFontAdvanced() + { + m_oFont.SetDefaultParams(); + m_arSignature.clear(); + } + + CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) { *this = oSrc; } - CFontTableEntry& CFontTableEntry::operator =(const CFontTableEntry& oSrc) + CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) { if (this == &oSrc) - { return *this; - } - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; + m_oFont = oSrc.m_oFont; + + m_dAscent = oSrc.m_dAscent; + m_dDescent = oSrc.m_dDescent; + m_dLineSpacing = oSrc.m_dLineSpacing; + m_dEmHeight = oSrc.m_dEmHeight; + m_dBaselineOffset = oSrc.m_dBaselineOffset; + m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; + + m_strFamilyName = oSrc.m_strFamilyName; + + for(int i = 0; i < 10; i++) + m_arPANOSE[i] = oSrc.m_arPANOSE[i]; + + m_arSignature = oSrc.m_arSignature; + m_bIsFixedWidth = oSrc.m_bIsFixedWidth; + m_lAvgWidth = oSrc.m_lAvgWidth; return *this; } - CFontManager::CFontManager(NSFonts::IApplicationFonts* pFonts) : CFontManagerBase(pFonts) + CFontManager::CFontManager(NSFonts::IApplicationFonts* pApplication) { + m_pManager = pApplication->GenerateFontManager(); + m_pManager->CreateOwnerCache(8); + SetDefaultFont(L"Arial"); } - void CFontManager::Init() + CFontManager::~CFontManager() { - m_oFontTable.m_mapTable.clear(); - ClearPickUps(); + RELEASEINTERFACE(m_pManager); } - void CFontManager::AddFontToMap() + void CFontManager::SetFont(const NSStructures::CFont& oFont) { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_oFontAdvanced.m_strFamilyName)) - { - CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_oFontAdvanced.m_strFamilyName; - oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; - oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFontAdvanced.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; - - m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); - } + m_oFontAdvanced.m_oFont = oFont; + } + void CFontManager::SetTransform(const Aggplus::CMatrix* pTransform) + { + m_pTransform = pTransform; } - void CFontManager::LoadFont(long lFaceIndex, bool bNeedAddToMap) + void CFontManager::LoadFont() { if (nullptr == m_pManager) return; - double dSize = m_pFont->Size; + double dSize = m_oFontAdvanced.m_oFont.Size; double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); + double dPix = m_oFontAdvanced.m_oFont.CharSpace / c_dPixToMM; - double dPix = m_pFont->CharSpace / c_dPixToMM; - - m_pFont->Size = dSizeFont; + m_oFontAdvanced.m_oFont.Size = dSizeFont; - if (m_pFont->IsEqual2(&m_oFontAdvanced.m_oFont)) + if (m_oFontAdvanced.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) { - m_pFont->Size = dSize; + m_oFontAdvanced.m_oFont.Size = dSize; m_pManager->SetCharSpacing(dPix); return; } - m_oFontAdvanced.m_oFont = *m_pFont; - m_pFont->Size = dSize; + m_oFontAdvanced.m_oFont.Size = dSize; - if (m_pFont->Path.empty()) - { - CFontManagerBase::LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); - } + if (m_oFontAdvanced.m_oFont.Path.empty()) + LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); else - { - CFontManagerBase::LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, lFaceIndex); - - m_pFont->SetStyle(m_oFontAdvanced.m_lStyle); - m_oFontAdvanced.m_oFont.SetStyle(m_oFontAdvanced.m_lStyle); - } + LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, 0); int bIsGID = m_pManager->GetStringGID(); m_pManager->SetStringGID(FALSE); @@ -89,22 +319,15 @@ namespace NSDocxRenderer m_pManager->LoadString2(L" ", 0, 0); TBBox bbox = m_pManager->MeasureString2(); - m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - if (0 >= m_dSpaceWidthMM) - { - m_dSpaceWidthMM = 1.0; - } + m_oFontAdvanced.m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + if (0 >= m_oFontAdvanced.m_dSpaceWidthMM) + m_oFontAdvanced.m_dSpaceWidthMM = 1.0; m_pManager->SetStringGID(bIsGID); - - if (bNeedAddToMap) - AddFontToMap(); } void CFontManager::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) { - LoadFont(); - dBoxX = 0; dBoxY = 0; dBoxWidth = 0; @@ -117,13 +340,9 @@ namespace NSDocxRenderer TBBox bbox; if (mtGlyph == measureType) - { bbox = m_pManager->MeasureString(); - } else if (mtPosition == measureType) - { bbox = m_pManager->MeasureString2(); - } dBoxX = (double)bbox.fMinX; dBoxY = (double)bbox.fMinY; @@ -139,8 +358,6 @@ namespace NSDocxRenderer void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) { - LoadFont(); - dBoxX = 0; dBoxY = 0; dBoxWidth = 0; @@ -153,13 +370,9 @@ namespace NSDocxRenderer TBBox bbox; if (mtGlyph == measureType) - { bbox = m_pManager->MeasureString(); - } else if (mtPosition == measureType) - { bbox = m_pManager->MeasureString2(); - } dBoxX = (double)bbox.fMinX; dBoxY = (double)bbox.fMinY; @@ -173,17 +386,6 @@ namespace NSDocxRenderer dBoxHeight *= c_dPixToMM; } - double CFontManager::GetBaseLineOffset() - { - LoadFont(); - - double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; - d1 /= 2.0; - - d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - return d1; - } - double CFontManager::GetFontHeight() { return c_dPtToMM * (m_oFontAdvanced.m_dLineSpacing * m_oFontAdvanced.m_oFont.Size ) / m_oFontAdvanced.m_dEmHeight; @@ -195,64 +397,321 @@ namespace NSDocxRenderer m_pManager->SetStringGID(lGid); } - void CFontManager::GenerateFontName2(NSStringUtils::CStringUTF32& oText) + void CFontManager::SetDefaultFont(const std::wstring& strName) + { + m_strDefaultFont = strName; + } + + + void CFontManager::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) + { + m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontParams(); + m_oFontAdvanced.m_lAvgWidth = -1; + } + + void CFontManager::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) { - bool bIsNeedAddToMap = CFontManagerBase::GenerateFontName(oText); + m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontParams(); + m_oFontAdvanced.m_lAvgWidth = -1; + + m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); + m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; + + - if (bIsNeedAddToMap) + bool bIsCID = false; + std::wstring sFileExt = NSFile::GetFileExtention(strPath); + if (std::wstring::npos != sFileExt.find(L"cid")) + bIsCID = true; + + std::wstring sFileName = NSFile::GetFileName(strPath); + std::wstring::size_type pos = sFileName.rfind('.'); + if (std::wstring::npos != pos) + sFileName = sFileName.substr(0, pos); + std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; + + XmlUtils::CXmlNode oMainNode; + oMainNode.FromXmlFile(sEncFilePath); + + if (L"PDF-resources" == oMainNode.GetName()) { - if (m_oFontTable.m_mapTable.end() == m_oFontTable.m_mapTable.find(m_strCurrentPickFont)) + if (bIsCID) { - CFontTableEntry oEntry; - oEntry.m_strFamilyName = m_strCurrentPickFont; - oEntry.m_strPANOSE = m_oFontAdvanced.m_strPANOSE; - oEntry.m_lStyle = m_oFontAdvanced.m_lStyle; - oEntry.m_bIsFixedWidth = m_oFontAdvanced.m_bIsFixedWidth; - oEntry.m_arSignature = m_oFontAdvanced.m_arSignature; - - m_oFontTable.m_mapTable.insert(std::pair(m_oFontAdvanced.m_strFamilyName, oEntry)); + XmlUtils::CXmlNode oType0Node; + if ( oMainNode.GetNode( L"Type0", oType0Node ) ) + { + XmlUtils::CXmlNode oNode; + if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) + { + XmlUtils::CXmlNode oDescNode; + if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { + m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); + } catch (std::invalid_argument &) {} + } + } + } + } + } + else + { + XmlUtils::CXmlNode oNode; + if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) + { + XmlUtils::CXmlNode oCurNode; + if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) + { + std::wstring sValue = oCurNode.GetAttribute(L"value"); + try { + m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); + } catch (std::invalid_argument &) {} + } + } } } } - CFontManagerLight::CFontManagerLight(NSFonts::IApplicationFonts* pFonts) + void CFontManager::LoadFontMetrics() { - m_pManager = NSFontManager::CreateFontManager(pFonts); + m_oFontAdvanced.m_dAscent = m_pManager->GetAscender(); + m_oFontAdvanced.m_dDescent = m_pManager->GetDescender(); + m_oFontAdvanced.m_dLineSpacing = m_pManager->GetLineHeight(); + m_oFontAdvanced.m_dEmHeight = m_pManager->GetUnitsPerEm(); + + m_oFontAdvanced.m_dBaselineOffset = (c_dPtToMM * m_oFontAdvanced.m_dDescent * m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); } - CFontManagerLight::~CFontManagerLight() + void CFontManager::LoadFontParams() { - RELEASEINTERFACE(m_pManager); + // читаем и выставляем все настройки шрифта + if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) + return; + + m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; + m_oFontAdvanced.m_oFont.Bold = m_pManager->GetFile()->IsBold(); + m_oFontAdvanced.m_oFont.Italic = m_pManager->GetFile()->IsItalic(); + + // PANOSE + BYTE pPanose[10]; + m_pManager->GetFile()->GetPanose(pPanose); + + for(int i = 0; i < 10; ++i) + m_oFontAdvanced.m_arPANOSE[i] = pPanose[i]; + + // IsFixed + m_oFontAdvanced.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); + + // Signature + m_oFontAdvanced.m_arSignature.clear(); + + for ( unsigned int i = 0; i < 6; ++i ) + { + DWORD value = 0; + for ( unsigned long bit = 0; bit < 32; ++bit ) + if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) + value |= ( 1 << bit ); + + m_oFontAdvanced.m_arSignature.push_back(value); + } } - double CFontManagerLight::GetSpaceWidth() + void CFontManager::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) { - return m_dSpaceWidth; + if (0 == lRangeNum) + lRange1 |= 1 << lRange; + else if (1 == lRangeNum) + lRange2 |= 1 << lRange; + else if (2 == lRangeNum) + lRange3 |= 1 << lRange; + else + lRange4 |= 1 << lRange; } - void CFontManagerLight::LoadFont(std::wstring& strFontName, LONG& lStyle, const double& dSize, const bool& bIsGID) + bool CFontManager::GenerateFontName(NSStringUtils::CStringUTF32& oText) { - if ((strFontName == m_strFontName) && (lStyle == m_lFontStyle) && (dSize == m_dSize)) + if (m_oFontAdvanced.m_oFont.Path.empty() || oText.empty()) + return false; + + + BYTE lRangeNum = 0xFF; + BYTE lRange = 0xFF; + + m_oRanges.CheckRange(oText[0], lRange, lRangeNum); +// std::list::iterator posStart, pos; +// posStart = pos = m_arListPicUps.begin(); + +// while (m_arListPicUps.end() != pos) +// { +// std::list::iterator posOld = pos; +// CFontPickUp& oPick = *(pos++); +// if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) +// { +// // нашли! ничего подбирать не нужно +// // нужно просто выкинуть этот шрифт наверх +// m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); +// m_strCurrentPickFont = oPick.m_strPickFont; +// m_lCurrentPictFontStyle = oPick.m_lPickStyle; +// return false; +// } +// } + +// // не нашли... +// CFontPickUp oPick; +// oPick.m_lRangeNum = lRangeNum; +// oPick.m_lRange = lRange; +// oPick.m_oFont = m_oFontAdvanced; +// oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; +// oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; + + UINT dwR1 = m_oFontAdvanced.m_arSignature[0]; + UINT dwR2 = m_oFontAdvanced.m_arSignature[1]; + UINT dwR3 = m_oFontAdvanced.m_arSignature[2]; + UINT dwR4 = m_oFontAdvanced.m_arSignature[3]; + UINT dwCodePage1 = 0; + UINT dwCodePage2 = 0; + + if ((lRangeNum == 1) && (lRange == 28)) { - m_pManager->SetStringGID(bIsGID); - return; + dwCodePage1 = 0x80000000; + //strText = (WCHAR)(strText[0] - 0xF000); + } + else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) + { + // арабский язык!!! + dwR1 = 1 << 13; + dwR2 = 1 << 31; + dwR3 = 1 << 3; + } + else + { + CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); } - m_strFontName = strFontName; - m_lFontStyle = lStyle; - m_dSize = dSize; + NSFonts::CFontSelectFormat oFormat; - m_pManager->LoadFontByName(strFontName, m_dSize, m_lFontStyle, c_dDpiX, c_dDpiY); - m_dSpaceWidth = MeasureStringWidth(L" "); + std::wstring sFontNameSelect = L""; + if (m_oFontAdvanced.m_strFamilyName.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) + sFontNameSelect = m_strDefaultFont; + else + sFontNameSelect = m_oFontAdvanced.m_strFamilyName; + + bool bSelectBold = false; + bool bSelectItalic = false; + CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); + + oFormat.wsName = new std::wstring(sFontNameSelect); + oFormat.pPanose = m_oFontAdvanced.m_arPANOSE; + + oFormat.bBold = new INT(m_oFontAdvanced.m_oFont.Bold); + oFormat.bItalic = new INT(m_oFontAdvanced.m_oFont.Italic); + oFormat.bFixedWidth = new INT(m_oFontAdvanced.m_bIsFixedWidth ? 1 : 0); + if (-1 != m_oFontAdvanced.m_lAvgWidth) + oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFontAdvanced.m_lAvgWidth); + oFormat.ulRange1 = new UINT(dwR1); + oFormat.ulRange2 = new UINT(dwR2); + oFormat.ulRange3 = new UINT(dwR3); + oFormat.ulRange4 = new UINT(dwR4); + oFormat.ulCodeRange1 = new UINT(dwCodePage1); + oFormat.ulCodeRange2 = new UINT(dwCodePage2); + + // ??? + if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) + oFormat.pPanose[2] = 7; + + oFormat.wsDefaultName = new std::wstring(L"Arial"); + + NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); + +// oPick.m_strPickFont = pInfo->m_wsFontName; +// oPick.m_lPickStyle = 0; +// if (pInfo->m_bBold) +// oPick.m_lPickStyle |= 0x01; +// if (pInfo->m_bItalic) +// oPick.m_lPickStyle |= 0x02; + +// m_strCurrentPickFont = oPick.m_strPickFont; +// m_lCurrentPictFontStyle = oPick.m_lPickStyle; + +// m_arListPicUps.push_front(oPick); + return true; + } - m_pManager->SetStringGID(bIsGID); + bool CFontManager::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) + { + size_t nPos = 0; + size_t nLenReplace = sStyle.length(); + bool bRet = false; + + std::wstring sName2 = sName; + NSStringExt::ToLower(sName2); + + while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) + { + size_t nOffset = 0; + if ((nPos > 0) && sName2.at(nPos - 1) == '-') + { + --nPos; + ++nOffset; + } + + bRet = true; + sName.erase(nPos, nLenReplace + nOffset); + sName2.erase(nPos, nLenReplace + nOffset); + } + return bRet; } - double CFontManagerLight::MeasureStringWidth(const std::wstring& sText) + void CFontManager::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) { - m_pManager->LoadString2(sText, (float)0, (float)0); - TBBox bbox = m_pManager->MeasureString2(); + if (sName.length() > 7 && sName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; ++nIndex) + { + wchar_t nChar = sName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + { + sName.erase(0, 7); + } + } - return (bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + CheckFontNameStyle(sName, L"regular"); + CheckFontNameStyle(sName, L"condensed"); + CheckFontNameStyle(sName, L"condensedlight"); + //CheckFontNameStyle(sName, L"light"); + + CheckFontNameStyle(sName, L"condensedbold"); + CheckFontNameStyle(sName, L"semibold"); + if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; + if (CheckFontNameStyle(sName, L"bold")) bBold = true; + + if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; + if (CheckFontNameStyle(sName, L"italic")) bItalic = true; + if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; + + if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } } } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 43f3fa3d412..9a4a563d601 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -1,96 +1,119 @@ #pragma once -#include "FontManagerBase.h" +#include +#include + #include "../DesktopEditor/graphics/Matrix.h" +#include "../DesktopEditor/graphics/structures.h" +#include "../DesktopEditor/graphics/pro/Fonts.h" +#include "../DesktopEditor/common/StringUTF32.h" namespace NSDocxRenderer { - using namespace NSFontManager; - - class CFontTableEntry + class CUnicodeRange { public: - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; - - public: - CFontTableEntry(){} - virtual ~CFontTableEntry(){} + BYTE RangeNum {0}; + BYTE Range {0}; - CFontTableEntry(const CFontTableEntry& oSrc); + int Start {0}; + int End {0}; - CFontTableEntry& operator =(const CFontTableEntry& oSrc); + CUnicodeRange(const int& _start = 0, + const int& _end = 0, + const BYTE& _range = 0, + const BYTE& _rangenum = 0); }; - class CFontTable + // класс для проставления Ranges для подбора шрифта по символу + class CUnicodeRanges { public: - std::map m_mapTable; + std::list m_arRanges; public: - CFontTable() : m_mapTable(){} + CUnicodeRanges(); + void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); + void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); }; - class CFontManager : public CFontManagerBase + class CFontAdvanced { public: - NSStructures::CFont* m_pFont {nullptr}; - Aggplus::CMatrix* m_pTransform {nullptr}; - double m_dSpaceWidthMM {0.0}; + NSStructures::CFont m_oFont; + + // font metrics + double m_dAscent {0.0}; + double m_dDescent {0.0}; + double m_dLineSpacing {0.0}; + double m_dEmHeight {0.0}; + double m_dBaselineOffset {0.0}; + double m_dSpaceWidthMM {0.0}; + + // font params + std::wstring m_strFamilyName {L""}; + BYTE m_arPANOSE[10] {}; + std::vector m_arSignature; + SHORT m_lAvgWidth {-1}; + bool m_bIsFixedWidth {false}; public: - CFontTable m_oFontTable; + CFontAdvanced(); + CFontAdvanced(const CFontAdvanced& oSrc); + CFontAdvanced& operator=(const CFontAdvanced& oSrc); + }; + class CFontManager + { public: + enum MeasureType + { + mtGlyph = 0, + mtPosition = 1 + }; + CFontManager(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManager(){} + virtual ~CFontManager(); - public: - void Init(); + void LoadFont(); - void AddFontToMap(); + void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); + void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - public: - virtual void LoadFont(long lFaceIndex = 0, bool bNeedAddToMap = true); + void SetFont(const NSStructures::CFont& oFont); + void SetTransform(const Aggplus::CMatrix* pTransform); + + CFontAdvanced GetFontAdvanced() const noexcept; + + void SetDefaultFont(const std::wstring& strName); - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType); + bool GenerateFontName(NSStringUtils::CStringUTF32& oText); + + + void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, + double& dBoxWidth, double& dBoxHeight, MeasureType measureType); void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); - double GetBaseLineOffset(); - double GetFontHeight(); - void SetStringGid(const LONG& lGid); - void GenerateFontName2(NSStringUtils::CStringUTF32& oText); - }; - - class CFontManagerLight - { private: - std::wstring m_strFontName {L""}; - LONG m_lFontStyle {0}; - double m_dSize {0.0}; + NSFonts::IFontManager* m_pManager; + std::wstring m_strDefaultFont; - double m_dSpaceWidth {0.0}; + CFontAdvanced m_oFontAdvanced; + const Aggplus::CMatrix* m_pTransform; - NSFonts::IFontManager* m_pManager {nullptr}; + // для подбора шрифтов + CUnicodeRanges m_oRanges; - public: - CFontManagerLight(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerLight(); + void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); - double GetSpaceWidth(); + void LoadFontMetrics(); + void LoadFontParams(); - public: - void LoadFont(std::wstring& strFontName, LONG& lStyle, const double &dSize, const bool& bIsGID); - - double MeasureStringWidth(const std::wstring& sText); + bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); + void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); }; - } diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.cpp b/DocxRenderer/src/logic/managers/FontManagerBase.cpp deleted file mode 100644 index 81e0a9d6844..00000000000 --- a/DocxRenderer/src/logic/managers/FontManagerBase.cpp +++ /dev/null @@ -1,701 +0,0 @@ -#include "FontManagerBase.h" -#include "../DesktopEditor/common/Directory.h" -#include "../DesktopEditor/xml/include/xmlutils.h" -#include "src/resources/Constants.h" - -namespace NSFontManager -{ - CUnicodeRange::CUnicodeRange(const int& _start, const int& _end, - const BYTE& _range, const BYTE& _rangenum): - RangeNum(_rangenum), Range(_range), Start(_start), End(_end) - { - } - - CUnicodeRanges::CUnicodeRanges() - { - // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur - - m_arRanges.push_back(CUnicodeRange(0x0000, 0x007F, 0, 0)); // Basic Latin - m_arRanges.push_back(CUnicodeRange(0x0080, 0x00FF, 1, 0)); // Latin-1 Supplement - m_arRanges.push_back(CUnicodeRange(0x0100, 0x017F, 2, 0)); // Latin Extended-A - m_arRanges.push_back(CUnicodeRange(0x0180, 0x024F, 3, 0)); // Latin Extended-B - m_arRanges.push_back(CUnicodeRange(0x0250, 0x02AF, 4, 0)); // IPA Extensions - m_arRanges.push_back(CUnicodeRange(0x1D00, 0x1D7F, 4, 0)); // Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x1D80, 0x1DBF, 4, 0)); // Phonetic Extensions Supplement - m_arRanges.push_back(CUnicodeRange(0x02B0, 0x02FF, 5, 0)); // Spacing Modifier Letters - m_arRanges.push_back(CUnicodeRange(0xA700, 0xA71F, 5, 0)); // Modifier Tone Letters - m_arRanges.push_back(CUnicodeRange(0x0300, 0x036F, 6, 0)); // Combining Diacritical Marks - m_arRanges.push_back(CUnicodeRange(0x1DC0, 0x1DFF, 6, 0)); // Combining Diacritical Marks Supplement - m_arRanges.push_back(CUnicodeRange(0x0370, 0x03FF, 7, 0)); // Greek and Coptic - m_arRanges.push_back(CUnicodeRange(0x2C80, 0x2CFF, 8, 0)); // Coptic - m_arRanges.push_back(CUnicodeRange(0x0400, 0x04FF, 9, 0)); // Cyrillic - m_arRanges.push_back(CUnicodeRange(0x0500, 0x052F, 9, 0)); // Cyrillic Supplement - m_arRanges.push_back(CUnicodeRange(0x2DE0, 0x2DFF, 9, 0)); // Cyrillic Extended-A - m_arRanges.push_back(CUnicodeRange(0xA640, 0xA69F, 9, 0)); // Cyrillic Extended-B - m_arRanges.push_back(CUnicodeRange(0x0530, 0x058F, 10, 0)); // Armenian - m_arRanges.push_back(CUnicodeRange(0x0590, 0x05FF, 11, 0)); // Hebrew - m_arRanges.push_back(CUnicodeRange(0xA500, 0xA63F, 12, 0)); // Vai - m_arRanges.push_back(CUnicodeRange(0x0600, 0x06FF, 13, 0)); // Arabic - m_arRanges.push_back(CUnicodeRange(0x0750, 0x077F, 13, 0)); // Arabic Supplement - m_arRanges.push_back(CUnicodeRange(0x07C0, 0x07FF, 14, 0)); // NKo - m_arRanges.push_back(CUnicodeRange(0x0900, 0x097F, 15, 0)); // Devanagari - m_arRanges.push_back(CUnicodeRange(0x0980, 0x09FF, 16, 0)); // Bengali - m_arRanges.push_back(CUnicodeRange(0x0A00, 0x0A7F, 17, 0)); // Gurmukhi - m_arRanges.push_back(CUnicodeRange(0x0A80, 0x0AFF, 18, 0)); // Gujarati - m_arRanges.push_back(CUnicodeRange(0x0B00, 0x0B7F, 19, 0)); // Oriya - m_arRanges.push_back(CUnicodeRange(0x0B80, 0x0BFF, 20, 0)); // Tamil - m_arRanges.push_back(CUnicodeRange(0x0C00, 0x0C7F, 21, 0)); // Telugu - m_arRanges.push_back(CUnicodeRange(0x0C80, 0x0CFF, 22, 0)); // Kannada - m_arRanges.push_back(CUnicodeRange(0x0D00, 0x0D7F, 23, 0)); // Malayalam - m_arRanges.push_back(CUnicodeRange(0x0E00, 0x0E7F, 24, 0)); // Thai - m_arRanges.push_back(CUnicodeRange(0x0E80, 0x0EFF, 25, 0)); // Lao - m_arRanges.push_back(CUnicodeRange(0x10A0, 0x10FF, 26, 0)); // Georgian - m_arRanges.push_back(CUnicodeRange(0x2D00, 0x2D2F, 26, 0)); // Georgian Supplement - m_arRanges.push_back(CUnicodeRange(0x1B00, 0x1B7F, 27, 0)); // Balinese - m_arRanges.push_back(CUnicodeRange(0x1100, 0x11FF, 28, 0)); // Hangul Jamo - m_arRanges.push_back(CUnicodeRange(0x1E00, 0x1EFF, 29, 0)); // Latin Extended Additional - m_arRanges.push_back(CUnicodeRange(0x2C60, 0x2C7F, 29, 0)); // Latin Extended-C - m_arRanges.push_back(CUnicodeRange(0xA720, 0xA7FF, 29, 0)); // Latin Extended-D - m_arRanges.push_back(CUnicodeRange(0x1F00, 0x1FFF, 30, 0)); // Greek Extended - m_arRanges.push_back(CUnicodeRange(0x2000, 0x206F, 31, 0)); // General Punctuation - m_arRanges.push_back(CUnicodeRange(0x2E00, 0x2E7F, 31, 0)); // Supplemental Punctuation - - m_arRanges.push_back(CUnicodeRange(0x2070, 0x209F, 0, 1)); // Superscripts And Subscripts - m_arRanges.push_back(CUnicodeRange(0x20A0, 0x20CF, 1, 1)); // Currency Symbols - m_arRanges.push_back(CUnicodeRange(0x20D0, 0x20FF, 2, 1)); // Combining Diacritical Marks For Symbols - m_arRanges.push_back(CUnicodeRange(0x2100, 0x214F, 3, 1)); // Letterlike Symbols - m_arRanges.push_back(CUnicodeRange(0x2150, 0x218F, 4, 1)); // Number Forms - m_arRanges.push_back(CUnicodeRange(0x2190, 0x21FF, 5, 1)); // Arrows - m_arRanges.push_back(CUnicodeRange(0x27F0, 0x27FF, 5, 1)); // Supplemental Arrows-A - m_arRanges.push_back(CUnicodeRange(0x2900, 0x297F, 5, 1)); // Supplemental Arrows-B - m_arRanges.push_back(CUnicodeRange(0x2B00, 0x2BFF, 5, 1)); // Miscellaneous Symbols and Arrows - m_arRanges.push_back(CUnicodeRange(0x2200, 0x22FF, 6, 1)); // Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x2A00, 0x2AFF, 6, 1)); // Supplemental Mathematical Operators - m_arRanges.push_back(CUnicodeRange(0x27C0, 0x27EF, 6, 1)); // Miscellaneous Mathematical Symbols-A - m_arRanges.push_back(CUnicodeRange(0x2980, 0x29FF, 6, 1)); // Miscellaneous Mathematical Symbols-B - m_arRanges.push_back(CUnicodeRange(0x2300, 0x23FF, 7, 1)); // Miscellaneous Technical - m_arRanges.push_back(CUnicodeRange(0x2400, 0x243F, 8, 1)); // Control Pictures - m_arRanges.push_back(CUnicodeRange(0x2440, 0x245F, 9, 1)); // Optical Character Recognition - m_arRanges.push_back(CUnicodeRange(0x2460, 0x24FF, 10, 1)); // Enclosed Alphanumerics - m_arRanges.push_back(CUnicodeRange(0x2500, 0x257F, 11, 1)); // Box Drawing - m_arRanges.push_back(CUnicodeRange(0x2580, 0x259F, 12, 1)); // Block Elements - m_arRanges.push_back(CUnicodeRange(0x25A0, 0x25FF, 13, 1)); // Geometric Shapes - m_arRanges.push_back(CUnicodeRange(0x2600, 0x26FF, 14, 1)); // Miscellaneous Symbols - m_arRanges.push_back(CUnicodeRange(0x2700, 0x27BF, 15, 1)); // Dingbats - m_arRanges.push_back(CUnicodeRange(0x3000, 0x303F, 16, 1)); // CJK Symbols And Punctuation - m_arRanges.push_back(CUnicodeRange(0x3040, 0x309F, 17, 1)); // Hiragana - m_arRanges.push_back(CUnicodeRange(0x30A0, 0x30FF, 18, 1)); // Katakana - m_arRanges.push_back(CUnicodeRange(0x31F0, 0x31FF, 18, 1)); // Katakana Phonetic Extensions - m_arRanges.push_back(CUnicodeRange(0x3100, 0x312F, 19, 1)); // Bopomofo - m_arRanges.push_back(CUnicodeRange(0x31A0, 0x31BF, 19, 1)); // Bopomofo Extended - m_arRanges.push_back(CUnicodeRange(0x3130, 0x318F, 20, 1)); // Hangul Compatibility Jamo - m_arRanges.push_back(CUnicodeRange(0xA840, 0xA87F, 21, 1)); // Phags-pa - m_arRanges.push_back(CUnicodeRange(0x3200, 0x32FF, 22, 1)); // Enclosed CJK Letters And Months - m_arRanges.push_back(CUnicodeRange(0x3300, 0x33FF, 23, 1)); // CJK Compatibility - m_arRanges.push_back(CUnicodeRange(0xAC00, 0xD7AF, 24, 1)); // Hangul Syllables - m_arRanges.push_back(CUnicodeRange(0x10000, 0x10FFFF, 25, 1)); // Non-Plane 0 - m_arRanges.push_back(CUnicodeRange(0x10900, 0x1091F, 26, 1)); // Phoenician - m_arRanges.push_back(CUnicodeRange(0x4E00, 0x9FFF, 27, 1)); // CJK Unified Ideographs - m_arRanges.push_back(CUnicodeRange(0x2E80, 0x2EFF, 27, 1)); // CJK Radicals Supplement - m_arRanges.push_back(CUnicodeRange(0x2F00, 0x2FDF, 27, 1)); // Kangxi Radicals - m_arRanges.push_back(CUnicodeRange(0x2FF0, 0x2FFF, 27, 1)); // Ideographic Description Characters - m_arRanges.push_back(CUnicodeRange(0x3400, 0x4DBF, 27, 1)); // CJK Unified Ideographs Extension A - m_arRanges.push_back(CUnicodeRange(0x3190, 0x319F, 27, 1)); // Kanbun - m_arRanges.push_back(CUnicodeRange(0x20000, 0x2A6DF, 27, 1)); // CJK Unified Ideographs Extension B - m_arRanges.push_back(CUnicodeRange(0xE000, 0xF8FF, 28, 1)); // Private Use Area (plane 0) - m_arRanges.push_back(CUnicodeRange(0x31C0, 0x31EF, 29, 1)); // CJK Strokes - m_arRanges.push_back(CUnicodeRange(0xF900, 0xFAFF, 29, 1)); // CJK Compatibility Ideographs - m_arRanges.push_back(CUnicodeRange(0x2F800, 0x2FA1F, 29, 1)); // CJK Compatibility Ideographs Supplement - m_arRanges.push_back(CUnicodeRange(0xFB00, 0xFB4F, 30, 1)); // Alphabetic Presentation Forms - m_arRanges.push_back(CUnicodeRange(0xFB50, 0xFDFF, 31, 1)); // Arabic Presentation Forms-A - - m_arRanges.push_back(CUnicodeRange(0xFE20, 0xFE2F, 0, 2)); // Combining Half Marks - m_arRanges.push_back(CUnicodeRange(0xFE10, 0xFE1F, 1, 2)); // Vertical Forms - m_arRanges.push_back(CUnicodeRange(0xFE30, 0xFE4F, 1, 2)); // CJK Compatibility Forms - m_arRanges.push_back(CUnicodeRange(0xFE50, 0xFE6F, 2, 2)); // Small Form Variants - m_arRanges.push_back(CUnicodeRange(0xFE70, 0xFEFF, 3, 2)); // Arabic Presentation Forms-B - m_arRanges.push_back(CUnicodeRange(0xFF00, 0xFFEF, 4, 2)); // Halfwidth And Fullwidth Forms - m_arRanges.push_back(CUnicodeRange(0xFFF0, 0xFFFF, 5, 2)); // Specials - m_arRanges.push_back(CUnicodeRange(0x0F00, 0x0FFF, 6, 2)); // Tibetan - m_arRanges.push_back(CUnicodeRange(0x0700, 0x074F, 7, 2)); // Syriac - m_arRanges.push_back(CUnicodeRange(0x0780, 0x07BF, 8, 2)); // Thaana - m_arRanges.push_back(CUnicodeRange(0x0D80, 0x0DFF, 9, 2)); // Sinhala - m_arRanges.push_back(CUnicodeRange(0x1000, 0x109F, 10, 2)); // Myanmar - m_arRanges.push_back(CUnicodeRange(0x1200, 0x137F, 11, 2)); // Ethiopic - m_arRanges.push_back(CUnicodeRange(0x1380, 0x139F, 11, 2)); // Ethiopic Supplement - m_arRanges.push_back(CUnicodeRange(0x2D80, 0x2DDF, 11, 2)); // Ethiopic Extended - m_arRanges.push_back(CUnicodeRange(0x13A0, 0x13FF, 12, 2)); // Cherokee - m_arRanges.push_back(CUnicodeRange(0x1400, 0x167F, 13, 2)); // Unified Canadian Aboriginal Syllabics - m_arRanges.push_back(CUnicodeRange(0x1680, 0x169F, 14, 2)); // Ogham - m_arRanges.push_back(CUnicodeRange(0x16A0, 0x16FF, 15, 2)); // Runic - m_arRanges.push_back(CUnicodeRange(0x1780, 0x17FF, 16, 2)); // Khmer - m_arRanges.push_back(CUnicodeRange(0x19E0, 0x19FF, 16, 2)); // Khmer Symbols - m_arRanges.push_back(CUnicodeRange(0x1800, 0x18AF, 17, 2)); // Mongolian - m_arRanges.push_back(CUnicodeRange(0x2800, 0x28FF, 18, 2)); // Braille Patterns - m_arRanges.push_back(CUnicodeRange(0xA000, 0xA48F, 19, 2)); // Yi Syllables - m_arRanges.push_back(CUnicodeRange(0xA490, 0xA4CF, 19, 2)); // Yi Radicals - m_arRanges.push_back(CUnicodeRange(0x1700, 0x171F, 20, 2)); // Tagalog - m_arRanges.push_back(CUnicodeRange(0x1720, 0x173F, 20, 2)); // Hanunoo - m_arRanges.push_back(CUnicodeRange(0x1740, 0x175F, 20, 2)); // Buhid - m_arRanges.push_back(CUnicodeRange(0x1760, 0x177F, 20, 2)); // Tagbanwa - m_arRanges.push_back(CUnicodeRange(0x10300, 0x1032F, 21, 2)); // Old Italic - m_arRanges.push_back(CUnicodeRange(0x10330, 0x1034F, 22, 2)); // Gothic - m_arRanges.push_back(CUnicodeRange(0x10400, 0x1044F, 23, 2)); // Deseret - m_arRanges.push_back(CUnicodeRange(0x1D000, 0x1D0FF, 24, 2)); // Byzantine Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D100, 0x1D1FF, 24, 2)); // Musical Symbols - m_arRanges.push_back(CUnicodeRange(0x1D200, 0x1D24F, 24, 2)); // Ancient Greek Musical Notation - m_arRanges.push_back(CUnicodeRange(0x1D400, 0x1D7FF, 25, 2)); // Mathematical Alphanumeric Symbols - m_arRanges.push_back(CUnicodeRange(0xF0000, 0xFFFFD, 26, 2)); // Private Use (plane 15) - m_arRanges.push_back(CUnicodeRange(0x100000, 0x10FFFD, 26, 2)); // Private Use (plane 16) - m_arRanges.push_back(CUnicodeRange(0xFE00, 0xFE0F, 27, 2)); // Variation Selectors - m_arRanges.push_back(CUnicodeRange(0xE0100, 0xE01EF, 27, 2)); // Variation Selectors Supplement - m_arRanges.push_back(CUnicodeRange(0xE0000, 0xE007F, 28, 2)); // Tags - m_arRanges.push_back(CUnicodeRange(0x1900, 0x194F, 29, 2)); // Limbu - m_arRanges.push_back(CUnicodeRange(0x1950, 0x197F, 30, 2)); // Tai Le - m_arRanges.push_back(CUnicodeRange(0x1980, 0x19DF, 31, 2)); // New Tai Lue - - m_arRanges.push_back(CUnicodeRange(0x1A00, 0x1A1F, 0, 3)); // Buginese - m_arRanges.push_back(CUnicodeRange(0x2C00, 0x2C5F, 1, 3)); // Glagolitic - m_arRanges.push_back(CUnicodeRange(0x2D30, 0x2D7F, 2, 3)); // Tifinagh - m_arRanges.push_back(CUnicodeRange(0x4DC0, 0x4DFF, 3, 3)); // Yijing Hexagram Symbols - m_arRanges.push_back(CUnicodeRange(0xA800, 0xA82F, 4, 3)); // Syloti Nagri - m_arRanges.push_back(CUnicodeRange(0x10000, 0x1007F, 5, 3)); // Linear B Syllabary - m_arRanges.push_back(CUnicodeRange(0x10080, 0x100FF, 5, 3)); // Linear B Ideograms - m_arRanges.push_back(CUnicodeRange(0x10100, 0x1013F, 5, 3)); // Aegean Numbers - m_arRanges.push_back(CUnicodeRange(0x10140, 0x1018F, 6, 3)); // Ancient Greek Numbers - m_arRanges.push_back(CUnicodeRange(0x10380, 0x1039F, 7, 3)); // Ugaritic - m_arRanges.push_back(CUnicodeRange(0x103A0, 0x103DF, 8, 3)); // Old Persian - m_arRanges.push_back(CUnicodeRange(0x10450, 0x1047F, 9, 3)); // Shavian - m_arRanges.push_back(CUnicodeRange(0x10480, 0x104AF, 10, 3)); // Osmanya - m_arRanges.push_back(CUnicodeRange(0x10800, 0x1083F, 11, 3)); // Cypriot Syllabary - m_arRanges.push_back(CUnicodeRange(0x10A00, 0x10A5F, 12, 3)); // Kharoshthi - m_arRanges.push_back(CUnicodeRange(0x1D300, 0x1D35F, 13, 3)); // Tai Xuan Jing Symbols - m_arRanges.push_back(CUnicodeRange(0x12000, 0x123FF, 14, 3)); // Cuneiform - m_arRanges.push_back(CUnicodeRange(0x12400, 0x1247F, 14, 3)); // Cuneiform Numbers and Punctuation - m_arRanges.push_back(CUnicodeRange(0x1D360, 0x1D37F, 15, 3)); // Counting Rod Numerals - m_arRanges.push_back(CUnicodeRange(0x1B80, 0x1BBF, 16, 3)); // Sundanese - m_arRanges.push_back(CUnicodeRange(0x1C00, 0x1C4F, 17, 3)); // Lepcha - m_arRanges.push_back(CUnicodeRange(0x1C50, 0x1C7F, 18, 3)); // Ol Chiki - m_arRanges.push_back(CUnicodeRange(0xA880, 0xA8DF, 19, 3)); // Saurashtra - m_arRanges.push_back(CUnicodeRange(0xA900, 0xA92F, 20, 3)); // Kayah Li - m_arRanges.push_back(CUnicodeRange(0xA930, 0xA95F, 21, 3)); // Rejang - m_arRanges.push_back(CUnicodeRange(0xAA00, 0xAA5F, 22, 3)); // Cham - m_arRanges.push_back(CUnicodeRange(0x10190, 0x101CF, 23, 3)); // Ancient Symbols - m_arRanges.push_back(CUnicodeRange(0x101D0, 0x101FF, 24, 3)); // Phaistos Disc - m_arRanges.push_back(CUnicodeRange(0x102A0, 0x102DF, 25, 3)); // Carian - m_arRanges.push_back(CUnicodeRange(0x10280, 0x1029F, 25, 3)); // Lycian - m_arRanges.push_back(CUnicodeRange(0x10920, 0x1093F, 25, 3)); // Lydian - m_arRanges.push_back(CUnicodeRange(0x1F030, 0x1F09F, 26, 3)); // Domino Tiles - m_arRanges.push_back(CUnicodeRange(0x1F000, 0x1F02F, 26, 3)); // Mahjong Tiles - // 27: "Reserved for process-internal usage" - // 28: "Reserved for process-internal usage" - // 29: "Reserved for process-internal usage" - // 30: "Reserved for process-internal usage" - // 31: "Reserved for process-internal usage" - } - - void CUnicodeRanges::CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum) - { - // определяем range и двигаем его в начало. - std::list::iterator iter = m_arRanges.begin(); - while (iter != m_arRanges.end()) - { - CUnicodeRange& range = *iter; - if (symbol >= range.Start && symbol <= range.End) - { - Range = range.Range; - RangeNum = range.RangeNum; - - m_arRanges.splice(m_arRanges.begin(), m_arRanges, iter); - return; - } - iter++; - } - } - - void CUnicodeRanges::CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4) - { - BYTE nRange = 0xFF; - BYTE nRangeNum = 0xFF; - CheckRange(symbol, nRange, nRangeNum); - - switch (nRangeNum) - { - case 0: Range1 |= (1 << nRange); break; - case 1: Range2 |= (1 << nRange); break; - case 2: Range3 |= (1 << nRange); break; - case 3: Range4 |= (1 << nRange); break; - default: - break; - } - } - - CFontAdvanced::CFontAdvanced() - { - m_oFont.SetDefaultParams(); - m_arSignature.clear(); - } - - CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) - { - *this = oSrc; - } - - CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - - m_dAscent = oSrc.m_dAscent; - m_dDescent = oSrc.m_dDescent; - m_dLineSpacing = oSrc.m_dLineSpacing; - m_dEmHeight = oSrc.m_dEmHeight; - - m_dBaselineOffset = oSrc.m_dBaselineOffset; - - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_strFamilyName = oSrc.m_strFamilyName; - m_strPANOSE = oSrc.m_strPANOSE; - m_lStyle = oSrc.m_lStyle; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - m_lAvgWidth = oSrc.m_lAvgWidth; - - return *this; - } - - CFontPickUp::CFontPickUp() : m_oFont() - { - } - - CFontPickUp::CFontPickUp(const CFontPickUp& oSrc) - { - *this = oSrc; - } - - CFontPickUp& CFontPickUp::operator=(const CFontPickUp& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_oFont = oSrc.m_oFont; - m_lRange = oSrc.m_lRange; - m_lRangeNum = oSrc.m_lRangeNum; - m_strPickFont = oSrc.m_strPickFont; - m_lPickStyle = oSrc.m_lPickStyle; - - return *this; - } - - CFontManagerBase::CFontManagerBase(NSFonts::IApplicationFonts* pFonts) - { - m_pManager = NSFontManager::CreateFontManager(pFonts); - - SetDefaultFont(L"Arial"); - - ClearPickUps(); - } - - CFontManagerBase::~CFontManagerBase() - { - RELEASEINTERFACE(m_pManager); - } - - void CFontManagerBase::ClearPickUps() - { - m_arListPicUps.clear(); - m_strCurrentPickFont = L""; - m_lCurrentPictFontStyle = 0; - } - - void CFontManagerBase::SetDefaultFont(const std::wstring& strName) - { - m_strDefaultFont = strName; - } - - std::wstring CFontManagerBase::GetDefaultFont() - { - return m_strDefaultFont; - } - - void CFontManagerBase::LoadFont(long lFaceIndex, bool bIsNeedAddToMap) - { - } - - void CFontManagerBase::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) - { - m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); - m_pManager->AfterLoad(); - - LoadFontMetrics(); - LoadFontParams(); - - m_oFontAdvanced.m_lAvgWidth = -1; - } - - void CFontManagerBase::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); - m_pManager->AfterLoad(); - - LoadFontMetrics(); - LoadFontParams(); - m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); - m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; - - m_oFontAdvanced.m_lAvgWidth = -1; - - bool bIsCID = false; - std::wstring sFileExt = NSFile::GetFileExtention(strPath); - if (std::wstring::npos != sFileExt.find(L"cid")) - bIsCID = true; - - std::wstring sFileName = NSFile::GetFileName(strPath); - std::wstring::size_type pos = sFileName.rfind('.'); - if (std::wstring::npos != pos) - sFileName = sFileName.substr(0, pos); - std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; - - XmlUtils::CXmlNode oMainNode; - oMainNode.FromXmlFile(sEncFilePath); - - if (L"PDF-resources" == oMainNode.GetName()) - { - if (bIsCID) - { - XmlUtils::CXmlNode oType0Node; - if ( oMainNode.GetNode( L"Type0", oType0Node ) ) - { - XmlUtils::CXmlNode oNode; - if ( oType0Node.GetNode( L"DescendantFonts", oNode ) ) - { - XmlUtils::CXmlNode oDescNode; - if ( oNode.GetNode( L"FontDescriptor", oDescNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { - m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } - else - { - XmlUtils::CXmlNode oNode; - if ( oMainNode.GetNode( L"FontDescriptor", oNode ) ) - { - XmlUtils::CXmlNode oCurNode; - if ( oNode.GetNode( L"AvgWidth", oCurNode ) ) - { - std::wstring sValue = oCurNode.GetAttribute(L"value"); - try { - m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); - } catch (std::invalid_argument &) {} - } - } - } - } - } - - void CFontManagerBase::CalculateBaselineOffset() - { - LoadFont(); - - double d1 = 3 * (m_oFontAdvanced.m_dLineSpacing - m_oFontAdvanced.m_dDescent) - m_oFontAdvanced.m_dAscent; - d1 /= 2.0; - - d1 *= (m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - m_oFontAdvanced.m_dBaselineOffset = d1; - } - - void CFontManagerBase::LoadFontMetrics() - { - m_oFontAdvanced.m_dAscent = m_pManager->GetAscender(); - m_oFontAdvanced.m_dDescent = m_pManager->GetDescender(); - m_oFontAdvanced.m_dLineSpacing = m_pManager->GetLineHeight(); - m_oFontAdvanced.m_dEmHeight = m_pManager->GetUnitsPerEm(); - - m_oFontAdvanced.m_dBaselineOffset = (c_dPtToMM * m_oFontAdvanced.m_dDescent * m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - } - - std::wstring CFontManagerBase::ToHexString( BYTE uc ) - { - std::wstring sRet = L""; - char c1 = (char)(uc >> 4); - char c2 = (char)(uc & 0x0F); - sRet += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); - sRet += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); - return sRet; - } - - BYTE CFontManagerBase::FromHexString( wchar_t c1, wchar_t c2 ) - { - BYTE res = 0; - res |= ((c1 >= 'A') ? (c1 - 'A' + 10) : (c1 - '0')); - res <<= 4; - res |= ((c2 >= 'A') ? (c2 - 'A' + 10) : (c2 - '0')); - return res; - } - - void CFontManagerBase::LoadFontParams(bool bIsPath) - { - // читаем и выставляем все настройки шрифта - if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) - return; - - m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; - - m_oFontAdvanced.m_lStyle = 0x00; - if (m_pManager->GetFile()->IsBold()) - { - m_oFontAdvanced.m_lStyle |= 0x01; - } - if (m_pManager->GetFile()->IsItalic()) - { - m_oFontAdvanced.m_lStyle |= 0x02; - } - - // PANOSE - BYTE pPanose[10]; - m_pManager->GetFile()->GetPanose(pPanose); - m_oFontAdvanced.m_strPANOSE.clear(); - for ( int i = 0; i < 10; ++i ) - { - m_oFontAdvanced.m_strPANOSE += ToHexString(pPanose[i]); - } - - // IsFixed - m_oFontAdvanced.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); - - // Signature - m_oFontAdvanced.m_arSignature.clear(); - - for ( unsigned int i = 0; i < 6; ++i ) - { - DWORD value = 0; - - for ( unsigned long bit = 0; bit < 32; ++bit ) - { - if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) - { - value |= ( 1 << bit ); - } - } - - m_oFontAdvanced.m_arSignature.push_back(value); - } - } - - void CFontManagerBase::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - - bool CFontManagerBase::GenerateFontName(NSStringUtils::CStringUTF32& oText) - { - if (m_oFontAdvanced.m_oFont.Path.empty() || oText.empty()) - { - m_strCurrentPickFont = m_oFontAdvanced.m_strFamilyName; - m_lCurrentPictFontStyle = m_oFontAdvanced.m_lStyle; - return false; - } - - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; - - m_oRanges.CheckRange(oText[0], lRange, lRangeNum); - std::list::iterator posStart, pos; - posStart = pos = m_arListPicUps.begin(); - - while (m_arListPicUps.end() != pos) - { - std::list::iterator posOld = pos; - CFontPickUp& oPick = *(pos++); - if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) - { - // нашли! ничего подбирать не нужно - // нужно просто выкинуть этот шрифт наверх - m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - return false; - } - } - - // не нашли... - CFontPickUp oPick; - oPick.m_lRangeNum = lRangeNum; - oPick.m_lRange = lRange; - oPick.m_oFont = m_oFontAdvanced; - oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; - oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; - - UINT dwR1 = m_oFontAdvanced.m_arSignature[0]; - UINT dwR2 = m_oFontAdvanced.m_arSignature[1]; - UINT dwR3 = m_oFontAdvanced.m_arSignature[2]; - UINT dwR4 = m_oFontAdvanced.m_arSignature[3]; - UINT dwCodePage1 = 0; - UINT dwCodePage2 = 0; - - if ((lRangeNum == 1) && (lRange == 28)) - { - dwCodePage1 = 0x80000000; - //strText = (WCHAR)(strText[0] - 0xF000); - } - else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) - { - // арабский язык!!! - dwR1 = 1 << 13; - dwR2 = 1 << 31; - dwR3 = 1 << 3; - } - else - { - CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); - } - - NSFonts::CFontSelectFormat oFormat; - - std::wstring sFontNameSelect = L""; - if (m_oFontAdvanced.m_strFamilyName.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) - sFontNameSelect = m_strDefaultFont; - else - sFontNameSelect = m_oFontAdvanced.m_strFamilyName; - - bool bSelectBold = false; - bool bSelectItalic = false; - CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - - oFormat.wsName = new std::wstring(sFontNameSelect); - - if (!m_oFontAdvanced.m_strPANOSE.empty()) - { - oFormat.pPanose = new BYTE[10]; - - const wchar_t* pPanoseStr = m_oFontAdvanced.m_strPANOSE.c_str(); - for (int i = 0; i < 10; ++i) - { - oFormat.pPanose[i] = FromHexString(pPanoseStr[0], pPanoseStr[1]); - pPanoseStr += 2; - } - } - - oFormat.bBold = new INT(((m_oFontAdvanced.m_lStyle & 0x01) == 0x01) ? 1 : 0); - oFormat.bItalic = new INT(((m_oFontAdvanced.m_lStyle & 0x02) == 0x02) ? 1 : 0); - oFormat.bFixedWidth = new INT(m_oFontAdvanced.m_bIsFixedWidth ? 1 : 0); - if (-1 != m_oFontAdvanced.m_lAvgWidth) - oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFontAdvanced.m_lAvgWidth); - oFormat.ulRange1 = new UINT(dwR1); - oFormat.ulRange2 = new UINT(dwR2); - oFormat.ulRange3 = new UINT(dwR3); - oFormat.ulRange4 = new UINT(dwR4); - oFormat.ulCodeRange1 = new UINT(dwCodePage1); - oFormat.ulCodeRange2 = new UINT(dwCodePage2); - - // ??? - if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) - oFormat.pPanose[2] = 7; - - oFormat.wsDefaultName = new std::wstring(L"Arial"); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - - oPick.m_strPickFont = pInfo->m_wsFontName; - oPick.m_lPickStyle = 0; - if (pInfo->m_bBold) - oPick.m_lPickStyle |= 0x01; - if (pInfo->m_bItalic) - oPick.m_lPickStyle |= 0x02; - - m_strCurrentPickFont = oPick.m_strPickFont; - m_lCurrentPictFontStyle = oPick.m_lPickStyle; - - m_arListPicUps.push_front(oPick); - return true; - } - - bool CFontManagerBase::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) - { - size_t nPos = 0; - size_t nLenReplace = sStyle.length(); - bool bRet = false; - - std::wstring sName2 = sName; - NSStringExt::ToLower(sName2); - - while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) - { - size_t nOffset = 0; - if ((nPos > 0) && sName2.at(nPos - 1) == '-') - { - --nPos; - ++nOffset; - } - - bRet = true; - sName.erase(nPos, nLenReplace + nOffset); - sName2.erase(nPos, nLenReplace + nOffset); - } - return bRet; - } - - void CFontManagerBase::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) - { - if (sName.length() > 7 && sName.at(6) == '+') - { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - wchar_t nChar = sName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } - } - if (bIsRemove) - { - sName.erase(0, 7); - } - } - - CheckFontNameStyle(sName, L"regular"); - CheckFontNameStyle(sName, L"condensed"); - CheckFontNameStyle(sName, L"condensedlight"); - //CheckFontNameStyle(sName, L"light"); - - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); - if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; - - if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - - if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } - } -} diff --git a/DocxRenderer/src/logic/managers/FontManagerBase.h b/DocxRenderer/src/logic/managers/FontManagerBase.h deleted file mode 100644 index 6c95e42bf8e..00000000000 --- a/DocxRenderer/src/logic/managers/FontManagerBase.h +++ /dev/null @@ -1,155 +0,0 @@ -#pragma once -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" -#include "../DesktopEditor/common/StringUTF32.h" -#include - -namespace NSFontManager -{ - static NSFonts::IFontManager* CreateFontManager(NSFonts::IApplicationFonts* pApplication) - { - NSFonts::IFontManager* pManager = pApplication->GenerateFontManager(); - pManager->CreateOwnerCache(8); - return pManager; - } - - class CUnicodeRange - { - public: - BYTE RangeNum {0}; - BYTE Range {0}; - - int Start {0}; - int End {0}; - - CUnicodeRange(const int& _start = 0, - const int& _end = 0, - const BYTE& _range = 0, - const BYTE& _rangenum = 0); - }; - - // класс для проставления Ranges для подбора шрифта по символу - class CUnicodeRanges - { - public: - std::list m_arRanges; - - public: - CUnicodeRanges(); - - void CheckRange(const int& symbol, BYTE& Range, BYTE& RangeNum); - - void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); - }; - - class CFontAdvanced - { - public: - NSStructures::CFont m_oFont; - - // font metrics - double m_dAscent {0.0}; - double m_dDescent {0.0}; - double m_dLineSpacing {0.0}; - double m_dEmHeight {0.0}; - - double m_dBaselineOffset {0.0}; - - double m_dSpaceWidthMM {0.0}; - - // font params - std::wstring m_strFamilyName {L""}; - std::wstring m_strPANOSE {L""}; - LONG m_lStyle {0}; - std::vector m_arSignature; - bool m_bIsFixedWidth {false}; - SHORT m_lAvgWidth {-1}; - - public: - CFontAdvanced(); - - CFontAdvanced(const CFontAdvanced& oSrc); - - CFontAdvanced& operator=(const CFontAdvanced& oSrc); - }; - - class CFontPickUp - { - public: - CFontAdvanced m_oFont; - BYTE m_lRangeNum {0xFF}; - BYTE m_lRange {0xFF}; - std::wstring m_strPickFont {L""}; - LONG m_lPickStyle {0}; - - public: - CFontPickUp(); - CFontPickUp(const CFontPickUp& oSrc); - CFontPickUp& operator=(const CFontPickUp& oSrc); - }; - - class CFontManagerBase - { - public: - enum MeasureType - { - mtGlyph = 0, - mtPosition = 1 - }; - - protected: - NSFonts::IFontManager* m_pManager; - std::wstring m_strDefaultFont; - - public: - - CFontAdvanced m_oFontAdvanced; - - //для подбора шрифтов - CUnicodeRanges m_oRanges; - - std::list m_arListPicUps; - std::wstring m_strCurrentPickFont; - LONG m_lCurrentPictFontStyle; - - public: - CFontManagerBase(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManagerBase(); - - void ClearPickUps(); - - public: - void SetDefaultFont(const std::wstring& strName); - std::wstring GetDefaultFont(); - - virtual void LoadFont(long lFaceIndex = 0, bool bIsNeedAddToMap = true); - - void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); - - void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - - public: - virtual void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType) = 0; - virtual void CalculateBaselineOffset(); - - public: - void LoadFontMetrics(); - - std::wstring ToHexString( BYTE uc ); - - BYTE FromHexString( wchar_t c1, wchar_t c2 ); - - void LoadFontParams(bool bIsPath = true); - - private: - void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); - - public: - bool GenerateFontName(NSStringUtils::CStringUTF32& oText); - - bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); - - void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); - }; -} diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index d3bce163819..101c63c7158 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = L""; - std::wstring sTempDirOut = L""; + std::wstring sTempDir = L"C:\\Work\\TestDocxR\\temp"; + std::wstring sTempDirOut = L"C:\\Work\\TestDocxR\\temp\\output"; if (!NSDirectory::Exists(sTempDir)) NSDirectory::CreateDirectory(sTempDir); @@ -91,9 +91,9 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - sSourceFiles.push_back(L""); + sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\CHIN_CHAN.pdf"); - std::wstring sTextDirOut = L""; + std::wstring sTextDirOut = L"C:\\Work\\TestDocxR\\text"; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); @@ -166,9 +166,9 @@ int main(int argc, char *argv[]) // проверить все режимы NSDocxRenderer::eTextAssociationType taType; - taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; + //taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; - //taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; + taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; //taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; oDocxRenderer.SetTextAssociationType(taType); From 21544a7ff71bd7b84baee0185ff9e5b63d96d660 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 14 Mar 2023 19:02:58 +0300 Subject: [PATCH 016/794] Refactoring --- DocxRenderer/src/logic/Document.cpp | 4 +- DocxRenderer/src/logic/Page.cpp | 6 +-- .../src/logic/managers/FontManager.cpp | 46 +++++++------------ DocxRenderer/src/logic/managers/FontManager.h | 16 +++---- DocxRenderer/test/main.cpp | 2 +- 5 files changed, 28 insertions(+), 46 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 1b6f1dcce9e..e6db30746c9 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -942,7 +942,7 @@ namespace NSDocxRenderer xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">"); - CFontTable* pFontTable = &m_oFontManager.m_oFontTable; + /*CFontTable* pFontTable = &m_oFontManager.m_oFontTable; for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); ++iterFont) { CFontTableEntry& oEntry = iterFont->second; @@ -982,7 +982,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); oWriter.WriteString(L""); - } + }*/ oWriter.WriteString(L""); NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 62720b22cee..f9bb5b671f4 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -343,13 +343,11 @@ namespace NSDocxRenderer if ((pUnicodes != nullptr) && (pGids != nullptr)) for (unsigned int i = 0; i < nCount; ++i) - if (!IsUnicodeSymbol( pUnicodes[i])) + if (!IsUnicodeSymbol(pUnicodes[i])) oText[i] = ' '; m_pFontManager->SetFont(*m_pFont); - m_pFontManager->SetTransform(m_pTransform); - m_pFontManager->LoadFont(); m_pFontManager->GenerateFontName(oText); @@ -396,7 +394,7 @@ namespace NSDocxRenderer m_pStyleManager->m_pCurrentStyle->m_oFont = oFontAdvanced.m_oFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = oFontAdvanced.m_strFamilyName; + m_pStyleManager->m_pCurrentStyle->m_strPickFontName = oFontAdvanced.m_strGeneratedName; m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = oFontAdvanced.m_oFont.GetStyle2(); //первичное получение стиля для текущего символа diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 5c871d600ca..387940c35de 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -255,7 +255,7 @@ namespace NSDocxRenderer m_dBaselineOffset = oSrc.m_dBaselineOffset; m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - m_strFamilyName = oSrc.m_strFamilyName; + m_strGeneratedName = oSrc.m_strGeneratedName; for(int i = 0; i < 10; i++) m_arPANOSE[i] = oSrc.m_arPANOSE[i]; @@ -283,35 +283,16 @@ namespace NSDocxRenderer { m_oFontAdvanced.m_oFont = oFont; } - void CFontManager::SetTransform(const Aggplus::CMatrix* pTransform) - { - m_pTransform = pTransform; - } void CFontManager::LoadFont() { if (nullptr == m_pManager) return; - double dSize = m_oFontAdvanced.m_oFont.Size; - double dSizeFont = dSize * ((m_pTransform->sx() + m_pTransform->sy()) / 2); - double dPix = m_oFontAdvanced.m_oFont.CharSpace / c_dPixToMM; - - m_oFontAdvanced.m_oFont.Size = dSizeFont; - - if (m_oFontAdvanced.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) - { - m_oFontAdvanced.m_oFont.Size = dSize; - m_pManager->SetCharSpacing(dPix); - return; - } - - m_oFontAdvanced.m_oFont.Size = dSize; - if (m_oFontAdvanced.m_oFont.Path.empty()) LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); else - LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, 0); + LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, m_oFontAdvanced.m_oFont.FaceIndex); int bIsGID = m_pManager->GetStringGID(); m_pManager->SetStringGID(FALSE); @@ -386,6 +367,11 @@ namespace NSDocxRenderer dBoxHeight *= c_dPixToMM; } + CFontAdvanced CFontManager::GetFontAdvanced() + { + return m_oFontAdvanced; + } + double CFontManager::GetFontHeight() { return c_dPtToMM * (m_oFontAdvanced.m_dLineSpacing * m_oFontAdvanced.m_oFont.Size ) / m_oFontAdvanced.m_dEmHeight; @@ -422,11 +408,6 @@ namespace NSDocxRenderer LoadFontParams(); m_oFontAdvanced.m_lAvgWidth = -1; - m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); - m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; - - - bool bIsCID = false; std::wstring sFileExt = NSFile::GetFileExtention(strPath); if (std::wstring::npos != sFileExt.find(L"cid")) @@ -500,9 +481,9 @@ namespace NSDocxRenderer if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) return; - m_oFontAdvanced.m_strFamilyName = m_oFontAdvanced.m_oFont.Name; m_oFontAdvanced.m_oFont.Bold = m_pManager->GetFile()->IsBold(); m_oFontAdvanced.m_oFont.Italic = m_pManager->GetFile()->IsItalic(); + m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); // PANOSE BYTE pPanose[10]; @@ -603,17 +584,19 @@ namespace NSDocxRenderer NSFonts::CFontSelectFormat oFormat; std::wstring sFontNameSelect = L""; - if (m_oFontAdvanced.m_strFamilyName.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) + if (m_oFontAdvanced.m_oFont.Name.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) sFontNameSelect = m_strDefaultFont; else - sFontNameSelect = m_oFontAdvanced.m_strFamilyName; + sFontNameSelect = m_oFontAdvanced.m_oFont.Name; bool bSelectBold = false; bool bSelectItalic = false; CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); oFormat.wsName = new std::wstring(sFontNameSelect); - oFormat.pPanose = m_oFontAdvanced.m_arPANOSE; + oFormat.pPanose = new BYTE[10]; + for(int i = 0; i < 10; i++) + oFormat.pPanose[i] = m_oFontAdvanced.m_arPANOSE[i]; oFormat.bBold = new INT(m_oFontAdvanced.m_oFont.Bold); oFormat.bItalic = new INT(m_oFontAdvanced.m_oFont.Italic); @@ -646,6 +629,9 @@ namespace NSDocxRenderer // m_lCurrentPictFontStyle = oPick.m_lPickStyle; // m_arListPicUps.push_front(oPick); + m_oFontAdvanced.m_oFont.Bold = pInfo->m_bBold; + m_oFontAdvanced.m_oFont.Italic = pInfo->m_bItalic; + m_oFontAdvanced.m_strGeneratedName = pInfo->m_wsFontName; return true; } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 9a4a563d601..d9f7d376b7c 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -36,6 +36,8 @@ namespace NSDocxRenderer void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); }; + // замена pickup + // убрать m_oFont? class CFontAdvanced { public: @@ -50,7 +52,7 @@ namespace NSDocxRenderer double m_dSpaceWidthMM {0.0}; // font params - std::wstring m_strFamilyName {L""}; + std::wstring m_strGeneratedName {L""}; BYTE m_arPANOSE[10] {}; std::vector m_arSignature; SHORT m_lAvgWidth {-1}; @@ -79,21 +81,18 @@ namespace NSDocxRenderer void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - void SetFont(const NSStructures::CFont& oFont); - void SetTransform(const Aggplus::CMatrix* pTransform); - - CFontAdvanced GetFontAdvanced() const noexcept; + bool GenerateFontName(NSStringUtils::CStringUTF32& oText); + void SetFont(const NSStructures::CFont& oFont); void SetDefaultFont(const std::wstring& strName); - bool GenerateFontName(NSStringUtils::CStringUTF32& oText); - + CFontAdvanced GetFontAdvanced(); void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, - double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType); + double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) ; double GetFontHeight(); void SetStringGid(const LONG& lGid); @@ -103,7 +102,6 @@ namespace NSDocxRenderer std::wstring m_strDefaultFont; CFontAdvanced m_oFontAdvanced; - const Aggplus::CMatrix* m_pTransform; // для подбора шрифтов CUnicodeRanges m_oRanges; diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 101c63c7158..87c2f69fff0 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\CHIN_CHAN.pdf"); + sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\test.pdf"); std::wstring sTextDirOut = L"C:\\Work\\TestDocxR\\text"; if (!NSDirectory::Exists(sTextDirOut)) From 8de7d01012fa20a198904b51baf815aea9383466 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 19 Mar 2023 18:45:10 +0300 Subject: [PATCH 017/794] Add FontSelector (Refactoring) --- DocxRenderer/src/logic/Document.cpp | 4 +- DocxRenderer/src/logic/Document.h | 1 + DocxRenderer/src/logic/Page.cpp | 28 +- DocxRenderer/src/logic/Page.h | 4 +- DocxRenderer/src/logic/elements/ContText.cpp | 10 +- .../src/logic/managers/FontManager.cpp | 639 +++++++++--------- DocxRenderer/src/logic/managers/FontManager.h | 129 ++-- DocxRenderer/test/main.cpp | 8 +- 8 files changed, 433 insertions(+), 390 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index e6db30746c9..2a3fa12ad30 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -3,7 +3,7 @@ namespace NSDocxRenderer { CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : - m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts) + m_pAppFonts(pFonts), m_oCurrentPage(pFonts), m_oFontManager(pFonts), m_oFontSelector(pFonts) { m_oSimpleGraphicsConverter.SetRenderer(pRenderer); } @@ -811,7 +811,7 @@ namespace NSDocxRenderer Clear(); m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager); + m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager, &m_oFontSelector); m_oImageManager.NewDocument(); m_oStyleManager.NewDocument(); diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index 7e333694041..d34cb01c36b 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -33,6 +33,7 @@ namespace NSDocxRenderer CImageManager m_oImageManager; CStyleManager m_oStyleManager; CFontManager m_oFontManager; + CFontSelector m_oFontSelector; double m_dWidth {0.0}; double m_dHeight {0.0}; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f9bb5b671f4..a1d9154a742 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -13,7 +13,8 @@ namespace NSDocxRenderer void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager) + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager, + CFontSelector* pFontSelector) { m_pFont = pFont; m_pPen = pPen; @@ -26,6 +27,7 @@ namespace NSDocxRenderer m_pStyleManager = pStyleManager; m_pFontManager = pFontManager; + m_pFontSelector = pFontSelector; m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; @@ -347,9 +349,7 @@ namespace NSDocxRenderer oText[i] = ' '; - m_pFontManager->SetFont(*m_pFont); - m_pFontManager->LoadFont(); - m_pFontManager->GenerateFontName(oText); + m_pFontManager->LoadFontByFile(*m_pFont); if (fabs(dTextW) < 0.01 || (dTextW > 10)) { @@ -381,9 +381,12 @@ namespace NSDocxRenderer pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; - CFontAdvanced oFontAdvanced = m_pFontManager->GetFontAdvanced(); + auto oMetrics = m_pFontManager->GetFontMetrics(); + auto oParams = m_pFontManager->GetFontSelectParams(); - pCont->m_dTop = dBaseLinePos - dTextH - oFontAdvanced.m_dBaselineOffset; + m_pFontSelector->SelectFont(oParams, oText); + + pCont->m_dTop = dBaseLinePos - dTextH - oMetrics.dBaselineOffset; pCont->m_dWidth = dTextW; pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; @@ -391,16 +394,21 @@ namespace NSDocxRenderer pCont->m_oText = oText; //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = oFontAdvanced.m_oFont; + m_pStyleManager->m_pCurrentStyle->m_oFont = *m_pFont; m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = oFontAdvanced.m_strGeneratedName; - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = oFontAdvanced.m_oFont.GetStyle2(); + m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontSelector->GetSelectedName(); + + long lStyle = 0; + if (m_pFontSelector->IsSelectedBold()) lStyle |= 0x01; + if (m_pFontSelector->IsSelectedItalic()) lStyle |= 0x02; + + m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = lStyle; //первичное получение стиля для текущего символа //при дальнейшем анализе может измениться pCont->m_pFontStyle = m_pStyleManager->GetStyle(); - pCont->m_dSpaceWidthMM = oFontAdvanced.m_dSpaceWidthMM; + pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); // собираем отдельно, т.к. такие символы не имею размера m_dWidth if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index a24d52b19d8..0d111475788 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -22,6 +22,7 @@ namespace NSDocxRenderer CStyleManager* m_pStyleManager {nullptr}; CFontManager* m_pFontManager {nullptr}; + CFontSelector* m_pFontSelector {nullptr}; CVectorGraphics m_oVector; double m_dWidth {0.0}; @@ -54,7 +55,8 @@ namespace NSDocxRenderer ~CPage(); void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager* pFontManager); + Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager, + CFontSelector* pFontSelector); void Clear(); void ClearImages(); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 6db00cbab57..523b615b16f 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -91,9 +91,11 @@ namespace NSDocxRenderer m_eVertAlignType != eVertAlignType::vatSuperscript) { // нужно перемерять... - m_pManager->LoadFontByName(m_pFontStyle->m_strPickFontName, m_pFontStyle->m_lPickFontStyle, m_pFontStyle->m_oFont.Size, - c_dDpiX, c_dDpiY); - m_pManager->GenerateFontName(m_oText); + NSStructures::CFont oFont; + oFont.Name = m_pFontStyle->m_strPickFontName; + oFont.SetStyle(m_pFontStyle->m_lPickFontStyle); + oFont.Size = m_pFontStyle->m_oFont.Size; + m_pManager->LoadFontByName(oFont); double dBoxX; double dBoxY; @@ -213,7 +215,7 @@ namespace NSDocxRenderer double dSpaceMMSize = m_dSpaceWidthMM; if (!m_pFontStyle->m_strPickFontName.empty()) { - dSpaceMMSize = m_pManager->GetFontAdvanced().m_dSpaceWidthMM; + dSpaceMMSize = m_pManager->GetSpaceWidthMM(); } LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 387940c35de..bf82ef3d37e 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -230,84 +230,316 @@ namespace NSDocxRenderer } } - CFontAdvanced::CFontAdvanced() + CFontSelectParams::CFontSelectParams() { - m_oFont.SetDefaultParams(); - m_arSignature.clear(); } + CFontSelectParams::CFontSelectParams(const CFontSelectParams& oOther) : CFontSelectParams() + { + *this = oOther; + } + CFontSelectParams& CFontSelectParams::operator=(const CFontSelectParams& oOther) + { + wsDefaultName = oOther.wsDefaultName; + bDefaultBold = oOther.bDefaultBold; + bDefaultItalic = oOther.bDefaultItalic; + + lAvgWidth = oOther.lAvgWidth; + bIsFixedWidth = oOther.bIsFixedWidth; + + for(int i = 0; i < 10; i++) + arPANOSE[i] = oOther.arPANOSE[i]; - CFontAdvanced::CFontAdvanced(const CFontAdvanced& oSrc) + arSignature.clear(); + arSignature.resize(oOther.arSignature.size()); + + for(int i = 0; i < arSignature.size(); i++) + arSignature[i] = oOther.arSignature[i]; + + return *this; + } + + CFontSelector::CFontSelector(NSFonts::IApplicationFonts* pApplication) + { + m_pManager = pApplication->GenerateFontManager(); + m_pManager->CreateOwnerCache(8); + } + CFontSelector::~CFontSelector() { - *this = oSrc; + RELEASEINTERFACE(m_pManager); } - CFontAdvanced& CFontAdvanced::operator=(const CFontAdvanced& oSrc) + std::wstring CFontSelector::GetSelectedName() const noexcept + { + return m_wsSelectedName; + } + bool CFontSelector::IsSelectedBold() const noexcept { - if (this == &oSrc) - return *this; + return m_bIsSelectedBold; + } + bool CFontSelector::IsSelectedItalic() const noexcept + { + return m_bIsSelectedItalic; + } - m_oFont = oSrc.m_oFont; + void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, NSStringUtils::CStringUTF32& oText) + { + BYTE lRangeNum = 0xFF; + BYTE lRange = 0xFF; - m_dAscent = oSrc.m_dAscent; - m_dDescent = oSrc.m_dDescent; - m_dLineSpacing = oSrc.m_dLineSpacing; - m_dEmHeight = oSrc.m_dEmHeight; - m_dBaselineOffset = oSrc.m_dBaselineOffset; - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; + m_oRanges.CheckRange(oText[0], lRange, lRangeNum); +// std::list::iterator posStart, pos; +// posStart = pos = m_arListPicUps.begin(); - m_strGeneratedName = oSrc.m_strGeneratedName; +// while (m_arListPicUps.end() != pos) +// { +// std::list::iterator posOld = pos; +// CFontPickUp& oPick = *(pos++); +// if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) +// { +// // нашли! ничего подбирать не нужно +// // нужно просто выкинуть этот шрифт наверх +// m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); +// m_strCurrentPickFont = oPick.m_strPickFont; +// m_lCurrentPictFontStyle = oPick.m_lPickStyle; +// return false; +// } +// } +// // не нашли... +// CFontPickUp oPick; +// oPick.m_lRangeNum = lRangeNum; +// oPick.m_lRange = lRange; +// oPick.m_oFont = m_oFontAdvanced; +// oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; +// oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; + + UINT dwR1 = oFontSelectParams.arSignature[0]; + UINT dwR2 = oFontSelectParams.arSignature[1]; + UINT dwR3 = oFontSelectParams.arSignature[2]; + UINT dwR4 = oFontSelectParams.arSignature[3]; + UINT dwCodePage1 = 0; + UINT dwCodePage2 = 0; + + if ((lRangeNum == 1) && (lRange == 28)) + { + dwCodePage1 = 0x80000000; + //strText = (WCHAR)(strText[0] - 0xF000); + } + else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) + { + // арабский язык!!! + dwR1 = 1 << 13; + dwR2 = 1 << 31; + dwR3 = 1 << 3; + } + else + { + CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); + } + + NSFonts::CFontSelectFormat oFormat; + std::wstring sFontNameSelect = oFontSelectParams.wsDefaultName; + + bool bSelectBold = false; + bool bSelectItalic = false; + CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); + + oFormat.wsName = NULL; + oFormat.pPanose = new BYTE[10]; for(int i = 0; i < 10; i++) - m_arPANOSE[i] = oSrc.m_arPANOSE[i]; + oFormat.pPanose[i] = oFontSelectParams.arPANOSE[i]; - m_arSignature = oSrc.m_arSignature; - m_bIsFixedWidth = oSrc.m_bIsFixedWidth; - m_lAvgWidth = oSrc.m_lAvgWidth; + oFormat.bBold = new INT(oFontSelectParams.bDefaultBold); + oFormat.bItalic = new INT(oFontSelectParams.bDefaultItalic); + oFormat.bFixedWidth = new INT(oFontSelectParams.bIsFixedWidth ? 1 : 0); - return *this; + if (-1 != oFontSelectParams.lAvgWidth) + oFormat.shAvgCharWidth = new SHORT((SHORT)oFontSelectParams.lAvgWidth); + + oFormat.ulRange1 = new UINT(dwR1); + oFormat.ulRange2 = new UINT(dwR2); + oFormat.ulRange3 = new UINT(dwR3); + oFormat.ulRange4 = new UINT(dwR4); + oFormat.ulCodeRange1 = new UINT(dwCodePage1); + oFormat.ulCodeRange2 = new UINT(dwCodePage2); + + // ??? + if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) + oFormat.pPanose[2] = 7; + + oFormat.wsDefaultName = new std::wstring(oFontSelectParams.wsDefaultName); + + NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); + +// oPick.m_strPickFont = pInfo->m_wsFontName; +// oPick.m_lPickStyle = 0; +// if (pInfo->m_bBold) +// oPick.m_lPickStyle |= 0x01; +// if (pInfo->m_bItalic) +// oPick.m_lPickStyle |= 0x02; + +// m_strCurrentPickFont = oPick.m_strPickFont; +// m_lCurrentPictFontStyle = oPick.m_lPickStyle; + +// m_arListPicUps.push_front(oPick); + m_bIsSelectedBold = pInfo->m_bBold; + m_bIsSelectedItalic = pInfo->m_bItalic; + m_wsSelectedName = pInfo->m_wsFontName; + return; + } + + void CFontSelector::CheckFontNamePDF(std::wstring& wsName, bool& bBold, bool& bItalic) + { + if (wsName.length() > 7 && wsName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; ++nIndex) + { + wchar_t nChar = wsName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + { + wsName.erase(0, 7); + } + } + + CheckFontNameStyle(wsName, L"regular"); + CheckFontNameStyle(wsName, L"condensed"); + CheckFontNameStyle(wsName, L"condensedlight"); + //CheckFontNameStyle(wsName, L"light"); + + CheckFontNameStyle(wsName, L"condensedbold"); + CheckFontNameStyle(wsName, L"semibold"); + if (CheckFontNameStyle(wsName, L"boldmt")) bBold = true; + if (CheckFontNameStyle(wsName, L"bold")) bBold = true; + + if (CheckFontNameStyle(wsName, L"italicmt")) bItalic = true; + if (CheckFontNameStyle(wsName, L"italic")) bItalic = true; + if (CheckFontNameStyle(wsName, L"oblique")) bItalic = true; + + if (CheckFontNameStyle(wsName, L"bolditalicmt")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bolditalic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bold_italic")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"boldoblique")) { bBold = true; bItalic = true; } + if (CheckFontNameStyle(wsName, L"bold_oblique")) { bBold = true; bItalic = true; } + } + bool CFontSelector::CheckFontNameStyle(std::wstring& wsName, const std::wstring& sStyle) + { + size_t nPos = 0; + size_t nLenReplace = sStyle.length(); + bool bRet = false; + + std::wstring wsName2 = wsName; + NSStringExt::ToLower(wsName2); + + while (std::wstring::npos != (nPos = wsName2.find(sStyle, nPos))) + { + size_t nOffset = 0; + if ((nPos > 0) && wsName2.at(nPos - 1) == '-') + { + --nPos; + ++nOffset; + } + + bRet = true; + wsName.erase(nPos, nLenReplace + nOffset); + wsName2.erase(nPos, nLenReplace + nOffset); + } + return bRet; + } + + void CFontSelector::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) + { + if (0 == lRangeNum) + lRange1 |= 1 << lRange; + else if (1 == lRangeNum) + lRange2 |= 1 << lRange; + else if (2 == lRangeNum) + lRange3 |= 1 << lRange; + else + lRange4 |= 1 << lRange; } CFontManager::CFontManager(NSFonts::IApplicationFonts* pApplication) { m_pManager = pApplication->GenerateFontManager(); m_pManager->CreateOwnerCache(8); - SetDefaultFont(L"Arial"); } - CFontManager::~CFontManager() { RELEASEINTERFACE(m_pManager); } - void CFontManager::SetFont(const NSStructures::CFont& oFont) + void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) { - m_oFontAdvanced.m_oFont = oFont; - } + m_oFont = oFont; + m_pManager->LoadFontFromFile(m_oFont.Path, (int)m_oFont.FaceIndex, (float)m_oFont.Size, c_dDpiX, c_dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontSelectParams(); - void CFontManager::LoadFont() + CheckPdfResources(); + } + void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) { - if (nullptr == m_pManager) - return; + m_oFont = oFont; + m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY); + m_pManager->AfterLoad(); - if (m_oFontAdvanced.m_oFont.Path.empty()) - LoadFontByName(m_oFontAdvanced.m_oFont.Name, m_oFontAdvanced.m_oFont.Size, m_oFontAdvanced.m_oFont.GetStyle(), c_dDpiX, c_dDpiY); - else - LoadFontByFile(m_oFontAdvanced.m_oFont.Path, m_oFontAdvanced.m_oFont.Size, c_dDpiX, c_dDpiY, m_oFontAdvanced.m_oFont.FaceIndex); + LoadFontMetrics(); + LoadFontSelectParams(); + } + + CFontSelectParams CFontManager::GetFontSelectParams() const noexcept + { + return m_oFontSelectParams; + } + CFontMetrics CFontManager::GetFontMetrics() const noexcept + { + return m_oFontMetrics; + } + double CFontManager::GetFontHeight() const + { + return c_dPtToMM * (m_oFontMetrics.dLineSpacing * m_oFont.Size ) / m_oFontMetrics.dEmHeight; + } + double CFontManager::GetSpaceWidthMM() const + { + double dSpaceWidthMM = 0.0; int bIsGID = m_pManager->GetStringGID(); m_pManager->SetStringGID(FALSE); m_pManager->LoadString2(L" ", 0, 0); TBBox bbox = m_pManager->MeasureString2(); - m_oFontAdvanced.m_dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; - if (0 >= m_oFontAdvanced.m_dSpaceWidthMM) - m_oFontAdvanced.m_dSpaceWidthMM = 1.0; + dSpaceWidthMM = (double)(bbox.fMaxX - bbox.fMinX) * c_dPixToMM; + if (0 >= dSpaceWidthMM) + dSpaceWidthMM = 1.0; m_pManager->SetStringGID(bIsGID); + return dSpaceWidthMM; + } + + void CFontManager::SetStringGid(const LONG& lGid) + { + if (nullptr != m_pManager) + m_pManager->SetStringGID(lGid); } - void CFontManager::MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) + void CFontManager::MeasureString(const std::wstring& wsText, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const { dBoxX = 0; dBoxY = 0; @@ -317,13 +549,11 @@ namespace NSDocxRenderer if (nullptr == m_pManager) return; - m_pManager->LoadString1(sText, (float)x, (float)y); + m_pManager->LoadString1(wsText, (float)x, (float)y); TBBox bbox; - if (mtGlyph == measureType) - bbox = m_pManager->MeasureString(); - else if (mtPosition == measureType) - bbox = m_pManager->MeasureString2(); + if (mtGlyph == measureType) bbox = m_pManager->MeasureString(); + else if (mtPosition == measureType) bbox = m_pManager->MeasureString2(); dBoxX = (double)bbox.fMinX; dBoxY = (double)bbox.fMinY; @@ -336,8 +566,15 @@ namespace NSDocxRenderer dBoxWidth *= c_dPixToMM; dBoxHeight *= c_dPixToMM; } - - void CFontManager::MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) + void CFontManager::MeasureStringGids(unsigned int* pGids, + unsigned int count, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const { dBoxX = 0; dBoxY = 0; @@ -350,10 +587,8 @@ namespace NSDocxRenderer m_pManager->LoadString1(pGids, count, (float)x, (float)y); TBBox bbox; - if (mtGlyph == measureType) - bbox = m_pManager->MeasureString(); - else if (mtPosition == measureType) - bbox = m_pManager->MeasureString2(); + if (mtGlyph == measureType) bbox = m_pManager->MeasureString(); + else if (mtPosition == measureType) bbox = m_pManager->MeasureString2(); dBoxX = (double)bbox.fMinX; dBoxY = (double)bbox.fMinY; @@ -367,57 +602,59 @@ namespace NSDocxRenderer dBoxHeight *= c_dPixToMM; } - CFontAdvanced CFontManager::GetFontAdvanced() + void CFontManager::LoadFontMetrics() { - return m_oFontAdvanced; + m_oFontMetrics.dAscent = m_pManager->GetAscender(); + m_oFontMetrics.dDescent = m_pManager->GetDescender(); + m_oFontMetrics.dLineSpacing = m_pManager->GetLineHeight(); + m_oFontMetrics.dEmHeight = m_pManager->GetUnitsPerEm(); + m_oFontMetrics.dBaselineOffset = (c_dPtToMM * m_oFontMetrics.dDescent * m_oFont.Size / m_oFontMetrics.dEmHeight); } - - double CFontManager::GetFontHeight() + void CFontManager::LoadFontSelectParams() { - return c_dPtToMM * (m_oFontAdvanced.m_dLineSpacing * m_oFontAdvanced.m_oFont.Size ) / m_oFontAdvanced.m_dEmHeight; - } + if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) + return; - void CFontManager::SetStringGid(const LONG& lGid) - { - if (nullptr != m_pManager) - m_pManager->SetStringGID(lGid); - } + m_oFontSelectParams.bDefaultBold = m_pManager->GetFile()->IsBold(); + m_oFontSelectParams.bDefaultItalic = m_pManager->GetFile()->IsItalic(); + m_oFontSelectParams.wsDefaultName = m_pManager->GetName(); - void CFontManager::SetDefaultFont(const std::wstring& strName) - { - m_strDefaultFont = strName; - } + // PANOSE + BYTE pPanose[10]; + m_pManager->GetFile()->GetPanose(pPanose); + for(int i = 0; i < 10; ++i) + m_oFontSelectParams.arPANOSE[i] = pPanose[i]; - void CFontManager::LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY) - { - m_pManager->LoadFontByName(strName, (float)dSize, lStyle, dDpiX, dDpiY); - m_pManager->AfterLoad(); + // IsFixed + m_oFontSelectParams.bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); - LoadFontMetrics(); - LoadFontParams(); - m_oFontAdvanced.m_lAvgWidth = -1; - } + // Signature + m_oFontSelectParams.arSignature.clear(); - void CFontManager::LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex) - { - m_pManager->LoadFontFromFile(strPath, (int)lFaceIndex, (float)dSize, dDpiX, dDpiY); - m_pManager->AfterLoad(); + for ( unsigned int i = 0; i < 6; ++i ) + { + DWORD value = 0; + for ( unsigned long bit = 0; bit < 32; ++bit ) + if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) + value |= ( 1 << bit ); - LoadFontMetrics(); - LoadFontParams(); - m_oFontAdvanced.m_lAvgWidth = -1; + m_oFontSelectParams.arSignature.push_back(value); + } + } + void CFontManager::CheckPdfResources() + { bool bIsCID = false; - std::wstring sFileExt = NSFile::GetFileExtention(strPath); + std::wstring sFileExt = NSFile::GetFileExtention(m_oFont.Path); if (std::wstring::npos != sFileExt.find(L"cid")) bIsCID = true; - std::wstring sFileName = NSFile::GetFileName(strPath); + std::wstring sFileName = NSFile::GetFileName(m_oFont.Path); std::wstring::size_type pos = sFileName.rfind('.'); if (std::wstring::npos != pos) sFileName = sFileName.substr(0, pos); - std::wstring sEncFilePath = NSFile::GetDirectoryName(strPath) + L"/" + sFileName + L".enc"; + std::wstring sEncFilePath = NSFile::GetDirectoryName(m_oFont.Path) + L"/" + sFileName + L".enc"; XmlUtils::CXmlNode oMainNode; oMainNode.FromXmlFile(sEncFilePath); @@ -440,7 +677,7 @@ namespace NSDocxRenderer { std::wstring sValue = oCurNode.GetAttribute(L"value"); try { - m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); + m_oFontSelectParams.lAvgWidth = (SHORT)std::stol(sValue); } catch (std::invalid_argument &) {} } } @@ -457,247 +694,11 @@ namespace NSDocxRenderer { std::wstring sValue = oCurNode.GetAttribute(L"value"); try { - m_oFontAdvanced.m_lAvgWidth = (SHORT)std::stol(sValue); + m_oFontSelectParams.lAvgWidth = (SHORT)std::stol(sValue); } catch (std::invalid_argument &) {} } } } } } - - void CFontManager::LoadFontMetrics() - { - m_oFontAdvanced.m_dAscent = m_pManager->GetAscender(); - m_oFontAdvanced.m_dDescent = m_pManager->GetDescender(); - m_oFontAdvanced.m_dLineSpacing = m_pManager->GetLineHeight(); - m_oFontAdvanced.m_dEmHeight = m_pManager->GetUnitsPerEm(); - - m_oFontAdvanced.m_dBaselineOffset = (c_dPtToMM * m_oFontAdvanced.m_dDescent * m_oFontAdvanced.m_oFont.Size / m_oFontAdvanced.m_dEmHeight); - } - - void CFontManager::LoadFontParams() - { - // читаем и выставляем все настройки шрифта - if (nullptr == m_pManager || nullptr == m_pManager->GetFile()) - return; - - m_oFontAdvanced.m_oFont.Bold = m_pManager->GetFile()->IsBold(); - m_oFontAdvanced.m_oFont.Italic = m_pManager->GetFile()->IsItalic(); - m_oFontAdvanced.m_oFont.Name = m_pManager->GetName(); - - // PANOSE - BYTE pPanose[10]; - m_pManager->GetFile()->GetPanose(pPanose); - - for(int i = 0; i < 10; ++i) - m_oFontAdvanced.m_arPANOSE[i] = pPanose[i]; - - // IsFixed - m_oFontAdvanced.m_bIsFixedWidth = m_pManager->GetFile()->IsFixedWidth(); - - // Signature - m_oFontAdvanced.m_arSignature.clear(); - - for ( unsigned int i = 0; i < 6; ++i ) - { - DWORD value = 0; - for ( unsigned long bit = 0; bit < 32; ++bit ) - if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) - value |= ( 1 << bit ); - - m_oFontAdvanced.m_arSignature.push_back(value); - } - } - - void CFontManager::CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange) - { - if (0 == lRangeNum) - lRange1 |= 1 << lRange; - else if (1 == lRangeNum) - lRange2 |= 1 << lRange; - else if (2 == lRangeNum) - lRange3 |= 1 << lRange; - else - lRange4 |= 1 << lRange; - } - - bool CFontManager::GenerateFontName(NSStringUtils::CStringUTF32& oText) - { - if (m_oFontAdvanced.m_oFont.Path.empty() || oText.empty()) - return false; - - - BYTE lRangeNum = 0xFF; - BYTE lRange = 0xFF; - - m_oRanges.CheckRange(oText[0], lRange, lRangeNum); -// std::list::iterator posStart, pos; -// posStart = pos = m_arListPicUps.begin(); - -// while (m_arListPicUps.end() != pos) -// { -// std::list::iterator posOld = pos; -// CFontPickUp& oPick = *(pos++); -// if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) -// { -// // нашли! ничего подбирать не нужно -// // нужно просто выкинуть этот шрифт наверх -// m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); -// m_strCurrentPickFont = oPick.m_strPickFont; -// m_lCurrentPictFontStyle = oPick.m_lPickStyle; -// return false; -// } -// } - -// // не нашли... -// CFontPickUp oPick; -// oPick.m_lRangeNum = lRangeNum; -// oPick.m_lRange = lRange; -// oPick.m_oFont = m_oFontAdvanced; -// oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; -// oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; - - UINT dwR1 = m_oFontAdvanced.m_arSignature[0]; - UINT dwR2 = m_oFontAdvanced.m_arSignature[1]; - UINT dwR3 = m_oFontAdvanced.m_arSignature[2]; - UINT dwR4 = m_oFontAdvanced.m_arSignature[3]; - UINT dwCodePage1 = 0; - UINT dwCodePage2 = 0; - - if ((lRangeNum == 1) && (lRange == 28)) - { - dwCodePage1 = 0x80000000; - //strText = (WCHAR)(strText[0] - 0xF000); - } - else if (((lRangeNum == 2) && (lRange == 3)) || ((lRangeNum == 1) && (lRange == 31)) || ((lRangeNum == 0) && (lRange == 13))) - { - // арабский язык!!! - dwR1 = 1 << 13; - dwR2 = 1 << 31; - dwR3 = 1 << 3; - } - else - { - CheckRanges(dwR1, dwR2, dwR3, dwR4, lRangeNum, lRange); - } - - NSFonts::CFontSelectFormat oFormat; - - std::wstring sFontNameSelect = L""; - if (m_oFontAdvanced.m_oFont.Name.empty() && !m_oFontAdvanced.m_oFont.Path.empty()) - sFontNameSelect = m_strDefaultFont; - else - sFontNameSelect = m_oFontAdvanced.m_oFont.Name; - - bool bSelectBold = false; - bool bSelectItalic = false; - CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - - oFormat.wsName = new std::wstring(sFontNameSelect); - oFormat.pPanose = new BYTE[10]; - for(int i = 0; i < 10; i++) - oFormat.pPanose[i] = m_oFontAdvanced.m_arPANOSE[i]; - - oFormat.bBold = new INT(m_oFontAdvanced.m_oFont.Bold); - oFormat.bItalic = new INT(m_oFontAdvanced.m_oFont.Italic); - oFormat.bFixedWidth = new INT(m_oFontAdvanced.m_bIsFixedWidth ? 1 : 0); - if (-1 != m_oFontAdvanced.m_lAvgWidth) - oFormat.shAvgCharWidth = new SHORT((SHORT)m_oFontAdvanced.m_lAvgWidth); - oFormat.ulRange1 = new UINT(dwR1); - oFormat.ulRange2 = new UINT(dwR2); - oFormat.ulRange3 = new UINT(dwR3); - oFormat.ulRange4 = new UINT(dwR4); - oFormat.ulCodeRange1 = new UINT(dwCodePage1); - oFormat.ulCodeRange2 = new UINT(dwCodePage2); - - // ??? - if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) - oFormat.pPanose[2] = 7; - - oFormat.wsDefaultName = new std::wstring(L"Arial"); - - NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); - -// oPick.m_strPickFont = pInfo->m_wsFontName; -// oPick.m_lPickStyle = 0; -// if (pInfo->m_bBold) -// oPick.m_lPickStyle |= 0x01; -// if (pInfo->m_bItalic) -// oPick.m_lPickStyle |= 0x02; - -// m_strCurrentPickFont = oPick.m_strPickFont; -// m_lCurrentPictFontStyle = oPick.m_lPickStyle; - -// m_arListPicUps.push_front(oPick); - m_oFontAdvanced.m_oFont.Bold = pInfo->m_bBold; - m_oFontAdvanced.m_oFont.Italic = pInfo->m_bItalic; - m_oFontAdvanced.m_strGeneratedName = pInfo->m_wsFontName; - return true; - } - - bool CFontManager::CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) - { - size_t nPos = 0; - size_t nLenReplace = sStyle.length(); - bool bRet = false; - - std::wstring sName2 = sName; - NSStringExt::ToLower(sName2); - - while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) - { - size_t nOffset = 0; - if ((nPos > 0) && sName2.at(nPos - 1) == '-') - { - --nPos; - ++nOffset; - } - - bRet = true; - sName.erase(nPos, nLenReplace + nOffset); - sName2.erase(nPos, nLenReplace + nOffset); - } - return bRet; - } - - void CFontManager::CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic) - { - if (sName.length() > 7 && sName.at(6) == '+') - { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - wchar_t nChar = sName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } - } - if (bIsRemove) - { - sName.erase(0, 7); - } - } - - CheckFontNameStyle(sName, L"regular"); - CheckFontNameStyle(sName, L"condensed"); - CheckFontNameStyle(sName, L"condensedlight"); - //CheckFontNameStyle(sName, L"light"); - - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); - if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; - - if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - - if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } - } } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index d9f7d376b7c..3f0af45bd53 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -36,34 +36,59 @@ namespace NSDocxRenderer void CheckRange(const int& symbol, int& Range1, int& Range2, int& Range3, int& Range4); }; - // замена pickup - // убрать m_oFont? - class CFontAdvanced + struct CFontMetrics { - public: - NSStructures::CFont m_oFont; - - // font metrics - double m_dAscent {0.0}; - double m_dDescent {0.0}; - double m_dLineSpacing {0.0}; - double m_dEmHeight {0.0}; - double m_dBaselineOffset {0.0}; - double m_dSpaceWidthMM {0.0}; - - // font params - std::wstring m_strGeneratedName {L""}; - BYTE m_arPANOSE[10] {}; - std::vector m_arSignature; - SHORT m_lAvgWidth {-1}; - bool m_bIsFixedWidth {false}; + double dAscent {0.0}; + double dDescent {0.0}; + double dLineSpacing {0.0}; + double dEmHeight {0.0}; + double dBaselineOffset {0.0}; + }; + + struct CFontSelectParams + { + // изначальные параметры, которые могут быть нам известны + std::wstring wsDefaultName {L""}; + bool bDefaultBold {false}; + bool bDefaultItalic {false}; + + SHORT lAvgWidth {-1}; + bool bIsFixedWidth {false}; + + BYTE arPANOSE[10] {}; + std::vector arSignature; + CFontSelectParams(); + CFontSelectParams(const CFontSelectParams& oOther); + CFontSelectParams& operator=(const CFontSelectParams& oOther); + }; + + // подбирает шрифт по параметрам + class CFontSelector + { public: - CFontAdvanced(); - CFontAdvanced(const CFontAdvanced& oSrc); - CFontAdvanced& operator=(const CFontAdvanced& oSrc); + CFontSelector(NSFonts::IApplicationFonts* pApplication); + ~CFontSelector(); + + void SelectFont(const CFontSelectParams& oFontSelectParams, NSStringUtils::CStringUTF32& oText); + std::wstring GetSelectedName() const noexcept; + bool IsSelectedBold() const noexcept; + bool IsSelectedItalic() const noexcept; + + private: + NSFonts::IFontManager* m_pManager; + std::wstring m_wsSelectedName; + bool m_bIsSelectedBold; + bool m_bIsSelectedItalic; + + CUnicodeRanges m_oRanges; + void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); + + void CheckFontNamePDF(std::wstring& wsName, bool& bBold, bool& bItalic); + bool CheckFontNameStyle(std::wstring& wsName, const std::wstring& sStyle); }; + // грузит шрифт, его параметры и метрики + измеряет шрифт class CFontManager { public: @@ -74,44 +99,48 @@ namespace NSDocxRenderer }; CFontManager(NSFonts::IApplicationFonts* pFonts); - virtual ~CFontManager(); - - void LoadFont(); - - void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle, const double& dDpiX, const double& dDpiY); - void LoadFontByFile(const std::wstring& strPath, const double& dSize, const double& dDpiX, const double& dDpiY, const LONG& lFaceIndex); - - bool GenerateFontName(NSStringUtils::CStringUTF32& oText); + ~CFontManager(); - void SetFont(const NSStructures::CFont& oFont); - void SetDefaultFont(const std::wstring& strName); + void LoadFontByFile(const NSStructures::CFont& oFont); + void LoadFontByName(const NSStructures::CFont& oFont); - CFontAdvanced GetFontAdvanced(); + CFontSelectParams GetFontSelectParams() const noexcept; + CFontMetrics GetFontMetrics() const noexcept; - void MeasureString(const std::wstring& sText, double x, double y, double& dBoxX, double& dBoxY, - double& dBoxWidth, double& dBoxHeight, MeasureType measureType); + double GetFontHeight() const; + double GetSpaceWidthMM() const; - void MeasureStringGids(unsigned int* pGids, unsigned int count, double x, double y, - double& dBoxX, double& dBoxY, double& dBoxWidth, double& dBoxHeight, MeasureType measureType) ; - - double GetFontHeight(); void SetStringGid(const LONG& lGid); + void MeasureString(const std::wstring& wsText, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; + + void MeasureStringGids(unsigned int* pGids, + unsigned int count, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; private: NSFonts::IFontManager* m_pManager; - std::wstring m_strDefaultFont; - - CFontAdvanced m_oFontAdvanced; - // для подбора шрифтов - CUnicodeRanges m_oRanges; - - void CheckRanges(UINT& lRange1, UINT& lRange2, UINT& lRange3, UINT& lRange4, BYTE& lRangeNum, BYTE& lRange); + NSStructures::CFont m_oFont; + CFontMetrics m_oFontMetrics; + CFontSelectParams m_oFontSelectParams; void LoadFontMetrics(); - void LoadFontParams(); + void LoadFontSelectParams(); + + void CheckPdfResources(); - bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle); - void CheckFontNamePDF(std::wstring& sName, bool& bBold, bool& bItalic); }; } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 87c2f69fff0..0e579392db1 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -79,8 +79,8 @@ int main(int argc, char *argv[]) NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = L"C:\\Work\\TestDocxR\\temp"; - std::wstring sTempDirOut = L"C:\\Work\\TestDocxR\\temp\\output"; + std::wstring sTempDir = L""; + std::wstring sTempDirOut = L""; if (!NSDirectory::Exists(sTempDir)) NSDirectory::CreateDirectory(sTempDir); @@ -91,9 +91,9 @@ int main(int argc, char *argv[]) //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); std::vector sSourceFiles; //Или добавляем любой нужный файл - sSourceFiles.push_back(L"C:\\Work\\TestDocxR\\tests\\test.pdf"); + sSourceFiles.push_back(L""); - std::wstring sTextDirOut = L"C:\\Work\\TestDocxR\\text"; + std::wstring sTextDirOut = L""; if (!NSDirectory::Exists(sTextDirOut)) NSDirectory::CreateDirectory(sTextDirOut); From 9cc07e916b4023219ad4a381b24dabd2f3e7c5a3 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Mar 2023 02:21:04 +0300 Subject: [PATCH 018/794] Refactoring --- DocxRenderer/src/logic/Document.cpp | 38 ++++---- DocxRenderer/src/logic/elements/ContText.cpp | 1 + DocxRenderer/src/logic/elements/TextLine.cpp | 18 +--- .../src/logic/managers/FontManager.cpp | 94 +++++++++++-------- DocxRenderer/src/logic/managers/FontManager.h | 20 +++- 5 files changed, 97 insertions(+), 74 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 2a3fa12ad30..6e064d13f46 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -942,25 +942,29 @@ namespace NSDocxRenderer xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" \ mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh\">"); - /*CFontTable* pFontTable = &m_oFontManager.m_oFontTable; - for (std::map::iterator iterFont = pFontTable->m_mapTable.begin(); iterFont != pFontTable->m_mapTable.end(); ++iterFont) + auto oFonts = m_oFontSelector.GetCache(); + for (auto& val : oFonts) { - CFontTableEntry& oEntry = iterFont->second; - - if (oEntry.m_strFamilyName.empty()) - { + if (val.wsSelectedName.empty()) continue; - } oWriter.WriteString(L""); oWriter.WriteString(L"> 4); + char c2 = (char)(uc & 0x0F); + strPANOSE += (wchar_t)((c1 < 10) ? ('0' + c1) : ('A' + c1 - 10)); + strPANOSE += (wchar_t)((c2 < 10) ? ('0' + c2) : ('A' + c2 - 10)); + } + oWriter.WriteString(strPANOSE); oWriter.WriteString(L"\"/>"); - if (oEntry.m_bIsFixedWidth) + if (val.oFontSelectParams.bIsFixedWidth) oWriter.WriteString(L""); else oWriter.WriteString(L""); @@ -968,21 +972,21 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); - }*/ + } oWriter.WriteString(L""); NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 523b615b16f..0940cfedcc1 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -219,6 +219,7 @@ namespace NSDocxRenderer } LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); + //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу lCalculatedSpacing -= 1; if (lCalculatedSpacing != 0) diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 2936cbfd5e5..5f1309113c1 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -61,8 +61,7 @@ namespace NSDocxRenderer //todo возможно стоит доработать логику bool bIsEqual = pFirst->IsEqual(pCurrent); - bool bIsBigDelta = ((pFirst->m_dRight < pCurrent->m_dLeft) && ((pCurrent->m_dLeft - pFirst->m_dRight) < pCurrent->m_dSpaceWidthMM)) || - fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace(); + bool bIsBigDelta = (fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace()); bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); if (bIsVeryBigDelta) @@ -169,19 +168,10 @@ namespace NSDocxRenderer } dDelta = pCurrent->m_dLeft - pPrev->m_dRight; - - if (dDelta < pPrev->CalculateWideSpace() || - pPrev->m_bSpaceIsNotNeeded) - { - // просто текст на тексте или сменились настройки (font/brush) - pPrev->ToXml(oWriter); - } - else - { - // расстояние слишком большое. нужно сделать большой пробел - pPrev->ToXml(oWriter); + pPrev->ToXml(oWriter); + if (!(dDelta < pPrev->CalculateWideSpace() || pPrev->m_bSpaceIsNotNeeded)) pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); - } + pPrev = pCurrent; } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index bf82ef3d37e..a9b75b07045 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -230,9 +230,6 @@ namespace NSDocxRenderer } } - CFontSelectParams::CFontSelectParams() - { - } CFontSelectParams::CFontSelectParams(const CFontSelectParams& oOther) : CFontSelectParams() { *this = oOther; @@ -257,6 +254,25 @@ namespace NSDocxRenderer return *this; } + bool CFontSelectParams::operator==(const CFontSelectParams& oOther) + { + bool bEqual = true; + + bEqual &= wsDefaultName == oOther.wsDefaultName; + bEqual &= bDefaultBold == oOther.bDefaultBold; + bEqual &= bDefaultItalic == oOther.bDefaultItalic; + + bEqual &= lAvgWidth == oOther.lAvgWidth; + bEqual &= bIsFixedWidth == oOther.bIsFixedWidth; + + for(int i = 0; i < 10; i++) + bEqual &= arPANOSE[i] == oOther.arPANOSE[i]; + + for(int i = 0; i < arSignature.size(); i++) + bEqual &= arSignature[i] == oOther.arSignature[i]; + + return bEqual; + } CFontSelector::CFontSelector(NSFonts::IApplicationFonts* pApplication) { @@ -281,37 +297,39 @@ namespace NSDocxRenderer return m_bIsSelectedItalic; } + const std::list& CFontSelector::GetCache() const + { + return m_arParamsCache; + } + void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, NSStringUtils::CStringUTF32& oText) { BYTE lRangeNum = 0xFF; BYTE lRange = 0xFF; m_oRanges.CheckRange(oText[0], lRange, lRangeNum); -// std::list::iterator posStart, pos; -// posStart = pos = m_arListPicUps.begin(); - -// while (m_arListPicUps.end() != pos) -// { -// std::list::iterator posOld = pos; -// CFontPickUp& oPick = *(pos++); -// if ((oPick.m_oFont.m_oFont.IsEqual2(&m_oFontAdvanced.m_oFont)) && (lRangeNum == oPick.m_lRangeNum) && (lRange == oPick.m_lRange)) -// { -// // нашли! ничего подбирать не нужно -// // нужно просто выкинуть этот шрифт наверх -// m_arListPicUps.splice(m_arListPicUps.begin(), m_arListPicUps, posOld); -// m_strCurrentPickFont = oPick.m_strPickFont; -// m_lCurrentPictFontStyle = oPick.m_lPickStyle; -// return false; -// } -// } - -// // не нашли... -// CFontPickUp oPick; -// oPick.m_lRangeNum = lRangeNum; -// oPick.m_lRange = lRange; -// oPick.m_oFont = m_oFontAdvanced; -// oPick.m_strPickFont = m_oFontAdvanced.m_strFamilyName; -// oPick.m_lPickStyle = m_oFontAdvanced.m_lStyle; + + for(auto it = m_arParamsCache.begin(); it != m_arParamsCache.end(); it++) + { + // нашли в кэше, ничего не подбираем, выкинем наверх + if(it->oFontSelectParams == oFontSelectParams && it->lRange == lRange && it->lRangeNum == lRangeNum) + { + m_bIsSelectedBold = it->bIsSelectedBold; + m_bIsSelectedItalic = it->bIsSelectedItalic; + m_wsSelectedName = it->wsSelectedName; + + m_arParamsCache.push_front(*it); + m_arParamsCache.erase(it); + return; + } + } + + + // не нашли... + CFontSelectInfo oInfoCache; + oInfoCache.oFontSelectParams = oFontSelectParams; + oInfoCache.lRange = lRange; + oInfoCache.lRangeNum = lRangeNum; UINT dwR1 = oFontSelectParams.arSignature[0]; UINT dwR2 = oFontSelectParams.arSignature[1]; @@ -344,7 +362,7 @@ namespace NSDocxRenderer bool bSelectItalic = false; CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - oFormat.wsName = NULL; + oFormat.wsName = new std::wstring(sFontNameSelect); oFormat.pPanose = new BYTE[10]; for(int i = 0; i < 10; i++) oFormat.pPanose[i] = oFontSelectParams.arPANOSE[i]; @@ -363,7 +381,6 @@ namespace NSDocxRenderer oFormat.ulCodeRange1 = new UINT(dwCodePage1); oFormat.ulCodeRange2 = new UINT(dwCodePage2); - // ??? if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) oFormat.pPanose[2] = 7; @@ -371,20 +388,15 @@ namespace NSDocxRenderer NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); -// oPick.m_strPickFont = pInfo->m_wsFontName; -// oPick.m_lPickStyle = 0; -// if (pInfo->m_bBold) -// oPick.m_lPickStyle |= 0x01; -// if (pInfo->m_bItalic) -// oPick.m_lPickStyle |= 0x02; - -// m_strCurrentPickFont = oPick.m_strPickFont; -// m_lCurrentPictFontStyle = oPick.m_lPickStyle; - -// m_arListPicUps.push_front(oPick); m_bIsSelectedBold = pInfo->m_bBold; m_bIsSelectedItalic = pInfo->m_bItalic; m_wsSelectedName = pInfo->m_wsFontName; + + // закинем в кэш, чтобы потом не подбирать + oInfoCache.bIsSelectedBold = m_bIsSelectedBold; + oInfoCache.bIsSelectedItalic = m_bIsSelectedItalic; + oInfoCache.wsSelectedName = m_wsSelectedName; + m_arParamsCache.push_back(oInfoCache); return; } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 3f0af45bd53..b4e4d465c2b 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -2,7 +2,6 @@ #include #include -#include "../DesktopEditor/graphics/Matrix.h" #include "../DesktopEditor/graphics/structures.h" #include "../DesktopEditor/graphics/pro/Fonts.h" #include "../DesktopEditor/common/StringUTF32.h" @@ -58,15 +57,28 @@ namespace NSDocxRenderer BYTE arPANOSE[10] {}; std::vector arSignature; - CFontSelectParams(); + CFontSelectParams() = default; CFontSelectParams(const CFontSelectParams& oOther); CFontSelectParams& operator=(const CFontSelectParams& oOther); + bool operator==(const CFontSelectParams& oOther); }; // подбирает шрифт по параметрам class CFontSelector { public: + // структура для хранения уже подобранных шрифтов + struct CFontSelectInfo + { + CFontSelectParams oFontSelectParams; + BYTE lRangeNum; + BYTE lRange; + + std::wstring wsSelectedName; + bool bIsSelectedBold; + bool bIsSelectedItalic; + }; + CFontSelector(NSFonts::IApplicationFonts* pApplication); ~CFontSelector(); @@ -75,7 +87,11 @@ namespace NSDocxRenderer bool IsSelectedBold() const noexcept; bool IsSelectedItalic() const noexcept; + const std::list& GetCache() const; + private: + std::list m_arParamsCache; + NSFonts::IFontManager* m_pManager; std::wstring m_wsSelectedName; bool m_bIsSelectedBold; From bacbfbf221d67941a0a01a96cbf179c65c44d3a6 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Mar 2023 02:51:15 +0300 Subject: [PATCH 019/794] Fix bug --- DocxRenderer/src/logic/Document.cpp | 1 + DocxRenderer/src/logic/Page.cpp | 7 ++++++- DocxRenderer/src/logic/Page.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 6e064d13f46..d757084f3bb 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -316,6 +316,7 @@ namespace NSDocxRenderer HRESULT CDocument::put_FontSize(double dSize) { m_oFont.Size = dSize; + m_oCurrentPage.m_bIsRecalcFontSize = true; return S_OK; } HRESULT CDocument::get_FontStyle(LONG* lStyle) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index a1d9154a742..f865f42e266 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -348,7 +348,12 @@ namespace NSDocxRenderer if (!IsUnicodeSymbol(pUnicodes[i])) oText[i] = ' '; - + // иногда приходит неверный? размер, нужно перемерить + if(m_bIsRecalcFontSize) + { + m_pFont->Size *= ((m_pTransform->sx() + m_pTransform->sy()) / 2); + m_bIsRecalcFontSize = false; + } m_pFontManager->LoadFontByFile(*m_pFont); if (fabs(dTextW) < 0.01 || (dTextW > 10)) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 0d111475788..8cd0cfb2ed7 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -49,6 +49,7 @@ namespace NSDocxRenderer eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; bool m_bIsDeleteTextClipPage {true}; + bool m_bIsRecalcFontSize {true}; public: CPage(NSFonts::IApplicationFonts* pFonts); From 39c19db22ad4162010007cb123d3db94f52137c1 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Mar 2023 02:55:43 +0300 Subject: [PATCH 020/794] Refactoring (faster) --- DocxRenderer/src/logic/managers/FontManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index a9b75b07045..63c925e9a8b 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -489,6 +489,9 @@ namespace NSDocxRenderer void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) { + if(m_oFont.IsEqual2(&oFont)) + return; + m_oFont = oFont; m_pManager->LoadFontFromFile(m_oFont.Path, (int)m_oFont.FaceIndex, (float)m_oFont.Size, c_dDpiX, c_dDpiY); m_pManager->AfterLoad(); @@ -500,6 +503,9 @@ namespace NSDocxRenderer } void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) { + if(m_oFont.IsEqual2(&oFont)) + return; + m_oFont = oFont; m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY); m_pManager->AfterLoad(); From 4007b826bf20744d77a71449b788c8784e345d32 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Mar 2023 03:44:36 +0300 Subject: [PATCH 021/794] Refactoring --- DocxRenderer/src/logic/managers/FontManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 63c925e9a8b..8561e0fa00f 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -384,7 +384,7 @@ namespace NSDocxRenderer if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) oFormat.pPanose[2] = 7; - oFormat.wsDefaultName = new std::wstring(oFontSelectParams.wsDefaultName); + oFormat.wsDefaultName = new std::wstring(L"Arial"); NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); From caea7fbe2f268b0d5c87c9badc2fdbb4b76659b5 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 21 Mar 2023 01:27:58 +0300 Subject: [PATCH 022/794] Fix bug + refactoring --- DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/resources/VectorGraphics.cpp | 15 +++++++++++---- DocxRenderer/src/resources/VectorGraphics.h | 5 +++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 0940cfedcc1..a9931c1872c 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -104,7 +104,7 @@ namespace NSDocxRenderer m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); - dSpacing *= c_dMMToDx; + // dSpacing *= c_dMMToDx; lCalculatedSpacing = static_cast(dSpacing); } diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index d7dd4b99782..cf5f3096fc1 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -10,6 +10,13 @@ namespace NSDocxRenderer { CVectorGraphics::CVectorGraphics() { + m_arData.resize(500); + + m_dLeftDefault = std::numeric_limits().max(); + m_dTopDefault = std::numeric_limits().max(); + m_dRightDefault = std::numeric_limits().min(); + m_dBottomDefault = std::numeric_limits().min(); + ResetBorders(); } @@ -20,10 +27,10 @@ namespace NSDocxRenderer void CVectorGraphics::ResetBorders() { - m_dLeft = std::numeric_limits().max(); - m_dTop = std::numeric_limits().max(); - m_dRight = std::numeric_limits().min(); - m_dBottom = std::numeric_limits().min(); + m_dLeft = m_dLeftDefault; + m_dTop = m_dTopDefault; + m_dRight = m_dRightDefault; + m_dBottom = m_dBottomDefault; } double CVectorGraphics::GetLeft() const noexcept diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index fd07e43b0a1..3c6fd671022 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -57,6 +57,11 @@ namespace NSDocxRenderer double m_dRight; double m_dBottom; + double m_dLeftDefault; + double m_dTopDefault; + double m_dRightDefault; + double m_dBottomDefault; + void ResetBorders(); }; } From 69cbba7b2b4e8a9deb8ea15ee0cbee1ae4315b6b Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 21 Mar 2023 01:35:08 +0300 Subject: [PATCH 023/794] Refactoring --- DocxRenderer/src/logic/managers/FontManager.h | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index b4e4d465c2b..c7008ee6ecb 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -17,10 +17,7 @@ namespace NSDocxRenderer int Start {0}; int End {0}; - CUnicodeRange(const int& _start = 0, - const int& _end = 0, - const BYTE& _range = 0, - const BYTE& _rangenum = 0); + CUnicodeRange(const int& _start = 0, const int& _end = 0, const BYTE& _range = 0, const BYTE& _rangenum = 0); }; // класс для проставления Ranges для подбора шрифта по символу @@ -37,25 +34,25 @@ namespace NSDocxRenderer struct CFontMetrics { - double dAscent {0.0}; - double dDescent {0.0}; - double dLineSpacing {0.0}; - double dEmHeight {0.0}; - double dBaselineOffset {0.0}; + double dAscent {0.0}; + double dDescent {0.0}; + double dLineSpacing {0.0}; + double dEmHeight {0.0}; + double dBaselineOffset {0.0}; }; struct CFontSelectParams { // изначальные параметры, которые могут быть нам известны - std::wstring wsDefaultName {L""}; - bool bDefaultBold {false}; - bool bDefaultItalic {false}; + std::wstring wsDefaultName {L""}; + bool bDefaultBold {false}; + bool bDefaultItalic {false}; - SHORT lAvgWidth {-1}; - bool bIsFixedWidth {false}; + SHORT lAvgWidth {-1}; + bool bIsFixedWidth {false}; - BYTE arPANOSE[10] {}; - std::vector arSignature; + BYTE arPANOSE[10] {}; + std::vector arSignature; CFontSelectParams() = default; CFontSelectParams(const CFontSelectParams& oOther); @@ -147,11 +144,11 @@ namespace NSDocxRenderer double& dBoxHeight, MeasureType measureType) const; private: - NSFonts::IFontManager* m_pManager; + NSFonts::IFontManager* m_pManager; - NSStructures::CFont m_oFont; - CFontMetrics m_oFontMetrics; - CFontSelectParams m_oFontSelectParams; + NSStructures::CFont m_oFont; + CFontMetrics m_oFontMetrics; + CFontSelectParams m_oFontSelectParams; void LoadFontMetrics(); void LoadFontSelectParams(); From c69da0df04e3eac3ef8ea964690012f5830665d5 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Apr 2023 04:39:08 +0300 Subject: [PATCH 024/794] Add path merging --- DocxRenderer/src/logic/Document.cpp | 2 +- DocxRenderer/src/logic/Page.cpp | 16 +++- DocxRenderer/src/logic/Page.h | 5 + DocxRenderer/src/logic/elements/Shape.cpp | 96 ++++++++++++++----- DocxRenderer/src/logic/elements/Shape.h | 9 +- .../src/logic/managers/FontManager.cpp | 4 +- DocxRenderer/src/logic/managers/FontManager.h | 4 +- DocxRenderer/src/resources/VectorGraphics.cpp | 21 +++- DocxRenderer/src/resources/VectorGraphics.h | 4 + 9 files changed, 125 insertions(+), 36 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index d757084f3bb..2b67d12ec30 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -526,7 +526,7 @@ namespace NSDocxRenderer return S_OK; m_lCurrentCommandType = (LONG)lType; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; + m_oCurrentPage.BeginCommand(lType); return S_OK; } diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f865f42e266..97eb80dae1b 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -35,6 +35,12 @@ namespace NSDocxRenderer CShape::ResetRelativeHeight(); } + void CPage::BeginCommand(DWORD lType) + { + m_lLastCommand = m_lCurrentCommand; + m_lCurrentCommand = lType; + } + void CPage::Clear() { ClearTextData(); @@ -250,6 +256,7 @@ namespace NSDocxRenderer m_oVector.Close(); } + void CPage::DrawPath(LONG lType, const std::shared_ptr pInfo) { double dLeft, dRight, dTop, dBottom; @@ -314,9 +321,14 @@ namespace NSDocxRenderer } } - pShape->GetDataFromVector(m_oVector); + pShape->SetVector(std::move(m_oVector)); + + bool bIsMerged = false; +// if(!m_arShapes.empty() && m_lLastCommand == m_lCurrentCommand) +// bIsMerged = m_arShapes.back()->TryMergeShape(pShape); - m_arShapes.push_back(pShape); + if(!bIsMerged) + m_arShapes.push_back(pShape); } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 8cd0cfb2ed7..2fa3c0112e7 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -50,6 +50,7 @@ namespace NSDocxRenderer bool m_bIsDeleteTextClipPage {true}; bool m_bIsRecalcFontSize {true}; + LONG m_lLastCommand = 0; public: CPage(NSFonts::IApplicationFonts* pFonts); @@ -59,6 +60,9 @@ namespace NSDocxRenderer Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager, CFontSelector* pFontSelector); + + void BeginCommand(DWORD lType); + void Clear(); void ClearImages(); void ClearTextData(); @@ -82,6 +86,7 @@ namespace NSDocxRenderer void Start(); void End(); void Close(); + //набивается содержимым вектор m_arShapes void DrawPath(LONG lType, const std::shared_ptr pInfo); diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index ed6b580c716..10f86d40be7 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -15,7 +15,7 @@ namespace NSDocxRenderer } CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etShape), - m_strPath(strDstMedia), m_pImageInfo(pInfo) + m_strDstMedia(strDstMedia), m_pImageInfo(pInfo) { m_nRelativeHeight = m_gRelativeHeight; m_gRelativeHeight += c_iStandartRelativeHeight; @@ -46,12 +46,41 @@ namespace NSDocxRenderer m_gRelativeHeight = c_iStandartRelativeHeight; } - void CShape::GetDataFromVector(const CVectorGraphics& oVector) + void CShape::SetVector(CVectorGraphics&& oVector) { - m_dLeft = oVector.GetLeft(); - m_dTop = oVector.GetTop(); - m_dWidth = oVector.GetRight() - m_dLeft; - m_dHeight = oVector.GetBottom() - m_dTop; + m_oVector = std::move(oVector); + + m_dLeft = m_oVector.GetLeft(); + m_dTop = m_oVector.GetTop(); + m_dWidth = m_oVector.GetRight() - m_dLeft; + m_dHeight = m_oVector.GetBottom() - m_dTop; + + auto arData = m_oVector.GetData(); + + size_t nPeacks = 0; + size_t nCurves = 0; + + for(auto& path_command : arData) + switch (path_command.type) + { + case CVectorGraphics::vgtMove: + nPeacks++; + break; + + case CVectorGraphics::vgtLine: + nPeacks++; + break; + + case CVectorGraphics::vgtCurve: + nCurves++; + break; + + case CVectorGraphics::vgtClose: + default: + break; + } + + DetermineGraphicsType(m_dWidth, m_dHeight, nPeacks, nCurves); if (m_dWidth < 0.0001) m_dWidth = 0.0001; @@ -60,28 +89,49 @@ namespace NSDocxRenderer m_dBaselinePos = m_dTop + m_dHeight; m_dRight = m_dLeft + m_dWidth; - - WritePath(oVector); } - void CShape::WritePath(const CVectorGraphics& oVector) + bool CShape::TryMergeShape(CShape* pShape) { - auto arData = oVector.GetData(); + if((pShape->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || + pShape->m_eGraphicsType == eGraphicsType::gtRectangle) && + + (this->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || + this->m_eGraphicsType == eGraphicsType::gtRectangle) && + + pShape->m_eType == this->m_eType && + pShape->m_oPen.IsEqual(&m_oPen) && + pShape->m_oBrush.IsEqual(&m_oBrush) && + pShape->m_bIsNoFill == m_bIsNoFill && + pShape->m_bIsNoStroke == m_bIsNoStroke && + pShape->m_pImageInfo == nullptr && + this->m_pImageInfo == nullptr) + { + CBaseItem::AddContent(pShape); + auto arData = pShape->m_oVector.GetData(); + + for(auto& command : arData) + m_oVector.Add(command); + + this->m_eGraphicsType = eGraphicsType::gtComplicatedFigure; + + return true; + } + return false; + } - double dWidth = oVector.GetRight() - oVector.GetLeft(); - double dHeight = oVector.GetBottom() - oVector.GetTop(); + std::wstring CShape::PathToStr() + { + auto arData = m_oVector.GetData(); NSStringUtils::CStringBuilder oWriter; oWriter.WriteString(L"(dWidth * c_dMMToEMU)); + oWriter.AddInt(static_cast(m_dWidth * c_dMMToEMU)); oWriter.WriteString(L"\" h=\""); - oWriter.AddInt(static_cast(dHeight * c_dMMToEMU)); + oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); oWriter.WriteString(L"\">"); - size_t nPeacks = 0; - size_t nCurves = 0; - for(auto& path_command : arData) { switch (path_command.type) @@ -119,17 +169,14 @@ namespace NSDocxRenderer { case CVectorGraphics::vgtMove: oWriter.WriteString(L""); - nPeacks++; break; case CVectorGraphics::vgtLine: oWriter.WriteString(L""); - nPeacks++; break; case CVectorGraphics::vgtCurve: oWriter.WriteString(L""); - nCurves++; break; case CVectorGraphics::vgtClose: @@ -141,9 +188,9 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - m_strPath = oWriter.GetData(); - DetermineGraphicsType(dWidth, dHeight, nPeacks, nCurves); + std::wstring strPath = oWriter.GetData(); oWriter.ClearNoAttack(); + return strPath.empty() ? m_strDstMedia : strPath; } void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) @@ -791,6 +838,7 @@ namespace NSDocxRenderer void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) { + std::wstring strPath = std::move(PathToStr()); //отвечает за размеры прямоугольного фрейма шейпа oWriter.WriteString(L" 0.01) @@ -810,7 +858,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); //Если просто текст без графики - if (m_strPath.empty()) + if (strPath.empty()) { oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -826,7 +874,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(m_strPath); + oWriter.WriteString(strPath); oWriter.WriteString(L""); oWriter.WriteString(L""); } diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 4dd186c6c92..8cca78656c9 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -31,7 +31,9 @@ namespace NSDocxRenderer public: eShapeType m_eType {eShapeType::stUnknown}; - std::wstring m_strPath {L""}; + //std::wstring m_strPath {L""}; + CVectorGraphics m_oVector; + std::wstring m_strDstMedia; NSStructures::CBrush m_oBrush; NSStructures::CPen m_oPen; double m_dRotate {0.0}; @@ -64,8 +66,9 @@ namespace NSDocxRenderer virtual void AddContent(CBaseItem* pObj) override final{}; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void GetDataFromVector(const CVectorGraphics& oVector); - void WritePath(const CVectorGraphics& oVector); + void SetVector(CVectorGraphics&& oVector); + bool TryMergeShape(CShape* pShape); + std::wstring PathToStr(); void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); bool IsItFitLine(); bool IsCorrelated(const CShape* pShape); diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 8561e0fa00f..b704e86afd8 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -514,11 +514,11 @@ namespace NSDocxRenderer LoadFontSelectParams(); } - CFontSelectParams CFontManager::GetFontSelectParams() const noexcept + const CFontSelectParams& CFontManager::GetFontSelectParams() const noexcept { return m_oFontSelectParams; } - CFontMetrics CFontManager::GetFontMetrics() const noexcept + const CFontMetrics& CFontManager::GetFontMetrics() const noexcept { return m_oFontMetrics; } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index c7008ee6ecb..0723aa3a1fc 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -117,8 +117,8 @@ namespace NSDocxRenderer void LoadFontByFile(const NSStructures::CFont& oFont); void LoadFontByName(const NSStructures::CFont& oFont); - CFontSelectParams GetFontSelectParams() const noexcept; - CFontMetrics GetFontMetrics() const noexcept; + const CFontSelectParams& GetFontSelectParams() const noexcept; + const CFontMetrics& GetFontMetrics() const noexcept; double GetFontHeight() const; double GetSpaceWidthMM() const; diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index cf5f3096fc1..e3e5522af67 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -10,8 +10,6 @@ namespace NSDocxRenderer { CVectorGraphics::CVectorGraphics() { - m_arData.resize(500); - m_dLeftDefault = std::numeric_limits().max(); m_dTopDefault = std::numeric_limits().max(); m_dRightDefault = std::numeric_limits().min(); @@ -24,6 +22,21 @@ namespace NSDocxRenderer { m_arData.clear(); } + CVectorGraphics& CVectorGraphics::operator=(CVectorGraphics&& other) + { + if(this == &other) + return *this; + + m_arData = std::move(other.m_arData); + + m_dLeft = other.m_dLeft; + m_dTop = other.m_dTop; + m_dRight = other.m_dRight; + m_dBottom = other.m_dBottom; + + other.Clear(); + return *this; + } void CVectorGraphics::ResetBorders() { @@ -101,6 +114,10 @@ namespace NSDocxRenderer { Clear(); } + void CVectorGraphics::Add(const PathCommand& command) + { + m_arData.push_back(command); + } void CVectorGraphics::CheckPoint(const Point& point) { diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 3c6fd671022..fde85432257 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -30,6 +30,8 @@ namespace NSDocxRenderer CVectorGraphics(); ~CVectorGraphics(); + CVectorGraphics& operator=(CVectorGraphics&& other); + public: const std::vector& GetData() const; @@ -45,6 +47,8 @@ namespace NSDocxRenderer void Close(); void End(); + void Add(const PathCommand& command); + void Clear(); void CheckPoint(const Point& point); void CheckPoint(const double& x, const double& y); From c3bd31a38e40fa4cc198bbde27eed31335da4e81 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Apr 2023 05:27:15 +0300 Subject: [PATCH 025/794] Add optimization --- DocxRenderer/src/logic/Page.cpp | 6 ++-- DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/logic/elements/Shape.cpp | 34 +++++++++++++------ DocxRenderer/src/resources/VectorGraphics.cpp | 11 ++++-- DocxRenderer/src/resources/VectorGraphics.h | 9 ++--- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 97eb80dae1b..f7876d86fc4 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -324,11 +324,13 @@ namespace NSDocxRenderer pShape->SetVector(std::move(m_oVector)); bool bIsMerged = false; -// if(!m_arShapes.empty() && m_lLastCommand == m_lCurrentCommand) -// bIsMerged = m_arShapes.back()->TryMergeShape(pShape); + if(!m_arShapes.empty() && m_lLastCommand == m_lCurrentCommand) + bIsMerged = m_arShapes.back()->TryMergeShape(pShape); if(!bIsMerged) m_arShapes.push_back(pShape); + else + delete pShape; } } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index a9931c1872c..32ab8dfd241 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -114,7 +114,7 @@ namespace NSDocxRenderer //note 1 -> 0.5pt lCalculatedSpacing -= 1; - if (lCalculatedSpacing != 0) + if (lCalculatedSpacing > 0) { oWriter.WriteString(L"m_eGraphicsType == eGraphicsType::gtComplicatedFigure || + // можно попробовать подбирать динамически, например в зависимости от размера + double dHorNearby = 30; + double dVerNearby = 30; + + if( + // только для фигур + (pShape->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || pShape->m_eGraphicsType == eGraphicsType::gtRectangle) && (this->m_eGraphicsType == eGraphicsType::gtComplicatedFigure || this->m_eGraphicsType == eGraphicsType::gtRectangle) && + // все совпадает pShape->m_eType == this->m_eType && pShape->m_oPen.IsEqual(&m_oPen) && pShape->m_oBrush.IsEqual(&m_oBrush) && pShape->m_bIsNoFill == m_bIsNoFill && pShape->m_bIsNoStroke == m_bIsNoStroke && + + // не картинка pShape->m_pImageInfo == nullptr && - this->m_pImageInfo == nullptr) + this->m_pImageInfo == nullptr && + + // недалеко друг от друга по горизонтали + (fabs(pShape->m_dRight - this->m_dLeft) < dHorNearby || + fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby) && + + // недалеко друг от друга по вертикали + fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby) { CBaseItem::AddContent(pShape); - auto arData = pShape->m_oVector.GetData(); - - for(auto& command : arData) - m_oVector.Add(command); + m_oVector.Join(std::move(pShape->m_oVector)); this->m_eGraphicsType = eGraphicsType::gtComplicatedFigure; - return true; } return false; @@ -124,6 +135,9 @@ namespace NSDocxRenderer { auto arData = m_oVector.GetData(); + if(arData.empty()) + return m_strDstMedia; + NSStringUtils::CStringBuilder oWriter; oWriter.WriteString(L"& CVectorGraphics::GetData() const + const std::list& CVectorGraphics::GetData() const { return m_arData; } @@ -90,7 +90,7 @@ namespace NSDocxRenderer const double &x2, const double &y2, const double &x3, const double &y3) { - std::vector points = {{x1, y1}, {x2, y2}, {x3, y3}}; + std::list points = {{x1, y1}, {x2, y2}, {x3, y3}}; VectorGraphicsType type = vgtCurve; m_arData.push_back({type, points}); @@ -118,6 +118,13 @@ namespace NSDocxRenderer { m_arData.push_back(command); } + void CVectorGraphics::Join(CVectorGraphics&& other) + { + CheckPoint(other.m_dLeft, other.m_dTop); + CheckPoint(other.m_dRight, other.m_dBottom); + m_arData.splice(m_arData.end(), std::move(other.m_arData)); + other.Clear(); + } void CVectorGraphics::CheckPoint(const Point& point) { diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index fde85432257..44d92a71fb9 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -1,5 +1,5 @@ #pragma once -#include +#include namespace NSDocxRenderer { @@ -23,7 +23,7 @@ namespace NSDocxRenderer struct PathCommand { VectorGraphicsType type; - std::vector points; + std::list points; }; public: @@ -33,7 +33,7 @@ namespace NSDocxRenderer CVectorGraphics& operator=(CVectorGraphics&& other); public: - const std::vector& GetData() const; + const std::list& GetData() const; double GetLeft() const noexcept; double GetTop() const noexcept; @@ -48,13 +48,14 @@ namespace NSDocxRenderer void End(); void Add(const PathCommand& command); + void Join(CVectorGraphics&& other); void Clear(); void CheckPoint(const Point& point); void CheckPoint(const double& x, const double& y); private: - std::vector m_arData; + std::list m_arData; double m_dLeft; double m_dTop; From 49f9c9657018510e010217994952f5bd7582bf88 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Apr 2023 10:15:43 +0300 Subject: [PATCH 026/794] Refactoring --- DocxRenderer/src/logic/Page.cpp | 2 +- DocxRenderer/src/logic/elements/ContText.cpp | 4 ++-- DocxRenderer/src/logic/elements/TextLine.cpp | 9 ++++++--- DocxRenderer/src/logic/managers/FontManager.cpp | 10 +++++++--- DocxRenderer/src/logic/managers/FontManager.h | 4 +++- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f7876d86fc4..62110bbcd42 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -403,7 +403,7 @@ namespace NSDocxRenderer auto oMetrics = m_pFontManager->GetFontMetrics(); auto oParams = m_pFontManager->GetFontSelectParams(); - m_pFontSelector->SelectFont(oParams, oText); + m_pFontSelector->SelectFont(oParams, oMetrics, oText); pCont->m_dTop = dBaseLinePos - dTextH - oMetrics.dBaselineOffset; pCont->m_dWidth = dTextW; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 32ab8dfd241..a01e3e42774 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -104,7 +104,7 @@ namespace NSDocxRenderer m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); - // dSpacing *= c_dMMToDx; + //dSpacing *= c_dMMToDx; lCalculatedSpacing = static_cast(dSpacing); } @@ -516,6 +516,6 @@ namespace NSDocxRenderer double CContText::CalculateThinSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.7; + return m_dSpaceWidthMM * 0.8; } } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 5f1309113c1..29bfb226c21 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -59,10 +59,13 @@ namespace NSDocxRenderer continue; } + double dSpaceDefaultSize = pCurrent->CalculateThinSpace(); + double dSpaceWideSize = pCurrent->CalculateWideSpace(); + //todo возможно стоит доработать логику bool bIsEqual = pFirst->IsEqual(pCurrent); - bool bIsBigDelta = (fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pCurrent->CalculateThinSpace()); - bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > pFirst->CalculateWideSpace(); + bool bIsBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > dSpaceDefaultSize; + bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > dSpaceWideSize; if (bIsVeryBigDelta) { @@ -72,7 +75,7 @@ namespace NSDocxRenderer } else if (bIsEqual) { - if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM) + if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < dSpaceDefaultSize) { pFirst->m_oText += pCurrent->m_oText; } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index b704e86afd8..50aebdbc90a 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -302,7 +302,9 @@ namespace NSDocxRenderer return m_arParamsCache; } - void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, NSStringUtils::CStringUTF32& oText) + void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, + const CFontMetrics& oFontMetrics, + NSStringUtils::CStringUTF32& oText) { BYTE lRangeNum = 0xFF; BYTE lRange = 0xFF; @@ -362,7 +364,6 @@ namespace NSDocxRenderer bool bSelectItalic = false; CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - oFormat.wsName = new std::wstring(sFontNameSelect); oFormat.pPanose = new BYTE[10]; for(int i = 0; i < 10; i++) oFormat.pPanose[i] = oFontSelectParams.arPANOSE[i]; @@ -381,10 +382,13 @@ namespace NSDocxRenderer oFormat.ulCodeRange1 = new UINT(dwCodePage1); oFormat.ulCodeRange2 = new UINT(dwCodePage2); +// oFormat.shAscent = new SHORT(oFontMetrics.dAscent); +// oFormat.shDescent = new SHORT(oFontMetrics.dDescent); + if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) oFormat.pPanose[2] = 7; - oFormat.wsDefaultName = new std::wstring(L"Arial"); + oFormat.wsDefaultName = new std::wstring(sFontNameSelect); NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 0723aa3a1fc..24fdb499948 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -79,7 +79,9 @@ namespace NSDocxRenderer CFontSelector(NSFonts::IApplicationFonts* pApplication); ~CFontSelector(); - void SelectFont(const CFontSelectParams& oFontSelectParams, NSStringUtils::CStringUTF32& oText); + void SelectFont(const CFontSelectParams& oFontSelectParams, + const CFontMetrics& oFontMetrics, + NSStringUtils::CStringUTF32& oText); std::wstring GetSelectedName() const noexcept; bool IsSelectedBold() const noexcept; bool IsSelectedItalic() const noexcept; From fb22675e69ebecf2ffa2e08511fe430e9a615bb5 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 8 Apr 2023 17:09:47 +0300 Subject: [PATCH 027/794] Fix bug or not --- DocxRenderer/src/logic/Page.cpp | 41 +++++++++++--------- DocxRenderer/src/logic/elements/TextLine.cpp | 6 ++- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 62110bbcd42..9263d94b5d0 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -352,6 +352,7 @@ namespace NSDocxRenderer m_pTransform->TransformPoint(dTextX, dTextY); m_pTransform->TransformPoint(dTextR, dTextB); + // иногда ширина приходит сильно меньше, почему? double dTextW = dTextR - dTextX; double dTextH = dTextB - dTextY; @@ -362,7 +363,7 @@ namespace NSDocxRenderer if (!IsUnicodeSymbol(pUnicodes[i])) oText[i] = ' '; - // иногда приходит неверный? размер, нужно перемерить + // иногда приходит неверный? размер, нужно перемерить (XPS) if(m_bIsRecalcFontSize) { m_pFont->Size *= ((m_pTransform->sx() + m_pTransform->sy()) / 2); @@ -370,27 +371,29 @@ namespace NSDocxRenderer } m_pFontManager->LoadFontByFile(*m_pFont); - if (fabs(dTextW) < 0.01 || (dTextW > 10)) - { - double _x = 0; - double _y = 0; - double _w = 0; - double _h = 0; + // закомментив это, все гуд + //if (fabs(dTextW) < 0.01 || (dTextW > 10)) + //{ - if (nullptr != pGids) - { - m_pFontManager->SetStringGid(1); - m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } - else - { - // такого быть не должно (только из xps) - m_pFontManager->SetStringGid(0); - m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); - } + double _x = 0; + double _y = 0; + double _w = 0; + double _h = 0; - dTextW = _w; + if (nullptr != pGids) + { + m_pFontManager->SetStringGid(1); + m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); } + else + { + // такого быть не должно (только из xps) + m_pFontManager->SetStringGid(0); + m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + + dTextW = _w; + //} double dBaseLinePos = dTextY + fBaseLineOffset; dTextH = m_pFontManager->GetFontHeight(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 29bfb226c21..8417e045ad7 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -62,10 +62,12 @@ namespace NSDocxRenderer double dSpaceDefaultSize = pCurrent->CalculateThinSpace(); double dSpaceWideSize = pCurrent->CalculateWideSpace(); + double dDifference = pCurrent->m_dLeft - pFirst->m_dRight; + //todo возможно стоит доработать логику bool bIsEqual = pFirst->IsEqual(pCurrent); - bool bIsBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > dSpaceDefaultSize; - bool bIsVeryBigDelta = fabs(pFirst->m_dRight - pCurrent->m_dLeft) > dSpaceWideSize; + bool bIsBigDelta = fabs(dDifference) > dSpaceDefaultSize; + bool bIsVeryBigDelta = fabs(dDifference) > dSpaceWideSize; if (bIsVeryBigDelta) { From 531fae148629a2266192700af345b6647eb05b97 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 10 Apr 2023 18:41:44 +0300 Subject: [PATCH 028/794] FontStyles refactoring --- DocxRenderer/DocxRenderer.pro | 5 +- DocxRenderer/src/logic/Document.cpp | 10 +- DocxRenderer/src/logic/Document.h | 4 +- DocxRenderer/src/logic/Page.cpp | 67 ++++--- DocxRenderer/src/logic/Page.h | 8 +- DocxRenderer/src/logic/elements/ContText.cpp | 47 ++--- DocxRenderer/src/logic/elements/ContText.h | 7 +- DocxRenderer/src/logic/elements/Converter.cpp | 1 + DocxRenderer/src/logic/elements/Paragraph.cpp | 1 + DocxRenderer/src/logic/elements/Shape.cpp | 4 +- DocxRenderer/src/logic/elements/Shape.h | 3 +- DocxRenderer/src/logic/elements/TextLine.h | 6 +- .../src/logic/managers/FontStyleManager.cpp | 68 +++++++ .../src/logic/managers/FontStyleManager.h | 31 +++ .../src/logic/managers/StyleManager.cpp | 38 ---- .../src/logic/managers/StyleManager.h | 21 -- DocxRenderer/src/logic/styles/BaseStyle.cpp | 6 - DocxRenderer/src/logic/styles/BaseStyle.h | 45 ----- DocxRenderer/src/logic/styles/FontStyle.cpp | 182 +++++++++--------- DocxRenderer/src/logic/styles/FontStyle.h | 50 +++-- DocxRenderer/src/resources/VectorGraphics.cpp | 1 - DocxRenderer/src/resources/VectorGraphics.h | 3 - 22 files changed, 297 insertions(+), 311 deletions(-) create mode 100644 DocxRenderer/src/logic/managers/FontStyleManager.cpp create mode 100644 DocxRenderer/src/logic/managers/FontStyleManager.h delete mode 100644 DocxRenderer/src/logic/managers/StyleManager.cpp delete mode 100644 DocxRenderer/src/logic/managers/StyleManager.h delete mode 100644 DocxRenderer/src/logic/styles/BaseStyle.cpp delete mode 100644 DocxRenderer/src/logic/styles/BaseStyle.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 8d35adfdec7..525510eb3f7 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -35,10 +35,9 @@ HEADERS += \ src/logic/elements/Shape.h \ src/logic/elements/Table.h \ src/logic/elements/TextLine.h \ + src/logic/managers/FontStyleManager.h \ src/logic/managers/ImageManager.h \ src/logic/managers/FontManager.h \ - src/logic/managers/StyleManager.h \ - src/logic/styles/BaseStyle.h \ src/logic/styles/FontStyle.h \ src/resources/ColorTable.h \ src/resources/Constants.h \ @@ -63,8 +62,8 @@ SOURCES += \ src/logic/elements/Table.cpp \ src/logic/elements/TextLine.cpp \ src/logic/managers/FontManager.cpp \ + src/logic/managers/FontStyleManager.cpp \ src/logic/managers/ImageManager.cpp \ - src/logic/managers/StyleManager.cpp \ src/logic/styles/FontStyle.cpp \ src/logic/Page.cpp \ src/logic/Document.cpp \ diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 2b67d12ec30..d9a52236742 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -812,10 +812,10 @@ namespace NSDocxRenderer Clear(); m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oStyleManager, &m_oFontManager, &m_oFontSelector); + m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oFontStyleManager, &m_oFontManager, &m_oFontSelector); m_oImageManager.NewDocument(); - m_oStyleManager.NewDocument(); + m_oFontStyleManager.NewDocument(); // media m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; @@ -1212,10 +1212,8 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - for (size_t i = 0; i < m_oStyleManager.m_arStyles.size(); ++i) - { - m_oStyleManager.m_arStyles[i]->ToXml(oWriter); - } + + m_oFontStyleManager.ToXml(oWriter); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index d34cb01c36b..eb1e8130275 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -3,7 +3,7 @@ #include "../DesktopEditor/common/Directory.h" #include "../resources/resources.h" #include "managers/ImageManager.h" -#include "managers/StyleManager.h" +#include "managers/FontStyleManager.h" namespace NSDocxRenderer { @@ -31,7 +31,7 @@ namespace NSDocxRenderer CPage m_oCurrentPage; CImageManager m_oImageManager; - CStyleManager m_oStyleManager; + CFontStyleManager m_oFontStyleManager; CFontManager m_oFontManager; CFontSelector m_oFontSelector; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 9263d94b5d0..9d355019703 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -13,7 +13,7 @@ namespace NSDocxRenderer void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager, + Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pFontStyleManager, CFontManager *pFontManager, CFontSelector* pFontSelector) { m_pFont = pFont; @@ -25,7 +25,7 @@ namespace NSDocxRenderer m_pTransform = pMatrix; m_pSimpleGraphicsConverter = pSimple; - m_pStyleManager = pStyleManager; + m_pFontStyleManager = pFontStyleManager; m_pFontManager = pFontManager; m_pFontSelector = pFontSelector; @@ -415,21 +415,13 @@ namespace NSDocxRenderer pCont->m_oText = oText; - //Первичное заполнение стилей - m_pStyleManager->m_pCurrentStyle->m_oFont = *m_pFont; - m_pStyleManager->m_pCurrentStyle->m_oBrush = *m_pBrush; - - m_pStyleManager->m_pCurrentStyle->m_strPickFontName = m_pFontSelector->GetSelectedName(); - - long lStyle = 0; - if (m_pFontSelector->IsSelectedBold()) lStyle |= 0x01; - if (m_pFontSelector->IsSelectedItalic()) lStyle |= 0x02; - - m_pStyleManager->m_pCurrentStyle->m_lPickFontStyle = lStyle; - - //первичное получение стиля для текущего символа - //при дальнейшем анализе может измениться - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + // первичное получение стиля для текущего символа + // при дальнейшем анализе может измениться + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(*m_pBrush, + m_pFontSelector->GetSelectedName(), + m_pFont->Size, + m_pFontSelector->IsSelectedItalic(), + m_pFontSelector->IsSelectedBold()); pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); // собираем отдельно, т.к. такие символы не имею размера m_dWidth @@ -1029,6 +1021,7 @@ namespace NSDocxRenderer void CPage::DetermineStrikeoutsUnderlinesHighlights() { + //определение различных эффектов на основании взаимного расположения символов и шейпов for (size_t i = 0; i < m_arShapes.size(); ++i) { @@ -1057,7 +1050,6 @@ namespace NSDocxRenderer { continue; } - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); @@ -1096,7 +1088,7 @@ namespace NSDocxRenderer if (!bIsComplicatedFigure) { - bool bIf1 = pCurrCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; + bool bIf1 = pCurrCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor; bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; @@ -1106,9 +1098,14 @@ namespace NSDocxRenderer { if (!bIf2) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCurrCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oBrush.Color1 = pShape->m_oPen.Color; - pCurrCont->m_pFontStyle = m_pStyleManager->GetStyle(); + auto oBrush = pCurrCont->m_pFontStyle->GetBrush(); + oBrush.Color1 = pShape->m_oPen.Color; + + pCurrCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(oBrush, + pCurrCont->m_pFontStyle->GetFontName(), + pCurrCont->m_pFontStyle->GetFontSize(), + pCurrCont->m_pFontStyle->IsItalic(), + pCurrCont->m_pFontStyle->IsBold()); pCurrCont->m_bIsShadowPresent = true; pCurrCont->m_bIsOutlinePresent = true; @@ -1169,7 +1166,7 @@ namespace NSDocxRenderer return bIf1 && bIf2 && bIf3 && bIf4; } - bool CPage::IsItHighlightingBackground(CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) + bool CPage::IsItHighlightingBackground(const CShape *pShape, CContText* pCont, const eHorizontalCrossingType& eHType) { double dSomeBaseLine1 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.75; double dSomeBaseLine2 = pCont->m_dBaselinePos - pCont->m_dHeight * 0.5; @@ -1189,7 +1186,7 @@ namespace NSDocxRenderer eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; //Цвета должны быть разными - bool bIf4 = pCont->m_pFontStyle->m_oBrush.Color1 != pShape->m_oBrush.Color1; + bool bIf4 = pCont->m_pFontStyle->GetBrush().Color1 != pShape->m_oBrush.Color1; bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; bool bIf6 = pShape->m_bIsNoFill == false; bool bIf7 = pShape->m_bIsNoStroke == true; @@ -1295,16 +1292,17 @@ namespace NSDocxRenderer { continue; } - - dFontSize = pCont->m_pFontStyle->m_oFont.Size; + dFontSize = pCont->m_pFontStyle->GetFontSize(); break; } for (auto pCont : pCurrLine->m_arConts) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->GetBrush(), + pCont->m_pFontStyle->GetFontName(), + dFontSize, + pCont->m_pFontStyle->IsItalic(), + pCont->m_pFontStyle->IsBold()); if (pBaseLine->m_dLeft > pCont->m_dLeft) { @@ -1337,16 +1335,17 @@ namespace NSDocxRenderer { continue; } - - dFontSize = pCont->m_pFontStyle->m_oFont.Size; + dFontSize = pCont->m_pFontStyle->GetFontSize(); break; } for (auto pCont : pSubLine->m_arConts) { - m_pStyleManager->m_pCurrentStyle->CopyFormat(*pCont->m_pFontStyle); - m_pStyleManager->m_pCurrentStyle->m_oFont.Size = dFontSize; - pCont->m_pFontStyle = m_pStyleManager->GetStyle(); + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->GetBrush(), + pCont->m_pFontStyle->GetFontName(), + dFontSize, + pCont->m_pFontStyle->IsItalic(), + pCont->m_pFontStyle->IsBold()); if (pCurrLine->m_dLeft > pCont->m_dLeft) { diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 2fa3c0112e7..9dd2f2fc06f 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -3,7 +3,7 @@ #include "elements/Paragraph.h" #include "elements/Shape.h" #include "elements/Table.h" -#include "managers/StyleManager.h" +#include "managers/FontStyleManager.h" namespace NSDocxRenderer @@ -20,7 +20,7 @@ namespace NSDocxRenderer Aggplus::CMatrix* m_pTransform {nullptr}; Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; - CStyleManager* m_pStyleManager {nullptr}; + CFontStyleManager* m_pFontStyleManager {nullptr}; CFontManager* m_pFontManager {nullptr}; CFontSelector* m_pFontSelector {nullptr}; CVectorGraphics m_oVector; @@ -57,7 +57,7 @@ namespace NSDocxRenderer ~CPage(); void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CStyleManager* pStyleManager, CFontManager *pFontManager, + Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pStyleManager, CFontManager *pFontManager, CFontSelector* pFontSelector); @@ -112,7 +112,7 @@ namespace NSDocxRenderer void DetermineStrikeoutsUnderlinesHighlights(); bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsItHighlightingBackground(CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); void AddDiacriticalSymbols(); void MergeLinesByVertAlignType(); void DetermineTextColumns(); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index a01e3e42774..d6243b4e13e 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -80,21 +80,22 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L"GetStyleId()); + oWriter.WriteString(m_pFontStyle->GetFontStyleId()); oWriter.WriteString(L"\"/>"); LONG lCalculatedSpacing = 0; - if (!m_pFontStyle->m_strPickFontName.empty() && !m_oText.empty()) + if (!m_pFontStyle->GetFontName().empty() && !m_oText.empty()) { if (m_eVertAlignType != eVertAlignType::vatSubscript && m_eVertAlignType != eVertAlignType::vatSuperscript) { // нужно перемерять... NSStructures::CFont oFont; - oFont.Name = m_pFontStyle->m_strPickFontName; - oFont.SetStyle(m_pFontStyle->m_lPickFontStyle); - oFont.Size = m_pFontStyle->m_oFont.Size; + oFont.Name = m_pFontStyle->GetFontName(); + oFont.Bold = m_pFontStyle->IsBold(); + oFont.Italic = m_pFontStyle->IsItalic(); + oFont.Size = m_pFontStyle->GetFontSize(); m_pManager->LoadFontByName(oFont); double dBoxX; @@ -158,7 +159,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L"GetStyleId()); + oWriter.WriteString(m_pFontStyle->GetFontStyleId()); oWriter.WriteString(L"\"/>"); double dSpaceMMSize = m_dSpaceWidthMM; - if (!m_pFontStyle->m_strPickFontName.empty()) - { - dSpaceMMSize = m_pManager->GetSpaceWidthMM(); - } - LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу @@ -266,7 +262,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"GetStyleId() == pCont->m_pFontStyle->GetStyleId(); + bool bIf1 = m_pFontStyle->GetFontStyleId() == pCont->m_pFontStyle->GetFontStyleId(); bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; @@ -326,12 +322,11 @@ namespace NSDocxRenderer UINT CContText::GetNumberOfFeatures() { UINT ret = 0; - - if (m_pFontStyle->m_oFont.Bold) + if (m_pFontStyle->IsBold()) { ret++; } - if (m_pFontStyle->m_oFont.Italic) + if (m_pFontStyle->IsItalic()) { ret++; } @@ -382,16 +377,16 @@ namespace NSDocxRenderer bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_pFontStyle->m_oFont.Size == pCont->m_pFontStyle->m_oFont.Size; + bool bIf5 = m_pFontStyle->GetFontSize() == m_pFontStyle->GetFontSize(); bool bIf6 = m_oText == pCont->m_oText; //Цвет тени должен быть серым - bool bIf7 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_pFontStyle->m_oBrush.Color1 == c_iGreyColor2; + bool bIf7 = m_pFontStyle->GetBrush().Color1 == c_iGreyColor; + bool bIf8 = pCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor; + bool bIf9 = m_pFontStyle->GetBrush().Color1 == c_iBlackColor; + bool bIf10 = pCont->m_pFontStyle->GetBrush().Color1 == c_iBlackColor; + bool bIf11 = m_pFontStyle->GetBrush().Color1 == c_iGreyColor2; + bool bIf12 = pCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor2; //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. @@ -466,8 +461,8 @@ namespace NSDocxRenderer eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; //Размеры шрифта должны бать разными - bool bIf5 = m_pFontStyle->m_oFont.Size * 0.7 > pCont->m_pFontStyle->m_oFont.Size; - bool bIf6 = m_pFontStyle->m_oFont.Size < pCont->m_pFontStyle->m_oFont.Size * 0.7; + bool bIf5 = m_pFontStyle->GetFontSize() * 0.7 > pCont->m_pFontStyle->GetFontSize(); + bool bIf6 = m_pFontStyle->GetFontSize() < pCont->m_pFontStyle->GetFontSize() * 0.7; if (bIf3 || bIf4) { diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 17c89eab334..e663a44052d 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -2,8 +2,7 @@ #include "BaseItem.h" #include "../DesktopEditor/common/StringBuilder.h" #include "../managers/FontManager.h" -#include "../managers/StyleManager.h" -#include "../styles/FontStyle.h" +#include "../managers/FontStyleManager.h" #include "../../resources/Constants.h" #include "../../resources/LinesTable.h" @@ -22,7 +21,7 @@ namespace NSDocxRenderer class CContText : public CBaseItem { public: - std::shared_ptr m_pFontStyle {nullptr}; + std::shared_ptr m_pFontStyle {nullptr}; bool m_bIsStrikeoutPresent {false}; bool m_bIsDoubleStrikeout {false}; @@ -54,7 +53,7 @@ namespace NSDocxRenderer UINT m_iNumDuplicates {0}; public: - CContText(CFontManager* m_pManager); + CContText(CFontManager* pManager); CContText(const CContText& rCont); virtual ~CContText(); virtual void Clear() override final; diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 95b7c227a9b..06f7ffca4b9 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -94,6 +94,7 @@ namespace NSDocxRenderer CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; double dBeforeSpacingWithShapes = 0; + //note Все параграфы были сдвинуты на данное значение от верхнего края страницы double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; eVerticalCrossingType eCrossingType; diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 99f215f7f1d..ce650b60f0e 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -183,6 +183,7 @@ namespace NSDocxRenderer CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) { + // поменять логику if (!pCurrentLine || !pNextLine) { return tatUnknown; diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index e7e35d4e7a6..57e50d8a85f 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -131,7 +131,7 @@ namespace NSDocxRenderer return false; } - std::wstring CShape::PathToStr() + std::wstring CShape::PathToWString() { auto arData = m_oVector.GetData(); @@ -852,7 +852,7 @@ namespace NSDocxRenderer void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) { - std::wstring strPath = std::move(PathToStr()); + std::wstring strPath = PathToWString(); //отвечает за размеры прямоугольного фрейма шейпа oWriter.WriteString(L" 0.01) diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 8cca78656c9..1b80846b9a1 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -31,7 +31,6 @@ namespace NSDocxRenderer public: eShapeType m_eType {eShapeType::stUnknown}; - //std::wstring m_strPath {L""}; CVectorGraphics m_oVector; std::wstring m_strDstMedia; NSStructures::CBrush m_oBrush; @@ -68,7 +67,7 @@ namespace NSDocxRenderer void SetVector(CVectorGraphics&& oVector); bool TryMergeShape(CShape* pShape); - std::wstring PathToStr(); + std::wstring PathToWString(); void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); bool IsItFitLine(); bool IsCorrelated(const CShape* pShape); diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 471981ce55f..c9ca4c3172b 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -16,16 +16,12 @@ namespace NSDocxRenderer }; std::vector m_arConts; - AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - CShape* m_pDominantShape {nullptr}; - UINT m_iNumDuplicates {0}; + public: CTextLine(); virtual ~CTextLine(); diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp new file mode 100644 index 00000000000..730dbb2a829 --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -0,0 +1,68 @@ +#include "FontStyleManager.h" +#include + +namespace NSDocxRenderer +{ + CFontStyleManager::CFontStyleManager() + { + } + + CFontStyleManager::~CFontStyleManager() + { + Clear(); + } + + void CFontStyleManager::Clear() + { + m_arFontStyles.clear(); + } + + void CFontStyleManager::NewDocument() + { + Clear(); + } + void CFontStyleManager::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + for(auto& val : m_arFontStyles) + val->ToXml(oWriter); + } + + std::shared_ptr CFontStyleManager::GetOrAddFontStyle(const CFontStyle& oFontStyle) + { + return GetOrAddFontStyle(oFontStyle.GetBrush(), + oFontStyle.GetFontName(), + oFontStyle.GetFontSize(), + oFontStyle.IsItalic(), + oFontStyle.IsBold()); + } + std::shared_ptr CFontStyleManager::GetOrAddFontStyle(const NSStructures::CBrush& oBrush, + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold) + { + for(auto& val : m_arFontStyles) + { + if(oBrush.Type == val->GetBrush().Type && + oBrush.Color1 == val->GetBrush().Color1 && + oBrush.Color2 == val->GetBrush().Color2 && + oBrush.Alpha1 == val->GetBrush().Alpha1 && + oBrush.Alpha2 == val->GetBrush().Alpha2 && + oBrush.LinearAngle == val->GetBrush().LinearAngle && + dFontSize == val->GetFontSize() && + wsFontName == val->GetFontName() && + (bItalic == val->IsItalic()) && (bBold == val->IsBold())) + + return val; + } + auto pFontStyle = std::make_shared(); + pFontStyle->SetBrush(oBrush); + pFontStyle->SetFontName(wsFontName); + pFontStyle->SetFontSize(dFontSize); + pFontStyle->SetItalic(bItalic); + pFontStyle->SetBold(bBold); + + m_arFontStyles.push_front(pFontStyle); + return pFontStyle; + } +} diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.h b/DocxRenderer/src/logic/managers/FontStyleManager.h new file mode 100644 index 00000000000..ecc993e7f32 --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.h @@ -0,0 +1,31 @@ +#pragma once +#include + +#include "../styles/FontStyle.h" + +namespace NSDocxRenderer +{ + class CFontStyleManager + { + public: + CFontStyleManager(); + ~CFontStyleManager(); + + void Clear(); + void NewDocument(); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + const std::shared_ptr GetFontStyle(const std::wstring& wsFontStyleId) const; + + std::shared_ptr GetOrAddFontStyle(const CFontStyle& oFontStyle); + std::shared_ptr GetOrAddFontStyle(const NSStructures::CBrush& oBrush, + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold); + + private: + std::list> m_arFontStyles; + }; +} + diff --git a/DocxRenderer/src/logic/managers/StyleManager.cpp b/DocxRenderer/src/logic/managers/StyleManager.cpp deleted file mode 100644 index 3680c95224b..00000000000 --- a/DocxRenderer/src/logic/managers/StyleManager.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "StyleManager.h" -#include - -namespace NSDocxRenderer -{ - CStyleManager::CStyleManager() - { - m_pCurrentStyle = std::make_shared(); - } - - CStyleManager::~CStyleManager() - { - Clear(); - } - - void CStyleManager::Clear() - { - m_arStyles.clear(); - } - - void CStyleManager::NewDocument() - { - Clear(); - } - - std::shared_ptr CStyleManager::GetStyle() - { - for (size_t i = 0; i < m_arStyles.size(); ++i) - if (m_arStyles[i]->IsEqual(m_pCurrentStyle)) - return m_arStyles[i]; - - m_arStyles.push_back(m_pCurrentStyle); - auto pStyle = m_pCurrentStyle; - m_pCurrentStyle = std::make_shared(); - - return pStyle; - } -} diff --git a/DocxRenderer/src/logic/managers/StyleManager.h b/DocxRenderer/src/logic/managers/StyleManager.h deleted file mode 100644 index a9be808e885..00000000000 --- a/DocxRenderer/src/logic/managers/StyleManager.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "../styles/FontStyle.h" - -namespace NSDocxRenderer -{ - class CStyleManager - { - public: - std::vector> m_arStyles; - std::shared_ptr m_pCurrentStyle; - - public: - CStyleManager(); - virtual ~CStyleManager(); - - void Clear(); - void NewDocument(); - std::shared_ptr GetStyle(); - }; -} - diff --git a/DocxRenderer/src/logic/styles/BaseStyle.cpp b/DocxRenderer/src/logic/styles/BaseStyle.cpp deleted file mode 100644 index f87eb708b73..00000000000 --- a/DocxRenderer/src/logic/styles/BaseStyle.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "BaseStyle.h" - -CBaseStyle::CBaseStyle() -{ - -} diff --git a/DocxRenderer/src/logic/styles/BaseStyle.h b/DocxRenderer/src/logic/styles/BaseStyle.h deleted file mode 100644 index 2a8e977a7f3..00000000000 --- a/DocxRenderer/src/logic/styles/BaseStyle.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include "../DesktopEditor/common/StringBuilder.h" - -namespace NSDocxRenderer -{ - class CBaseStyle - { - protected: - enum class eStyleType - { - stUnknown, - stParagraph, - stCharacter, - stTable, - stNumbering - }; - - public: - CBaseStyle(const eStyleType& eType): m_eType(eType) {} - virtual ~CBaseStyle() {} - - CBaseStyle& operator=(const CBaseStyle& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; - - return *this; - } - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - - private: - eStyleType m_eType {eStyleType::stUnknown}; - - public: - bool m_bIsNotNecessaryToUse {false}; - }; - -} - diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index ef271a9bace..ad9242d69aa 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -4,103 +4,119 @@ namespace NSDocxRenderer { - CFontStyle::CFontStyle() : CBaseStyle(CBaseStyle::eStyleType::stCharacter) + CFontStyle::CFontStyle() { - static UINT iId = 0; - iId++; - if (iId < 10) - { - m_strStyleId = L"fontstyle0" + std::to_wstring(iId); - } + static LONG lId = 0; + lId++; + m_wsFontStyleId = m_wsIdStart; + + if(lId < 10) + m_wsFontStyleId += L"0" + std::to_wstring(lId); else - { - m_strStyleId = L"fontstyle" + std::to_wstring(iId); - } + m_wsFontStyleId += std::to_wstring(lId); + } + CFontStyle::CFontStyle(const CFontStyle& oFontStyle) : CFontStyle() + { + *this = oFontStyle; + } + CFontStyle::~CFontStyle() + { } CFontStyle& CFontStyle::operator=(const CFontStyle& oSrc) { if (this == &oSrc) - { return *this; - } - - CBaseStyle::operator=(oSrc); - - m_strStyleId = oSrc.m_strStyleId; - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; + m_dFontSize = oSrc.m_dFontSize; + m_oBrush = oSrc.m_oBrush; + m_wsFontName = oSrc.m_wsFontName; + m_bBold = oSrc.m_bBold; + m_bItalic = oSrc.m_bItalic; return *this; } - - void CFontStyle::CopyFormat(const CFontStyle& oSrc) + bool CFontStyle::operator==(const CFontStyle& oSrc) { - if (this == &oSrc) - { - return; - } + bool bIf1 = m_oBrush.Type == oSrc.m_oBrush.Type; + bool bIf2 = m_oBrush.Color1 == oSrc.m_oBrush.Color1; + bool bIf3 = m_oBrush.Color2 == oSrc.m_oBrush.Color2; + bool bIf4 = m_oBrush.Alpha1 == oSrc.m_oBrush.Alpha1; + bool bIf5 = m_oBrush.Alpha2 == oSrc.m_oBrush.Alpha2; + bool bIf6 = m_oBrush.LinearAngle == oSrc.m_oBrush.LinearAngle; - CBaseStyle::operator=(oSrc); + bool bIf7 = m_dFontSize == oSrc.m_dFontSize; + bool bIf8 = m_wsFontName == oSrc.m_wsFontName; + bool bIf9 = (m_bItalic == oSrc.m_bItalic) && (m_bBold == oSrc.m_bBold); - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; + //todo + // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && + // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); + //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; + return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && + bIf7 && bIf8 && bIf9); } - bool CFontStyle::IsEqual(std::shared_ptr oSrc) + const std::wstring& CFontStyle::GetFontStyleId() const noexcept { - //note Бывают fonts только с разными path => новый стиль => m_oFont.IsEqual не берем - //todo проверить FaceIndex StringGID - bool bIf1 = m_oFont.Name == oSrc->m_oFont.Name; - bool bIf2 = m_oFont.Size == oSrc->m_oFont.Size; - bool bIf3 = m_oFont.Bold == oSrc->m_oFont.Bold; - bool bIf4 = m_oFont.Italic == oSrc->m_oFont.Italic; - bool bIf5 = m_oFont.Underline == oSrc->m_oFont.Underline; - bool bIf6 = m_oFont.Strikeout == oSrc->m_oFont.Strikeout; - - bool bIf7 = m_oBrush.Type == oSrc->m_oBrush.Type; - bool bIf8 = m_oBrush.Color1 == oSrc->m_oBrush.Color1; - bool bIf9 = m_oBrush.Color2 == oSrc->m_oBrush.Color2; - bool bIf10 = m_oBrush.Alpha1 == oSrc->m_oBrush.Alpha1; - bool bIf11 = m_oBrush.Alpha2 == oSrc->m_oBrush.Alpha2; - bool bIf12 = m_oBrush.LinearAngle == oSrc->m_oBrush.LinearAngle; + return m_wsFontStyleId; + } + const std::wstring& CFontStyle::GetFontName() const noexcept + { + return m_wsFontName; + } + const NSStructures::CBrush& CFontStyle::GetBrush() const noexcept + { + return m_oBrush; + } - //todo - // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && - // (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); - //bool bIf7 = m_oBrush.IsEqual(&oSrc->m_oBrush); + double CFontStyle::GetFontSize() const noexcept + { + return m_dFontSize; + } + bool CFontStyle::IsBold() const noexcept + { + return m_bBold; + } + bool CFontStyle::IsItalic() const noexcept + { + return m_bItalic; + } - bool bIf13 = m_strPickFontName == oSrc->m_strPickFontName; - bool bIf14 = m_lPickFontStyle == oSrc->m_lPickFontStyle; + void CFontStyle::SetFontName(const std::wstring& wsFontName) + { + m_wsFontName = wsFontName; + } + void CFontStyle::SetBrush(const NSStructures::CBrush& oBrush) + { + m_oBrush = oBrush; + } - return (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && - bIf7 && bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && - bIf13 && bIf14); + void CFontStyle::SetFontSize(double dFontSize) + { + m_dFontSize = dFontSize; + } + void CFontStyle::SetBold(bool bBold) + { + m_bBold = bBold; + } + void CFontStyle::SetItalic(double bItalic) + { + m_bItalic = bItalic; } void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) { - if (m_bIsNotNecessaryToUse) - { - return; - } - oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; oWriter.WriteString(L""); - if (m_strPickFontName.empty()) + if (m_bBold) { - if (m_oFont.Bold) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (m_oFont.Italic) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } + oWriter.WriteString(L""); + oWriter.WriteString(L""); } - else + if (m_bItalic) { - if (0x01 == (0x01 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (0x02 == (0x02 & m_lPickFontStyle)) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } + oWriter.WriteString(L""); + oWriter.WriteString(L""); } if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) @@ -154,7 +153,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); } - int lSize = static_cast(2 * m_oFont.Size); + int lSize = static_cast(2 * m_dFontSize); oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L""); } } diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 45d122087fb..0021ebc01f5 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -1,33 +1,49 @@ #pragma once #include -#include "BaseStyle.h" -#include "../managers/FontManager.h" + +#include "../DesktopEditor/graphics/structures.h" +#include "../DesktopEditor/common/StringBuilder.h" namespace NSDocxRenderer { - class CFontStyle : public CBaseStyle + class CFontStyle { public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; + CFontStyle(); + CFontStyle(const CFontStyle& oFontStyle); + ~CFontStyle(); - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; + CFontStyle& operator=(const CFontStyle& oSrc); + bool operator==(const CFontStyle& oSrc); - private: - std::wstring m_strStyleId {L""}; + const std::wstring& GetFontStyleId() const noexcept; + const std::wstring& GetFontName() const noexcept; + const NSStructures::CBrush& GetBrush() const noexcept; - public: - CFontStyle(); - ~CFontStyle(){} + double GetFontSize() const noexcept; + bool IsBold() const noexcept; + bool IsItalic() const noexcept; - CFontStyle& operator=(const CFontStyle& oSrc); + void SetFontName(const std::wstring& wsFontName); + void SetBrush(const NSStructures::CBrush& oBrush); + + void SetFontSize(double dFontSize); + void SetBold(bool bBold); + void SetItalic(double bItalic); - void CopyFormat(const CFontStyle& oSrc); - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - bool IsEqual(std::shared_ptr oSrc); - std::wstring GetStyleId() {return m_strStyleId;} + void CopyNoId(const CFontStyle& oSrc); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + private: + std::wstring m_wsFontStyleId {L""}; + NSStructures::CBrush m_oBrush; + std::wstring m_wsFontName {L""}; + double m_dFontSize {0}; + bool m_bItalic {false}; + bool m_bBold {false}; + + const std::wstring m_wsIdStart = L"fontstyle"; }; } diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 96883cca1ed..a29eab00965 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -3,7 +3,6 @@ #include #include "VectorGraphics.h" -#include "../DesktopEditor/common/Types.h" namespace NSDocxRenderer diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 44d92a71fb9..b982d650917 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -26,13 +26,11 @@ namespace NSDocxRenderer std::list points; }; - public: CVectorGraphics(); ~CVectorGraphics(); CVectorGraphics& operator=(CVectorGraphics&& other); - public: const std::list& GetData() const; double GetLeft() const noexcept; @@ -40,7 +38,6 @@ namespace NSDocxRenderer double GetRight() const noexcept; double GetBottom() const noexcept; - public: void MoveTo(const double& x1, const double& y1); void LineTo(const double& x1, const double& y1); void CurveTo(const double& x1, const double& y1, const double& x2, const double& y2, const double& x3, const double& y3); From 9a0d42b9577643d9618b3932019f63403147d3d0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 10 Apr 2023 19:11:42 +0300 Subject: [PATCH 029/794] Update shape merging --- DocxRenderer/src/logic/elements/Paragraph.cpp | 2 ++ DocxRenderer/src/logic/elements/Shape.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index ce650b60f0e..ad33cc67051 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -28,6 +28,8 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); + // тут должны быть стили для параграфов + oWriter.WriteString(L" 0) { diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 57e50d8a85f..3a427eefa6f 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -117,10 +117,19 @@ namespace NSDocxRenderer // недалеко друг от друга по горизонтали (fabs(pShape->m_dRight - this->m_dLeft) < dHorNearby || - fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby) && + fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby || + + // друг в друге тоже учитываем + fabs(pShape->m_dRight - this->m_dRight) <= dHorNearby || + fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) && // недалеко друг от друга по вертикали - fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby) + (fabs(pShape->m_dBaselinePos - this->m_dTop) < dHorNearby || + fabs(pShape->m_dTop - this->m_dBaselinePos) < dHorNearby || + + // друг в друге + fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dHorNearby || + fabs(pShape->m_dTop - this->m_dTop) < dHorNearby)) { CBaseItem::AddContent(pShape); m_oVector.Join(std::move(pShape->m_oVector)); From acb9af928f0f9e64866a0895cb4822166136063f Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 18 Apr 2023 22:05:29 +0300 Subject: [PATCH 030/794] Add paragraph styles --- DocxRenderer/DocxRenderer.pro | 4 + DocxRenderer/src/logic/Document.cpp | 13 +-- DocxRenderer/src/logic/Document.h | 2 + DocxRenderer/src/logic/Page.cpp | 44 ++++---- DocxRenderer/src/logic/Page.h | 5 +- DocxRenderer/src/logic/elements/ContText.cpp | 48 ++++----- DocxRenderer/src/logic/elements/Converter.cpp | 11 +- DocxRenderer/src/logic/elements/Converter.h | 5 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 3 +- DocxRenderer/src/logic/elements/Paragraph.h | 3 +- .../src/logic/managers/FontStyleManager.cpp | 38 +++---- .../src/logic/managers/FontStyleManager.h | 2 - .../logic/managers/ParagraphStyleManager.cpp | 52 +++++++++ .../logic/managers/ParagraphStyleManager.h | 29 +++++ DocxRenderer/src/logic/styles/FontStyle.cpp | 102 +++++------------- DocxRenderer/src/logic/styles/FontStyle.h | 30 ++---- .../src/logic/styles/ParagraphStyle.cpp | 33 ++++++ .../src/logic/styles/ParagraphStyle.h | 26 +++++ 18 files changed, 273 insertions(+), 177 deletions(-) create mode 100644 DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp create mode 100644 DocxRenderer/src/logic/managers/ParagraphStyleManager.h create mode 100644 DocxRenderer/src/logic/styles/ParagraphStyle.cpp create mode 100644 DocxRenderer/src/logic/styles/ParagraphStyle.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 525510eb3f7..509ae7607f1 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -38,7 +38,9 @@ HEADERS += \ src/logic/managers/FontStyleManager.h \ src/logic/managers/ImageManager.h \ src/logic/managers/FontManager.h \ + src/logic/managers/ParagraphStyleManager.h \ src/logic/styles/FontStyle.h \ + src/logic/styles/ParagraphStyle.h \ src/resources/ColorTable.h \ src/resources/Constants.h \ src/resources/ImageInfo.h \ @@ -64,9 +66,11 @@ SOURCES += \ src/logic/managers/FontManager.cpp \ src/logic/managers/FontStyleManager.cpp \ src/logic/managers/ImageManager.cpp \ + src/logic/managers/ParagraphStyleManager.cpp \ src/logic/styles/FontStyle.cpp \ src/logic/Page.cpp \ src/logic/Document.cpp \ + src/logic/styles/ParagraphStyle.cpp \ src/resources/VectorGraphics.cpp \ src/resources/resources.cpp \ DocxRenderer.cpp diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index d9a52236742..05676aca301 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -812,7 +812,7 @@ namespace NSDocxRenderer Clear(); m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oFontStyleManager, &m_oFontManager, &m_oFontSelector); + m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oFontStyleManager, &m_oFontManager, &m_oFontSelector, &m_oParagraphStyleManager); m_oImageManager.NewDocument(); m_oFontStyleManager.NewDocument(); @@ -1019,8 +1019,8 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L""); + //oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -1158,9 +1158,6 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -1212,8 +1209,12 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); + //oWriter.WriteString(L""); + //oWriter.WriteString(L""); + m_oFontStyleManager.ToXml(oWriter); + m_oParagraphStyleManager.ToXml(oWriter); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index eb1e8130275..f867dcd95af 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -4,6 +4,7 @@ #include "../resources/resources.h" #include "managers/ImageManager.h" #include "managers/FontStyleManager.h" +#include "managers/ParagraphStyleManager.h" namespace NSDocxRenderer { @@ -32,6 +33,7 @@ namespace NSDocxRenderer CImageManager m_oImageManager; CFontStyleManager m_oFontStyleManager; + CParagraphStyleManager m_oParagraphStyleManager; CFontManager m_oFontManager; CFontSelector m_oFontSelector; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 9d355019703..b66aa742a01 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -14,7 +14,7 @@ namespace NSDocxRenderer void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pFontStyleManager, CFontManager *pFontManager, - CFontSelector* pFontSelector) + CFontSelector* pFontSelector, CParagraphStyleManager* pParagraphStyleManager) { m_pFont = pFont; m_pPen = pPen; @@ -28,6 +28,7 @@ namespace NSDocxRenderer m_pFontStyleManager = pFontStyleManager; m_pFontManager = pFontManager; m_pFontSelector = pFontSelector; + m_pParagraphStyleManager = pParagraphStyleManager; m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; @@ -423,6 +424,7 @@ namespace NSDocxRenderer m_pFontSelector->IsSelectedItalic(), m_pFontSelector->IsSelectedBold()); pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); + m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); // собираем отдельно, т.к. такие символы не имею размера m_dWidth if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) @@ -942,7 +944,8 @@ namespace NSDocxRenderer SingletonInstance().BuildLines(m_arTextLine); SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etParagraph, - m_arTextLine, m_arTables, m_arOutputObjects); + m_arTextLine, m_arTables, m_arOutputObjects, + m_pParagraphStyleManager); } void CPage::AnalyzeCollectedConts() @@ -1088,7 +1091,7 @@ namespace NSDocxRenderer if (!bIsComplicatedFigure) { - bool bIf1 = pCurrCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor; + bool bIf1 = pCurrCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; @@ -1098,14 +1101,14 @@ namespace NSDocxRenderer { if (!bIf2) { - auto oBrush = pCurrCont->m_pFontStyle->GetBrush(); + auto oBrush = pCurrCont->m_pFontStyle->oBrush; oBrush.Color1 = pShape->m_oPen.Color; pCurrCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(oBrush, - pCurrCont->m_pFontStyle->GetFontName(), - pCurrCont->m_pFontStyle->GetFontSize(), - pCurrCont->m_pFontStyle->IsItalic(), - pCurrCont->m_pFontStyle->IsBold()); + pCurrCont->m_pFontStyle->wsFontName, + pCurrCont->m_pFontStyle->dFontSize, + pCurrCont->m_pFontStyle->bItalic, + pCurrCont->m_pFontStyle->bBold); pCurrCont->m_bIsShadowPresent = true; pCurrCont->m_bIsOutlinePresent = true; @@ -1186,7 +1189,7 @@ namespace NSDocxRenderer eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; //Цвета должны быть разными - bool bIf4 = pCont->m_pFontStyle->GetBrush().Color1 != pShape->m_oBrush.Color1; + bool bIf4 = pCont->m_pFontStyle->oBrush.Color1 != pShape->m_oBrush.Color1; bool bIf5 = pShape->m_oBrush.Color1 == c_iBlackColor && pShape->m_oPen.Color == c_iWhiteColor; bool bIf6 = pShape->m_bIsNoFill == false; bool bIf7 = pShape->m_bIsNoStroke == true; @@ -1292,17 +1295,17 @@ namespace NSDocxRenderer { continue; } - dFontSize = pCont->m_pFontStyle->GetFontSize(); + dFontSize = pCont->m_pFontStyle->dFontSize; break; } for (auto pCont : pCurrLine->m_arConts) { - pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->GetBrush(), - pCont->m_pFontStyle->GetFontName(), + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, + pCont->m_pFontStyle->wsFontName, dFontSize, - pCont->m_pFontStyle->IsItalic(), - pCont->m_pFontStyle->IsBold()); + pCont->m_pFontStyle->bItalic, + pCont->m_pFontStyle->bBold); if (pBaseLine->m_dLeft > pCont->m_dLeft) { @@ -1335,17 +1338,17 @@ namespace NSDocxRenderer { continue; } - dFontSize = pCont->m_pFontStyle->GetFontSize(); + dFontSize = pCont->m_pFontStyle->dFontSize; break; } for (auto pCont : pSubLine->m_arConts) { - pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->GetBrush(), - pCont->m_pFontStyle->GetFontName(), + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, + pCont->m_pFontStyle->wsFontName, dFontSize, - pCont->m_pFontStyle->IsItalic(), - pCont->m_pFontStyle->IsBold()); + pCont->m_pFontStyle->bItalic, + pCont->m_pFontStyle->bBold); if (pCurrLine->m_dLeft > pCont->m_dLeft) { @@ -1547,7 +1550,8 @@ namespace NSDocxRenderer SingletonInstance().BuildLines(pCell->m_arTextLine); SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etCell, - pCell->m_arTextLine, pCell->m_arOutputObjects); + pCell->m_arTextLine, pCell->m_arOutputObjects, + m_pParagraphStyleManager); pRow->AddContent(pCell); } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 9dd2f2fc06f..30084f9ec7e 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -4,6 +4,8 @@ #include "elements/Shape.h" #include "elements/Table.h" #include "managers/FontStyleManager.h" +#include "managers/ParagraphStyleManager.h" +#include "styles/ParagraphStyle.h" namespace NSDocxRenderer @@ -21,6 +23,7 @@ namespace NSDocxRenderer Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; CFontStyleManager* m_pFontStyleManager {nullptr}; + CParagraphStyleManager* m_pParagraphStyleManager {nullptr}; CFontManager* m_pFontManager {nullptr}; CFontSelector* m_pFontSelector {nullptr}; CVectorGraphics m_oVector; @@ -58,7 +61,7 @@ namespace NSDocxRenderer void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pStyleManager, CFontManager *pFontManager, - CFontSelector* pFontSelector); + CFontSelector* pFontSelector, CParagraphStyleManager* pParagraphStyleManager); void BeginCommand(DWORD lType); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index d6243b4e13e..030e57c8487 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -80,22 +80,22 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L"GetFontStyleId()); + oWriter.WriteString(m_pFontStyle->wsFontStyleId); oWriter.WriteString(L"\"/>"); LONG lCalculatedSpacing = 0; - if (!m_pFontStyle->GetFontName().empty() && !m_oText.empty()) + if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { if (m_eVertAlignType != eVertAlignType::vatSubscript && m_eVertAlignType != eVertAlignType::vatSuperscript) { // нужно перемерять... NSStructures::CFont oFont; - oFont.Name = m_pFontStyle->GetFontName(); - oFont.Bold = m_pFontStyle->IsBold(); - oFont.Italic = m_pFontStyle->IsItalic(); - oFont.Size = m_pFontStyle->GetFontSize(); + oFont.Name = m_pFontStyle->wsFontName; + oFont.Bold = m_pFontStyle->bBold; + oFont.Italic = m_pFontStyle->bItalic; + oFont.Size = m_pFontStyle->dFontSize; m_pManager->LoadFontByName(oFont); double dBoxX; @@ -105,7 +105,7 @@ namespace NSDocxRenderer m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); - //dSpacing *= c_dMMToDx; + dSpacing *= c_dMMToDx; lCalculatedSpacing = static_cast(dSpacing); } @@ -115,7 +115,7 @@ namespace NSDocxRenderer //note 1 -> 0.5pt lCalculatedSpacing -= 1; - if (lCalculatedSpacing > 0) + if (lCalculatedSpacing != 0) { oWriter.WriteString(L""); oWriter.WriteString(L"GetFontStyleId()); + oWriter.WriteString(m_pFontStyle->wsFontStyleId); oWriter.WriteString(L"\"/>"); double dSpaceMMSize = m_dSpaceWidthMM; @@ -262,7 +262,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"GetFontStyleId() == pCont->m_pFontStyle->GetFontStyleId(); + bool bIf1 = m_pFontStyle->wsFontStyleId == pCont->m_pFontStyle->wsFontStyleId; bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; bool bIf3 = m_bIsDoubleStrikeout == pCont->m_bIsDoubleStrikeout; bool bIf4 = m_bIsHighlightPresent == pCont->m_bIsHighlightPresent; @@ -322,11 +322,11 @@ namespace NSDocxRenderer UINT CContText::GetNumberOfFeatures() { UINT ret = 0; - if (m_pFontStyle->IsBold()) + if (m_pFontStyle->bBold) { ret++; } - if (m_pFontStyle->IsItalic()) + if (m_pFontStyle->bItalic) { ret++; } @@ -377,16 +377,16 @@ namespace NSDocxRenderer bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_pFontStyle->GetFontSize() == m_pFontStyle->GetFontSize(); + bool bIf5 = m_pFontStyle->dFontSize == m_pFontStyle->dFontSize; bool bIf6 = m_oText == pCont->m_oText; //Цвет тени должен быть серым - bool bIf7 = m_pFontStyle->GetBrush().Color1 == c_iGreyColor; - bool bIf8 = pCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor; - bool bIf9 = m_pFontStyle->GetBrush().Color1 == c_iBlackColor; - bool bIf10 = pCont->m_pFontStyle->GetBrush().Color1 == c_iBlackColor; - bool bIf11 = m_pFontStyle->GetBrush().Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_pFontStyle->GetBrush().Color1 == c_iGreyColor2; + bool bIf7 = m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf8 = pCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf9 = m_pFontStyle->oBrush.Color1 == c_iBlackColor; + bool bIf10 = pCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; + bool bIf11 = m_pFontStyle->oBrush.Color1 == c_iGreyColor2; + bool bIf12 = pCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. @@ -461,8 +461,8 @@ namespace NSDocxRenderer eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; //Размеры шрифта должны бать разными - bool bIf5 = m_pFontStyle->GetFontSize() * 0.7 > pCont->m_pFontStyle->GetFontSize(); - bool bIf6 = m_pFontStyle->GetFontSize() < pCont->m_pFontStyle->GetFontSize() * 0.7; + bool bIf5 = m_pFontStyle->dFontSize * 0.7 > pCont->m_pFontStyle->dFontSize; + bool bIf6 = m_pFontStyle->dFontSize < pCont->m_pFontStyle->dFontSize * 0.7; if (bIf3 || bIf4) { @@ -511,6 +511,6 @@ namespace NSDocxRenderer double CContText::CalculateThinSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.8; + return m_dSpaceWidthMM * 0.4; } } diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 06f7ffca4b9..e80bd6165f1 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -2,6 +2,7 @@ #include "Shape.h" #include "src/resources/utils.h" + namespace NSDocxRenderer { //общая функция для сборки строк в любом текстовом объекте @@ -79,17 +80,19 @@ namespace NSDocxRenderer void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rOutputObjects) + std::vector& rOutputObjects, + CParagraphStyleManager* pParagraphStyleManager) { std::vector oStubVector; //просто объект-заглушка - BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects); + BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects, pParagraphStyleManager); } // eBaseType == etCell или etParagraph // eType == 2 - 5 из eTextAssociationType void CConverter::BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects) + std::vector& rTables, std::vector &rOutputObjects, + CParagraphStyleManager* pParagraphStyleManager) { CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; @@ -465,6 +468,7 @@ namespace NSDocxRenderer pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); pParagraph->RemoveHighlightColor(); + // pParagraph->MergeLines(); } else @@ -484,6 +488,7 @@ namespace NSDocxRenderer } else { + pParagraph->m_wsStyleId = pParagraphStyleManager->GetDefaultParagraphStyleId(*pParagraph); rOutputObjects.push_back(pParagraph); } diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h index 2f3e8ac6741..c9186aed27d 100644 --- a/DocxRenderer/src/logic/elements/Converter.h +++ b/DocxRenderer/src/logic/elements/Converter.h @@ -1,5 +1,6 @@ #pragma once #include "Table.h" +#include "../managers/ParagraphStyleManager.h" namespace NSDocxRenderer { @@ -11,10 +12,10 @@ namespace NSDocxRenderer void BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector &rOutputObjects); + std::vector &rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); void BuildParagraphes(double dPageWidth, eTextAssociationType eType, CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects); + std::vector& rTables, std::vector &rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector &rOutputObjects); void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index ad33cc67051..3fdae0949ab 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -28,7 +28,8 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - // тут должны быть стили для параграфов + // styles + if(!m_wsStyleId.empty()) oWriter.WriteString(L""); oWriter.WriteString(L" 0) diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 39910abb9b9..cbd649a1ce3 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -45,6 +45,8 @@ namespace NSDocxRenderer size_t m_nNumLines {0}; + std::wstring m_wsStyleId; + public: CParagraph(); virtual ~CParagraph(); @@ -54,7 +56,6 @@ namespace NSDocxRenderer virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; void RemoveHighlightColor(); - void MergeLines(); static TextAlignmentType DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp index 730dbb2a829..49e6e64bafc 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -29,11 +29,11 @@ namespace NSDocxRenderer std::shared_ptr CFontStyleManager::GetOrAddFontStyle(const CFontStyle& oFontStyle) { - return GetOrAddFontStyle(oFontStyle.GetBrush(), - oFontStyle.GetFontName(), - oFontStyle.GetFontSize(), - oFontStyle.IsItalic(), - oFontStyle.IsBold()); + return GetOrAddFontStyle(oFontStyle.oBrush, + oFontStyle.wsFontName, + oFontStyle.dFontSize, + oFontStyle.bItalic, + oFontStyle.bBold); } std::shared_ptr CFontStyleManager::GetOrAddFontStyle(const NSStructures::CBrush& oBrush, const std::wstring& wsFontName, @@ -43,24 +43,24 @@ namespace NSDocxRenderer { for(auto& val : m_arFontStyles) { - if(oBrush.Type == val->GetBrush().Type && - oBrush.Color1 == val->GetBrush().Color1 && - oBrush.Color2 == val->GetBrush().Color2 && - oBrush.Alpha1 == val->GetBrush().Alpha1 && - oBrush.Alpha2 == val->GetBrush().Alpha2 && - oBrush.LinearAngle == val->GetBrush().LinearAngle && - dFontSize == val->GetFontSize() && - wsFontName == val->GetFontName() && - (bItalic == val->IsItalic()) && (bBold == val->IsBold())) + if(oBrush.Type == val->oBrush.Type && + oBrush.Color1 == val->oBrush.Color1 && + oBrush.Color2 == val->oBrush.Color2 && + oBrush.Alpha1 == val->oBrush.Alpha1 && + oBrush.Alpha2 == val->oBrush.Alpha2 && + oBrush.LinearAngle == val->oBrush.LinearAngle && + dFontSize == val->dFontSize && + wsFontName == val->wsFontName && + (bItalic == val->bItalic) && (bBold == val->bBold)) return val; } auto pFontStyle = std::make_shared(); - pFontStyle->SetBrush(oBrush); - pFontStyle->SetFontName(wsFontName); - pFontStyle->SetFontSize(dFontSize); - pFontStyle->SetItalic(bItalic); - pFontStyle->SetBold(bBold); + pFontStyle->oBrush = oBrush; + pFontStyle->wsFontName = wsFontName; + pFontStyle->dFontSize = dFontSize; + pFontStyle->bItalic = bItalic; + pFontStyle->bBold = bBold; m_arFontStyles.push_front(pFontStyle); return pFontStyle; diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.h b/DocxRenderer/src/logic/managers/FontStyleManager.h index ecc993e7f32..b8673361d23 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.h +++ b/DocxRenderer/src/logic/managers/FontStyleManager.h @@ -15,8 +15,6 @@ namespace NSDocxRenderer void NewDocument(); void ToXml(NSStringUtils::CStringBuilder& oWriter); - const std::shared_ptr GetFontStyle(const std::wstring& wsFontStyleId) const; - std::shared_ptr GetOrAddFontStyle(const CFontStyle& oFontStyle); std::shared_ptr GetOrAddFontStyle(const NSStructures::CBrush& oBrush, const std::wstring& wsFontName, diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp new file mode 100644 index 00000000000..0b4cb456329 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -0,0 +1,52 @@ +#include "ParagraphStyleManager.h" + + +namespace NSDocxRenderer +{ + CParagraphStyleManager::CParagraphStyleManager() + { + // стандартные стили + CParagraphStyle oNormal(L"Normal", L"Normal"); + CParagraphStyle oHeading1(L"Heading1", L"Heading 1"); + + oNormal.bIsDefault = true; + oHeading1.wsBasedOn = oNormal.wsStyleId; + oHeading1.nUiPriority = 9; + + m_arDefaultParagraphStyles.push_back(oNormal); + m_arDefaultParagraphStyles.push_back(oHeading1); + + } + CParagraphStyleManager::~CParagraphStyleManager() + { + m_arDefaultParagraphStyles.clear(); + } + + std::wstring CParagraphStyleManager::GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept + { + if(oParagraph.m_nNumLines > 1) return L"Normal"; + + bool isHeading = true; + for(auto& val : oParagraph.m_arLines[0]->m_arConts) + if(val->m_pFontStyle->dFontSize <= m_dAvgFontSize && !val->m_pFontStyle->bBold) + isHeading = false; + + return isHeading ? L"Heading1" : L"Normal"; + } + double CParagraphStyleManager::GetAvgFontSize() const noexcept + { + return m_dAvgFontSize; + } + void CParagraphStyleManager::UpdateAvgFontSize(double dFontSize) + { + m_dAvgFontSize = (m_dAvgFontSize / (m_nN + 1)) * m_nN + (dFontSize / (m_nN + 1)); + m_nN++; + } + + void CParagraphStyleManager::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + for(auto& val : m_arDefaultParagraphStyles) + val.ToXml(oWriter); + } +} + diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.h b/DocxRenderer/src/logic/managers/ParagraphStyleManager.h new file mode 100644 index 00000000000..fce153122ce --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +#include "../elements/Paragraph.h" +#include "../styles/ParagraphStyle.h" + +namespace NSDocxRenderer +{ + class CParagraphStyleManager + { + public: + CParagraphStyleManager(); + ~CParagraphStyleManager(); + + std::wstring GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept; + double GetAvgFontSize() const noexcept; + + void UpdateAvgFontSize(double dFontSize); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + private: + std::list m_arDefaultParagraphStyles; + // std::list m_arCustomParagraphStyles; + + double m_dAvgFontSize = 0; + int m_nN = 0; + }; +} diff --git a/DocxRenderer/src/logic/styles/FontStyle.cpp b/DocxRenderer/src/logic/styles/FontStyle.cpp index ad9242d69aa..1fb978b6513 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -8,12 +8,12 @@ namespace NSDocxRenderer { static LONG lId = 0; lId++; - m_wsFontStyleId = m_wsIdStart; + wsFontStyleId = m_wsIdStart; if(lId < 10) - m_wsFontStyleId += L"0" + std::to_wstring(lId); + wsFontStyleId += L"0" + std::to_wstring(lId); else - m_wsFontStyleId += std::to_wstring(lId); + wsFontStyleId += std::to_wstring(lId); } CFontStyle::CFontStyle(const CFontStyle& oFontStyle) : CFontStyle() { @@ -28,26 +28,26 @@ namespace NSDocxRenderer if (this == &oSrc) return *this; - m_dFontSize = oSrc.m_dFontSize; - m_oBrush = oSrc.m_oBrush; + dFontSize = oSrc.dFontSize; + oBrush = oSrc.oBrush; - m_wsFontName = oSrc.m_wsFontName; - m_bBold = oSrc.m_bBold; - m_bItalic = oSrc.m_bItalic; + wsFontName = oSrc.wsFontName; + bBold = oSrc.bBold; + bItalic = oSrc.bItalic; return *this; } bool CFontStyle::operator==(const CFontStyle& oSrc) { - bool bIf1 = m_oBrush.Type == oSrc.m_oBrush.Type; - bool bIf2 = m_oBrush.Color1 == oSrc.m_oBrush.Color1; - bool bIf3 = m_oBrush.Color2 == oSrc.m_oBrush.Color2; - bool bIf4 = m_oBrush.Alpha1 == oSrc.m_oBrush.Alpha1; - bool bIf5 = m_oBrush.Alpha2 == oSrc.m_oBrush.Alpha2; - bool bIf6 = m_oBrush.LinearAngle == oSrc.m_oBrush.LinearAngle; + bool bIf1 = oBrush.Type == oSrc.oBrush.Type; + bool bIf2 = oBrush.Color1 == oSrc.oBrush.Color1; + bool bIf3 = oBrush.Color2 == oSrc.oBrush.Color2; + bool bIf4 = oBrush.Alpha1 == oSrc.oBrush.Alpha1; + bool bIf5 = oBrush.Alpha2 == oSrc.oBrush.Alpha2; + bool bIf6 = oBrush.LinearAngle == oSrc.oBrush.LinearAngle; - bool bIf7 = m_dFontSize == oSrc.m_dFontSize; - bool bIf8 = m_wsFontName == oSrc.m_wsFontName; - bool bIf9 = (m_bItalic == oSrc.m_bItalic) && (m_bBold == oSrc.m_bBold); + bool bIf7 = dFontSize == oSrc.dFontSize; + bool bIf8 = wsFontName == oSrc.wsFontName; + bool bIf9 = (bItalic == oSrc.bItalic) && (bBold == oSrc.bBold); //todo // (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && @@ -58,65 +58,17 @@ namespace NSDocxRenderer bIf7 && bIf8 && bIf9); } - const std::wstring& CFontStyle::GetFontStyleId() const noexcept - { - return m_wsFontStyleId; - } - const std::wstring& CFontStyle::GetFontName() const noexcept - { - return m_wsFontName; - } - const NSStructures::CBrush& CFontStyle::GetBrush() const noexcept - { - return m_oBrush; - } - - double CFontStyle::GetFontSize() const noexcept - { - return m_dFontSize; - } - bool CFontStyle::IsBold() const noexcept - { - return m_bBold; - } - bool CFontStyle::IsItalic() const noexcept - { - return m_bItalic; - } - - void CFontStyle::SetFontName(const std::wstring& wsFontName) - { - m_wsFontName = wsFontName; - } - void CFontStyle::SetBrush(const NSStructures::CBrush& oBrush) - { - m_oBrush = oBrush; - } - - void CFontStyle::SetFontSize(double dFontSize) - { - m_dFontSize = dFontSize; - } - void CFontStyle::SetBold(bool bBold) - { - m_bBold = bBold; - } - void CFontStyle::SetItalic(double bItalic) - { - m_bItalic = bItalic; - } - void CFontStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) { oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); - if (m_bBold) + if (bBold) { oWriter.WriteString(L""); oWriter.WriteString(L""); } - if (m_bItalic) + if (bItalic) { oWriter.WriteString(L""); oWriter.WriteString(L""); } - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) + if (ConvertColorBGRToRGB(oBrush.Color1) != c_iBlackColor2) { oWriter.WriteString(L""); } - int lSize = static_cast(2 * m_dFontSize); + int lSize = static_cast(2 * dFontSize); oWriter.WriteString(L"wsStyleId = wsStyleId; + this->wsName = wsName; + } + CParagraphStyle::~CParagraphStyle() + { + } + + void CParagraphStyle::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + if(!wsBasedOn.empty()) oWriter.WriteString(L""); + if(bIsUnhideWhenUsed) oWriter.WriteString(L""); + if(bIsSemiHidden) oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + } +} + diff --git a/DocxRenderer/src/logic/styles/ParagraphStyle.h b/DocxRenderer/src/logic/styles/ParagraphStyle.h new file mode 100644 index 00000000000..8c4b6071dce --- /dev/null +++ b/DocxRenderer/src/logic/styles/ParagraphStyle.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../DesktopEditor/graphics/structures.h" +#include "../DesktopEditor/common/StringBuilder.h" + +namespace NSDocxRenderer +{ + class CParagraphStyle + { + public: + CParagraphStyle(); + CParagraphStyle(const std::wstring& wsStyleId, const std::wstring& wsName); + ~CParagraphStyle(); + + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + std::wstring wsStyleId; + std::wstring wsName; + std::wstring wsBasedOn; + + bool bIsDefault {false}; + bool bIsSemiHidden {false}; + bool bIsUnhideWhenUsed {true}; + LONG nUiPriority {0}; + }; +} From 265e9d8af8da2ae2088162dd6660aefcd9d8f9a0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 25 Apr 2023 03:37:21 +0300 Subject: [PATCH 031/794] Fix bug --- DocxRenderer/src/logic/Document.cpp | 6 +++--- DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 05676aca301..e3b71f279b3 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -1018,9 +1018,9 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - //oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp index 0b4cb456329..81c1bc8acb7 100644 --- a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -8,13 +8,19 @@ namespace NSDocxRenderer // стандартные стили CParagraphStyle oNormal(L"Normal", L"Normal"); CParagraphStyle oHeading1(L"Heading1", L"Heading 1"); + CParagraphStyle oHeading2(L"Heading2", L"Heading 2"); oNormal.bIsDefault = true; + oHeading1.wsBasedOn = oNormal.wsStyleId; oHeading1.nUiPriority = 9; + oHeading2.wsBasedOn = oNormal.wsStyleId; + oHeading2.nUiPriority = 9; + m_arDefaultParagraphStyles.push_back(oNormal); m_arDefaultParagraphStyles.push_back(oHeading1); + m_arDefaultParagraphStyles.push_back(oHeading2); } CParagraphStyleManager::~CParagraphStyleManager() From cf85c54f4362de4fc0df1a3b5538ca3ef2a86706 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 28 Apr 2023 00:52:58 +0300 Subject: [PATCH 032/794] Fix font selection --- DocxRenderer/src/logic/Document.cpp | 29 +-- .../src/logic/managers/FontManager.cpp | 68 +++++-- DocxRenderer/test/main.cpp | 184 +++++++++--------- 3 files changed, 159 insertions(+), 122 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index e3b71f279b3..19728b79e6d 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -972,19 +972,22 @@ namespace NSDocxRenderer oWriter.WriteString(L""); - oWriter.WriteString(L""); + if (!val.oFontSelectParams.arSignature.empty()) + { + oWriter.WriteString(L""); + } oWriter.WriteString(L""); } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 50aebdbc90a..b086d1ac290 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -268,8 +268,13 @@ namespace NSDocxRenderer for(int i = 0; i < 10; i++) bEqual &= arPANOSE[i] == oOther.arPANOSE[i]; - for(int i = 0; i < arSignature.size(); i++) - bEqual &= arSignature[i] == oOther.arSignature[i]; + if (arSignature.size() == oOther.arSignature.size()) + { + for(int i = 0; i < arSignature.size(); i++) + bEqual &= arSignature[i] == oOther.arSignature[i]; + } + else + bEqual = false; return bEqual; } @@ -326,17 +331,25 @@ namespace NSDocxRenderer } } - // не нашли... CFontSelectInfo oInfoCache; oInfoCache.oFontSelectParams = oFontSelectParams; oInfoCache.lRange = lRange; oInfoCache.lRangeNum = lRangeNum; - UINT dwR1 = oFontSelectParams.arSignature[0]; - UINT dwR2 = oFontSelectParams.arSignature[1]; - UINT dwR3 = oFontSelectParams.arSignature[2]; - UINT dwR4 = oFontSelectParams.arSignature[3]; + UINT dwR1 = 0; + UINT dwR2 = 0; + UINT dwR3 = 0; + UINT dwR4 = 0; + + if (!oFontSelectParams.arSignature.empty()) + { + dwR1 = oFontSelectParams.arSignature[0]; + dwR2 = oFontSelectParams.arSignature[1]; + dwR3 = oFontSelectParams.arSignature[2]; + dwR4 = oFontSelectParams.arSignature[3]; + } + UINT dwCodePage1 = 0; UINT dwCodePage2 = 0; @@ -364,9 +377,21 @@ namespace NSDocxRenderer bool bSelectItalic = false; CheckFontNamePDF(sFontNameSelect, bSelectBold, bSelectItalic); - oFormat.pPanose = new BYTE[10]; - for(int i = 0; i < 10; i++) - oFormat.pPanose[i] = oFontSelectParams.arPANOSE[i]; + bool bIsPanosePresent = false; + for (int i = 0; i < 10; i++) + { + if (0 != oFontSelectParams.arPANOSE[i]) + { + bIsPanosePresent = true; + break; + } + } + + if (bIsPanosePresent) + { + oFormat.pPanose = new BYTE[10]; + memcpy(oFormat.pPanose, oFontSelectParams.arPANOSE, 10 * sizeof(BYTE)); + } oFormat.bBold = new INT(oFontSelectParams.bDefaultBold); oFormat.bItalic = new INT(oFontSelectParams.bDefaultItalic); @@ -388,7 +413,7 @@ namespace NSDocxRenderer if (oFormat.bBold && *(oFormat.bBold) == 1 && oFormat.pPanose && oFormat.pPanose[2] < 7) oFormat.pPanose[2] = 7; - oFormat.wsDefaultName = new std::wstring(sFontNameSelect); + oFormat.wsName = new std::wstring(sFontNameSelect); NSFonts::CFontInfo* pInfo = m_pManager->GetFontInfoByParams(oFormat); @@ -503,6 +528,9 @@ namespace NSDocxRenderer LoadFontMetrics(); LoadFontSelectParams(); + if (m_oFontSelectParams.wsDefaultName.empty()) + m_oFontSelectParams.wsDefaultName = m_oFont.Name; + CheckPdfResources(); } void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) @@ -654,14 +682,20 @@ namespace NSDocxRenderer // Signature m_oFontSelectParams.arSignature.clear(); - for ( unsigned int i = 0; i < 6; ++i ) + // check os2 present: + bool bIsOS2Present = (-1 != m_pManager->GetFile()->IsUnicodeRangeAvailable(0, 0)) ? true : false; + + if (bIsOS2Present) { - DWORD value = 0; - for ( unsigned long bit = 0; bit < 32; ++bit ) - if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) - value |= ( 1 << bit ); + for ( unsigned int i = 0; i < 6; ++i ) + { + DWORD value = 0; + for ( unsigned long bit = 0; bit < 32; ++bit ) + if (m_pManager->GetFile()->IsUnicodeRangeAvailable(bit, i)) + value |= ( 1 << bit ); - m_oFontSelectParams.arSignature.push_back(value); + m_oFontSelectParams.arSignature.push_back(value); + } } } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index d82b6e1eea4..73e19a4d448 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -55,135 +55,135 @@ int main(int argc, char *argv[]) { #ifdef TEST_XML_BOM - std::wstring sFileXmlSrc = L"PATH_TO_SRC_XML"; - std::wstring sFileXmlDst = L"PATH_TO_DST_XML"; + std::wstring sFileXmlSrc = L"PATH_TO_SRC_XML"; + std::wstring sFileXmlDst = L"PATH_TO_DST_XML"; - BYTE* pBufferXml = NULL; - DWORD lBufferXmlLen = 0; - NSFile::CFileBinary::ReadAllBytes(sFileXmlSrc, &pBufferXml, lBufferXmlLen); + BYTE* pBufferXml = NULL; + DWORD lBufferXmlLen = 0; + NSFile::CFileBinary::ReadAllBytes(sFileXmlSrc, &pBufferXml, lBufferXmlLen); - std::string sUtf8 = XmlUtils::GetUtf8FromFileContent(pBufferXml, lBufferXmlLen); - std::wstring sUnicode = UTF8_TO_U(sUtf8); + std::string sUtf8 = XmlUtils::GetUtf8FromFileContent(pBufferXml, lBufferXmlLen); + std::wstring sUnicode = UTF8_TO_U(sUtf8); - NSFile::CFileBinary::SaveToFile(sFileXmlDst, sUnicode, true); + NSFile::CFileBinary::SaveToFile(sFileXmlDst, sUnicode, true); - RELEASEARRAYOBJECTS(pBufferXml); + RELEASEARRAYOBJECTS(pBufferXml); #endif - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker.m_bIsNeedThumbnails = false; - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); + if (!NSDirectory::Exists(oWorker.m_sDirectory)) + NSDirectory::CreateDirectory(oWorker.m_sDirectory); - NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring sTempDir = L""; - std::wstring sTempDirOut = L""; + std::wstring sTempDir = NSFile::GetProcessDirectory() + L"/temp"; + std::wstring sTempDirOut = NSFile::GetProcessDirectory() + L"/temp/output"; - if (!NSDirectory::Exists(sTempDir)) - NSDirectory::CreateDirectory(sTempDir); - if (!NSDirectory::Exists(sTempDirOut)) - NSDirectory::CreateDirectory(sTempDirOut); + if (!NSDirectory::Exists(sTempDir)) + NSDirectory::CreateDirectory(sTempDir); + if (!NSDirectory::Exists(sTempDirOut)) + NSDirectory::CreateDirectory(sTempDirOut); - //Добавляем все файлы из определенного каталога - //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); - std::vector sSourceFiles; - //Или добавляем любой нужный файл + //Добавляем все файлы из определенного каталога + //std::vector sSourceFiles = NSDirectory::GetFiles(L"C:\\Folder"); + std::vector sSourceFiles; + //Или добавляем любой нужный файл sSourceFiles.push_back(L""); - std::wstring sTextDirOut = L""; - if (!NSDirectory::Exists(sTextDirOut)) - NSDirectory::CreateDirectory(sTextDirOut); + std::wstring sTextDirOut = NSFile::GetProcessDirectory() + L"/output"; + if (!NSDirectory::Exists(sTextDirOut)) + NSDirectory::CreateDirectory(sTextDirOut); - IOfficeDrawingFile* pReader = NULL; + IOfficeDrawingFile* pReader = NULL; - COfficeFileFormatChecker oChecker; - int nFileType = 0; + COfficeFileFormatChecker oChecker; + int nFileType = 0; - CDocxRenderer oDocxRenderer(pFonts); - oDocxRenderer.SetTempFolder(sTempDirOut); + CDocxRenderer oDocxRenderer(pFonts); + oDocxRenderer.SetTempFolder(sTempDirOut); - for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++) - { - if (oChecker.isOfficeFile(sSourceFiles[nIndex])) - { - nFileType = oChecker.nFileType; - switch (nFileType) - { - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: + for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++) + { + if (oChecker.isOfficeFile(sSourceFiles[nIndex])) + { + nFileType = oChecker.nFileType; + switch (nFileType) + { + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: pReader = new CPdfFile(pFonts); - break; - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: - pReader = new CXpsFile(pFonts); - break; - case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: - pReader = new CDjVuFile(pFonts); - break; - default: - break; - } - } - - if (!pReader) - { - pFonts->Release(); - return 0; - } - - pReader->SetTempDirectory(sTempDir); + break; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: + pReader = new CXpsFile(pFonts); + break; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: + pReader = new CDjVuFile(pFonts); + break; + default: + break; + } + } + + if (!pReader) + { + pFonts->Release(); + return 0; + } + + pReader->SetTempDirectory(sTempDir); #ifndef LOAD_FILE_AS_BINARY - pReader->LoadFromFile(sSourceFiles[nIndex]); + pReader->LoadFromFile(sSourceFiles[nIndex]); #else - BYTE* pFileBinary = NULL; - DWORD nFileBinaryLen = 0; - NSFile::CFileBinary::ReadAllBytes(sSourceFile, &pFileBinary, nFileBinaryLen); + BYTE* pFileBinary = NULL; + DWORD nFileBinaryLen = 0; + NSFile::CFileBinary::ReadAllBytes(sSourceFile, &pFileBinary, nFileBinaryLen); - pReader->LoadFromMemory(pFileBinary, nFileBinaryLen); + pReader->LoadFromMemory(pFileBinary, nFileBinaryLen); #endif #ifdef TEST_FOR_HTML_RENDERER_TEXT - if (true) - { - int nPagesCount = pReader->GetPagesCount(); - - NSHtmlRenderer::CHTMLRendererText oTextRenderer; - for (int i = 0; i < nPagesCount; i++) - { - oTextRenderer.Init(pReader, 8); - pReader->DrawPageOnRenderer(&oTextRenderer, i, NULL); - } - } + if (true) + { + int nPagesCount = pReader->GetPagesCount(); + + NSHtmlRenderer::CHTMLRendererText oTextRenderer; + for (int i = 0; i < nPagesCount; i++) + { + oTextRenderer.Init(pReader, 8); + pReader->DrawPageOnRenderer(&oTextRenderer, i, NULL); + } + } #else - std::wstring sExtention = NSFile::GetFileExtention(sSourceFiles[nIndex]); - std::wstring sFileNameWithExtention = NSFile::GetFileName(sSourceFiles[nIndex]); - std::wstring sFileName = sFileNameWithExtention.substr(0, sFileNameWithExtention.size() - 1 - sExtention.size()); - std::wstring sDocx = L"/" + sFileName + L".docx"; - std::wstring sZip = L"/" + sFileName + L".zip"; + std::wstring sExtention = NSFile::GetFileExtention(sSourceFiles[nIndex]); + std::wstring sFileNameWithExtention = NSFile::GetFileName(sSourceFiles[nIndex]); + std::wstring sFileName = sFileNameWithExtention.substr(0, sFileNameWithExtention.size() - 1 - sExtention.size()); + std::wstring sDocx = L"/" + sFileName + L".docx"; + std::wstring sZip = L"/" + sFileName + L".zip"; - // проверить все режимы - NSDocxRenderer::eTextAssociationType taType; + // проверить все режимы + NSDocxRenderer::eTextAssociationType taType; //taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; //taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; - oDocxRenderer.SetTextAssociationType(taType); - oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); - //Если сразу нужен zip-архив - //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); + oDocxRenderer.SetTextAssociationType(taType); + oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); + //Если сразу нужен zip-архив + //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); #endif - delete pReader; - } + delete pReader; + } - pFonts->Release(); + pFonts->Release(); #ifdef LOAD_FILE_AS_BINARY - RELEASEARRAYOBJECTS(pFileBinary); + RELEASEARRAYOBJECTS(pFileBinary); #endif - return 0; + return 0; } From 3bb66721a189272211bc1695ce26b849495643a7 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 2 May 2023 18:57:40 +0300 Subject: [PATCH 033/794] Fix bug --- DocxRenderer/src/logic/Document.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 19728b79e6d..f097811cb94 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -20,13 +20,16 @@ namespace NSDocxRenderer m_lClipMode = 0; m_lPagesCount = 0; + for(auto& val : m_mapXmlString) + delete val.second; + m_mapXmlString.clear(); } CDocument::~CDocument() { + Clear(); m_lClipMode = 0; RELEASEINTERFACE(m_pFontManager); - m_mapXmlString.clear(); } HRESULT CDocument::NewPage() @@ -38,9 +41,7 @@ namespace NSDocxRenderer m_oEdge.SetDefaultParams(); m_oTransform.Reset(); - m_oCurrentPage.Clear(); - return S_OK; } HRESULT CDocument::get_Height(double* dHeight) @@ -543,7 +544,7 @@ namespace NSDocxRenderer auto pWriter = new NSStringUtils::CStringBuilder(); pWriter->AddSize(100000); m_oCurrentPage.ProcessingAndRecordingOfPageData(*pWriter, m_lPagesCount, m_lNumberPages); - m_mapXmlString[m_lPagesCount] = std::move(pWriter); + m_mapXmlString[m_lPagesCount] = pWriter; } else if (c_nPathType == lType) { From bac28708c1abd525990aac8de0680061f2fce4a8 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 10 May 2023 12:36:10 +0300 Subject: [PATCH 034/794] Fix bug --- DocxRenderer/DocxRenderer.cpp | 2 +- DocxRenderer/src/logic/Document.cpp | 4 +--- DocxRenderer/src/logic/Page.cpp | 3 +++ DocxRenderer/src/logic/elements/Shape.cpp | 1 + DocxRenderer/src/logic/managers/FontManager.cpp | 7 +++++++ DocxRenderer/src/logic/managers/FontManager.h | 1 + 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index fb28fcc972d..26ab5cfdaac 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -47,7 +47,6 @@ class CDocxRenderer_Private } ~CDocxRenderer_Private() { - } }; @@ -122,6 +121,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi HRESULT hr = S_OK; m_pInternal->m_oDocument.Close(); + m_pInternal->m_oDocument.Clear(); if (bIsOutCompress) hr = Close(); return (hr == S_OK) ? 0 : 1; diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index f097811cb94..53733d0a1b4 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -16,10 +16,9 @@ namespace NSDocxRenderer m_oEdge.SetDefaultParams(); m_oTransform.Reset(); - m_lClipMode = 0; - m_lPagesCount = 0; + for(auto& val : m_mapXmlString) delete val.second; @@ -28,7 +27,6 @@ namespace NSDocxRenderer CDocument::~CDocument() { Clear(); - m_lClipMode = 0; RELEASEINTERFACE(m_pFontManager); } diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index b66aa742a01..4969ecfa2c3 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -54,6 +54,9 @@ namespace NSDocxRenderer m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; + m_oVector.Clear(); + + m_pFontSelector->ClearCache(); } void CPage::ClearImages() diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 3a427eefa6f..75917ac9bb6 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -32,6 +32,7 @@ namespace NSDocxRenderer m_arOutputObjects[i]->Clear(); m_arOutputObjects.clear(); + m_oVector.Clear(); } UINT CShape::GenerateShapeId() diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index b086d1ac290..b387b2b3608 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -286,6 +286,7 @@ namespace NSDocxRenderer } CFontSelector::~CFontSelector() { + ClearCache(); RELEASEINTERFACE(m_pManager); } @@ -307,6 +308,12 @@ namespace NSDocxRenderer return m_arParamsCache; } + void CFontSelector::ClearCache() + { + if(!m_arParamsCache.empty()) + m_arParamsCache.clear(); + } + void CFontSelector::SelectFont(const CFontSelectParams& oFontSelectParams, const CFontMetrics& oFontMetrics, NSStringUtils::CStringUTF32& oText) diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 24fdb499948..682e5f74b02 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -87,6 +87,7 @@ namespace NSDocxRenderer bool IsSelectedItalic() const noexcept; const std::list& GetCache() const; + void ClearCache(); private: std::list m_arParamsCache; From 41c351b72dfbce161e4f4edbbddb98a7509ec70e Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 10 May 2023 13:10:29 +0300 Subject: [PATCH 035/794] Fix memory leaks --- DocxRenderer/src/logic/Page.cpp | 28 +++++++------------- DocxRenderer/src/logic/elements/TextLine.cpp | 2 ++ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 4969ecfa2c3..47a9e470f1f 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -61,46 +61,36 @@ namespace NSDocxRenderer void CPage::ClearImages() { + for(auto& val : m_arImages) + delete val; m_arImages.clear(); } void CPage::ClearTextData() { + for(auto& val : m_arDiacriticalSymbol) + delete val; m_arDiacriticalSymbol.clear(); } void CPage::ClearTextLines() { + for(auto& val : m_arTextLine) + val->Clear(); m_arTextLine.clear(); } void CPage::ClearShapes() { + for(auto& val : m_arShapes) + val->Clear(); m_arShapes.clear(); } void CPage::ClearOutputObjects() { for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->Clear(); - break; - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } + delete m_arOutputObjects[i]; m_arOutputObjects.clear(); } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 8417e045ad7..b14f860406d 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -11,6 +11,8 @@ namespace NSDocxRenderer void CTextLine::Clear() { + for(auto& val: m_arConts) + delete val; m_arConts.clear(); } From ad3a23a70833253a9b79fb5a9ae6201e8305f886 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 11 May 2023 15:23:22 +0300 Subject: [PATCH 036/794] Fix bug --- DocxRenderer/src/logic/Page.cpp | 3 ++- DocxRenderer/src/logic/elements/TextLine.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 47a9e470f1f..028ac2211f6 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -76,7 +76,8 @@ namespace NSDocxRenderer void CPage::ClearTextLines() { for(auto& val : m_arTextLine) - val->Clear(); + if(!val->m_bIsNotNecessaryToUse) + delete val; m_arTextLine.clear(); } diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index b14f860406d..c4dfd5f3de3 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -11,8 +11,8 @@ namespace NSDocxRenderer void CTextLine::Clear() { - for(auto& val: m_arConts) - delete val; + for(auto& val : m_arConts) + delete val; m_arConts.clear(); } @@ -64,12 +64,12 @@ namespace NSDocxRenderer double dSpaceDefaultSize = pCurrent->CalculateThinSpace(); double dSpaceWideSize = pCurrent->CalculateWideSpace(); - double dDifference = pCurrent->m_dLeft - pFirst->m_dRight; + double dDifference = fabs(pCurrent->m_dLeft - pFirst->m_dRight); //todo возможно стоит доработать логику bool bIsEqual = pFirst->IsEqual(pCurrent); - bool bIsBigDelta = fabs(dDifference) > dSpaceDefaultSize; - bool bIsVeryBigDelta = fabs(dDifference) > dSpaceWideSize; + bool bIsBigDelta = dDifference > dSpaceDefaultSize; + bool bIsVeryBigDelta = dDifference > dSpaceWideSize; if (bIsVeryBigDelta) { From c012741f7ffbec7472a766aa5f14354ff6ababff Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 19 May 2023 00:29:22 +0300 Subject: [PATCH 037/794] Fix memory leaks Finally --- DocxRenderer/src/logic/Page.cpp | 53 +++++-------------- DocxRenderer/src/logic/elements/Paragraph.cpp | 2 + DocxRenderer/src/logic/elements/Shape.cpp | 2 +- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 028ac2211f6..8430cc3796d 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -43,56 +43,29 @@ namespace NSDocxRenderer } void CPage::Clear() - { - ClearTextData(); - ClearTextLines(); - ClearOutputObjects(); - ClearShapes(); - ClearImages(); - - ClearTables(); - - m_pCurrentLine = nullptr; - m_pCurrentRow = nullptr; - m_oVector.Clear(); - - m_pFontSelector->ClearCache(); - } - - void CPage::ClearImages() - { - for(auto& val : m_arImages) - delete val; - m_arImages.clear(); - } - - void CPage::ClearTextData() { for(auto& val : m_arDiacriticalSymbol) delete val; m_arDiacriticalSymbol.clear(); - } - void CPage::ClearTextLines() - { - for(auto& val : m_arTextLine) - if(!val->m_bIsNotNecessaryToUse) - delete val; - m_arTextLine.clear(); - } + for(auto& val : m_arImages) + delete val; + m_arImages.clear(); - void CPage::ClearShapes() - { for(auto& val : m_arShapes) - val->Clear(); + delete val; m_arShapes.clear(); - } - void CPage::ClearOutputObjects() - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - delete m_arOutputObjects[i]; + for(auto& val : m_arOutputObjects) + delete val; m_arOutputObjects.clear(); + + m_arTextLine.clear(); + ClearTables(); + m_pCurrentLine = nullptr; + m_pCurrentRow = nullptr; + m_oVector.Clear(); + m_pFontSelector->ClearCache(); } void CPage::ClearTables() diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 3fdae0949ab..2caeac8b55c 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -15,6 +15,8 @@ namespace NSDocxRenderer void CParagraph::Clear() { + for(auto& val: m_arLines) + delete val; m_arLines.clear(); } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 75917ac9bb6..6c7812aadbe 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -29,7 +29,7 @@ namespace NSDocxRenderer void CShape::Clear() { for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - m_arOutputObjects[i]->Clear(); + delete m_arOutputObjects[i]; m_arOutputObjects.clear(); m_oVector.Clear(); From 66d846dcfcfb89bbb0be82faefeea90367a2cb46 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 19 May 2023 01:26:33 +0300 Subject: [PATCH 038/794] Fix bug --- DocxRenderer/src/logic/Page.cpp | 16 +++++++++++----- DocxRenderer/src/logic/Page.h | 6 ------ DocxRenderer/src/logic/elements/Paragraph.cpp | 8 ++------ 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 8430cc3796d..eacb1580afb 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -44,6 +44,10 @@ namespace NSDocxRenderer void CPage::Clear() { + for(auto& val : m_arTextLine) + delete val; + m_arTextLine.clear(); + for(auto& val : m_arDiacriticalSymbol) delete val; m_arDiacriticalSymbol.clear(); @@ -60,7 +64,7 @@ namespace NSDocxRenderer delete val; m_arOutputObjects.clear(); - m_arTextLine.clear(); + ClearTables(); m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; @@ -1266,7 +1270,7 @@ namespace NSDocxRenderer break; } - for (auto pCont : pCurrLine->m_arConts) + for (auto& pCont : pCurrLine->m_arConts) { pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, pCont->m_pFontStyle->wsFontName, @@ -1285,7 +1289,8 @@ namespace NSDocxRenderer pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; - pBaseLine->m_arConts.push_back(std::move(pCont)); + pBaseLine->m_arConts.push_back(pCont); + pCont = nullptr; } CBaseItem::SortByLeft(pBaseLine->m_arConts); pCurrLine->m_bIsNotNecessaryToUse = true; @@ -1309,7 +1314,7 @@ namespace NSDocxRenderer break; } - for (auto pCont : pSubLine->m_arConts) + for (auto& pCont : pSubLine->m_arConts) { pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, pCont->m_pFontStyle->wsFontName, @@ -1328,7 +1333,8 @@ namespace NSDocxRenderer pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; - pCurrLine->m_arConts.push_back(std::move(pCont)); + pCurrLine->m_arConts.push_back(pCont); + pCont = nullptr; } CBaseItem::SortByLeft(pCurrLine->m_arConts); pSubLine->m_bIsNotNecessaryToUse = true; diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 30084f9ec7e..5745113e13b 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -67,12 +67,6 @@ namespace NSDocxRenderer void BeginCommand(DWORD lType); void Clear(); - void ClearImages(); - void ClearTextData(); - void ClearTextLines(); - void ClearShapes(); - void ClearOutputObjects(); - void ClearTables(); //удаляем то, что выходит за границы страницы diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 2caeac8b55c..3b414b80d3d 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -15,8 +15,6 @@ namespace NSDocxRenderer void CParagraph::Clear() { - for(auto& val: m_arLines) - delete val; m_arLines.clear(); } @@ -159,7 +157,6 @@ namespace NSDocxRenderer pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthMM; auto pNext = m_arLines[i]; - auto pCont = pNext->m_arConts.front(); if (pLastCont->IsEqual(pCont)) @@ -169,19 +166,18 @@ namespace NSDocxRenderer pLastCont->m_dRight = pCont->m_dRight; pLastCont->m_bSpaceIsNotNeeded = false; - pCont->m_bIsNotNecessaryToUse = true; } for (size_t j = 0; j < pNext->m_arConts.size(); ++j) { - auto pCont = pNext->m_arConts[j]; + auto& pCont = pNext->m_arConts[j]; if (!pCont->m_bIsNotNecessaryToUse) { pLine->m_arConts.push_back(pCont); + pCont = nullptr; } } - pNext->m_bIsNotNecessaryToUse = true; } } From e626d013a87bdd123e851cd44e887aa9fa2c464d Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 21 May 2023 15:13:37 +0300 Subject: [PATCH 039/794] Fix bug --- DocxRenderer/src/logic/Page.cpp | 35 +++++++++++++++++++++++---------- DocxRenderer/src/logic/Page.h | 2 ++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index eacb1580afb..ee97c584055 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -294,15 +294,7 @@ namespace NSDocxRenderer } pShape->SetVector(std::move(m_oVector)); - - bool bIsMerged = false; - if(!m_arShapes.empty() && m_lLastCommand == m_lCurrentCommand) - bIsMerged = m_arShapes.back()->TryMergeShape(pShape); - - if(!bIsMerged) - m_arShapes.push_back(pShape); - else - delete pShape; + m_arShapes.push_back(pShape); } } @@ -443,10 +435,30 @@ namespace NSDocxRenderer { AnalyzeCollectedShapes(); AnalyzeCollectedTextLines(); + TryMergeShapes(); ToXml(oWriter); WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } + void CPage::TryMergeShapes() + { + + for(size_t i = 0; i < m_arShapes.size() - 1; i++) + { + bool bIsMerged = false; + auto& val = m_arShapes[i]; + auto& nextVal = m_arShapes[i + 1]; + + if(!val->m_bIsNotNecessaryToUse && !nextVal->m_bIsNotNecessaryToUse) + bIsMerged = nextVal->TryMergeShape(val); + + if(bIsMerged) + { + val->m_bIsNotNecessaryToUse = true; + } + } + } + void CPage::AnalyzeCollectedShapes() { //BuildTables(); @@ -1306,7 +1318,7 @@ namespace NSDocxRenderer for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) { auto pCont = pCurrLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) + if (pCont == nullptr || pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) { continue; } @@ -1316,6 +1328,9 @@ namespace NSDocxRenderer for (auto& pCont : pSubLine->m_arConts) { + if (pCont == nullptr) + continue; + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, pCont->m_pFontStyle->wsFontName, dFontSize, diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 5745113e13b..5a7801a087a 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -115,6 +115,8 @@ namespace NSDocxRenderer void DetermineTextColumns(); void DetermineDominantGraphics(); + void TryMergeShapes(); + //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку void ToXml(NSStringUtils::CStringBuilder& oWriter); From 25db8ee8371467ef55ff59298eab5b8e9c2925a4 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 21 May 2023 15:22:31 +0300 Subject: [PATCH 040/794] Fix bug --- DocxRenderer/src/logic/Page.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index ee97c584055..e857acc43a7 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -442,6 +442,8 @@ namespace NSDocxRenderer void CPage::TryMergeShapes() { + if(m_arShapes.empty()) + return; for(size_t i = 0; i < m_arShapes.size() - 1; i++) { From 01b114770a02d7ee7d2d57c6168efaac9e78f407 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Mon, 19 Jun 2023 12:11:36 +0300 Subject: [PATCH 041/794] . --- OOXML/XlsbFormat/Biff12_records/SupTabs.h | 3 +- OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h | 1 + OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h | 2 +- OOXML/XlsbFormat/SlicerCachesStream.cpp | 2 +- .../ExternalLinks/ExternalLinks.cpp | 40 +++++++++++++++++++ .../XlsxFormat/ExternalLinks/ExternalLinks.h | 4 ++ X2tConverter/src/ASCConverters.cpp | 39 ++++++++++++++++++ 7 files changed, 87 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsbFormat/Biff12_records/SupTabs.h b/OOXML/XlsbFormat/Biff12_records/SupTabs.h index 301176ce389..79a384f3736 100644 --- a/OOXML/XlsbFormat/Biff12_records/SupTabs.h +++ b/OOXML/XlsbFormat/Biff12_records/SupTabs.h @@ -53,8 +53,7 @@ namespace XLSB _UINT32 cTab; std::vector sheetNames; - }; - + typedef boost::shared_ptr SupTabsPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h b/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h index 90c3546f025..a301bb27aed 100644 --- a/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h +++ b/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h @@ -57,6 +57,7 @@ namespace XLSB ExternalReferenceType sbt; }; + typedef boost::shared_ptr EXTERNALBOOKPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h b/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h index d97dd76eeac..0498a8ac6a5 100644 --- a/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h +++ b/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h @@ -56,8 +56,8 @@ namespace XLSB XLS::BaseObjectPtr m_DDEOLELINK; std::vector m_arFRT; bool m_bBrtEndSupBook; - }; + typedef boost::shared_ptr EXTERNALLINKPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/SlicerCachesStream.cpp b/OOXML/XlsbFormat/SlicerCachesStream.cpp index 82415305ffb..e2ae61c71c4 100644 --- a/OOXML/XlsbFormat/SlicerCachesStream.cpp +++ b/OOXML/XlsbFormat/SlicerCachesStream.cpp @@ -76,7 +76,7 @@ const bool SlicerCachesStream::loadContent(BinProcessor& proc) proc.SkipRecord(); }break; } - } + } return true; } diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index eb4433b397d..09af6496791 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -118,6 +118,16 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalSheetNames::toBin() + { + XLSB::SupTabsPtr supTabs(new XLSB::SupTabs); + for (auto& item : m_arrItems) + { + XLSB::XLWideString str = *item->m_sVal; + supTabs->sheetNames.push_back(str); + } + return supTabs; + } void CExternalSheetNames::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -697,6 +707,21 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalBook::toBin() + { + XLSB::EXTERNALLINKPtr externalLINK(new XLSB::EXTERNALLINK()); + + XLSB::ExternalReferenceType type; + XLSB::EXTERNALBOOKPtr externalBOOK(new XLSB::EXTERNALBOOK(type)); + + externalLINK->m_EXTERNALBOOK = externalBOOK; + if (externalBOOK != nullptr) + { + if (m_oSheetNames.IsInit()) + externalBOOK->m_BrtSupTabs = m_oSheetNames->toBin(); + } + return externalLINK; + } void CExternalBook::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1481,6 +1506,21 @@ namespace Spreadsheet CExternalLink::~CExternalLink() { } + XLS::BaseObjectPtr CExternalLink::writeBin() + { + XLSB::ExternalLinkStreamPtr externalLinkStreamStream(new XLSB::ExternalLinkStream); + + if (externalLinkStreamStream != nullptr) + { + if (m_oExternalBook.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oExternalBook->toBin(); + //if (m_oDdeLink.IsInit()) + // externalLinkStreamStream->m_EXTERNALLINK = m_oDdeLink->toBin(); + //if (m_oOleLink.IsInit()) + // externalLinkStreamStream->m_EXTERNALLINK = m_oOleLink->toBin(); + } + return externalLinkStreamStream; + } void CExternalLink::readBin(const CPath& oPath) { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index 358ee01686c..b34f7da6276 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -78,6 +78,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; class CAlternateUrls : public WritingElement @@ -251,6 +252,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -454,7 +456,9 @@ namespace OOX CExternalLink(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath, const std::wstring & rId); virtual ~CExternalLink(); + XLS::BaseObjectPtr writeBin(); void readBin(const CPath& oPath); + virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 24fafbfc1c9..ccd852a2327 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1131,6 +1131,41 @@ namespace NExtractTools } return nRes; } + _UINT32 xlsx2xlsb(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& sTemp, InputParams& params) + { + std::wstring sTempUnpackedXLSX = sTemp + FILE_SEPARATOR_STR + L"xlsx_unpacked"; + + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK == oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0)) + { + return xlsx_dir2xlsb(sTempUnpackedXLSX, sTo, sTemp, params); + } + return AVS_FILEUTILS_ERROR_CONVERT; + } + _UINT32 xlsx_dir2xlsb(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& sTemp, InputParams& params) + { + std::wstring sTempUnpackedXLSB = sTemp + FILE_SEPARATOR_STR + L"xlsb_unpacked"; + NSDirectory::CreateDirectory(sTempUnpackedXLSB); + + _UINT32 nRes = 0; +//--------------------------------------------------------------------- + const OOX::CPath oox_path(sFrom); + + OOX::Spreadsheet::CXlsx xlsx(oox_path); + OOX::Spreadsheet::CXlsb xlsb; + + //XLS::BaseObjectPtr object = xlsx.toBin(); + //xlsb.WriteBin(sTempUnpackedXLSB, object.get()); +//--------------------------------------------------------------------- + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSB, sTo, false, Z_DEFLATED)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + return nRes; + } _UINT32 xltm2xlsx_dir (const std::wstring &sFrom, const std::wstring &sTo, InputParams& params) { COfficeUtils oCOfficeUtils(NULL); @@ -5777,6 +5812,10 @@ namespace NExtractTools { result = msVbaProject2Xml(sFileFrom, sFileTo, sTempDir, oInputParams); }break; + case TCD_XLSX2XLSB: + { + result = xlsx2xlsb(sFileFrom, sFileTo, sTempDir, oInputParams); + }break; //TCD_FB22DOCT, //TCD_FB22DOCT_BIN, From 0b46254fed42eda60acd03945374f0d1f1c54028 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jun 2023 17:09:54 +0300 Subject: [PATCH 042/794] Fix rescale pen bug --- DocxRenderer/src/logic/Page.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index e857acc43a7..784f30ab36b 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -293,6 +293,9 @@ namespace NSDocxRenderer } } + double dDeterminant = sqrt(fabs(m_pTransform->Determinant())); + pShape->m_oPen.Size *= dDeterminant; + pShape->SetVector(std::move(m_oVector)); m_arShapes.push_back(pShape); } From 8669470692c5f19ea457bc955423c48242e23a45 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jun 2023 17:15:42 +0300 Subject: [PATCH 043/794] Fix bug --- DocxRenderer/src/logic/elements/Shape.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 6c7812aadbe..2ca2db718f5 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -125,12 +125,12 @@ namespace NSDocxRenderer fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) && // недалеко друг от друга по вертикали - (fabs(pShape->m_dBaselinePos - this->m_dTop) < dHorNearby || - fabs(pShape->m_dTop - this->m_dBaselinePos) < dHorNearby || + (fabs(pShape->m_dBaselinePos - this->m_dTop) < dVerNearby || + fabs(pShape->m_dTop - this->m_dBaselinePos) < dVerNearby || // друг в друге - fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dHorNearby || - fabs(pShape->m_dTop - this->m_dTop) < dHorNearby)) + fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby || + fabs(pShape->m_dTop - this->m_dTop) < dVerNearby)) { CBaseItem::AddContent(pShape); m_oVector.Join(std::move(pShape->m_oVector)); From ee3d0543738061f139667626ce1b2c7c3631c614 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 23 Jun 2023 21:00:47 +0600 Subject: [PATCH 044/794] completed external links converting --- OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h | 2 +- .../Biff12_unions/DDEOLEITEMVALUE.h | 2 +- .../Biff12_unions/DDEOLEITEMVALUES.h | 2 +- OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h | 1 + .../ExternalLinks/ExternalLinks.cpp | 189 +++++++++++++++++- .../XlsxFormat/ExternalLinks/ExternalLinks.h | 18 +- 6 files changed, 201 insertions(+), 13 deletions(-) diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h index a439c497840..2d6d18f3d06 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h @@ -56,6 +56,6 @@ namespace XLSB ExternalReferenceType sbt; }; - + typedef boost::shared_ptr DDEOLEITEMPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h index 4e0dad286c0..6e82c2e139d 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h @@ -51,6 +51,6 @@ namespace XLSB XLS::BaseObjectPtr m_source; }; - + typedef boost::shared_ptr DDEOLEITEMVALUEPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h index b470e5b9da0..3a507facd3c 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h @@ -55,6 +55,6 @@ namespace XLSB bool m_bBrtSupNameValueEnd; }; - + typedef boost::shared_ptr DDEOLEITEMVALUESPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h index d58ea61a01f..1d21a1c8c4d 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h @@ -55,6 +55,7 @@ namespace XLSB ExternalReferenceType sbt; }; + typedef boost::shared_ptr DDEOLELINKPtr; } // namespace XLSB diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index 09af6496791..12dccca9c1c 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -66,6 +66,8 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" +#include + namespace OOX { namespace Spreadsheet @@ -811,6 +813,77 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CDdeValue::toBin() + { + XLSB::DDEOLEITEMVALUEPtr ptr(new XLSB::DDEOLEITEMVALUE); + if(!m_oType.IsInit()) + return ptr; + auto type = m_oType->GetValue(); + switch(type) + { + case XLSB::rt_SupNameNum: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameNum}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast(ptr->m_source.get()); + castedSource->value.data.value = std::stod(m_arrItems.back()->m_sText); + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameBool: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameBool}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast(ptr->m_source.get()); + castedSource->value = std::stoi(m_arrItems.back()->m_sText); + m_arrItems.pop_back(); + } + + } + break; + case XLSB::rt_SupNameErr: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameErr}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast(ptr->m_source.get()); + auto error = m_arrItems.back()->m_sText.c_str(); + + if(error == L"#NULL!"){ castedSource->value = 0x00;} + else if(error == L"#DIV/0!"){castedSource->value = 0x07;} + else if(error == L"#VALUE!"){ castedSource->value = 0x0F;} + else if(error == L"#REF!"){ castedSource->value = 0x17;} + else if(error == L"#NAME?"){ castedSource->value = 0x1D;} + else if(error == L"#NUM!"){castedSource->value = 0x24;} + else if(error == L"#N/A"){castedSource->value = 0x2A;} + else if(error == L"#GETTING_DATA"){castedSource->value = 0x2B;} + + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameSt: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameSt}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast(ptr->m_source.get()); + castedSource->value = m_arrItems.back()->m_sText; + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameNil: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameNil}; + } + break; + } + return ptr; + } void CDdeValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -968,6 +1041,18 @@ namespace Spreadsheet m_arrItems.push_back(new CDdeValue(item)); } } + XLS::BaseObjectPtr CDdeValues::toBin() + { + XLSB::DDEOLEITEMVALUESPtr ptr(new XLSB::DDEOLEITEMVALUES); + auto castedPtr = static_cast(ptr->m_BrtSupNameValueStart.get()); + if(m_oRows.IsInit()) + castedPtr->cRw = m_oRows->GetValue(); + if(m_oCols.IsInit()) + castedPtr->cCol = m_oCols->GetValue(); + for (auto &item : m_arrItems) + ptr->m_arDDEOLEITEMVALUE.push_back(item->toBin()); + return ptr; + } void CDdeValues::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1036,6 +1121,31 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CDdeItem::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLEITEMPtr ptr(new XLSB::DDEOLEITEM(type)); + if (m_oDdeValues.IsInit()) + ptr->m_DDEOLEITEMVALUES = m_oDdeValues->toBin(); + if(m_oName.IsInit()) + { + ptr->m_BrtSupNameStart = XLS::BaseObjectPtr{new XLSB::SupNameStart}; + auto ptrSupNameStart = static_cast(ptr->m_BrtSupNameStart.get()); + ptrSupNameStart->name = m_oName.get(); + } + if(m_oOle.IsInit() || m_oAdvise.IsInit() || m_oPreferPic.IsInit()) + { + ptr->m_BrtSupNameBits = XLS::BaseObjectPtr{new XLSB::SupNameBits(type)}; + auto ptrSupNameBits = static_cast(ptr->m_BrtSupNameBits.get()); + if(m_oOle.IsInit()) + ptrSupNameBits->contentsDDE.fOLE = m_oOle->ToBool(); + if(m_oAdvise.IsInit()) + ptrSupNameBits->contentsDDE.fWantAdvise = m_oAdvise->ToBool(); + if(m_oPreferPic.IsInit()) + ptrSupNameBits->contentsDDE.fWantPict = m_oPreferPic->ToBool(); + } + return ptr; + } void CDdeItem::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1133,6 +1243,15 @@ namespace Spreadsheet } } + XLS::BaseObjectPtr CDdeItems::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLELINKPtr ptr(new XLSB::DDEOLELINK(type)); + for (auto item : m_arrItems) + ptr->m_arDDEOLEITEM.push_back(item->toBin()); + return ptr; + } + void CDdeLink::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); @@ -1180,6 +1299,18 @@ namespace Spreadsheet m_oDdeItems = ptr->m_DDEOLELINK; } } + XLS::BaseObjectPtr CDdeLink::toBin() + { + XLSB::EXTERNALLINKPtr ptr(new XLSB::EXTERNALLINK); + ptr->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; + auto castedBook = static_cast(ptr->m_BrtBeginSupBook.get()); + if (m_oDdeService.IsInit()) + castedBook->string1 = m_oDdeService.get(); + if (m_oDdeTopic.IsInit()) + castedBook->string2 = m_oDdeTopic.get(); + ptr->m_DDEOLELINK = m_oDdeItems->toBin(); + return ptr; + } CDdeLink::CDdeLink() { @@ -1248,6 +1379,29 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr COleItem::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLEITEMPtr coleItem(new XLSB::DDEOLEITEM(type)); + if(m_oName.IsInit()) + { + coleItem->m_BrtSupNameStart = XLS::BaseObjectPtr{new XLSB::SupNameStart}; + auto castedName = static_cast(coleItem->m_BrtSupNameStart.get()); + castedName->name = m_oName.get(); + } + if(m_oIcon.IsInit() || m_oAdvise.IsInit() || m_oPreferPic.IsInit()) + { + coleItem->m_BrtSupNameBits = XLS::BaseObjectPtr{new XLSB::SupNameBits(type)}; + auto ptrSupNameBits = static_cast(coleItem->m_BrtSupNameBits.get()); + if(m_oIcon.IsInit()) + ptrSupNameBits->contentsOLE.fIcon = m_oIcon->ToBool(); + if(m_oAdvise.IsInit()) + ptrSupNameBits->contentsOLE.fWantAdvise = m_oAdvise->ToBool(); + if(m_oPreferPic.IsInit()) + ptrSupNameBits->contentsOLE.fWantPict = m_oPreferPic->ToBool(); + } + return coleItem; + } void COleItem::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1341,6 +1495,17 @@ namespace Spreadsheet m_arrItems.push_back(new COleItem(item)); } } + XLS::BaseObjectPtr COleItems::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLELINKPtr ptr(new XLSB::DDEOLELINK(type)); + + for(auto i: m_arrItems) + { + ptr->m_arDDEOLEITEM.push_back(i->toBin()); + } + return ptr; + } COleLink::COleLink() { @@ -1402,6 +1567,20 @@ namespace Spreadsheet m_oOleItems = ptr->m_DDEOLELINK; } } + XLS::BaseObjectPtr COleLink::toBin() + { + XLSB::EXTERNALLINKPtr COleLink(new XLSB::EXTERNALLINK); + COleLink->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; + auto castedBook = static_cast(COleLink->m_BrtBeginSupBook.get()); + + if(m_oRid.IsInit()) + castedBook->string1 = m_oRid->ToString(); + if(m_oProgId.IsInit()) + castedBook->string2 = m_oProgId.get(); + + COleLink->m_DDEOLELINK = m_oOleItems->toBin(); + return COleLink; + } void COleLink::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1440,7 +1619,7 @@ namespace Spreadsheet if (oReader.IsEmptyNode()) return; - + int nCurDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth)) { @@ -1514,10 +1693,10 @@ namespace Spreadsheet { if (m_oExternalBook.IsInit()) externalLinkStreamStream->m_EXTERNALLINK = m_oExternalBook->toBin(); - //if (m_oDdeLink.IsInit()) - // externalLinkStreamStream->m_EXTERNALLINK = m_oDdeLink->toBin(); - //if (m_oOleLink.IsInit()) - // externalLinkStreamStream->m_EXTERNALLINK = m_oOleLink->toBin(); + if (m_oDdeLink.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oDdeLink->toBin(); + if (m_oOleLink.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oOleLink->toBin(); } return externalLinkStreamStream; } diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index b34f7da6276..355359effe6 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -67,17 +67,17 @@ namespace OOX public: WritingElement_AdditionMethods(CExternalSheetNames) WritingElement_XlsbConstructors(CExternalSheetNames) - + CExternalSheetNames(); virtual ~CExternalSheetNames(); virtual void fromXML(XmlUtils::CXmlNode& oNode); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; - void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; @@ -104,7 +104,7 @@ namespace OOX nullable m_oAbsoluteUrlRid; nullable m_oRelativeUrlRid; - + nullable_string m_oDriveId; nullable_string m_oItemId; }; @@ -167,7 +167,7 @@ namespace OOX virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable m_oRef; nullable m_oType; nullable m_oValueMetadata; @@ -280,6 +280,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -303,6 +304,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -326,6 +328,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -355,6 +358,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; @@ -373,6 +377,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -398,6 +403,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -422,6 +428,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; @@ -439,6 +446,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From f5d972573eaa18dc821345fc54ffb2660487fd82 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 27 Jun 2023 10:44:25 +0300 Subject: [PATCH 045/794] Fix bug (tabulation) \t symbol skipped and addded during analysis --- DocxRenderer/src/logic/Page.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 784f30ab36b..a48af59a692 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -305,7 +305,8 @@ namespace NSDocxRenderer const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fBaseLineOffset, const bool& bIsPDFAnalyzer) { - if (pUnicodes != nullptr && nCount == 1 && IsSpaceUtf32(*pUnicodes)) + // 9 - \t + if (pUnicodes != nullptr && nCount == 1 && (IsSpaceUtf32(*pUnicodes) || *pUnicodes == 9)) { //note пробелы не нужны, добавляются при анализе return; @@ -319,9 +320,8 @@ namespace NSDocxRenderer m_pTransform->TransformPoint(dTextX, dTextY); m_pTransform->TransformPoint(dTextR, dTextB); - // иногда ширина приходит сильно меньше, почему? - double dTextW = dTextR - dTextX; - double dTextH = dTextB - dTextY; + double dTextW; // = dTextR - dTextX; + double dTextH; // = dTextB - dTextY; NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); @@ -361,9 +361,9 @@ namespace NSDocxRenderer dTextW = _w; //} - - double dBaseLinePos = dTextY + fBaseLineOffset; dTextH = m_pFontManager->GetFontHeight(); + double dBaseLinePos = dTextY + fBaseLineOffset; + auto pCont = new CContText(m_pFontManager); From a74bb35ecd83b2237f96ec178181bd453910c743 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 27 Jun 2023 16:02:49 +0600 Subject: [PATCH 046/794] added cols convertation --- OOXML/XlsxFormat/Worksheets/Cols.cpp | 39 ++++++++++++++++++++++++++++ OOXML/XlsxFormat/Worksheets/Cols.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index df7739a53fd..c10922071fe 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -81,6 +81,36 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCol::toBin() + { + auto castedPtr = new XLSB::ColInfo; + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oBestFit.IsInit()) + castedPtr->fBestFit = m_oBestFit->ToBool(); + if(m_oCollapsed.IsInit()) + castedPtr->fCollapsed = m_oCollapsed->ToBool(); + if(m_oCustomWidth.IsInit()) + castedPtr->fUserSet = m_oCustomWidth->ToBool(); + if(m_oHidden.IsInit()) + castedPtr->fHidden = m_oHidden->ToBool(); + if(m_oMax.IsInit()) + castedPtr->colLast = m_oMax->m_eValue - 1; + if(m_oMin.IsInit()) + castedPtr->colFirst = m_oMin->m_eValue - 1; + if(m_oOutlineLevel.IsInit()) + castedPtr->iOutLevel = m_oOutlineLevel->m_eValue; + if(m_oPhonetic.IsInit()) + castedPtr->fPhonetic = m_oPhonetic->ToBool(); + if(m_oStyle.IsInit()) + castedPtr->ixfeXLSB = m_oStyle->m_eValue; + + if (m_oWidth.IsInit()) + { + if(m_oWidth->GetValue() > 0) + castedPtr->coldx = m_oWidth->GetValue() * 256; + } + return ptr; + } EElementType CCol::getType() const { return et_x_Col; @@ -230,6 +260,15 @@ namespace OOX } } } + std::vector CCols::toBin() + { + std::vector ptrVector; + for(auto i:m_arrItems) + { + ptrVector.push_back(i->toBin()); + } + return ptrVector; + } EElementType CCols::getType () const { return et_x_Cols; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.h b/OOXML/XlsxFormat/Worksheets/Cols.h index 7c000a45f96..5d2dbba6154 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.h +++ b/OOXML/XlsxFormat/Worksheets/Cols.h @@ -61,6 +61,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; private: @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: From 98eb8566415247b61a0d2b067a22548a32344ad8 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 27 Jun 2023 16:20:26 +0600 Subject: [PATCH 047/794] add drawning conversion --- OOXML/XlsxFormat/Drawing/Drawing.h | 1 + OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/OOXML/XlsxFormat/Drawing/Drawing.h b/OOXML/XlsxFormat/Drawing/Drawing.h index 56f197f22c7..c615372ba51 100644 --- a/OOXML/XlsxFormat/Drawing/Drawing.h +++ b/OOXML/XlsxFormat/Drawing/Drawing.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp b/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp index e52a6e2cff1..22bcdbdceb9 100644 --- a/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp +++ b/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp @@ -72,6 +72,17 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDrawingWorksheet::toBin() + { + auto castedPtr(new XLSB::Drawing); + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oId.IsInit()) + { + if(!m_oId->GetValue().empty()) + castedPtr->stRelId.value = m_oId->GetValue(); + } + return ptr; + } EElementType CDrawingWorksheet::getType () const { return et_x_FromTo; From 75853c8cb3b0d197ebd9123fb584ac6e49e3e024 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 27 Jun 2023 16:24:22 +0600 Subject: [PATCH 048/794] added Cdimension conversion --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 10 +++++++++- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 5beec42fca8..e358235103c 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -675,6 +675,14 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDimension::toBin() + { + auto castedPtr(new XLSB::WsDim); + XLS::BaseObjectPtr ptr(castedPtr); + if (m_oRef.IsInit()) + castedPtr->rfx = m_oRef.get(); + return ptr; + } EElementType CDimension::getType() const { return et_x_Dimension; @@ -2298,7 +2306,7 @@ namespace OOX WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) WritingElement_ReadAttributes_Read_else_if(oReader, L"sqref", m_oSqref) WritingElement_ReadAttributes_End(oReader) - } + } void CUserProtectedRange::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 5ad4d9a39ba..154c6fbe836 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -269,6 +269,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; From f56184505f91483f60851e5010ac03a130b8184b Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 27 Jun 2023 16:43:09 +0600 Subject: [PATCH 049/794] added BrtLegacyDrawing conversion --- OOXML/XlsxFormat/Comments/Comments.h | 1 + OOXML/XlsxFormat/Comments/XlsxComments.cpp | 8 ++++++++ OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 8 ++++++++ OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h | 1 + 4 files changed, 18 insertions(+) diff --git a/OOXML/XlsxFormat/Comments/Comments.h b/OOXML/XlsxFormat/Comments/Comments.h index 9ca4bf5ed13..4aa90a91a72 100644 --- a/OOXML/XlsxFormat/Comments/Comments.h +++ b/OOXML/XlsxFormat/Comments/Comments.h @@ -191,6 +191,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index ff124aa7621..babca8545ed 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -451,6 +451,14 @@ mc:Ignorable=\"xr\">"); { ReadAttributes(obj); } + XLS::BaseObjectPtr CLegacyDrawingWorksheet::toBin() + { + auto castedPtr(new XLSB::LegacyDrawing); + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oId.IsInit()) + castedPtr->stRelId.value = m_oId->GetValue(); + return ptr; + } EElementType CLegacyDrawingWorksheet::getType () const { return et_x_LegacyDrawingWorksheet; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index e358235103c..9ec2c660ea9 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1645,6 +1645,14 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CLegacyDrawingHFWorksheet::toBin() + { + auto castedPtr(new XLSB::LegacyDrawingHF); + XLS::BaseObjectPtr ptr(castedPtr); + if (m_oId.IsInit()) + castedPtr->stRelId.value = m_oId->GetValue(); + return ptr; + } EElementType CLegacyDrawingHFWorksheet::getType() const { return et_x_LegacyDrawingHFWorksheet; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 154c6fbe836..46cf02be763 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -602,6 +602,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 311c70816fd247622395083549352c28334eddbd Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 27 Jun 2023 21:22:23 +0600 Subject: [PATCH 050/794] added hyperlinks conversion --- OOXML/XlsxFormat/Worksheets/Hyperlinks.h | 3 ++ .../XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h index a04c61a30bc..1e548d960da 100644 --- a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h +++ b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h @@ -59,6 +59,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -90,6 +91,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); + virtual EElementType getType () const; }; diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 38782073a35..79292d33316 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -35,6 +35,8 @@ #include "../../Common/SimpleTypes_Shared.h" +#include "..\..\XlsbFormat\Biff12_unions\HLINKS.h" + namespace OOX { namespace Spreadsheet @@ -73,6 +75,24 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CHyperlink::toBin() + { + auto castedPtr(new XLSB::HLink); + XLS::BaseObjectPtr ptr(castedPtr); + + if(m_oDisplay.IsInit()) + castedPtr->display = m_oDisplay.get(); + if(m_oRid.IsInit()) + castedPtr->relId.value = m_oRid->GetValue(); + if(m_oLocation.IsInit()) + castedPtr->location = m_oLocation.get(); + if(m_oRef.IsInit()) + castedPtr->rfx = m_oRef.get(); + if(m_oTooltip.IsInit()) + castedPtr->tooltip = m_oTooltip.get(); + + return ptr; + } EElementType CHyperlink::getType () const { return et_x_Hyperlink; @@ -160,6 +180,19 @@ namespace OOX pHyperlink->fromBin(hyperlink); } } + XLS::BaseObjectPtr CHyperlinks::toBin() + { + + auto castedPtr(new XLSB::HLINKS); + XLS::BaseObjectPtr ptr(castedPtr); + + for(auto i:m_arrItems) + { + castedPtr->m_arHlinks.push_back(i->toBin()); + } + return ptr; + } + EElementType CHyperlinks::getType () const { return et_x_Hyperlinks; From 4f068159d7a056c2173988ab637f02e2a72a6cf9 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 28 Jun 2023 17:55:59 +0600 Subject: [PATCH 051/794] add merged cells conversion --- OOXML/XlsxFormat/Worksheets/MergeCells.cpp | 18 ++++++++++++++++++ OOXML/XlsxFormat/Worksheets/MergeCells.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index 4d0cfd34462..ea9f80a7a57 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -34,6 +34,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/MergeCell.h" +#include "../../XlsbFormat\Biff12_unions\MERGECELLS.h" namespace OOX { @@ -69,6 +70,13 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CMergeCell::toBin() + { + auto castedPtr(new XLSB::MergeCell); + XLS::BaseObjectPtr ptr(castedPtr); + castedPtr->rfx = m_oRef.get(); + return ptr; + } EElementType CMergeCell::getType () const { return et_x_MergeCell; @@ -152,6 +160,16 @@ namespace OOX pMergeCell->fromBin(mergeCell); } } + XLS::BaseObjectPtr CMergeCells::toBin() + { + auto castedPtr(new XLSB::MERGECELLS); + XLS::BaseObjectPtr ptr(castedPtr); + for(auto i:m_arrItems) + { + castedPtr->m_arBrtMergeCell.push_back(i->toBin()); + } + return ptr; + } EElementType CMergeCells::getType () const { return et_x_MergeCells; diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.h b/OOXML/XlsxFormat/Worksheets/MergeCells.h index c761e0ea755..ce9064f602d 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.h +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.h @@ -59,6 +59,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -83,6 +84,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(std::vector& obj); virtual EElementType getType () const; From 7bf8a55d258b92f83e34cd83534aae959fcee886 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 28 Jun 2023 17:56:42 +0600 Subject: [PATCH 052/794] added sheetformatpr conversion --- .../Worksheets/WorksheetChildOther.cpp | 22 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 23 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 9ec2c660ea9..c2d8694ecb8 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -738,6 +738,28 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSheetFormatPr::toBin() + { + auto ptr(new XLSB::WsFmtInfo); + XLS::BaseObjectPtr Castedptr(ptr); + if(m_oBaseColWidth.IsInit()) + ptr->dxGCol = m_oBaseColWidth.get() * 256.; + if(m_oDefaultColWidth.IsInit()) + ptr->cchDefColWidth = m_oDefaultColWidth.get(); + + if (m_oDefaultRowHeight.IsInit()) + ptr->miyDefRwHeight = m_oDefaultRowHeight.get(); + else + ptr->miyDefRwHeight = 14.4; + + if (m_oOutlineLevelCol.IsInit()) ptr->iOutLevelCol = m_oOutlineLevelCol.get(); + if (m_oOutlineLevelRow.IsInit()) ptr->iOutLevelRw = m_oOutlineLevelRow.get(); + + if (m_oThickBottom.IsInit()) ptr->fExDesc = m_oThickBottom.get(); + if (m_oThickTop.IsInit()) ptr->fExAsc = m_oThickTop.get(); + if (m_oZeroHeight.IsInit()) ptr->fDyZero = m_oZeroHeight.get(); + return Castedptr; + } EElementType CSheetFormatPr::getType() const { return et_x_SheetFormatPr; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 46cf02be763..5c0b672f44a 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -296,6 +296,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 264bec5feb412579779f71e7711f1d5789920af3 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 28 Jun 2023 22:50:08 +0600 Subject: [PATCH 053/794] added sheet view conversion --- .../Worksheets/WorksheetChildOther.cpp | 57 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 2 + 2 files changed, 59 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index c2d8694ecb8..49495d84fcc 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1041,6 +1041,43 @@ namespace OOX ReadAttributes(pCSVIEW->m_BrtBeginCsView); } } + XLS::BaseObjectPtr CSheetView::toBin() + { + if(m_oView.IsInit() || m_oTopLeftCell.IsInit() || m_oTopLeftCell.IsInit()) + { + auto pWsView(new XLSB::BeginWsView); + XLS::BaseObjectPtr castedPtr(pWsView); + pWsView->icvHdr = m_oColorId->m_eValue; + pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; + pWsView->fRightToLeft = m_oRightToLeft->m_eValue; + pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; + pWsView->fDspGridRt = m_oShowGridLines->m_eValue; + pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; + pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; + pWsView->fDspRuler = m_oShowRuler->m_eValue; + pWsView->fWhitespaceHidden = m_oShowWhiteSpace->m_eValue; + pWsView->fDspZerosRt = m_oShowZeros->m_eValue; + pWsView->fSelected = m_oTabSelected->m_eValue; + pWsView->topLeftCell = m_oTopLeftCell.get(); + pWsView->xlView = m_oView->m_eValue; + pWsView->fWnProt = m_oWindowProtection->m_eValue; + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + pWsView->wScale = m_oZoomScale->m_eValue; + pWsView->wScaleNormal = m_oZoomScaleNormal->m_eValue; + pWsView->wScalePLV = m_oZoomScalePageLayoutView->m_eValue; + pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; + return castedPtr; + } + else + { + auto pWsView(new XLSB::BeginCsView); + XLS::BaseObjectPtr castedPtr(pWsView); + pWsView->fSelected = m_oTabSelected->m_eValue; + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + pWsView->wScale = m_oZoomScale->m_eValue; + return castedPtr; + } + } EElementType CSheetView::getType() const { return et_x_SheetView; @@ -1180,6 +1217,26 @@ namespace OOX } } } + XLS::BaseObjectPtr CSheetViews::toBin() + { + auto view = m_arrItems.back(); + if(view->m_oView.IsInit() || view->m_oTopLeftCell.IsInit() || view->m_oTopLeftCell.IsInit()) + { + auto castedPtr(new XLSB::WSVIEWS2); + XLS::BaseObjectPtr ptr(castedPtr); + for(auto i:m_arrItems) + castedPtr->m_arWSVIEW2.push_back(i->toBin()); + return ptr; + } + else + { + auto castedPtr(new XLSB::CSVIEWS); + XLS::BaseObjectPtr ptr(castedPtr); + for(auto i:m_arrItems) + castedPtr->m_arCSVIEW.push_back(i->toBin()); + return ptr; + } + } EElementType CSheetViews::getType() const { return et_x_SheetViews; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 5c0b672f44a..6bbd28d5d79 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -390,6 +390,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -435,6 +436,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; }; From 1e068075f4caa20a690059bee710a4b1ab0f3f7e Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 29 Jun 2023 14:12:54 +0600 Subject: [PATCH 054/794] added page margins conversion --- .../Worksheets/WorksheetChildOther.cpp | 25 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 26 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 49495d84fcc..9c57638ddc6 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -386,6 +386,31 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPageMargins::toBin() + { + auto ptr(new XLSB::Margins); + XLS::BaseObjectPtr objPtr(ptr); + + if(m_oLeft.IsInit()) + ptr->xnumLeft.data.value = m_oLeft->GetValue(); + + if(m_oTop.IsInit()) + ptr->xnumTop.data.value = m_oTop->GetValue(); + + if(m_oRight.IsInit()) + ptr->xnumRight.data.value = m_oRight->GetValue(); + + if(m_oBottom.IsInit()) + ptr->xnumBottom.data.value = m_oBottom->GetValue(); + + if(m_oHeader.IsInit()) + ptr->xnumHeader.data.value = m_oHeader->GetValue(); + + if(m_oFooter.IsInit()) + ptr->xnumFooter.data.value = m_oFooter->GetValue(); + + return objPtr; + } EElementType CPageMargins::getType() const { return et_x_PageMargins; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 6bbd28d5d79..3cbc566457c 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -169,6 +169,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 62b480b00c11ee9def5329696b3d323980e35555 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 29 Jun 2023 16:03:29 +0600 Subject: [PATCH 055/794] added page setup conversion --- .../Worksheets/WorksheetChildOther.cpp | 74 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 75 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 9c57638ddc6..4820ce4a37e 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -503,6 +503,80 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPageSetup::toBin() + { + if(m_oErrors.IsInit() || m_oScale.IsInit()) + { + auto ptr(new XLSB::PageSetup); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + if (ptr->fNoColor) + { + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } + + ptr->iCopies = m_oCopies->m_eValue; + ptr->fDraft = m_oDraft->m_eValue; + ptr->iErrors = m_oErrors->m_eValue; + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + ptr->iFitHeight = m_oFitToHeight->m_eValue; + ptr->iFitWidth = m_oFitToWidth->m_eValue; + ptr->iRes = m_oHorizontalDpi->m_eValue; + ptr->szRelID = m_oRId->GetValue(); + + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; + + if ( m_oPageOrder == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) + ptr->fLeftToRight = true; + else + ptr->fLeftToRight = false; + + ptr->iPaperSize = m_oPaperSize->m_eValue; + ptr->iScale = m_oScale->m_eValue; + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + ptr->iVRes = m_oVerticalDpi->m_eValue; + + return objectPtr; + } + else + { + auto ptr(new XLSB::CsPageSetup); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + if (ptr->fNoColor) + { + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } + + ptr->iCopies = m_oCopies->m_eValue; + ptr->fDraft = m_oDraft->m_eValue; + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + ptr->iRes = m_oHorizontalDpi->m_eValue; + ptr->szRelID = m_oRId->GetValue(); + + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; + + ptr->iPaperSize = m_oPaperSize->m_eValue; + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + ptr->iVRes = m_oVerticalDpi->m_eValue; + return objectPtr; + } + } EElementType CPageSetup::getType() const { return et_x_PageSetup; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 3cbc566457c..ee352ac746a 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -200,6 +200,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From 2d13189051eaaaf6ef63353e26e447996fe815e5 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 29 Jun 2023 16:12:31 +0600 Subject: [PATCH 056/794] added print options conversion --- .../Worksheets/WorksheetChildOther.cpp | 17 +++++++++++++++++ .../XlsxFormat/Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 18 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 4820ce4a37e..80a15b07a08 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -720,6 +720,23 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPrintOptions::toBin() + { + auto ptr(new XLSB::PrintOptions); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oGridLines.IsInit()) + ptr->fPrintGrid = m_oGridLines->m_eValue; + if(m_oGridLinesSet.IsInit()) + ptr->fPrintGrid = m_oGridLinesSet->m_eValue; + if(m_oHeadings.IsInit()) + ptr->fPrintHeaders = m_oHeadings->m_eValue; + if(m_oHorizontalCentered.IsInit()) + ptr->fHCenter = m_oHorizontalCentered->m_eValue; + if(m_oVerticalCentered.IsInit()) + ptr->fVCenter = m_oVerticalCentered->m_eValue; + + return objectPtr; + } EElementType CPrintOptions::getType() const { return et_x_PrintOptions; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index ee352ac746a..898e0e7a0ec 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -243,6 +243,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 8fe5139272e40723b1668d89434fdc61c3d2d82d Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 29 Jun 2023 17:35:19 +0600 Subject: [PATCH 057/794] added protection and headerfooter conversion --- .../Worksheets/WorksheetChildOther.cpp | 86 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 2 + 2 files changed, 88 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 80a15b07a08..c743492df00 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1764,6 +1764,34 @@ namespace OOX } } } + XLS::BaseObjectPtr CHeaderFooter::toBin() + { + auto ptr(new XLSB::HEADERFOOTER); + + XLS::BaseObjectPtr objectPtr(ptr); + + auto castedBegin(new XLSB::BeginHeaderFooter); + ptr->m_BrtBeginHeaderFooter = XLS::BaseObjectPtr{castedBegin}; + + castedBegin->fHFAlignMargins = m_oAlignWithMargins->m_eValue; + castedBegin->fHFDiffFirst = m_oDifferentFirst->m_eValue; + castedBegin->fHFDiffOddEven = m_oDifferentOddEven->m_eValue; + castedBegin->fHFScaleWithDoc = m_oScaleWithDoc->m_eValue; + + if(m_oOddHeader.IsInit()) + castedBegin->stHeader = m_oOddHeader->m_sText; + if(m_oOddFooter.IsInit()) + ptr->stFooter = m_oOddFooter->m_sText; + if(m_oEvenHeader.IsInit()) + ptr->stHeaderEven = m_oEvenHeader->m_sText; + if(m_oEvenFooter.IsInit()) + ptr->stFooterEven = m_oEvenFooter->m_sText; + if(m_oFirstHeader.IsInit()) + ptr->stHeaderFirst = m_oFirstHeader->m_sText; + if(m_oFirstFooter.IsInit()) + ptr->stFooterFirst = m_oFirstFooter->m_sText; + return objectPtr; + } EElementType CHeaderFooter::getType() const { return et_x_HeaderFooterWorksheet; @@ -2163,6 +2191,64 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSheetProtection::toBin() + { + if(m_oPassword.IsInit()) + { + auto ptr(new XLSB::SheetProtection); + XLS::BaseObjectPtr castedPtr(ptr); + + ptr->protpwd = m_oPassword.get(); + ptr->fAutoFilter = m_oAutoFilter->GetValue(); + + ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + ptr->fDeleteRows = m_oDeleteRows->GetValue(); + ptr->fFormatCells = m_oFormatCells->GetValue(); + ptr->fFormatColumns = m_oFormatColumns->GetValue(); + ptr->fFormatRows = m_oFormatRows->GetValue(); + ptr->fInsertColumns = m_oInsertColumns->GetValue(); + ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + ptr->fInsertRows = m_oInsertRows->GetValue(); + ptr->fObjects = m_oObjects->GetValue(); + ptr->fPivotTables = m_oPivotTables->GetValue(); + ptr->fScenarios = m_oScenarios->GetValue(); + ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + ptr->fLocked = m_oSheet->GetValue(); + ptr->fSort = m_oSort->GetValue(); + + return castedPtr; + } + else + { + auto ptr(new XLSB::SheetProtectionIso); + XLS::BaseObjectPtr castedPtr(ptr); + + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + ptr->dwSpinCount = m_oSpinCount->GetValue(); + ptr->ipdPasswordData.rgbHash = m_oHashValue->GetValue(); + ptr->ipdPasswordData.rgbSalt = m_oSaltValue->GetValue(); + + ptr->fAutoFilter = m_oAutoFilter->GetValue(); + + ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + ptr->fDeleteRows = m_oDeleteRows->GetValue(); + ptr->fFormatCells = m_oFormatCells->GetValue(); + ptr->fFormatColumns = m_oFormatColumns->GetValue(); + ptr->fFormatRows = m_oFormatRows->GetValue(); + ptr->fInsertColumns = m_oInsertColumns->GetValue(); + ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + ptr->fInsertRows = m_oInsertRows->GetValue(); + ptr->fObjects = m_oObjects->GetValue(); + ptr->fPivotTables = m_oPivotTables->GetValue(); + ptr->fScenarios = m_oScenarios->GetValue(); + ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + ptr->fLocked = m_oSheet->GetValue(); + ptr->fSort = m_oSort->GetValue(); + return castedPtr; + } + } EElementType CSheetProtection::getType() const { return et_x_SheetProtection; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 898e0e7a0ec..370c1843c1b 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -571,6 +571,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -734,6 +735,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From dee93bae01068d389b5eb381147a2db01793bd50 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 30 Jun 2023 15:14:57 +0600 Subject: [PATCH 058/794] added sortstate conversion --- OOXML/XlsxFormat/Table/Autofilter.cpp | 54 +++++++++++++++++++++++++++ OOXML/XlsxFormat/Table/Autofilter.h | 2 + 2 files changed, 56 insertions(+) diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index 908052d894a..a541c87e1ac 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -104,6 +104,35 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSortCondition::toBin() + { + auto ptr(new XLSB::BeginSortCond); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->fSortDes = m_oDescending->GetValue(); + ptr->rfx = m_oRef->GetValue(); + + if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyValue) + { + ptr->sortOn = 0; + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyCellColor) + { + ptr->sortOn = 1; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyFontColor) + { + ptr->sortOn = 2; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyIcon) + { + ptr->sortOn = 3; + } + + return objectPtr; + } EElementType CSortCondition::getType () const { return et_x_SortCondition; @@ -254,8 +283,33 @@ namespace OOX for(auto &pSORTCOND14 : ptrACSORTCONDS->m_arSORTCOND14) m_arrItems.push_back(new CSortCondition(static_cast(pSORTCOND14.get())->m_BrtBeginSortCond14)); } + } + XLS::BaseObjectPtr CSortState::toBin() + { + auto ptr(new XLSB::SORTSTATE); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginSortState(new XLSB::BeginSortState); + ptr->m_BrtBeginSortState = XLS::BaseObjectPtr{beginSortState}; + if(m_oRef.IsInit()) + beginSortState->rfx = m_oRef->GetValue(); + if(m_oCaseSensitive.IsInit()) + beginSortState->fCaseSensitive = m_oCaseSensitive->GetValue(); + if(m_oColumnSort.IsInit()) + beginSortState->fCol = m_oColumnSort->GetValue(); + if(m_oSortMethod == SimpleTypes::Spreadsheet::ESortMethod::sortmethodStroke) + beginSortState->fAltMethod = true; + else + beginSortState->fAltMethod = false; + + auto sortConds(new XLSB::SORTCONDS); + ptr->m_source = XLS::BaseObjectPtr{sortConds}; + for(auto i:m_arrItems) + { + sortConds->m_arSORTCOND.push_back(i->toBin()); + } + return objectPtr; } EElementType CSortState::getType () const { diff --git a/OOXML/XlsxFormat/Table/Autofilter.h b/OOXML/XlsxFormat/Table/Autofilter.h index 4a4ab8d6abb..037f989bf60 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.h +++ b/OOXML/XlsxFormat/Table/Autofilter.h @@ -71,6 +71,7 @@ namespace OOX void toXMLWithNS(NSStringUtils::CStringBuilder& writer, const std::wstring &node_ns, const std::wstring &node_name, const std::wstring &child_ns) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -101,6 +102,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 950212b23b4cc0fca29c60a3b97059b3d44f57a4 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 30 Jun 2023 18:54:39 +0600 Subject: [PATCH 059/794] corrected conversion --- .../Worksheets/WorksheetChildOther.cpp | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index c743492df00..5f71aca8da5 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1781,15 +1781,15 @@ namespace OOX if(m_oOddHeader.IsInit()) castedBegin->stHeader = m_oOddHeader->m_sText; if(m_oOddFooter.IsInit()) - ptr->stFooter = m_oOddFooter->m_sText; + castedBegin->stFooter = m_oOddFooter->m_sText; if(m_oEvenHeader.IsInit()) - ptr->stHeaderEven = m_oEvenHeader->m_sText; + castedBegin->stHeaderEven = m_oEvenHeader->m_sText; if(m_oEvenFooter.IsInit()) - ptr->stFooterEven = m_oEvenFooter->m_sText; + castedBegin->stFooterEven = m_oEvenFooter->m_sText; if(m_oFirstHeader.IsInit()) - ptr->stHeaderFirst = m_oFirstHeader->m_sText; + castedBegin->stHeaderFirst = m_oFirstHeader->m_sText; if(m_oFirstFooter.IsInit()) - ptr->stFooterFirst = m_oFirstFooter->m_sText; + castedBegin->stFooterFirst = m_oFirstFooter->m_sText; return objectPtr; } EElementType CHeaderFooter::getType() const @@ -2198,7 +2198,7 @@ namespace OOX auto ptr(new XLSB::SheetProtection); XLS::BaseObjectPtr castedPtr(ptr); - ptr->protpwd = m_oPassword.get(); + ptr->protpwd = std::stoul(m_oPassword.get()); ptr->fAutoFilter = m_oAutoFilter->GetValue(); ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); @@ -2226,8 +2226,17 @@ namespace OOX ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); ptr->dwSpinCount = m_oSpinCount->GetValue(); - ptr->ipdPasswordData.rgbHash = m_oHashValue->GetValue(); - ptr->ipdPasswordData.rgbSalt = m_oSaltValue->GetValue(); + byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + + byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; ptr->fAutoFilter = m_oAutoFilter->GetValue(); From b2b628b5b7819c065d786e0773fff1619f97fb51 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 30 Jun 2023 18:55:13 +0600 Subject: [PATCH 060/794] added autofilter conversion --- OOXML/XlsxFormat/Table/Autofilter.cpp | 273 ++++++++++++++++++++++++++ OOXML/XlsxFormat/Table/Autofilter.h | 12 +- 2 files changed, 284 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index a541c87e1ac..6c4733e3159 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -382,6 +382,15 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CColorFilter::toBin() + { + auto ptr(new XLSB::ColorFilter); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->fCellColor = m_oCellColor->GetValue(); + ptr->dxfid = m_oDxfId->GetValue(); + + return objectPtr; + } EElementType CColorFilter::getType () const { return et_x_ColorFilter; @@ -446,6 +455,94 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDynamicFilter::toBin() + { + auto ptr(new XLSB::DynamicFilter); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNull) + ptr->cft = 0x00000000; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeAboveAverage) + ptr->cft = 0x00000001; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeBelowAverage) + ptr->cft = 0x00000002; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeTomorrow) + ptr->cft = 0x00000008; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeToday) + ptr->cft = 0x00000009; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeYesterday) + ptr->cft = 0x0000000A; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextWeek) + ptr->cft = 0x0000000B; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisWeek) + ptr->cft = 0x0000000C; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastWeek) + ptr->cft = 0x0000000D; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextMonth) + ptr->cft = 0x0000000E; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisMonth) + ptr->cft = 0x0000000F; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastMonth) + ptr->cft = 0x00000010; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextQuarter) + ptr->cft = 0x00000011; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisQuarter) + ptr->cft = 0x00000012; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastQuarter) + ptr->cft = 0x00000013; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeNextYear) + ptr->cft = 0x00000014; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeThisYear) + ptr->cft = 0x00000015; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeLastYear) + ptr->cft = 0x00000016; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeYearToDate) + ptr->cft = 0x00000017; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ1) + ptr->cft = 0x00000018; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ2) + ptr->cft = 0x00000019; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ3) + ptr->cft = 0x0000001A; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeQ4) + ptr->cft = 0x0000001B; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM1) + ptr->cft = 0x0000001C; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM2) + ptr->cft = 0x0000001D; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM3) + ptr->cft = 0x0000001E; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM4) + ptr->cft = 0x0000001F; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM5) + ptr->cft = 0x00000020; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM6) + ptr->cft = 0x00000021; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM7) + ptr->cft = 0x00000022; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM8) + ptr->cft = 0x00000023; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM9) + ptr->cft = 0x00000024; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM10) + ptr->cft = 0x00000025; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM11) + ptr->cft = 0x00000026; + else if (m_oType == SimpleTypes::Spreadsheet::EDynamicFilterType::dynamicfiltertypeM12) + ptr->cft = 0x00000027; + } + if (m_oVal.IsInit()) + { + ptr->xNumValue.data.value = m_oVal->GetValue(); + } + + if (m_oMaxVal.IsInit()) + { + ptr->xNumValueMax.data.value = m_oMaxVal->GetValue(); + } + return objectPtr; + } EElementType CDynamicFilter::getType () const { return et_x_DynamicFilter; @@ -585,6 +682,40 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCustomFilter::toBin() + { + auto ptr(new XLSB::CustomFilter); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterLessThan) + { + ptr->grbitSgn = 0x01; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterEqual) + { + ptr->grbitSgn = 0x02; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterLessThanOrEqual) + { + ptr->grbitSgn = 0x03; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterGreaterThan) + { + ptr->grbitSgn = 0x04; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterNotEqual) + { + ptr->grbitSgn = 0x05; + } + else if (m_oOperator == SimpleTypes::Spreadsheet::ECustomFilter::customfilterGreaterThanOrEqual) + { + ptr->grbitSgn = 0x06; + } + ptr->vts = 0x00000006; + ptr->vtsStringXls = m_oVal.get(); + + return objectPtr; + } EElementType CCustomFilter::getType () const { return et_x_CustomFilters; @@ -701,6 +832,21 @@ namespace OOX } } } + XLS::BaseObjectPtr CCustomFilters::toBin() + { + auto ptr(new XLSB::CUSTOMFILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + auto customFilters(new XLSB::BeginCustomFilters); + ptr->m_BrtBeginCustomFilters = XLS::BaseObjectPtr{customFilters}; + + customFilters->fAnd = m_oAnd->GetValue(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtCustomFilter.push_back(i->toBin()); + } + return objectPtr; + } EElementType CCustomFilters::getType () const { return et_x_CustomFilters; @@ -761,6 +907,13 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CFilter::toBin() + { + auto ptr(new XLSB::Filter); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->rgch = m_oVal.get(); + return objectPtr; + } EElementType CFilter::getType () const { return et_x_Filter; @@ -827,6 +980,44 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDateGroupItem::toBin() + { + auto ptr(new XLSB::AFilterDateGroupItem); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupYear) + { + ptr->dntChecked = 0x00000000; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupMonth) + { + ptr->dntChecked = 0x00000001; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupDay) + { + ptr->dntChecked = 0x00000002; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupHour) + { + ptr->dntChecked = 0x00000003; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupMinute) + { + ptr->dntChecked = 0x00000004; + } + else if (m_oDateTimeGrouping == SimpleTypes::Spreadsheet::EDateTimeGroup::datetimegroupSecond) + { + ptr->dntChecked = 0x00000005; + } + + ptr->dom = m_oDay->GetValue(); + ptr->hour = m_oHour->GetValue(); + ptr->min = m_oMinute->GetValue(); + ptr->mon = m_oMonth->GetValue(); + ptr->sec = m_oSecond->GetValue(); + ptr->yr = m_oYear->GetValue(); + return objectPtr; + } EElementType CDateGroupItem::getType () const { return et_x_DateGroupItem; @@ -965,6 +1156,27 @@ namespace OOX } } } + XLS::BaseObjectPtr CFilters::toBin() + { + auto ptr(new XLSB::FILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBlank.IsInit()) + { + auto beginFilters(new XLSB::BeginFilters); + beginFilters->fBlank = m_oBlank->GetValue(); + } + for(auto i: m_arrItems) + { + if (CFilter* cfilter = dynamic_cast(i)) { + // Элемент является экземпляром класса CFilter + ptr->m_arBrtFilter.push_back(cfilter->toBin()); + } else if (CDateGroupItem* groupItem = dynamic_cast(i)) { + // Элемент является экземпляром класса CDateGroupItem + ptr->m_arBrtAFilterDateGroupItem.push_back(groupItem->toBin()); + } + } + return objectPtr; + } EElementType CFilters::getType () const { return et_x_Filters; @@ -1030,6 +1242,25 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTop10::toBin() + { + auto ptr(new XLSB::Top10Filter); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oFilterVal.IsInit()) + ptr->xNumValue.data.value = m_oFilterVal->GetValue(); + + if (m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + + if (m_oTop.IsInit()) + ptr->fTop = m_oTop->GetValue(); + + if (m_oVal.IsInit()) + ptr->xNumFilter.data.value = m_oVal->GetValue(); + + return objectPtr; + } EElementType CTop10::getType () const { return et_x_ColorFilter; @@ -1146,6 +1377,33 @@ namespace OOX } } } + XLS::BaseObjectPtr CFilterColumn::toBin() + { + auto ptr(new XLSB::FILTERCOLUMN); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginfilter(new XLSB::BeginFilterColumn); + ptr->m_BrtBeginFilterColumn = XLS::BaseObjectPtr{beginfilter}; + + if(m_oColId.IsInit()) + beginfilter->dwCol = m_oColId->GetValue(); + if(m_oHiddenButton.IsInit()) + beginfilter->fHideArrow = m_oHiddenButton->GetValue(); + if(m_oShowButton.IsInit()) + beginfilter->fNoBtn = m_oShowButton->GetValue(); + + if(m_oColorFilter.IsInit()) + ptr->m_source = m_oColorFilter->toBin(); + else if(m_oDynamicFilter.IsInit()) + ptr->m_source = m_oDynamicFilter->toBin(); + else if(m_oCustomFilters.IsInit()) + ptr->m_source = m_oCustomFilters->toBin(); + else if(m_oFilters.IsInit()) + ptr->m_source = m_oFilters->toBin(); + else if(m_oTop10.IsInit()) + ptr->m_source = m_oTop10->toBin(); + + return objectPtr; + } EElementType CFilterColumn::getType () const { return et_x_FilterColumn; @@ -1244,6 +1502,21 @@ namespace OOX } } } + XLS::BaseObjectPtr CAutofilter::toBin() + { + auto ptr(new XLSB::AUTOFILTER); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRef.IsInit()) + { + auto beginFilter(new XLSB::BeginAFilter); + ptr->m_BrtBeginAFilter = XLS::BaseObjectPtr{beginFilter}; + beginFilter->rfx = m_oRef->GetValue(); + } + if(m_oSortState.IsInit()) + ptr->m_SORTSTATE = m_oSortState->toBin(); + + return objectPtr; + } EElementType CAutofilter::getType () const { return et_x_Autofilter; diff --git a/OOXML/XlsxFormat/Table/Autofilter.h b/OOXML/XlsxFormat/Table/Autofilter.h index 037f989bf60..ce6d0fd1279 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.h +++ b/OOXML/XlsxFormat/Table/Autofilter.h @@ -133,6 +133,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -161,6 +162,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -190,6 +192,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -218,6 +221,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -244,7 +248,8 @@ namespace OOX void toXMLWithNS(NSStringUtils::CStringBuilder& writer, const std::wstring &node_ns, const std::wstring &node_name, const std::wstring &child_ns) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - void fromBin(XLS::BaseObjectPtr& obj);; + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -272,6 +277,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -305,6 +311,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -332,6 +339,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -362,6 +370,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -395,6 +404,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; From 5e1c67b29ee95298b6aec7e1c24ce2bf2245ad5c Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 30 Jun 2023 19:31:57 +0600 Subject: [PATCH 061/794] added table parts conversion --- OOXML/XlsxFormat/Table/Table.h | 2 + OOXML/XlsxFormat/Table/Tables.cpp | 65 +++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/OOXML/XlsxFormat/Table/Table.h b/OOXML/XlsxFormat/Table/Table.h index b5be81fa45b..c8b9db642b9 100644 --- a/OOXML/XlsxFormat/Table/Table.h +++ b/OOXML/XlsxFormat/Table/Table.h @@ -300,6 +300,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TablePart; @@ -334,6 +335,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 79b4b0764f3..1643f0d8202 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -169,11 +169,11 @@ namespace Spreadsheet //есть такой баг: при сохранениии "sum" и названия таблицы "Table1" (русский excel), выдается ошибка в формулах WritingStringNullableAttrString(L"totalsRowFunction", m_oTotalsRowFunction, m_oTotalsRowFunction->ToString()); WritingStringNullableAttrInt(L"queryTableFieldId", m_oQueryTableFieldId, m_oQueryTableFieldId->GetValue()); - WritingStringNullableAttrString(L"dataCellStyle", m_oDataCellStyle, *m_oDataCellStyle); + WritingStringNullableAttrString(L"dataCellStyle", m_oDataCellStyle, *m_oDataCellStyle); WritingStringNullableAttrInt(L"dataDxfId", m_oDataDxfId, m_oDataDxfId->GetValue()); - WritingStringNullableAttrString(L"headerRowCellStyle", m_oHeaderRowCellStyle, *m_oHeaderRowCellStyle); + WritingStringNullableAttrString(L"headerRowCellStyle", m_oHeaderRowCellStyle, *m_oHeaderRowCellStyle); WritingStringNullableAttrInt(L"headerRowDxfId", m_oHeaderRowDxfId, m_oHeaderRowDxfId->GetValue()); - WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); + WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); WritingStringNullableAttrInt(L"totalsRowDxfId", m_oTotalsRowDxfId, m_oTotalsRowDxfId->GetValue()); if(m_oTotalsRowFormula.IsInit() || m_oCalculatedColumnFormula.IsInit()) { @@ -326,7 +326,7 @@ namespace Spreadsheet writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -334,7 +334,7 @@ namespace Spreadsheet m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CTableColumns::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -405,17 +405,17 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); WritingStringNullableAttrInt(L"totalsRowDxfId", m_oTotalsRowDxfId, m_oTotalsRowDxfId->GetValue()); WritingStringNullableAttrInt(L"totalsRowBorderDxfId", m_oTotalsRowBorderDxfId, m_oTotalsRowBorderDxfId->GetValue()); - + //if (m_oHeaderRowCount.IsInit() && 0 == m_oHeaderRowCount->GetValue()) // WritingStringAttrString(L"headerRowCount", L"1"); //if (m_oTotalsRowCount.IsInit() && m_oTotalsRowCount->GetValue() > 0) // WritingStringAttrString(L"totalsRowCount", L"1"); // else - // WritingStringAttrString(L"totalsRowShown", L"0");//m_oTotalsRowShown + // WritingStringAttrString(L"totalsRowShown", L"0");//m_oTotalsRowShown WritingStringNullableAttrInt(L"headerRowCount", m_oHeaderRowCount, m_oHeaderRowCount->GetValue()); WritingStringNullableAttrInt(L"totalsRowCount", m_oTotalsRowCount, m_oTotalsRowCount->GetValue()); WritingStringNullableAttrBool2(L"totalsRowShown", m_oTotalsRowShown); - + WritingStringNullableAttrBool2(L"insertRow", m_oInsertRow); WritingStringNullableAttrBool2(L"insertRowShift", m_oInsertRowShift); WritingStringNullableAttrBool2(L"published", m_oPublished); @@ -439,7 +439,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") void CTable::toXML2(NSStringUtils::CStringBuilder& writer, int nIndex) { if(false == m_oRef.IsInit() || false == m_oDisplayName.IsInit()) return; - + if(!m_oId.IsInit()) { m_oId.Init(); @@ -508,7 +508,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingElement_ReadAttributes_Read_else_if ( oReader, L"comment", m_oComment ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataDxfId", m_oDataDxfId ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataCellStyle", m_oDataCellStyle ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"dataCellStyle", m_oDataCellStyle ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowBorderDxfId", m_oHeaderRowBorderDxfId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowCellStyle", m_oHeaderRowCellStyle ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"headerRowDxfId", m_oHeaderRowDxfId ) @@ -624,6 +624,14 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") { ReadAttributes(obj); } + XLS::BaseObjectPtr CTablePart::toBin() + { + auto ptr(new XLSB::ListPart); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + ptr->stRelID.value = m_oRId->GetValue(); + return objectPtr; + } void CTablePart::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start_No_NS( oReader ) @@ -644,7 +652,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -652,8 +660,8 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - - writer.WriteString(L""); + + writer.WriteString(L""); } void CTableParts::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -689,6 +697,23 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CTableParts::toBin() + { + auto ptr(new XLSB::LISTPARTS); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oCount.IsInit()) + { + auto beginlistParts(new XLSB::BeginListParts); + ptr->m_BrtBeginListParts = XLS::BaseObjectPtr{beginlistParts}; + beginlistParts->cParts = m_oCount->m_eValue; + } + for(auto i:m_arrItems) + { + ptr->m_arBrtListPart.push_back(i->toBin()); + } + return objectPtr; + } void CTableParts::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -837,7 +862,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -845,7 +870,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CQueryTableFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -931,7 +956,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -1071,7 +1096,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") WritingElement_ReadAttributes_Read_else_if ( oReader, (L"unboundColumnsRight"), m_UnboundColumnsRight ) WritingElement_ReadAttributes_End( oReader ) } - + void CQueryTable::toXML(NSStringUtils::CStringBuilder& writer) const { if(false == m_oName.IsInit()) return; @@ -1107,7 +1132,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrBool2(L"refreshOnLoad", m_oRefreshOnLoad); WritingStringNullableAttrBool2(L"removeDataOnSave", m_oRemoveDataOnSave); WritingStringNullableAttrBool2(L"rowNumbers", m_oRowNumbers); - + writer.WriteString(L">"); if(m_oQueryTableRefresh.IsInit()) @@ -1203,10 +1228,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyFontFormats", m_oApplyFontFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyNumberFormats", m_oApplyNumberFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyPatternFormats", m_oApplyPatternFormats ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyWidthHeightFormats", m_oApplyWidthHeightFormats ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"applyWidthHeightFormats", m_oApplyWidthHeightFormats ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"autoFormatId", m_oAutoFormatId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"backgroundRefresh", m_oBackgroundRefresh ) - WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"connectionId", m_oConnectionId ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"disableEdit", m_oDisableEdit ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"disableRefresh", m_oDisableRefresh ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"fillFormulas", m_oFillFormulas ) From e42f3031f86808d2d868043174fbed41df710580 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Jul 2023 18:19:07 +0300 Subject: [PATCH 062/794] Add caching fontstyle like in fontmanager --- .../src/logic/managers/FontManager.cpp | 7 +++-- .../src/logic/managers/FontStyleManager.cpp | 31 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index b387b2b3608..9556c34c246 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -332,8 +332,11 @@ namespace NSDocxRenderer m_bIsSelectedItalic = it->bIsSelectedItalic; m_wsSelectedName = it->wsSelectedName; - m_arParamsCache.push_front(*it); - m_arParamsCache.erase(it); + if(it != m_arParamsCache.begin()) + { + m_arParamsCache.push_front(*it); + m_arParamsCache.erase(it); + } return; } } diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp index 49e6e64bafc..ae0fc7cf026 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -41,19 +41,26 @@ namespace NSDocxRenderer bool bItalic, bool bBold) { - for(auto& val : m_arFontStyles) + for(auto it = m_arFontStyles.begin(); it != m_arFontStyles.end(); ++it) { - if(oBrush.Type == val->oBrush.Type && - oBrush.Color1 == val->oBrush.Color1 && - oBrush.Color2 == val->oBrush.Color2 && - oBrush.Alpha1 == val->oBrush.Alpha1 && - oBrush.Alpha2 == val->oBrush.Alpha2 && - oBrush.LinearAngle == val->oBrush.LinearAngle && - dFontSize == val->dFontSize && - wsFontName == val->wsFontName && - (bItalic == val->bItalic) && (bBold == val->bBold)) - - return val; + if(oBrush.Type == (*it)->oBrush.Type && + oBrush.Color1 == (*it)->oBrush.Color1 && + oBrush.Color2 == (*it)->oBrush.Color2 && + oBrush.Alpha1 == (*it)->oBrush.Alpha1 && + oBrush.Alpha2 == (*it)->oBrush.Alpha2 && + oBrush.LinearAngle == (*it)->oBrush.LinearAngle && + dFontSize == (*it)->dFontSize && + wsFontName == (*it)->wsFontName && + (bItalic == (*it)->bItalic) && (bBold == (*it)->bBold)) + { + // в начало списка + if(it != m_arFontStyles.begin()) + { + m_arFontStyles.push_front(*it); + m_arFontStyles.erase(it); + } + return *it; + } } auto pFontStyle = std::make_shared(); pFontStyle->oBrush = oBrush; From e2a3e82770a99d3f90abec85836198c71d831143 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Jul 2023 18:31:27 +0300 Subject: [PATCH 063/794] Fix bug iterator exeption --- DocxRenderer/src/logic/managers/FontStyleManager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp index ae0fc7cf026..73d76f5a655 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -53,13 +53,16 @@ namespace NSDocxRenderer wsFontName == (*it)->wsFontName && (bItalic == (*it)->bItalic) && (bBold == (*it)->bBold)) { + auto val = *it; + // в начало списка if(it != m_arFontStyles.begin()) { - m_arFontStyles.push_front(*it); m_arFontStyles.erase(it); + m_arFontStyles.push_front(val); + } - return *it; + return val; } } auto pFontStyle = std::make_shared(); From 1b155518c2b0682ab566809d4269349afefeb8b3 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 2 Jul 2023 19:18:16 +0300 Subject: [PATCH 064/794] Less comparsions --- DocxRenderer/src/logic/managers/FontManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 9556c34c246..e431f6a3398 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -528,7 +528,7 @@ namespace NSDocxRenderer void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) { - if(m_oFont.IsEqual2(&oFont)) + if(m_oFont.Path == oFont.Path && m_oFont.FaceIndex == oFont.FaceIndex && m_oFont.Size == oFont.Size) return; m_oFont = oFont; @@ -545,7 +545,7 @@ namespace NSDocxRenderer } void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) { - if(m_oFont.IsEqual2(&oFont)) + if(m_oFont.Name == oFont.Name && m_oFont.Size == oFont.Size && m_oFont.GetStyle2() == oFont.GetStyle2()) return; m_oFont = oFont; From a1ac26ada9cec82aaf29e85f753053dd5abcfb40 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 5 Jul 2023 19:48:11 +0600 Subject: [PATCH 065/794] added ole objects convertation --- OOXML/XlsxFormat/Ole/OleObjects.cpp | 44 +++++++++++++++++++++++++++++ OOXML/XlsxFormat/Ole/OleObjects.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/OOXML/XlsxFormat/Ole/OleObjects.cpp b/OOXML/XlsxFormat/Ole/OleObjects.cpp index b6f273cb8a0..0db040495ee 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.cpp +++ b/OOXML/XlsxFormat/Ole/OleObjects.cpp @@ -293,6 +293,40 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr COleObject::toBin() + { + auto ptr(new XLSB::OleObject); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDvAspect.IsInit()) + { + if(m_oDvAspect == SimpleTypes::Spreadsheet::EDvAspect::Content) + ptr->dwAspect = 0x00000001; + else if(m_oDvAspect == SimpleTypes::Spreadsheet::EDvAspect::Icon) + ptr->dwAspect = 0x00000004; + } + if(m_oOleUpdate.IsInit()) + { + if(m_oOleUpdate == SimpleTypes::Spreadsheet::EOleUpdate::Always) + ptr->dwOleUpdate = 0x00000001; + else if(m_oOleUpdate == SimpleTypes::Spreadsheet::EOleUpdate::OnCall) + ptr->dwOleUpdate = 0x00000003; + } + + if(m_oShapeId.IsInit()) + ptr->shapeId = m_oShapeId->GetValue(); + + ptr->fAutoLoad = m_oAutoLoad->GetValue(); + + if(m_oProgId.IsInit()) + ptr->strProgID.value() = m_oProgId.get(); + + if(m_oLink.IsInit()) + ptr->link = m_oLink.get(); + if(m_oRid.IsInit()) + ptr->strRelID.value = m_oRid->GetValue(); + + return objectPtr; + } EElementType COleObject::getType () const { return et_x_OleObject; @@ -455,6 +489,16 @@ namespace OOX } } } + XLS::BaseObjectPtr COleObjects::toBin() + { + auto ptr(new XLSB::OLEOBJECTS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_mapOleObjects) + { + ptr->m_arBrtOleObject.push_back(i.second->toBin()); + } + return objectPtr; + } EElementType COleObjects::getType () const { return et_x_OleObjects; diff --git a/OOXML/XlsxFormat/Ole/OleObjects.h b/OOXML/XlsxFormat/Ole/OleObjects.h index 20c32d0df51..450f1997bcc 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.h +++ b/OOXML/XlsxFormat/Ole/OleObjects.h @@ -136,6 +136,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -171,6 +172,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From c49508902222bb5f3102d7a59fe873f8b3e7ba8c Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 5 Jul 2023 21:31:25 +0600 Subject: [PATCH 066/794] added controls conversion --- OOXML/XlsxFormat/Controls/Controls.cpp | 26 ++++++++++++++++++++++++++ OOXML/XlsxFormat/Controls/Controls.h | 24 +++++++++++++----------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Controls/Controls.cpp b/OOXML/XlsxFormat/Controls/Controls.cpp index c3ac52b8c84..9e48da5966a 100644 --- a/OOXML/XlsxFormat/Controls/Controls.cpp +++ b/OOXML/XlsxFormat/Controls/Controls.cpp @@ -202,6 +202,20 @@ namespace OOX } } } + XLS::BaseObjectPtr CControl::toBin() + { + auto ptr(new XLSB::ActiveX); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oShapeId.IsInit()) + ptr->shapeId = m_oShapeId->GetValue(); + + if (!m_oName.IsInit()) + ptr->strName = m_oName.get(); + + if (!m_oRid.IsInit()) + ptr->strRelID.value = m_oRid->GetValue(); + return objectPtr; + } void CControl::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -335,6 +349,18 @@ namespace OOX } } + XLS::BaseObjectPtr CControls::toBin() + { + auto ptr(new XLSB::ACTIVEXCONTROLS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_mapControls) + { + ptr->m_arBrtActiveX.push_back(i.second->toBin()); + } + + return objectPtr; + } CListItem::CListItem() {} CListItem::~CListItem() {} diff --git a/OOXML/XlsxFormat/Controls/Controls.h b/OOXML/XlsxFormat/Controls/Controls.h index cee8bba539e..a721d54c38f 100644 --- a/OOXML/XlsxFormat/Controls/Controls.h +++ b/OOXML/XlsxFormat/Controls/Controls.h @@ -67,10 +67,10 @@ namespace OOX { public: WritingElement_AdditionMethods(CListItem) - + CListItem(); virtual ~CListItem(); - + virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -80,7 +80,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_string m_oVal; }; //----------------------------------------------------------------------------------------------------------------------------- @@ -88,10 +88,10 @@ namespace OOX { public: WritingElement_AdditionMethods(CListItems) - + CListItems(); virtual ~CListItems(); - + virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -101,7 +101,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader){} - + std::vector> m_arrItems; nullable m_oExtLst; }; @@ -122,7 +122,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable m_oDropLines; nullable m_oObjectType; nullable m_oChecked; @@ -142,7 +142,7 @@ namespace OOX nullable_string m_oFmlaGroup; nullable_string m_oFmlaLink; nullable_string m_oFmlaRange; - nullable_string m_oFmlaTxbx; + nullable_string m_oFmlaTxbx; nullable_bool m_oColored; nullable_bool m_oFirstButton; nullable_bool m_oHoriz; @@ -215,9 +215,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void toXML2(NSStringUtils::CStringBuilder& writer, bool bControlPr) const; - + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -252,9 +253,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - + void read(XmlUtils::CXmlLiteReader& oReader, bool bOldVersion = false); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; From 9c119635da0db3a7c75dc3855b96dc2cb4940f97 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 6 Jul 2023 15:15:00 +0600 Subject: [PATCH 067/794] added cheetpr conversion --- OOXML/XlsxFormat/Styles/rPr.cpp | 33 +++++++++++++++++++ OOXML/XlsxFormat/Styles/rPr.h | 8 +++-- .../Worksheets/WorksheetChildOther.cpp | 27 +++++++++++++++ .../Worksheets/WorksheetChildOther.h | 1 + 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index fb570852894..9499de767ec 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -429,6 +429,39 @@ namespace OOX { ReadAttributes(obj); } + XLSB::Color CColor::toColor() + { + XLSB::Color ptr; + + if(m_oAuto.IsInit()) + { + if(m_oAuto->GetValue()) + ptr.xColorType = 0; + } + else if(m_oIndexed.IsInit()) + { + ptr.index = m_oIndexed->GetValue(); + ptr.xColorType = 1; + } + else if(m_oThemeColor.IsInit()) + { + ptr.index = m_oThemeColor->GetValue(); + ptr.xColorType = 3; + } + else + { + ptr.bAlpha = m_oRgb->Get_A(); + ptr.bBlue = m_oRgb->Get_B(); + ptr.bGreen = m_oRgb->Get_G(); + ptr.bRed = m_oRgb->Get_R(); + } + + if ( m_oTint.IsInit()) + { + ptr.nTintAndShade = m_oTint->GetValue() * 32767.0; + } + return ptr; + } EElementType CColor::getType () const { return et_x_Color; diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index f0ec51018ae..a22e3b60c84 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -33,6 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" +#include "../../XlsbFormat/Biff12_records/Color.h" namespace NSBinPptxRW { @@ -55,7 +56,7 @@ namespace SimpleTypes class CFontCharset; class CFontFamily; class CFontScheme; - class CUnderline; + class CUnderline; } } @@ -65,7 +66,7 @@ namespace ComplexTypes { class COnOff2; class String; - class CDouble; + class CDouble; } } @@ -98,7 +99,7 @@ namespace OOX public: nullable m_oRgb; }; - + class CIndexedColors : public WritingElementWithChilds { public: @@ -144,6 +145,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::BaseObject* obj); + XLSB::Color toColor(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 5f71aca8da5..0fc89ece3fb 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1530,6 +1530,33 @@ namespace OOX m_oOutlinePr = oReader; } } + XLS::BaseObjectPtr CSheetPr::toBin() + { + XLS::BaseObjectPtr objectPtr; + + if(m_oEnableFormatConditionsCalculation.IsInit() || m_oSyncHorizontal.IsInit() || m_oSyncHorizontal.IsInit() || m_oTransitionEvaluation.IsInit()) + { + auto ptr(new XLSB::WsProp); + objectPtr = XLS::BaseObjectPtr{ptr}; + + ptr->strName.value = m_oCodeName.get(); + + ptr->fCondFmtCalc = m_oEnableFormatConditionsCalculation->GetValue(); + ptr->fFilterMode = m_oFilterMode->GetValue(); + ptr->fPublish = m_oPublished->GetValue(); + ptr->fSyncHoriz = m_oSyncHorizontal->GetValue(); + ptr->fSyncVert = m_oSyncVertical->GetValue(); + ptr->fAltFormulaEntry = m_oTransitionEntry->GetValue(); + ptr->fAltExprEval = m_oTransitionEvaluation->GetValue(); + + if (m_oSyncRef.IsInit()) + ptr->syncRef = m_oSyncRef.get(); + + ptr->brtcolorTab = m_oTabColor->toColor(); + } + + return objectPtr; + } void CSheetPr::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeWsProp) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 370c1843c1b..b5c7432ca2d 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -512,6 +512,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From f70718822b653cc2fe0e7dd3cab001adb34bf950 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 6 Jul 2023 15:31:33 +0600 Subject: [PATCH 068/794] added picture worksheet conversion --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 10 ++++++++++ OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h | 1 + 2 files changed, 11 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 0fc89ece3fb..78a2e931a0e 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1969,6 +1969,16 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CPictureWorksheet::toBin() + { + auto ptr(new XLSB::BkHim); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oId.IsInit()) + ptr->rgb.value = m_oId->GetValue(); + + return objectPtr; + } void CPictureWorksheet::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index b5c7432ca2d..5c5aaf34b9f 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -654,6 +654,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From df147106b3cefb96848135329b3294b0c53f2579 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 6 Jul 2023 16:12:49 +0600 Subject: [PATCH 069/794] added breaks conversion --- .../Worksheets/WorksheetChildOther.cpp | 52 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 3 ++ 2 files changed, 55 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 78a2e931a0e..7b9f3dac0e0 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2033,6 +2033,24 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CBreak::toBin() + { + auto ptr(new XLSB::Brk); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oId.IsInit()) + ptr->unRwCol = m_oId->GetValue(); + if(m_oMan.IsInit()) + ptr->fMan = m_oMan->GetValue(); + if(m_oMax.IsInit()) + ptr->unColRwStrt = m_oMax->GetValue(); + if(m_oMin.IsInit()) + ptr->unColRwEnd = m_oMin->GetValue(); + if(m_oPt.IsInit()) + ptr->fPivot = m_oPt->GetValue(); + + return objectPtr; + } void CBreak::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -2119,6 +2137,40 @@ namespace OOX } } } + XLS::BaseObjectPtr CRowColBreaks::toBinRow() + { + auto ptr(new XLSB::RWBRK); + XLS::BaseObjectPtr objectPtr(ptr); + auto rowPtr(new XLSB::BeginRwBrk); + ptr->m_BrtBeginRwBrk = XLS::BaseObjectPtr{rowPtr}; + if(m_oCount.IsInit()) + rowPtr->ibrkMac = m_oCount->GetValue(); + if(m_oManualBreakCount.IsInit()) + rowPtr->ibrkManMac = m_oManualBreakCount->GetValue(); + for(auto i:m_arrItems) + { + ptr->m_arBrtBrk.push_back(i->toBin()); + } + return objectPtr; + } + + XLS::BaseObjectPtr CRowColBreaks::toBinColumn() + { + auto ptr(new XLSB::COLBRK); + XLS::BaseObjectPtr objectPtr(ptr); + auto colPtr(new XLSB::BeginColBrk); + ptr->m_BrtBeginColBrk = XLS::BaseObjectPtr{colPtr}; + if(m_oCount.IsInit()) + colPtr->ibrkMac = m_oCount->GetValue(); + if(m_oManualBreakCount.IsInit()) + colPtr->ibrkManMac = m_oManualBreakCount->GetValue(); + for(auto i:m_arrItems) + { + ptr->m_arBrtBrk.push_back(i->toBin()); + } + return objectPtr; + } + void CRowColBreaks::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeRWBRK) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 5c5aaf34b9f..8219c92da03 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -680,6 +680,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -710,6 +711,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinColumn(); + XLS::BaseObjectPtr toBinRow(); virtual EElementType getType () const; From ae185f6cd3b3da4e2c2cd619f87bb81bbf51a40c Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 6 Jul 2023 21:10:34 +0600 Subject: [PATCH 070/794] added data consolifate conversion --- .../Worksheets/WorksheetChildOther.cpp | 51 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 3 ++ 2 files changed, 54 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 7b9f3dac0e0..9e89d260c67 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2493,6 +2493,25 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDataRef::toBin() + { + auto ptr(new XLSB::DRef); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oId.IsInit()) + ptr->relId.value = m_oId->GetValue(); + + if (m_oName.IsInit()) + ptr->xstrName = m_oName.get(); + + if (m_oRef.IsInit()) + ptr->rfx = m_oRef.get(); + + if (m_oSheet.IsInit()) + ptr->xstrSheet = m_oSheet.get(); + + return objectPtr; + } EElementType CDataRef::getType() const { return et_x_DataRef; @@ -2584,6 +2603,16 @@ namespace OOX m_arrItems.push_back(new CDataRef(dref)); } } + XLS::BaseObjectPtr CDataRefs::toBin() + { + auto ptr(new XLSB::DREFS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + ptr->m_arBrtDRef.push_back(i->toBin()); + } + return objectPtr; + } EElementType CDataRefs::getType() const { return et_x_DataRefs; @@ -2635,6 +2664,28 @@ namespace OOX m_oDataRefs = oReader; } } + XLS::BaseObjectPtr CDataConsolidate::toBin() + { + auto ptr(new XLSB::DCON); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginPtr(new XLSB::BeginDCon); + ptr->m_BrtBeginDCon = XLS::BaseObjectPtr{beginPtr}; + + if(m_oFunction.IsInit()) + beginPtr->iiftab = m_oFunction->GetValue(); + if(m_oFunction.IsInit()) + beginPtr->fLinkConsol = m_oLink->GetValue(); + if(m_oFunction.IsInit()) + beginPtr->fLeftCat = m_oStartLabels->GetValue(); + if(m_oFunction.IsInit()) + beginPtr->fTopCat = m_oTopLabels->GetValue(); + + if(m_oDataRefs.IsInit()) + { + ptr->m_DREFS = m_oDataRefs->toBin(); + } + return objectPtr; + } void CDataConsolidate::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 8219c92da03..8d7750a8119 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -786,6 +786,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -812,6 +813,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -836,6 +838,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XLS::BaseObjectPtr& obj); From dac999e9e6a1d3eff100be7ccc1e05c3938a13f9 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 7 Jul 2023 13:48:58 +0300 Subject: [PATCH 071/794] Clearing cache after document, not page more optimization no error if convert wasnt called --- DocxRenderer/src/logic/Document.cpp | 1 + DocxRenderer/src/logic/Page.cpp | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 53733d0a1b4..14fe319e0f9 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -23,6 +23,7 @@ namespace NSDocxRenderer delete val.second; m_mapXmlString.clear(); + m_oFontSelector.ClearCache(); } CDocument::~CDocument() { diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index a48af59a692..56a0c931395 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -69,7 +69,6 @@ namespace NSDocxRenderer m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; m_oVector.Clear(); - m_pFontSelector->ClearCache(); } void CPage::ClearTables() @@ -458,9 +457,7 @@ namespace NSDocxRenderer bIsMerged = nextVal->TryMergeShape(val); if(bIsMerged) - { val->m_bIsNotNecessaryToUse = true; - } } } From 69e5dd8cdf5db1e71e212d4a72073cb56efff36f Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 7 Jul 2023 19:54:52 +0600 Subject: [PATCH 072/794] added ProtectedRange conversion --- .../Worksheets/WorksheetChildOther.cpp | 52 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 2 + 2 files changed, 54 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 9e89d260c67..3fdf81143b3 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -134,6 +134,49 @@ namespace OOX } } + XLS::BaseObjectPtr CProtectedRange::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oSpinCount.IsInit() || m_oSpinCount.IsInit() || m_oSpinCount.IsInit() || m_oSaltValue.IsInit()) + { + auto ptr(new XLSB::RangeProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oSqref.IsInit()) + ptr->sqRfX.strValue = m_oSqref.get(); + + if (m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + + if (m_oName.IsInit()) + ptr->rangeProtectionTitleSDRel.rgchTitle = m_oName.get(); + + byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + + byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + else + { + auto ptr(new XLSB::RangeProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oSqref.IsInit()) + ptr->sqRfX.strValue = m_oSqref.get(); + + if (m_oName.IsInit()) + ptr->rangeProtectionTitleSDRel.rgchTitle = m_oName.get(); + + } + return objectPtr; + } void CProtectedRange::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -239,6 +282,15 @@ namespace OOX } } } + std::vector CProtectedRanges::toBin() + { + std::vector result; + for(auto i:m_arrItems) + { + result.push_back(i->toBin()); + } + return result; + } void CProtectedRanges::fromBin(std::vector& obj) { for (auto &protRange : obj) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 8d7750a8119..c744b9073af 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -79,6 +79,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -108,6 +109,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType() const; }; From 35cec4cbd833ef62ced1bcb97e0008ca2506a3e1 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 7 Jul 2023 21:01:31 +0600 Subject: [PATCH 073/794] added data validation conversion --- .../XlsxFormat/Worksheets/DataValidation.cpp | 98 +++++++++++++++++++ OOXML/XlsxFormat/Worksheets/DataValidation.h | 6 +- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index 751fcd4ede6..b152a62f0ba 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -191,6 +191,84 @@ namespace OOX return result1 || result2; } + XLS::BaseObjectPtr CDataValidation::toBin() + { + auto ptr(new XLSB::DVal); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeNone) + ptr->valType = XLS::typeDvNone; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeWhole) + ptr->valType = XLS::typeDvWhole; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDecimal) + ptr->valType = XLS::typeDvDecimal; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeList) + ptr->valType = XLS::typeDvList; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDate) + ptr->valType = XLS::typeDvDate; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTime) + ptr->valType = XLS::typeDvTime; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTextLength) + ptr->valType = XLS::typeDvTextLength; + else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeCustom) + ptr->valType = XLS::typeDvCustom; + + ptr->fAllowBlank = m_oAllowBlank->GetValue(); + if(m_oError.IsInit()) + ptr->Error = m_oError.get(); + + if (m_oErrorTitle.IsInit()) + ptr->ErrorTitle = m_oErrorTitle.get(); + + if (m_oPrompt.IsInit()) + ptr->Prompt = m_oPrompt.get(); + + if (m_oPromptTitle.IsInit()) + ptr->PromptTitle = m_oPromptTitle.get(); + + ptr->errStyle = m_oErrorStyle->GetValue(); + + if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOn) + { + ptr->mdImeMode = 0x01; + } + else if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOff) + { + ptr->mdImeMode = 0x02; + } + else + { + ptr->mdImeMode = m_oImeMode->GetValue(); + } + + if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotBetween; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvEquals; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotEquals; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThan; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThan; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThanOrEqual; + else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThanOrEqual; + + ptr->fSuppressCombo = m_oShowDropDown->GetValue(); + ptr->fShowErrorMsg = m_oShowErrorMessage->GetValue(); + ptr->fShowInputMsg = m_oShowInputMessage->GetValue(); + + ptr->sqrfx.strValue = m_oSqRef.get(); + + ptr->formula1 = m_oFormula1->m_sText; + ptr->formula2 = m_oFormula2->m_sText; + + return objectPtr; + } void CDataValidation::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -490,6 +568,26 @@ namespace OOX } } } + XLS::BaseObjectPtr CDataValidations::toBin() + { + XLS::BaseObjectPtr objectPtr; + auto ptr(new XLSB::DVALS); + objectPtr = XLS::BaseObjectPtr{ptr}; + + auto beginPtr(new XLSB::BeginDVals); + ptr->m_BrtBeginDVals = XLS::BaseObjectPtr{beginPtr}; + beginPtr->dVals.idvMac = m_oCount.get() ; + beginPtr->dVals.fWnClosed = m_oDisablePrompts->GetValue(); + beginPtr->dVals.xLeft = m_oXWindow->GetValue(); + beginPtr->dVals.yTop = m_oYWindow->GetValue(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtDVal.push_back(i->toBin()); + } + + return objectPtr; + } void CDataValidations::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.h b/OOXML/XlsxFormat/Worksheets/DataValidation.h index bc46c90b068..fd375940422 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.h +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.h @@ -63,10 +63,10 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; - void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; + void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; virtual void toXML(NSStringUtils::CStringBuilder& writer) const; - virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType () const; std::wstring m_sNodeName; @@ -90,6 +90,7 @@ namespace OOX bool IsExtended(); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -133,6 +134,7 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From b0721b2c16735cbcf9c6c24f4b9796e50e5b5787 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sun, 9 Jul 2023 21:35:44 +0300 Subject: [PATCH 074/794] Rename param for x2t & remove src dependency for library (paragraph) --- DocxRenderer/DocxRenderer.cpp | 2 +- DocxRenderer/DocxRenderer.h | 6 +-- DocxRenderer/convert_params.h | 45 +++++++++++++++++++ DocxRenderer/src/logic/Page.h | 2 +- DocxRenderer/src/logic/elements/ContText.cpp | 4 +- DocxRenderer/src/logic/elements/Converter.cpp | 14 +++--- DocxRenderer/src/logic/elements/Converter.h | 4 +- DocxRenderer/src/logic/elements/Paragraph.h | 11 +---- DocxRenderer/src/resources/LinesTable.h | 2 +- DocxRenderer/test/main.cpp | 17 +++---- X2tConverter/src/ASCConverters.cpp | 10 ++--- 11 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 DocxRenderer/convert_params.h diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 26ab5cfdaac..2f0836a8a0c 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -79,7 +79,7 @@ HRESULT CDocxRenderer::Close() return hr; } -HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType) +HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType) { m_pInternal->m_oDocument.m_oCurrentPage.m_eTextAssociationType = eType; return S_OK; diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index e5b82c7db51..ceae2bd9461 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -34,8 +34,6 @@ #include "../DesktopEditor/graphics/pro/officedrawingfile.h" #include "../DesktopEditor/graphics/pro/Fonts.h" -#include "src/logic/elements/Paragraph.h" - #ifndef DOCXRENDERER_USE_DYNAMIC_LIBRARY #define DOCXRENDERER_DECL_EXPORT #else @@ -43,6 +41,8 @@ #define DOCXRENDERER_DECL_EXPORT Q_DECL_EXPORT #endif +#include "convert_params.h" + class CDocxRenderer_Private; class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer { @@ -187,7 +187,7 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); // методы, которыми будет пользоваться конвертер - HRESULT SetTextAssociationType(const NSDocxRenderer::eTextAssociationType& eType); + HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); private: diff --git a/DocxRenderer/convert_params.h b/DocxRenderer/convert_params.h new file mode 100644 index 00000000000..a0d5caef180 --- /dev/null +++ b/DocxRenderer/convert_params.h @@ -0,0 +1,45 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +namespace NSDocxRenderer +{ + enum class TextAssociationType + { + tatBlockChar = 0, // Каждый символ во фрейме + tatBlockLine = 1, // Каждая линия - параграф во фрейме. Линии могут объединяться в рамках одного блока. + tatPlainLine = 2, // Каждая линия - параграф обычный + tatShapeLine = 3, // Каждая линия - параграф в шейпе. Линии могут объединяться в рамках одного блока. + tatPlainParagraph = 4, // Все линии объединяются в параграфы + tatParagraphToShape = 5 // Параграфы записываем в шейпы + }; +} diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 5a7801a087a..de261bc19e3 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -49,7 +49,7 @@ namespace NSDocxRenderer CRow* m_pCurrentRow {nullptr}; - eTextAssociationType m_eTextAssociationType {eTextAssociationType::tatPlainParagraph}; + TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; bool m_bIsDeleteTextClipPage {true}; bool m_bIsRecalcFontSize {true}; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 030e57c8487..1cb8026cf8e 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -157,7 +157,7 @@ namespace NSDocxRenderer if (m_bIsUnderlinePresent) { oWriter.WriteString(L"second; diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 73e19a4d448..71f429f6f70 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -127,10 +127,7 @@ int main(int argc, char *argv[]) } if (!pReader) - { - pFonts->Release(); - return 0; - } + continue; pReader->SetTempDirectory(sTempDir); @@ -165,18 +162,18 @@ int main(int argc, char *argv[]) std::wstring sZip = L"/" + sFileName + L".zip"; // проверить все режимы - NSDocxRenderer::eTextAssociationType taType; - //taType = NSDocxRenderer::eTextAssociationType::tatPlainLine; - //taType = NSDocxRenderer::eTextAssociationType::tatShapeLine; - taType = NSDocxRenderer::eTextAssociationType::tatPlainParagraph; - //taType = NSDocxRenderer::eTextAssociationType::tatParagraphToShape; + NSDocxRenderer::TextAssociationType taType; + //taType = NSDocxRenderer::TextAssociationType::tatPlainLine; + //taType = NSDocxRenderer::TextAssociationType::tatShapeLine; + taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; + //taType = NSDocxRenderer::TextAssociationType::tatParagraphToShape; oDocxRenderer.SetTextAssociationType(taType); oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); //Если сразу нужен zip-архив //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); #endif - delete pReader; + RELEASEOBJECT(pReader); } pFonts->Release(); diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 06e5ebf0bc9..a172e10d1d9 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -4991,7 +4991,7 @@ namespace NExtractTools CDocxRenderer oDocxRenderer(pApplicationFonts); - NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::tatPlainLine; + NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::TextAssociationType::tatPlainLine; if (params.m_oTextParams) { InputParamsText* oTextParams = params.m_oTextParams; @@ -5001,16 +5001,16 @@ namespace NExtractTools switch (*oTextParams->m_nTextAssociationType) { case 0: - taType = NSDocxRenderer::tatBlockChar; + taType = NSDocxRenderer::TextAssociationType::tatBlockChar; break; case 1: - taType = NSDocxRenderer::tatBlockLine; + taType = NSDocxRenderer::TextAssociationType::tatBlockLine; break; case 2: - taType = NSDocxRenderer::tatPlainLine; + taType = NSDocxRenderer::TextAssociationType::tatPlainLine; break; case 3: - taType = NSDocxRenderer::tatPlainParagraph; + taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; break; default: break; From e2932091e8e9daaec2cc7d6e26538f305bda4215 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Mon, 10 Jul 2023 18:24:51 +0600 Subject: [PATCH 075/794] added conditional formatting conversion --- OOXML/XlsxFormat/Styles/rPr.cpp | 35 ++ OOXML/XlsxFormat/Styles/rPr.h | 1 + .../Worksheets/ConditionalFormatting.cpp | 392 +++++++++++++++++- .../Worksheets/ConditionalFormatting.h | 16 +- 4 files changed, 419 insertions(+), 25 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 9499de767ec..568d7ec681e 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -462,6 +462,41 @@ namespace OOX } return ptr; } + XLS::BaseObjectPtr CColor::toBin() + { + auto ptr(new XLSB::Color); + + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oAuto.IsInit()) + { + if(m_oAuto->GetValue()) + ptr->xColorType = 0; + } + else if(m_oIndexed.IsInit()) + { + ptr->index = m_oIndexed->GetValue(); + ptr->xColorType = 1; + } + else if(m_oThemeColor.IsInit()) + { + ptr->index = m_oThemeColor->GetValue(); + ptr->xColorType = 3; + } + else + { + ptr->bAlpha = m_oRgb->Get_A(); + ptr->bBlue = m_oRgb->Get_B(); + ptr->bGreen = m_oRgb->Get_G(); + ptr->bRed = m_oRgb->Get_R(); + } + + if ( m_oTint.IsInit()) + { + ptr->nTintAndShade = m_oTint->GetValue() * 32767.0; + } + return objectPtr; + } EElementType CColor::getType () const { return et_x_Color; diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index a22e3b60c84..3596e3de2a1 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -145,6 +145,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::BaseObject* obj); + XLS::BaseObjectPtr toBin(); XLSB::Color toColor(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 30b5a0fc6af..5de0b0492e0 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -108,7 +108,7 @@ EElementType CFormulaCF::getType () const void CFormulaCF::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const { std::wstring node_name = bExtendedWrite ? L"xm:f" : L"formula"; - + writer.WriteString(L"<" + node_name + L">"); writer.WriteEncodeXmlString(m_sText); writer.WriteString(L""); @@ -125,7 +125,7 @@ void CFormulaCF::fromXML(XmlUtils::CXmlLiteReader& oReader) const CFormulaCF CFormulaCF::Merge(const CFormulaCF& oPrev, const CFormulaCF& oCurrent) { CFormulaCF oFormula; - + if (oCurrent.m_sText.empty() == false) { oFormula.m_sText = oCurrent.m_sText; @@ -180,11 +180,11 @@ void CConditionalFormatValueObject::ReadAttributes(XmlUtils::CXmlLiteReader& oRe void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const { if (false == m_oType.IsInit()) return; - + if (bExtendedWrite == false) { if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMin) m_oType->SetValue(SimpleTypes::Spreadsheet::Minimum); - if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMax) m_oType->SetValue(SimpleTypes::Spreadsheet::Maximum); + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::autoMax) m_oType->SetValue(SimpleTypes::Spreadsheet::Maximum); } std::wstring node_name = bExtendedWrite ? L"x14:cfvo" : L"cfvo"; @@ -220,7 +220,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer CFormulaCF formla; formla.m_sText = m_oVal.get(); formla.toXML2(writer, true); } - + } writer.WriteString(L""); @@ -228,7 +228,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); - + if (oReader.IsEmptyNode()) return; @@ -240,6 +240,37 @@ void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) m_oFormula = oReader; } } +XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() +{ + auto ptr(new XLSB::uCFVO); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::CFVO); + ptr->m_BrtCFVO = XLS::BaseObjectPtr{ptr1}; + ptr1->fGTE = m_oGte->GetValue(); + + if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) + ptr1->iType = XLSB::CFVOtype::CFVONUM; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) + ptr1->iType = XLSB::CFVOtype::CFVOMIN; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Maximum) + ptr1->iType = XLSB::CFVOtype::CFVOMAX; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percent) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENT; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percentile) + ptr1->iType = XLSB::CFVOtype::CFVOPERCENTILE; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) + ptr1->iType = XLSB::CFVOtype::CFVOFMLA; + + ptr1->numParam.data.value = std::stod(m_oVal.get()); + + if(m_oFormula.IsInit()) + { + ptr1->formula = m_oFormula->m_sText; + } + + return objectPtr; +} void CConditionalFormatValueObject::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -617,6 +648,14 @@ void CColorScale::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr CColorScale::toBin() +{ + auto ptr(new XLSB::COLORSCALE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + return objectPtr; +} EElementType CColorScale::getType () const { return et_x_ColorScale; @@ -635,7 +674,7 @@ nullable CColorScale::Merge(const nullable &oPrev, const nullablem_BrtBeginDatabar = XLS::BaseObjectPtr{ptr1}; + ptr1->bLenMax = m_oMaxLength->GetValue(); + ptr1->bLenMin = m_oMinLength->GetValue(); + ptr1->fShowValue = m_oShowValue->GetValue(); + + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + if(m_oColor.IsInit()) + + ptr->m_BrtColor = m_oColor->toBin(); + + return objectPtr; +} void CDataBar::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginDatabar) @@ -896,13 +954,13 @@ const CDataBar CDataBar::Merge(const CDataBar& oPrev, const CDataBar& oCurrent) oDataBar.m_oDirection = Merge( oPrev.m_oDirection, oCurrent.m_oDirection ); oDataBar.m_oNegativeBarColorSameAsPositive = Merge( oPrev.m_oNegativeBarColorSameAsPositive, oCurrent.m_oNegativeBarColorSameAsPositive ); oDataBar.m_oNegativeBarBorderColorSameAsPositive = Merge( oPrev.m_oNegativeBarBorderColorSameAsPositive, oCurrent.m_oNegativeBarBorderColorSameAsPositive ); - + oDataBar.m_oColor = Merge( oPrev.m_oColor, oCurrent.m_oColor ); oDataBar.m_oAxisColor = Merge( oPrev.m_oAxisColor, oCurrent.m_oAxisColor ); oDataBar.m_oBorderColor = Merge( oPrev.m_oBorderColor, oCurrent.m_oBorderColor ); oDataBar.m_oNegativeFillColor = Merge( oPrev.m_oNegativeFillColor, oCurrent.m_oNegativeFillColor ); oDataBar.m_oNegativeBorderColor = Merge( oPrev.m_oNegativeBorderColor, oCurrent.m_oNegativeBorderColor ); - + for (size_t i = 0; i < oPrev.m_arrValues.size(); i++) { if (i < oCurrent.m_arrValues.size()) @@ -1059,6 +1117,95 @@ void CIconSet::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr CIconSet::toBin() +{ + auto ptr(new XLSB::ICONSET); + XLS::BaseObjectPtr objectPtr(ptr); + + auto beginPtr(new XLSB::BeginIconSet); + ptr->m_BrtBeginIconSet = XLS::BaseObjectPtr{beginPtr}; + if(m_oShowValue.IsInit()) + beginPtr->fIcon = !m_oShowValue->GetValue(); + if(m_oReverse.IsInit()) + beginPtr->fReverse = m_oReverse->GetValue(); + + if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::NoIcons) + { + beginPtr->iSet.set = KPISets::KPINIL; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows3) + { + beginPtr->iSet.set = KPISets::KPI3ARROWS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows3Gray) + { + beginPtr->iSet.set = KPISets::KPI3ARROWSGRAY; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Flags3) + { + beginPtr->iSet.set = KPISets::KPI3FLAGS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights1) + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights2) + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS2; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Signs3) + { + beginPtr->iSet.set = KPISets::KPI3SIGNS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Symbols3) + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Symbols3_2) + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS2; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows4) + { + beginPtr->iSet.set = KPISets::KPI4ARROWS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows4Gray) + { + beginPtr->iSet.set = KPISets::KPI4ARROWSGRAY; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::RedToBlack4) + { + beginPtr->iSet.set = KPISets::KPI4REDTOBLACK; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Rating4) + { + beginPtr->iSet.set = KPISets::KPI4RATING; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic4Lights) + { + beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows5) + { + beginPtr->iSet.set = KPISets::KPI5ARROWS; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows5Gray) + { + beginPtr->iSet.set = KPISets::KPI5ARROWSGRAY; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Rating5) + { + beginPtr->iSet.set = KPISets::KPI5RATING; + } + else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Quarters5) + { + beginPtr->iSet.set = KPISets::KPI5QUARTERS; + } + + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + return objectPtr; +} void CIconSet::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginIconSet) @@ -1307,7 +1454,7 @@ const CIconSet CIconSet::Merge(const CIconSet& oPrev, const CIconSet& oCurrent) oIconSet.m_oReverse = Merge( oPrev.m_oReverse, oCurrent.m_oReverse ); oIconSet.m_oShowValue = Merge( oPrev.m_oShowValue, oCurrent.m_oShowValue ); oIconSet.m_oCustom = Merge( oPrev.m_oCustom, oCurrent.m_oCustom ); - + for (size_t i = 0; i < oPrev.m_arrValues.size(); i++) { if (i < oCurrent.m_arrValues.size()) @@ -1381,7 +1528,7 @@ bool CConditionalFormattingRule::isExtended() if (m_oDataBar.IsInit()) return m_oDataBar->isExtended(); if (m_oIconSet.IsInit()) return m_oIconSet->isExtended(); if (m_oColorScale.IsInit()) return m_oColorScale->isExtended(); - + for (size_t i = 0; i < m_arrFormula.size(); i++) { if ((m_arrFormula[i].IsInit()) && m_arrFormula[i]->isExtended()) @@ -1394,7 +1541,7 @@ void CConditionalFormattingRule::toXML2(NSStringUtils::CStringBuilder& writer, b if (false == isValid()) return; std::wstring node_name = bExtendedWrite ? L"x14:cfRule" : L"cfRule"; - + writer.WriteString(L"<" + node_name); WritingStringNullableAttrString(L"type", m_oType, m_oType->ToString()); WritingStringNullableAttrInt(L"priority", m_oPriority, m_oPriority->GetValue()); @@ -1432,7 +1579,7 @@ void CConditionalFormattingRule::toXML2(NSStringUtils::CStringBuilder& writer, b m_oColorScale->toXML2(writer, bExtendedWrite); if (m_oDataBar.IsInit()) m_oDataBar->toXML2(writer, bExtendedWrite); - + for (size_t i = 0; i < m_arrFormula.size(); i++) { if (m_arrFormula[i].IsInit()) @@ -1458,7 +1605,7 @@ void CConditionalFormattingRule::fromXML(XmlUtils::CXmlLiteReader& oReader) while (oReader.ReadNextSiblingNode(nCurDepth)) { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - + if (L"colorScale" == sName ) m_oColorScale = oReader; else if ( L"dataBar" == sName) @@ -1557,6 +1704,182 @@ void CConditionalFormattingRule::fromBin(XLS::BaseObjectPtr& obj) } } } + +XLS::BaseObjectPtr CConditionalFormattingRule::toBin() +{ + XLS::CellRef cellRef; + auto ptr(new XLSB::CFRULE(cellRef)); + XLS::BaseObjectPtr objPtr(ptr); + + auto beginRule(new XLSB::BeginCFRule(cellRef)); + ptr->m_BrtBeginCFRule = WriteAttributes(); + + if(m_oColorScale.IsInit()) + { + ptr->m_source = m_oColorScale->toBin(); + } + else if(m_oDataBar.IsInit()) + { + ptr->m_source = m_oDataBar->toBin(); + } + else if(m_oIconSet.IsInit()) + { + ptr->m_source = m_oIconSet->toBin(); + } + return objPtr; +} + +XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() +{ + XLS::CellRef cellRef; + auto ptr(new XLSB::BeginCFRule(cellRef)); + BaseObjectPtr objectPtr(ptr); + + if(m_oDxfId.IsInit()) + { + ptr->dxfId = m_oDxfId->GetValue(); + } + ptr->iPri = m_oPriority->GetValue(); + ptr->fStopTrue = m_oStopIfTrue->GetValue(); + ptr->fAbove = m_oAboveAverage->GetValue(); + ptr->fBottom = m_oBottom->GetValue(); + ptr->fPercent = m_oPercent->GetValue(); + ptr->strParam = m_oText.get(); + + if(!m_arrFormula.empty()) + { + ptr->rgce1 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + } + if(!m_arrFormula.empty()) + { + ptr->rgce2 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + } + if(!m_arrFormula.empty()) + { + ptr->rgce3 = m_arrFormula.front()->m_sText; + m_arrFormula.erase(m_arrFormula.begin()); + } + + if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) +{ + if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_between) + ptr->iParam = XLSB::CFOper::CF_OPER_BN; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notBetween) + ptr->iParam = XLSB::CFOper::CF_OPER_NB; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_equal) + ptr->iParam = XLSB::CFOper::CF_OPER_EQ; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_notEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_NE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThan) + ptr->iParam = XLSB::CFOper::CF_OPER_GT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThan) + ptr->iParam = XLSB::CFOper::CF_OPER_LT; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_greaterThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_GE; + else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThanOrEqual) + ptr->iParam = XLSB::CFOper::CF_OPER_LE; +} + +if (m_oType == SimpleTypes::Spreadsheet::ECfType::expression) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FMLA; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::uniqueValues) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_UNIQUEVALUES; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsText) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_CONTAINS; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsText) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_NOTCONTAINS; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::beginsWith) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_BEGINSWITH; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::endsWith) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSTEXT; + ptr->iParam = XLSB::CFTextOper::CF_TEXTOPER_ENDSWITH; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsBlanks) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSBLANKS; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsBlanks) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOBLANKS; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::containsErrors) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSERRORS; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsErrors) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_CONTAINSNOERRORS; +} + +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) +{ + if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::today) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::tomorrow) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::yesterday) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::last7Days) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastMonth) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextMonth) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisWeek) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextWeek) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastWeek) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; + else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisMonth) + ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; +} + +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) +{ + ptr->iTemplate= XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; + ptr->iParam = m_oStdDev->GetValue(); +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) +{ + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DUPLICATEVALUES; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale) +{ + ptr->iType = XLSB::CFType::CF_TYPE_GRADIENT; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar) +{ + ptr->iType = XLSB::CFType::CF_TYPE_DATABAR; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) +{ + ptr->iType = XLSB::CFType::CF_TYPE_MULTISTATE; +} +else if (m_oType == SimpleTypes::Spreadsheet::ECfType::top10) +{ + ptr->iType = XLSB::CFType::CF_TYPE_FILTER; + ptr->iParam = m_oRank->GetValue(); +} + + return objectPtr; +} template nullable CConditionalFormattingRule::Merge(const nullable &oPrev, const nullable &oCurrent) { @@ -1570,7 +1893,7 @@ nullable CConditionalFormattingRule::Merge(const nullable &oPrev, co const CConditionalFormattingRule CConditionalFormattingRule::Merge(const CConditionalFormattingRule& oPrev, const CConditionalFormattingRule& oCurrent) { CConditionalFormattingRule oRule; - + oRule.m_oAboveAverage = Merge( oPrev.m_oAboveAverage, oCurrent.m_oAboveAverage ); oRule.m_oBottom = Merge( oPrev.m_oBottom, oCurrent.m_oBottom ); oRule.m_oDxfId = Merge( oPrev.m_oDxfId, oCurrent.m_oDxfId ); @@ -1602,7 +1925,7 @@ const CConditionalFormattingRule CConditionalFormattingRule::Merge(const CCondit oRule.m_oColorScale = Merge( oPrev.m_oColorScale, oCurrent.m_oColorScale ); if (oPrev.m_oDataBar.IsInit() && oCurrent.m_oDataBar.IsInit()) - oRule.m_oDataBar = CDataBar::Merge ( oPrev.m_oDataBar.get(), oCurrent.m_oDataBar.get()); + oRule.m_oDataBar = CDataBar::Merge ( oPrev.m_oDataBar.get(), oCurrent.m_oDataBar.get()); else oRule.m_oDataBar = Merge( oPrev.m_oDataBar, oCurrent.m_oDataBar ); @@ -2127,7 +2450,7 @@ bool CConditionalFormatting::IsExtended() { m_bIsExtended = false; m_bIsValid = false; - + if (m_oSqRef.IsInit() == false) return m_bIsExtended; m_bIsValid = true; @@ -2135,7 +2458,7 @@ bool CConditionalFormatting::IsExtended() for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( !m_arrItems[i]) continue; - + if (m_arrItems[i]->isValid() == false) m_bIsValid = false; if (m_arrItems[i]->isExtended() == true) @@ -2144,7 +2467,7 @@ bool CConditionalFormatting::IsExtended() return m_bIsExtended; } void CConditionalFormatting::toXML2(NSStringUtils::CStringBuilder& writer, bool bExtendedWrite) const -{ +{ std::wstring node_name = bExtendedWrite ? L"x14:conditionalFormatting" : L"conditionalFormatting"; writer.WriteString(L"<" + node_name); @@ -2161,7 +2484,7 @@ void CConditionalFormatting::toXML2(NSStringUtils::CStringBuilder& writer, bool writer.WriteString(L" pivot=\"1\""); } writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -2224,6 +2547,33 @@ void CConditionalFormatting::fromBin(XLS::BaseObjectPtr& obj) m_arrItems.push_back(new CConditionalFormattingRule(pCFRULE14)); } } + +XLS::BaseObjectPtr CConditionalFormatting::toBin() +{ + XLS::BaseObjectPtr objectPtr; + if(m_arrItems.empty()) + { + return objectPtr; + } + if(m_arrItems.back()->m_oExtId.IsInit()) + { + auto ptr(new XLSB::CONDITIONALFORMATTING); + objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oSqRef.IsInit()) + { + auto conditionPtr(new XLSB::BeginConditionalFormatting); + ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; + + conditionPtr->sqrfx.strValue = m_oSqRef.get(); + conditionPtr->fPivot = m_oPivot->GetValue(); + } + for(auto i: m_arrItems) + { + ptr->m_arCFRULE.push_back(i->toBin()); + } + } + return objectPtr; +} bool CConditionalFormatting::IsUsage() { for ( size_t i = 0; i < m_arrItems.size(); ++i) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h index 14d011972b7..acda290e53e 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h @@ -106,6 +106,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; bool isExtended (); @@ -166,6 +167,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -199,6 +201,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -214,7 +217,7 @@ namespace OOX nullable m_oMaxLength; nullable m_oMinLength; nullable m_oShowValue; - + nullable m_oColor; std::vector> m_arrValues; @@ -229,7 +232,7 @@ namespace OOX nullable m_oAxisColor; nullable m_oBorderColor; - + nullable m_oNegativeFillColor; nullable m_oNegativeBorderColor; }; @@ -251,6 +254,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -295,6 +299,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; bool isValid () const; @@ -306,6 +311,8 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr WriteAttributes(); + public: nullable m_oDxf; @@ -323,7 +330,7 @@ namespace OOX nullable m_oText; nullable m_oTimePeriod; nullable m_oType; - + nullable m_oExtLst; nullable_string m_oExtId; @@ -353,10 +360,11 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; bool IsUsage(); - + private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); From 0c6a72df990bcc1e484e284e30c17e1ca7f54808 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 12 Jul 2023 13:31:35 +0300 Subject: [PATCH 076/794] Fix bug with left sort + Changed consts space width --- DocxRenderer/src/logic/elements/BaseItem.h | 2 +- DocxRenderer/src/logic/elements/ContText.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index e4371aae30a..a1b66220119 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -87,7 +87,7 @@ namespace NSDocxRenderer static void SortByLeft(std::vector& oArray) { std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return a->IsCurrentLeftOfNext(a); + return a->IsCurrentLeftOfNext(b); }); } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 1cb8026cf8e..921e142464c 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -107,13 +107,13 @@ namespace NSDocxRenderer double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); dSpacing *= c_dMMToDx; + //mm to points * 20 lCalculatedSpacing = static_cast(dSpacing); } } //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - //note 1 -> 0.5pt - lCalculatedSpacing -= 1; + lCalculatedSpacing -= 6; if (lCalculatedSpacing != 0) { @@ -505,12 +505,12 @@ namespace NSDocxRenderer double CContText::CalculateWideSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 4; + return m_dSpaceWidthMM * 2.5; } double CContText::CalculateThinSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.4; + return m_dSpaceWidthMM * 0.25; } } From bc7bbb94aaaef878799238509c91c51fb9d22e64 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 12 Jul 2023 18:08:02 +0600 Subject: [PATCH 077/794] added extension list conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 42 ++++++++++++-- OOXML/DocxFormat/Drawing/DrawingExt.h | 7 ++- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 21 ++++++- OOXML/XlsxFormat/Slicer/SlicerCacheExt.h | 2 + OOXML/XlsxFormat/Worksheets/Sparkline.cpp | 67 ++++++++++++++++++++++ OOXML/XlsxFormat/Worksheets/Sparkline.h | 2 + 6 files changed, 132 insertions(+), 9 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 90aee2b1880..163f8dc3433 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -129,7 +129,7 @@ namespace OOX sResult += L" relId=\"" + m_oRelId->ToString() + L"\""; } sResult += L" minVer=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"/>"; - + return sResult; } EElementType CDataModelExt::getType() const @@ -214,9 +214,9 @@ namespace OOX *m_sUri == L"{46F421CA-312F-682f-3DD2-61675219B42D}" || *m_sUri == L"{DE250136-89BD-433C-8126-D09CA5730AF9}" || *m_sUri == L"{19B8F6BF-5375-455C-9EA6-DF929625EA0E}" || - *m_sUri == L"{725AE2AE-9491-48be-B2B4-4EB974FC3084}" || + *m_sUri == L"{725AE2AE-9491-48be-B2B4-4EB974FC3084}" || *m_sUri == L"{231B7EB2-2AFC-4442-B178-5FFDF5851E7C}" || - *m_sUri == L"http://schemas.microsoft.com/office/drawing/2008/diagram")) + *m_sUri == L"http://schemas.microsoft.com/office/drawing/2008/diagram")) { int nCurDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth)) @@ -491,7 +491,7 @@ namespace OOX NSStringUtils::CStringBuilder writer; writer.StartNode(L"externalReference"); writer.StartAttributes(); - + if (m_oFileKey.IsInit()) writer.WriteAttribute(L"fileKey", *m_oFileKey); if (m_oInstanceId.IsInit()) writer.WriteAttribute(L"instanceId", *m_oInstanceId); @@ -585,7 +585,7 @@ namespace OOX } pWriter->WriteNodeEnd(ns + L"extLst"); - } + } std::wstring COfficeArtExtensionList::toXML() const { return toXMLWithNS(L"a:"); @@ -606,6 +606,38 @@ namespace OOX return sResult; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorksheet() + { + auto ptr(new XLSB::FRTWORKSHEET); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_arrExt.empty()) + return objectPtr; + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}") + { + auto formatPtr(new XLSB::CONDITIONALFORMATTINGS); + ptr->m_CONDITIONALFORMATTINGS = XLS::BaseObjectPtr{formatPtr}; + for(auto j:i->m_arrConditionalFormatting) + { + formatPtr->m_arCONDITIONALFORMATTING14.push_back(j->toBin()); + } + } + else if(i->m_sUri == L"{CCE6A557-97BC-4B89-ADB6-D9C93CAAB3DF}") + { + ptr->m_DVALS14 = i->m_oDataValidations->toBin(); + } + else if(i->m_sUri == L"{05C60535-1F16-4fd2-B633-F4F36F0B64E0}") + { + ptr->m_SPARKLINEGROUPS = i->m_oSparklineGroups->toBin(); + } + else if(i->m_sUri == L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}") + { + ptr->m_SLICERSEX = i->m_oSlicerList->toBin(); + } + } + return objectPtr; + } void COfficeArtExtensionList::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeFRTWORKBOOK) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 4d433323369..93d1cd95e48 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -105,7 +105,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtension 20.1.2.2.14 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtension : public WritingElement { @@ -150,7 +150,7 @@ namespace OOX std::vector m_oSlicerCachePivotTables; nullable m_oTableSlicerCache; nullable m_oSlicerCacheHideItemsWithNoData; - + std::vector m_arrConditionalFormatting; nullable m_oPresenceInfo; @@ -167,7 +167,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtensionList 20.1.2.2.15 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtensionList : public WritingElement { @@ -185,6 +185,7 @@ namespace OOX virtual std::wstring toXML() const; std::wstring toXMLWithNS(const std::wstring& sNamespace) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinWorksheet(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index fbb809808e1..9655bfca25a 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -540,6 +540,15 @@ void CSlicerCache::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { pReader->SkipRecord(); } +XLS::BaseObjectPtr CSlicerRef::toBin() +{ + auto ptr(new XLSB::SLICEREX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerEx); + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + + return objectPtr; +} void CSlicerRef::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -557,7 +566,6 @@ void CSlicerRef::ReadAttributes(XLS::BaseObjectPtr &obj) if(!ptr1->FRTheader.relID.relId.value().empty()) m_oRId = ptr1->FRTheader.relID.relId.value(); } - } } else if(obj->get_type() == XLS::typeTABLESLICEREX) @@ -778,6 +786,17 @@ void CSlicerCaches::toXML(NSStringUtils::CStringBuilder& writer, const std::wstr } writer.EndNode(sPrefix + sName); } +XLS::BaseObjectPtr CSlicerRefs::toBin() +{ + auto ptr(new XLSB::SLICERSEX); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_oSlicer) + { + ptr->m_arSLICEREX.push_back(i.toBin()); + } + return objectPtr; +} void CSlicerRefs::fromBin(XLS::BaseObjectPtr &obj) { if(obj->get_type() == XLS::typeSLICERSEX) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index a94ddcd7a10..fa79a0c1c90 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -206,6 +206,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -280,6 +281,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType() const { diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp index 9263752056f..64ec4da5b80 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp @@ -393,6 +393,65 @@ namespace OOX m_oSparklines = obj; } } + XLS::BaseObjectPtr CSparklineGroup::toBin() + { + auto ptr1(new XLSB::SPARKLINEGROUP); + XLS::BaseObjectPtr objectPtr(ptr1); + + auto ptr(new XLSB::BeginSparklineGroup); + ptr1->m_BrtBeginSparklineGroup = XLS::BaseObjectPtr{ptr}; + + ptr->dManualMax.data.value = m_oManualMax->GetValue(); + ptr->dManualMin.data.value = m_oManualMin->GetValue(); + ptr->dLineWeight.data.value = m_oLineWeight->GetValue(); + ptr->isltype = static_castisltype)>(m_oType->GetValue()); + ptr->fDateAxis = m_oDateAxis->GetValue(); + ptr->fShowEmptyCellAsZero = (m_oDisplayEmptyCellsAs == OOX::Spreadsheet::ST_DispBlanksAs::st_dispblanksasZERO) ? 0x01 : 0x00; + ptr->fMarkers = m_oMarkers->GetValue(); + ptr->fHigh = m_oHigh->GetValue(); + ptr->fLow = m_oLow->GetValue(); + ptr->fFirst = m_oFirst->GetValue(); + ptr->fLast = m_oLast->GetValue(); + ptr->fNegative = m_oNegative->GetValue(); + ptr->fAxis = m_oDisplayXAxis->GetValue(); + ptr->fDisplayHidden = m_oDisplayHidden->GetValue(); + ptr->fRTL = m_oRightToLeft->GetValue(); + + if(m_oMaxAxisType == SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Individual) + ptr->fIndividualAutoMax = true; + + + if(m_oColorSeries.IsInit()) + ptr->brtcolorSeries = m_oColorSeries->toColor(); + + if(m_oColorNegative.IsInit()) + ptr->brtcolorNegative = m_oColorNegative->toColor(); + + if(m_oColorAxis.IsInit()) + ptr->brtcolorAxis = m_oColorAxis->toColor(); + + if(m_oColorMarkers.IsInit()) + ptr->brtcolorMarkers = m_oColorMarkers->toColor(); + + if(m_oColorFirst.IsInit()) + ptr->brtcolorFirst = m_oColorFirst->toColor(); + + if(m_oColorLast.IsInit()) + ptr->brtcolorLast = m_oColorLast->toColor(); + + if(m_oColorHigh.IsInit()) + ptr->brtcolorHigh = m_oColorHigh->toColor(); + + if(m_oColorLow.IsInit()) + ptr->brtcolorLow = m_oColorLow->toColor(); + + if(ptr->FRTheader.rgFormulas.array.size() > 0) + { + ptr->FRTheader.rgFormulas.array[0].formula = m_oRef.get(); + } + + return objectPtr; + } EElementType CSparklineGroup::getType () const { return et_x_SparklineGroup; @@ -556,6 +615,14 @@ namespace OOX m_arrItems.push_back(new CSparklineGroup(sparklineGroup)); } } + XLS::BaseObjectPtr CSparklineGroups::toBin() + { + auto ptr(new XLSB::SPARKLINEGROUPS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSPARKLINEGROUP.push_back(i->toBin()); + return objectPtr; + } EElementType CSparklineGroups::getType () const { return et_x_SparklineGroups; diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.h b/OOXML/XlsxFormat/Worksheets/Sparkline.h index c2968e768d8..938fc399d0f 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.h +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.h @@ -109,6 +109,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -163,6 +164,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 1864a6d0c0243a6f1b69a8d8fc3d36a90a2a4672 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 12 Jul 2023 18:08:56 +0600 Subject: [PATCH 078/794] added worksheet conversion --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 112 +++++++++++++++++++--- OOXML/XlsxFormat/Worksheets/Worksheet.h | 7 +- 2 files changed, 105 insertions(+), 14 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 4c62e56793c..fd68ac31100 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -66,11 +66,11 @@ namespace OOX if (xlsx) { m_bPrepareForBinaryWriter = true; // подготовка для бинарника при чтении - + xlsx->m_arWorksheets.push_back( this ); //xlsx->m_mapWorksheets.insert( std::make_pair(rId, this) ); } - else + else m_bPrepareForBinaryWriter = false; } CWorksheet::CWorksheet(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath, const std::wstring & rId, bool isChartSheet) : OOX::File(pMain), OOX::IFileContainer(pMain), WritingElement(pMain) @@ -86,11 +86,11 @@ namespace OOX if (xlsx) { m_bPrepareForBinaryWriter = true; - + xlsx->m_arWorksheets.push_back( this ); xlsx->m_mapWorksheets.insert( std::make_pair(rId, this) ); } - else + else m_bPrepareForBinaryWriter = false; read( oRootPath, oPath ); @@ -229,6 +229,96 @@ namespace OOX } } + XLS::BaseObjectPtr CWorksheet::writeBin() + { + if(m_bIsChartSheet) + { + XLSB::ChartSheetStreamPtr chartSheetStream(new XLSB::ChartSheetStream); + return chartSheetStream; + } + else + { + XLSB::WorkSheetStreamPtr workSheetStream(new XLSB::WorkSheetStream); + + if (m_oCols.IsInit()) + workSheetStream->m_arCOLINFOS = m_oCols->toBin(); + if (m_oDimension.IsInit()) + workSheetStream->m_BrtWsDim = m_oDimension->toBin(); + if (m_oDrawing.IsInit()) + workSheetStream->m_BrtDrawing = m_oDrawing->toBin(); + if (m_oLegacyDrawing.IsInit()) + workSheetStream->m_BrtLegacyDrawing = m_oLegacyDrawing->toBin(); + if (m_oLegacyDrawingHF.IsInit()) + workSheetStream->m_BrtLegacyDrawingHF = m_oLegacyDrawingHF->toBin(); + if (m_oHyperlinks.IsInit()) + workSheetStream->m_HLINKS = m_oHyperlinks->toBin(); + if (m_oMergeCells.IsInit()) + workSheetStream->m_MERGECELLS = m_oMergeCells->toBin(); + + if (m_oSheetFormatPr.IsInit()) + workSheetStream->m_BrtWsFmtInfo = m_oSheetFormatPr->toBin(); + if (m_oSheetViews.IsInit()) + workSheetStream->m_WSVIEWS2 = m_oSheetViews->toBin(); + if (m_oPageMargins.IsInit()) + workSheetStream->m_BrtMargins = m_oPageMargins->toBin(); + if (m_oPageSetup.IsInit()) + workSheetStream->m_BrtPageSetup = m_oPageSetup->toBin(); + if (m_oPrintOptions.IsInit()) + workSheetStream->m_BrtPrintOptions = m_oPrintOptions->toBin(); + if (m_oHeaderFooter.IsInit()) + workSheetStream->m_HEADERFOOTER = m_oHeaderFooter->toBin(); + if(m_oSheetProtection.IsInit()) + { + if (m_oSheetProtection->m_oAlgorithmName.IsInit()) + workSheetStream->m_BrtSheetProtectionIso = m_oSheetProtection->toBin(); + else if(m_oSheetProtection->m_oPassword.IsInit()) + workSheetStream->m_BrtSheetProtection = m_oSheetProtection->toBin(); + } + if (m_oTableParts.IsInit()) + workSheetStream->m_LISTPARTS = m_oTableParts->toBin(); + if (m_oSortState.IsInit()) + workSheetStream->m_SORTSTATE = m_oSortState->toBin(); + if (!m_arrConditionalFormatting.empty()) + for(auto &item : m_arrConditionalFormatting) + workSheetStream->m_arCONDITIONALFORMATTING.push_back(item->toBin()); + + if (m_oAutofilter.IsInit()) + workSheetStream->m_AUTOFILTER = m_oAutofilter->toBin(); + if (m_oDataValidations.IsInit()) + workSheetStream->m_DVALS = m_oDataValidations->toBin(); + if (m_oOleObjects.IsInit()) + workSheetStream->m_OLEOBJECTS = m_oOleObjects->toBin(); + if (m_oControls.IsInit()) + workSheetStream->m_ACTIVEXCONTROLS = m_oControls->toBin(); + if (m_oSheetPr.IsInit()) + workSheetStream->m_BrtWsProp = m_oSheetPr->toBin(); + if (m_oPicture.IsInit()) + workSheetStream->m_BrtBkHim = m_oPicture->toBin(); + if (m_oRowBreaks.IsInit()) + workSheetStream->m_RWBRK = m_oRowBreaks->toBinRow(); + if (m_oColBreaks.IsInit()) + workSheetStream->m_COLBRK = m_oColBreaks->toBinColumn(); + if (m_oDataConsolidate.IsInit()) + workSheetStream->m_DCON = m_oDataConsolidate->toBin(); + + if (m_oProtectedRanges.IsInit()) + { + if(m_oProtectedRanges->m_arrItems.empty()) + { + auto arrayPtr = m_oProtectedRanges->m_arrItems.back(); + if(arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSpinCount.IsInit() || arrayPtr->m_oSaltValue.IsInit()) + workSheetStream->m_arBrtRangeProtectionIso = m_oProtectedRanges->toBin(); + else + workSheetStream->m_arBrtRangeProtection = m_oProtectedRanges->toBin(); + } + } + if (m_oExtLst.IsInit()) + workSheetStream->m_FRTWORKSHEET = m_oExtLst->toBinWorksheet(); + + return workSheetStream; + } + + } void CWorksheet::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -265,7 +355,7 @@ namespace OOX if ( oReader.IsEmptyNode() ) return; - + int nDocumentDepth = oReader.GetDepth(); std::wstring sName; @@ -417,7 +507,7 @@ namespace OOX void CWorksheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { nullable_string sName; - + WritingElement_ReadAttributes_Start( oReader ) WritingElement_ReadAttributes_Read_if ( oReader, L"ss:Name", sName ) WritingElement_ReadAttributes_End( oReader ) @@ -501,10 +591,10 @@ namespace OOX } if(false == m_oSheetViews.IsInit()) m_oSheetViews.Init(); - + if(m_oSheetViews->m_arrItems.empty()) m_oSheetViews->m_arrItems.push_back(new CSheetView()); - + CSheetView* pSheetView = m_oSheetViews->m_arrItems.front(); if(false == pSheetView->m_oWorkbookViewId.IsInit()) @@ -587,7 +677,7 @@ namespace OOX if (!m_bWriteDirectlyToFile) { NSStringUtils::CStringBuilder sXml; - + toXMLStart(sXml); toXML(sXml); toXMLEnd(sXml); @@ -695,14 +785,14 @@ mc:Ignorable=\"x14ac\">"); if (!m_oLegacyDrawing.IsInit()) return oElement; if (!m_oLegacyDrawing->m_oId.IsInit()) return oElement; - + smart_ptr oFile = this->Find(m_oLegacyDrawing->m_oId->GetValue()); smart_ptr oVmlDrawing = oFile.smart_dynamic_cast(); OOX::WritingElement* pShapeElem = NULL; if (oVmlDrawing.IsInit()) { - oElement = oVmlDrawing->FindVmlObject(spid); + oElement = oVmlDrawing->FindVmlObject(spid); } return oElement; } diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.h b/OOXML/XlsxFormat/Worksheets/Worksheet.h index 240696a9abe..e472137843d 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.h +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.h @@ -76,6 +76,7 @@ namespace OOX virtual ~CWorksheet(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr writeBin(); virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); @@ -85,9 +86,9 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - + void toXMLStart(NSStringUtils::CStringBuilder& writer) const; void toXMLEnd(NSStringUtils::CStringBuilder& writer) const; virtual const OOX::FileType type() const; @@ -107,7 +108,7 @@ namespace OOX void ReadWorksheetOptions(XmlUtils::CXmlLiteReader& oReader); CPath m_oReadPath; - + bool m_bPrepareForBinaryWriter; bool m_bWriteDirectlyToFile; bool m_bIsChartSheet; From c4fe64423c07c351e04f0d18ddc534bdcfd25b8b Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 12 Jul 2023 17:19:43 +0300 Subject: [PATCH 079/794] Calc width in selected font --- DocxRenderer/src/logic/elements/ContText.cpp | 47 +++++++++++++------ DocxRenderer/src/logic/elements/ContText.h | 4 ++ DocxRenderer/src/logic/elements/Converter.cpp | 8 ---- DocxRenderer/src/logic/elements/TextLine.cpp | 4 ++ .../src/logic/managers/FontManager.cpp | 6 +-- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 921e142464c..116f8356b93 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -57,6 +57,9 @@ namespace NSDocxRenderer m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; m_bSpaceIsNotNeeded = rCont.m_bSpaceIsNotNeeded; + m_dSpaceWidthSelected = rCont.m_dSpaceWidthSelected; + m_dWidthSelected = rCont.m_dWidthSelected; + m_eVertAlignType = rCont.m_eVertAlignType; m_pManager = rCont.m_pManager; @@ -69,21 +72,10 @@ namespace NSDocxRenderer return *this; } - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CContText::CalcSelectedWidth() { - if (m_bIsNotNecessaryToUse) - { + if(m_bIsNotNecessaryToUse) return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L"wsFontStyleId); - oWriter.WriteString(L"\"/>"); - - LONG lCalculatedSpacing = 0; if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { @@ -102,9 +94,36 @@ namespace NSDocxRenderer double dBoxY; double dBoxWidth; double dBoxHeight; + m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); + m_dWidthSelected = dBoxWidth; + m_dSpaceWidthSelected = m_pManager->GetSpaceWidthMM(); + } + } + } - double dSpacing = (m_dWidth - dBoxWidth) / (m_oText.length()); + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + if (m_bIsNotNecessaryToUse) + { + return; + } + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L"wsFontStyleId); + oWriter.WriteString(L"\"/>"); + + LONG lCalculatedSpacing = 0; + + if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) + { + if (m_eVertAlignType != eVertAlignType::vatSubscript && + m_eVertAlignType != eVertAlignType::vatSuperscript) + { + double dSpacing = (m_dWidth - m_dWidthSelected) / (m_oText.length()); dSpacing *= c_dMMToDx; //mm to points * 20 diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index e663a44052d..8fc0c2e380e 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -43,6 +43,9 @@ namespace NSDocxRenderer double m_dSpaceWidthMM {0}; bool m_bSpaceIsNotNeeded {false}; + double m_dWidthSelected {0}; + double m_dSpaceWidthSelected {0}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; CFontManager* m_pManager {nullptr}; @@ -70,6 +73,7 @@ namespace NSDocxRenderer bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); + void CalcSelectedWidth(); double CalculateWideSpace(); double CalculateThinSpace(); diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 62a1d4ed7f2..6e89ff242fa 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -11,25 +11,17 @@ namespace NSDocxRenderer for (size_t i = 0; i < rTextLines.size(); ++i) { auto pCurrLine = rTextLines[i]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { continue; - } for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) { auto pCurrCont = pCurrLine->m_arConts[j]; - if (pCurrCont->m_bIsNotNecessaryToUse) - { continue; - } if (pCurrCont->m_iNumDuplicates > 0) - { pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); - } } pCurrLine->MergeConts(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index c4dfd5f3de3..1c4b118a9a4 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -175,13 +175,17 @@ namespace NSDocxRenderer } dDelta = pCurrent->m_dLeft - pPrev->m_dRight; + pPrev->CalcSelectedWidth(); pPrev->ToXml(oWriter); + if (!(dDelta < pPrev->CalculateWideSpace() || pPrev->m_bSpaceIsNotNeeded)) pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); pPrev = pCurrent; } + pPrev->CalcSelectedWidth(); pPrev->ToXml(oWriter); + } } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index e431f6a3398..06548155ed7 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -572,8 +572,8 @@ namespace NSDocxRenderer double CFontManager::GetSpaceWidthMM() const { double dSpaceWidthMM = 0.0; - int bIsGID = m_pManager->GetStringGID(); - m_pManager->SetStringGID(FALSE); + // int bIsGID = m_pManager->GetStringGID(); + // m_pManager->SetStringGID(FALSE); m_pManager->LoadString2(L" ", 0, 0); TBBox bbox = m_pManager->MeasureString2(); @@ -582,7 +582,7 @@ namespace NSDocxRenderer if (0 >= dSpaceWidthMM) dSpaceWidthMM = 1.0; - m_pManager->SetStringGID(bIsGID); + // m_pManager->SetStringGID(bIsGID); return dSpaceWidthMM; } From 21d883e083ffd3378713de9e635095f3f35b737c Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 12 Jul 2023 21:55:13 +0600 Subject: [PATCH 080/794] added book views conversion --- OOXML/XlsxFormat/Workbook/BookViews.cpp | 57 +++++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/BookViews.h | 2 + 2 files changed, 59 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index b960837f4da..86bcc02f7a6 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -74,6 +74,55 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CWorkbookView::toBin() + { + auto ptr(new XLSB::BookView); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oActiveTab.IsInit()) + ptr->itabCur = m_oActiveTab->GetValue(); + + if (m_oAutoFilterDateGrouping.IsInit()) + ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); + if (m_oFirstSheet.IsInit()) + ptr->itabFirst = m_oFirstSheet->GetValue(); + if (m_oMinimized.IsInit()) + ptr->fIconic = m_oMinimized->GetValue(); + if (m_oShowHorizontalScroll.IsInit()) + ptr->fDspHScroll = m_oShowHorizontalScroll->GetValue(); + if (m_oShowSheetTabs.IsInit()) + ptr->fBotAdornment = m_oShowSheetTabs->GetValue(); + if (m_oShowVerticalScroll.IsInit()) + ptr->fDspVScroll = m_oShowVerticalScroll->GetValue(); + if (m_oTabRatio.IsInit()) + ptr->wTabRatio = m_oTabRatio->GetValue(); + if (m_oWindowHeight.IsInit()) + ptr->dyWn = m_oWindowHeight->GetValue(); + if (m_oWindowWidth.IsInit()) + ptr->dxWn = m_oWindowWidth->GetValue(); + if (m_oXWindow.IsInit()) + ptr->xWn = m_oXWindow->GetValue(); + if (m_oYWindow.IsInit()) + ptr->yWn = m_oYWindow->GetValue(); + + if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + { + ptr->fHidden = true; + ptr->fVeryHidden = false; + } + else if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + { + ptr->fHidden = false; + ptr->fVeryHidden = true; + } + else + { + ptr->fHidden = false; + ptr->fVeryHidden = false; + } + + return objectPtr; + } EElementType CWorkbookView::getType () const { return et_x_WorkbookView; @@ -183,6 +232,14 @@ namespace OOX m_arrItems.push_back(new CWorkbookView(workbookView)); } } + std::vector CBookViews::toBin() + { + std::vector ptrVector{}; + for(auto i:m_arrItems) + ptrVector.push_back(i->toBin()); + + return ptrVector; + } EElementType CBookViews::getType () const { return et_x_BookViews; diff --git a/OOXML/XlsxFormat/Workbook/BookViews.h b/OOXML/XlsxFormat/Workbook/BookViews.h index 5083d26c156..bd5c418df5e 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.h +++ b/OOXML/XlsxFormat/Workbook/BookViews.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -104,6 +105,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: From 54a85f17fb75501bf5a19adbd477f2023af93156 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 13 Jul 2023 14:45:36 +0600 Subject: [PATCH 081/794] added calcPr conversion --- OOXML/XlsxFormat/Workbook/CalcPr.cpp | 21 +++++++++++++++++++++ OOXML/XlsxFormat/Workbook/CalcPr.h | 1 + 2 files changed, 22 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.cpp b/OOXML/XlsxFormat/Workbook/CalcPr.cpp index 1cfd708051a..f63ac42d314 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.cpp +++ b/OOXML/XlsxFormat/Workbook/CalcPr.cpp @@ -82,6 +82,27 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCalcPr::toBin() + { + auto ptr(new XLSB::CalcProp); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->recalcID = m_oCalcId->GetValue(); + ptr->fAutoRecalc = m_oCalcMode->GetValue(); + ptr->fFullCalcOnLoad = m_oFullCalcOnLoad->GetValue(); + ptr->fRefA1 = !m_oRefMode->GetValue(); + ptr->fIter = m_oIterate->GetValue(); + ptr->cCalcCount = m_oIterateCount->GetValue(); + ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); + ptr->fFullPrec = m_oFullPrecision->GetValue(); + ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); + ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); + ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); + ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); + ptr->fNoDeps = m_oForceFullCalc->GetValue(); + + return objectPtr; + } EElementType CCalcPr::getType () const { return et_x_CalcPr; diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.h b/OOXML/XlsxFormat/Workbook/CalcPr.h index 821d0adb0b0..2e193e766f8 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.h +++ b/OOXML/XlsxFormat/Workbook/CalcPr.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From a0262cf5f91b0153125584107a36e60e4f234576 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 13 Jul 2023 15:34:44 +0600 Subject: [PATCH 082/794] added defined names conversion --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 36 ++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/DefinedNames.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index bfaaa6090d8..549742369b7 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -72,6 +72,33 @@ namespace OOX m_oRef = oReader.GetText3(); } + XLS::BaseObjectPtr CDefinedName::toBin() + { + auto ptr(new XLSB::Name); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->comment = m_oComment.get(); + + ptr->description = m_oDescription.get(); + ptr->fFunc = m_oFunction->GetValue(); + ptr->fGrp = m_oFunctionGroupId->GetValue(); + ptr->helpTopic = m_oHelp.get(); + ptr->fHidden = m_oHidden->GetValue(); + + if (m_oLocalSheetId.IsInit()) + ptr->itab = m_oLocalSheetId->GetValue(); + + ptr->name = m_oName.get(); + ptr->fPublished = m_oPublishToServer->GetValue(); + ptr->chKey = std::stoi(m_oShortcutKey.get()); + + ptr->fOB = m_oVbProcedure->GetValue(); + ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); + ptr->fFutureFunction = m_oXlm->GetValue(); + ptr->rgce = m_oRef.get(); + + return objectPtr; + } void CDefinedName::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -157,6 +184,15 @@ namespace OOX } } } + std::vector CDefinedNames::toBin() + { + std::vector objectVector; + + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + + return objectVector; + } void CDefinedNames::fromBin(std::vector& obj) { //ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.h b/OOXML/XlsxFormat/Workbook/DefinedNames.h index 971c6ebc969..4e5c3edc4a7 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.h +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.h @@ -60,6 +60,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -102,6 +103,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: From f6e6e2240175583f7b7ee61b09222e7a87594f99 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 13 Jul 2023 17:01:00 +0600 Subject: [PATCH 083/794] added sheets conversion --- OOXML/XlsxFormat/Workbook/Sheets.cpp | 25 +++++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/Sheets.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index bcb06ac25e8..7b64bb9a31d 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -69,6 +69,24 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CSheet::toBin() + { + auto ptr(new XLSB::BundleSh); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->strRelID.value = m_oRid->GetValue(); + ptr->strName = m_oName.get(); + ptr->iTabID = m_oSheetId->GetValue(); + + if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleVisible) + ptr->hsState = XLSB::BundleSh::ST_SheetState::VISIBLE; + else if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + ptr->hsState = XLSB::BundleSh::ST_SheetState::HIDDEN; + else if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + ptr->hsState = XLSB::BundleSh::ST_SheetState::VERYHIDDEN; + + return objectPtr; + } void CSheet::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -171,6 +189,13 @@ namespace OOX m_arrItems.push_back(new CSheet(sheet)); } } + std::vector CSheets::toBin() + { + std::vector objectVector; + for(auto i: m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CSheets::getType () const { return et_x_Sheets; diff --git a/OOXML/XlsxFormat/Workbook/Sheets.h b/OOXML/XlsxFormat/Workbook/Sheets.h index 7cee9f7af05..fc1956be6ad 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.h +++ b/OOXML/XlsxFormat/Workbook/Sheets.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: From 368fdbec18e90fc4e382b2f079df6ba0043af5e3 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 13 Jul 2023 18:30:38 +0600 Subject: [PATCH 084/794] added workbookPr conversion --- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 28 +++++++++++++++++++++++- OOXML/XlsxFormat/Workbook/WorkbookPr.h | 9 ++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 211dca4ff23..173df827db3 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -89,6 +89,32 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CWorkbookPr::toBin() + { + auto ptr(new XLSB::WbProp); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->fNoSaveSup = m_oAllowRefreshQuery->GetValue(); + ptr->fAutoCompressPictures = m_oAutoCompressPictures->GetValue(); + ptr->fBackup = m_oBackupFile->GetValue(); + ptr->fCheckCompat = m_oCheckCompatibility->GetValue(); + ptr->strName.value= m_oCodeName->GetValue(); + ptr->f1904 = m_oDate1904->GetValue(); + ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); + ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); + ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); + ptr->fHidePivotTableFList = m_oHidePivotFieldList->GetValue(); + ptr->fBuggedUserAboutSolution = m_oPromptedSolutions->GetValue(); + ptr->fPublishedBookItems = m_oPublishItems->GetValue(); + ptr->fRefreshAll = m_oRefreshAllConnections->GetValue(); + ptr->fHideBorderUnselLists = m_oShowBorderUnselectedTables->GetValue(); + ptr->fShowInkAnnotation = m_oShowInkAnnotation->GetValue(); + ptr->mdDspObj = m_oShowObjects->GetValue() ? 1 : 2; + ptr->fShowPivotChartFilter = m_oShowPivotChartFilter->GetValue(); + ptr->grbitUpdateLinks = m_oUpdateLinks->GetValue(); + + return objectPtr; + } void CWorkbookPr::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -247,7 +273,7 @@ namespace OOX { writer.WriteString(L"ToString()); WritingStringNullableAttrString(L"hashValue", m_oHashValue, m_oHashValue.get()); WritingStringNullableAttrString(L"saltValue", m_oSaltValue, m_oSaltValue.get()); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 86132084bda..1bdf9749b2c 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -56,7 +56,7 @@ namespace OOX public: WritingElement_AdditionMethods(CWorkbookPr) WritingElement_XlsbConstructors(CWorkbookPr) - + CWorkbookPr(); virtual ~CWorkbookPr(); @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -98,7 +99,7 @@ namespace OOX public: WritingElement_AdditionMethods(CWorkbookProtection) WritingElement_XlsbConstructors(CWorkbookProtection) - + CWorkbookProtection(); virtual ~CWorkbookProtection(); @@ -135,7 +136,7 @@ namespace OOX public: WritingElement_AdditionMethods(CFileSharing) WritingElement_XlsbConstructors(CFileSharing) - + CFileSharing(); virtual ~CFileSharing(); @@ -153,7 +154,7 @@ namespace OOX nullable_bool m_oReadOnlyRecommended; nullable_string m_oUserName; - + nullable m_oAlgorithmName; nullable m_oSpinCount; nullable_string m_oHashValue; From 23dee6d7eff9666e2613d8654c2d311b4e6d979f Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 13 Jul 2023 20:42:42 +0600 Subject: [PATCH 085/794] added workbook protection conversion --- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 58 ++++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/WorkbookPr.h | 1 + 2 files changed, 59 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 173df827db3..ab785456e6d 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -202,6 +202,64 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CWorkbookProtection::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oWorkbookAlgorithmName.IsInit() || m_oWorkbookSpinCount.IsInit() || m_oRevisionsAlgorithmName.IsInit() || + m_oRevisionsSpinCount.IsInit()) + { + auto ptr(new XLSB::BookProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); + + ptr->ipdBookPasswordData.szAlgName = m_oWorkbookAlgorithmName->GetValue(); + ptr->dwBookSpinCount = m_oWorkbookSpinCount->GetValue(); + + auto len = 0; + auto bytes = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oWorkbookHashValue.get().begin(), m_oWorkbookHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + ptr->ipdBookPasswordData.rgbHash.cbLength = len; + + + auto len1 = 0; + auto bytes1 = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData1 = {m_oWorkbookSaltValue.get().begin(), m_oWorkbookSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + ptr->ipdBookPasswordData.rgbSalt.cbLength = len1; + + ptr->ipdRevPasswordData.szAlgName = m_oRevisionsAlgorithmName->GetValue(); + ptr->dwRevSpinCount = m_oRevisionsSpinCount->GetValue(); + + auto len2 = 0; + auto bytes2 = ptr->ipdRevPasswordData.rgbHash.rgbData.data(); + std::string strData2 = {m_oRevisionsHashValue.get().begin(), m_oRevisionsHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData2.c_str(), strData2.size(), + bytes2, len2); + ptr->ipdRevPasswordData.rgbHash.cbLength = len2; + + auto len3 = 0; + auto bytes3 = ptr->ipdRevPasswordData.rgbSalt.rgbData.data(); + std::string strData3 = {m_oRevisionsSaltValue.get().begin(), m_oRevisionsSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData3.c_str(), strData3.size(), + bytes3, len3); + ptr->ipdRevPasswordData.rgbSalt.cbLength = len3; + } + else + { + auto ptr(new XLSB::BookProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); + } + return objectPtr; + } void CWorkbookProtection::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 1bdf9749b2c..0a2cd42fc81 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -110,6 +110,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From 5398d4598bdfdebf4fd1c0c3cdbf0d7a1935a4a0 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 14 Jul 2023 18:05:55 +0600 Subject: [PATCH 086/794] added external references conversion --- .../Workbook/ExternalReferences.cpp | 23 ++++++++++++++++++- .../XlsxFormat/Workbook/ExternalReferences.h | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp b/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp index 72452ca976d..106178cfba6 100644 --- a/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp +++ b/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp @@ -39,7 +39,7 @@ namespace OOX { namespace Spreadsheet - { + { CExternalReference::CExternalReference() { } @@ -66,6 +66,20 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CExternalReference::toBin() + { + auto ptr(new XLSB::SUP); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRid.IsInit()) + { + auto ptr1(new XLSB::SupBookSrc); + ptr->m_source = XLS::BaseObjectPtr{ptr1}; + ptr1->strRelID.value = m_oRid->GetValue(); + } + + return objectPtr; + } + void CExternalReference::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -154,6 +168,13 @@ namespace OOX m_arrItems.push_back(new CExternalReference(externalReference)); } } + std::vector CExternalReferences::toBin() + { + std::vector objectVector; + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CExternalReferences::getType () const { return et_x_ExternalReferences; diff --git a/OOXML/XlsxFormat/Workbook/ExternalReferences.h b/OOXML/XlsxFormat/Workbook/ExternalReferences.h index 557ef3a8763..55a4813638c 100644 --- a/OOXML/XlsxFormat/Workbook/ExternalReferences.h +++ b/OOXML/XlsxFormat/Workbook/ExternalReferences.h @@ -57,6 +57,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -83,6 +84,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; From 281d9abd8fc2049c2d4a0bf758f5d784ee761f2f Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 14 Jul 2023 18:49:04 +0600 Subject: [PATCH 087/794] added file sharing conversion --- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 40 ++++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/WorkbookPr.h | 1 + 2 files changed, 41 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index ab785456e6d..c113a44e7ed 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -346,6 +346,46 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CFileSharing::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oSpinCount.IsInit() || m_oAlgorithmName.IsInit() || m_oHashValue.IsInit()) + { + auto ptr(new XLSB::FileSharingIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + if (m_oReadOnlyRecommended.IsInit()) + ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); + ptr->stUserName = m_oUserName.get(); + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + ptr->dwSpinCount = m_oSpinCount->GetValue(); + + auto len = 0; + auto bytes = ptr->ipdPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oHashValue.get().begin(), m_oHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + ptr->ipdPasswordData.rgbHash.cbLength = len; + + auto len1 = 0; + auto bytes1 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + std::string strData1 = {m_oSaltValue.get().begin(), m_oSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + ptr->ipdPasswordData.rgbSalt.cbLength = len1; + + } + else + { + auto ptr(new XLSB::FileSharing); + objectPtr = XLS::BaseObjectPtr{ptr}; + if (m_oReadOnlyRecommended.IsInit()) + ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); + ptr->stUserName = m_oUserName.get(); + ptr->wResPass = m_oPassword.get(); + } + return objectPtr; + } void CFileSharing::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 0a2cd42fc81..38b07d58335 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -148,6 +148,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From 537e7aa9f5aa97032f2c0cc423de699213f4d2a7 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 14 Jul 2023 19:44:43 +0600 Subject: [PATCH 088/794] added drawing ext conversion of workbook --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 20 ++++++++++++++++++ OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 24 ++++++++++++++++++++++ OOXML/XlsxFormat/Slicer/SlicerCacheExt.h | 3 +++ 4 files changed, 48 insertions(+) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 163f8dc3433..1d7dbe83a8b 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -606,6 +606,26 @@ namespace OOX return sResult; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorkBook() + { + auto ptr(new XLSB::FRTWORKBOOK); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_arrExt.empty()) + return objectPtr; + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{46BE6895-7355-4a93-B00E-2C351335B9C9}") + { + ptr->m_TABLESLICERCACHEIDS = i->m_oSlicerCachesExt->toBin(); + } + else if(i->m_sUri == L"{BBE1A952-AA13-448e-AADC-164F8A28A991}") + { + ptr->m_SLICERCACHEIDS = i->m_oSlicerCaches->toBin(); + } + } + return objectPtr; + } XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorksheet() { auto ptr(new XLSB::FRTWORKSHEET); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 93d1cd95e48..3c28dc94c75 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -186,6 +186,7 @@ namespace OOX std::wstring toXMLWithNS(const std::wstring& sNamespace) const; void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBinWorksheet(); + XLS::BaseObjectPtr toBinWorkBook(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 9655bfca25a..247de917d86 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -493,6 +493,18 @@ void CSlicerStyleElement::ReadAttributes(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheID); + ptr->m_BrtBeginSlicerCacheID = XLS::BaseObjectPtr{ptr1}; + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + } + return objectPtr; +} void CSlicerCache::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -547,6 +559,7 @@ XLS::BaseObjectPtr CSlicerRef::toBin() auto ptr1(new XLSB::BeginSlicerEx); ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + return objectPtr; } void CSlicerRef::fromBin(XLS::BaseObjectPtr &obj) @@ -733,6 +746,17 @@ void CSlicerStyle::ReadAttributes(XLS::BaseObjectPtr &obj) m_oName = ptr->stName.value(); } +XLS::BaseObjectPtr CSlicerCaches::toBin() +{ + auto ptr(new XLSB::SLICERCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicerCache) + { + ptr->m_arSLICERCACHEID.push_back(i.toBin()); + } + return objectPtr; +} + void CSlicerCaches::fromBin(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index fa79a0c1c90..e48b5699444 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -181,6 +181,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -258,7 +259,9 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const{} virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName, const std::wstring& sPrefix) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType() const { From b792f98deac7bddb2d9e7157ceb5b351fee47e49 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 14 Jul 2023 19:45:12 +0600 Subject: [PATCH 089/794] added workbook conversion --- OOXML/XlsxFormat/Workbook/Workbook.cpp | 81 +++++++++++++++++++++++++- OOXML/XlsxFormat/Workbook/Workbook.h | 5 +- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 8c6c71b1b07..015217a2cca 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -51,7 +51,7 @@ namespace OOX { namespace Spreadsheet - { + { CWorkbookPivotCache::CWorkbookPivotCache() { } @@ -84,6 +84,18 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginPivotCacheID); } } + XLS::BaseObjectPtr CWorkbookPivotCache::toBin() + { + auto ptr(new XLSB::PIVOTCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPivotCacheID); + ptr->m_BrtBeginPivotCacheID = XLS::BaseObjectPtr{ptr1}; + + ptr1->idSx = m_oCacheId->GetValue(); + if(m_oRid.IsInit()) + ptr1->irstcacheRelID.value = m_oRid->GetValue(); + return objectPtr; + } EElementType CWorkbookPivotCache::getType() const { return et_x_WorkbookPivotCache; @@ -166,6 +178,16 @@ namespace OOX } } + XLS::BaseObjectPtr CWorkbookPivotCaches::toBin() + { + auto ptr(new XLSB::PIVOTCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + ptr->m_arPIVOTCACHEID.push_back(i->toBin()); + + return objectPtr; + } EElementType CWorkbookPivotCaches::getType() const { return et_x_WorkbookPivotCaches; @@ -238,7 +260,7 @@ namespace OOX if (workBookStream->m_FRTWORKBOOK != nullptr) m_oExtLst = workBookStream->m_FRTWORKBOOK; - + if (workBookStream->m_BrtFileSharingIso != nullptr) m_oFileSharing = workBookStream->m_BrtFileSharingIso; else if (workBookStream->m_BrtFileSharing != nullptr) @@ -249,6 +271,59 @@ namespace OOX } } + + XLS::BaseObjectPtr CWorkbook::WriteBin() + { + XLSB::WorkBookStreamPtr workBookStream(new XLSB::WorkBookStream); + + if (m_oBookViews.IsInit()) + { auto viewPtr(new XLSB::BOOKVIEWS); + workBookStream->m_BOOKVIEWS = XLS::BaseObjectPtr{viewPtr}; + + viewPtr->m_arBrtBookView = m_oBookViews->toBin(); + } + if (m_oCalcPr.IsInit()) + workBookStream->m_BrtCalcProp = m_oCalcPr->toBin(); + if (m_oDefinedNames.IsInit()) + { + workBookStream->m_arBrtName = m_oDefinedNames->toBin(); + } + if (m_oSheets.IsInit()) + { + auto ptr(new XLSB::BUNDLESHS); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_arBrtBundleSh = m_oSheets->toBin(); + workBookStream->m_BUNDLESHS = objectPtr; + } + if (m_oWorkbookPr.IsInit()) + workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); + if (m_oPivotCaches.IsInit()) + workBookStream->m_PIVOTCACHEIDS = m_oPivotCaches->toBin(); + + if (m_oWorkbookProtection.IsInit()) + workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); + + if (m_oExternalReferences.IsInit()) + { + auto ptr(new XLSB::EXTERNALS); + ptr->m_arSUP = m_oExternalReferences->toBin(); + workBookStream->m_EXTERNALS = XLS::BaseObjectPtr{ptr}; + } + if (m_oAppName.IsInit()) + { + auto ptr(new XLSB::FileVersion); + ptr->stAppName = m_oAppName.get(); + workBookStream->m_BrtFileVersion = XLS::BaseObjectPtr{ptr}; + } + + if (m_oExtLst.IsInit()) + workBookStream->m_FRTWORKBOOK = m_oExtLst->toBinWorkBook(); + + if (m_oFileSharing.IsInit()) + workBookStream->m_BrtFileSharing = m_oFileSharing->toBin(); + + return workBookStream; + } void CWorkbook::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -371,7 +446,7 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"appName", m_oAppName) WritingElement_ReadAttributes_End(oReader) - } + } else if (L"WindowHeight" == sName) { } diff --git a/OOXML/XlsxFormat/Workbook/Workbook.h b/OOXML/XlsxFormat/Workbook/Workbook.h index 59d4a11399a..433dbefb452 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -81,6 +81,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType() const; @@ -106,6 +107,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType() const; }; @@ -120,6 +122,7 @@ namespace OOX virtual ~CWorkbook(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin(); virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void fromXML(XmlUtils::CXmlNode& node); @@ -154,7 +157,7 @@ namespace OOX nullablem_oPivotCaches; nullable m_oPivotCachesXml; nullable m_oFileSharing; - + CPersonList* m_pPersonList; bool m_bMacroEnabled; }; From 781338fb1ec531b2e73320f8f4adb93cfa21af0b Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 14 Jul 2023 18:17:22 +0300 Subject: [PATCH 090/794] Sets Gid to 0 --- DocxRenderer/src/logic/elements/ContText.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 116f8356b93..093c4b1515e 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -95,6 +95,7 @@ namespace NSDocxRenderer double dBoxWidth; double dBoxHeight; + m_pManager->SetStringGid(0); m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); m_dWidthSelected = dBoxWidth; m_dSpaceWidthSelected = m_pManager->GetSpaceWidthMM(); From 03335551b68cf67e73c07595d85cd8481fca2da4 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 17 Jul 2023 10:35:47 +0300 Subject: [PATCH 091/794] Clear fonts cache & font streams on each convertaion --- DocxRenderer/DocxRenderer.cpp | 8 ++++++++ DocxRenderer/src/logic/managers/FontManager.cpp | 7 +++++++ DocxRenderer/src/logic/managers/FontManager.h | 2 ++ 3 files changed, 17 insertions(+) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 2f0836a8a0c..389438d74fa 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -87,6 +87,14 @@ HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociat int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) { + // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", + // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) + // может быть одной и той же. И создание там файлов функцией создания временных файлов + // может вернуть один и тот же путь. И шрифт возьмется из старого файла. + m_pInternal->m_oDocument.m_oFontManager.ClearCache(); + if (m_pInternal->m_oDocument.m_pAppFonts) + m_pInternal->m_oDocument.m_pAppFonts->GetStreams()->Clear(); + CreateNewFile(sDstFile, bIsOutCompress); if (odftPDF == pFile->GetType()) diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 06548155ed7..b9dcf786e0f 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -767,4 +767,11 @@ namespace NSDocxRenderer } } } + + void CFontManager::ClearCache() + { + if (nullptr == m_pManager) + return; + m_pManager->GetCache()->Clear(); + } } diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 682e5f74b02..628766f3750 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -146,6 +146,8 @@ namespace NSDocxRenderer double& dBoxWidth, double& dBoxHeight, MeasureType measureType) const; + + void ClearCache(); private: NSFonts::IFontManager* m_pManager; From a65183616fc349d08e5ec920973ea91383decc84 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 17 Jul 2023 10:40:12 +0300 Subject: [PATCH 092/794] Fix check files in test --- DocxRenderer/test/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 71f429f6f70..909ce379c25 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -107,6 +107,8 @@ int main(int argc, char *argv[]) for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++) { + // нужно скинуть тип, чтобы не определялся как OOXML всегда (см чеккер). + oChecker.nFileType = 0; if (oChecker.isOfficeFile(sSourceFiles[nIndex])) { nFileType = oChecker.nFileType; From 7118da40a265f50e050dd47368eb0d87edcd4df9 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 28 Jul 2023 11:36:33 +0300 Subject: [PATCH 093/794] Fix bug reload fonts --- DocxRenderer/src/logic/elements/ContText.cpp | 4 ++-- DocxRenderer/src/logic/managers/FontManager.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 093c4b1515e..c4392263aa8 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -525,12 +525,12 @@ namespace NSDocxRenderer double CContText::CalculateWideSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 2.5; + return m_dSpaceWidthMM * 3; } double CContText::CalculateThinSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.25; + return m_dSpaceWidthMM * 0.2; } } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index b9dcf786e0f..f72202de4a1 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -528,7 +528,7 @@ namespace NSDocxRenderer void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) { - if(m_oFont.Path == oFont.Path && m_oFont.FaceIndex == oFont.FaceIndex && m_oFont.Size == oFont.Size) + if(m_oFont.IsEqual2(&oFont)) return; m_oFont = oFont; @@ -545,7 +545,7 @@ namespace NSDocxRenderer } void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) { - if(m_oFont.Name == oFont.Name && m_oFont.Size == oFont.Size && m_oFont.GetStyle2() == oFont.GetStyle2()) + if(m_oFont.IsEqual2(&oFont)) return; m_oFont = oFont; From d358f2eb5f5701d507ae718eeff7c314a4e1bf08 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Wed, 2 Aug 2023 14:46:55 +0600 Subject: [PATCH 094/794] added conversion attributes check --- OOXML/XlsxFormat/Workbook/CalcPr.cpp | 39 ++- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 13 + OOXML/XlsxFormat/Workbook/Workbook.cpp | 3 +- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 96 ++++-- .../Worksheets/WorksheetChildOther.cpp | 303 +++++++++++++----- 5 files changed, 325 insertions(+), 129 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.cpp b/OOXML/XlsxFormat/Workbook/CalcPr.cpp index f63ac42d314..01c6c8cd80a 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.cpp +++ b/OOXML/XlsxFormat/Workbook/CalcPr.cpp @@ -87,19 +87,32 @@ namespace OOX auto ptr(new XLSB::CalcProp); XLS::BaseObjectPtr objectPtr(ptr); - ptr->recalcID = m_oCalcId->GetValue(); - ptr->fAutoRecalc = m_oCalcMode->GetValue(); - ptr->fFullCalcOnLoad = m_oFullCalcOnLoad->GetValue(); - ptr->fRefA1 = !m_oRefMode->GetValue(); - ptr->fIter = m_oIterate->GetValue(); - ptr->cCalcCount = m_oIterateCount->GetValue(); - ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); - ptr->fFullPrec = m_oFullPrecision->GetValue(); - ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); - ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); - ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); - ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); - ptr->fNoDeps = m_oForceFullCalc->GetValue(); + if(m_oCalcId.IsInit()) + ptr->recalcID = m_oCalcId->GetValue(); + if(m_oCalcMode.IsInit()) + ptr->fAutoRecalc = m_oCalcMode->GetValue(); + if(m_oFullCalcOnLoad.IsInit()) + ptr->fFullCalcOnLoad = m_oFullCalcOnLoad->GetValue(); + if(m_oRefMode.IsInit()) + ptr->fRefA1 = !m_oRefMode->GetValue(); + if(m_oIterate.IsInit()) + ptr->fIter = m_oIterate->GetValue(); + if(m_oIterateCount.IsInit()) + ptr->cCalcCount = m_oIterateCount->GetValue(); + if(m_oIterateDelta.IsInit()) + ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); + if(m_oFullPrecision.IsInit()) + ptr->fFullPrec = m_oFullPrecision->GetValue(); + if(m_oCalcCompleted.IsInit()) + ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); + if(m_oCalcOnSave.IsInit()) + ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); + if(m_oConcurrentCalc.IsInit()) + ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); + if(m_oConcurrentManualCount.IsInit()) + ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); + if(m_oForceFullCalc.IsInit()) + ptr->fNoDeps = m_oForceFullCalc->GetValue(); return objectPtr; } diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 549742369b7..123b50a4431 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -77,24 +77,37 @@ namespace OOX auto ptr(new XLSB::Name); XLS::BaseObjectPtr objectPtr(ptr); + if(m_oComment.IsInit()) ptr->comment = m_oComment.get(); + if(m_oDescription.IsInit()) ptr->description = m_oDescription.get(); + if(m_oFunction.IsInit()) ptr->fFunc = m_oFunction->GetValue(); + if(m_oFunctionGroupId.IsInit()) ptr->fGrp = m_oFunctionGroupId->GetValue(); + if(m_oHelp.IsInit()) ptr->helpTopic = m_oHelp.get(); + if(m_oHidden.IsInit()) ptr->fHidden = m_oHidden->GetValue(); if (m_oLocalSheetId.IsInit()) ptr->itab = m_oLocalSheetId->GetValue(); + if (m_oName.IsInit()) ptr->name = m_oName.get(); + if (m_oPublishToServer.IsInit()) ptr->fPublished = m_oPublishToServer->GetValue(); + if (m_oShortcutKey.IsInit()) ptr->chKey = std::stoi(m_oShortcutKey.get()); + if (m_oVbProcedure.IsInit()) ptr->fOB = m_oVbProcedure->GetValue(); + if (m_oWorkbookParameter.IsInit()) ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); + if (m_oXlm.IsInit()) ptr->fFutureFunction = m_oXlm->GetValue(); + if (m_oRef.IsInit()) ptr->rgce = m_oRef.get(); return objectPtr; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 015217a2cca..91c3cedf14c 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -91,7 +91,8 @@ namespace OOX auto ptr1(new XLSB::BeginPivotCacheID); ptr->m_BrtBeginPivotCacheID = XLS::BaseObjectPtr{ptr1}; - ptr1->idSx = m_oCacheId->GetValue(); + if(m_oCacheId.IsInit()) + ptr1->idSx = m_oCacheId->GetValue(); if(m_oRid.IsInit()) ptr1->irstcacheRelID.value = m_oRid->GetValue(); return objectPtr; diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index c113a44e7ed..b5c8a37e537 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -94,23 +94,43 @@ namespace OOX auto ptr(new XLSB::WbProp); XLS::BaseObjectPtr objectPtr(ptr); - ptr->fNoSaveSup = m_oAllowRefreshQuery->GetValue(); + if(m_oAllowRefreshQuery.IsInit()) + ptr->fNoSaveSup = m_oAllowRefreshQuery->GetValue(); + if(m_oAutoCompressPictures.IsInit()) ptr->fAutoCompressPictures = m_oAutoCompressPictures->GetValue(); + if(m_oBackupFile.IsInit()) ptr->fBackup = m_oBackupFile->GetValue(); + if(m_oCheckCompatibility.IsInit()) ptr->fCheckCompat = m_oCheckCompatibility->GetValue(); - ptr->strName.value= m_oCodeName->GetValue(); + if(m_oCodeName.IsInit()) + ptr->strName.value = m_oCodeName->GetValue(); + else + ptr->strName.value = false; + if(m_oDate1904.IsInit()) ptr->f1904 = m_oDate1904->GetValue(); + if(m_oDateCompatibility.IsInit()) ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); + if(m_oDefaultThemeVersion.IsInit()) ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); + if(m_oFilterPrivacy.IsInit()) ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); + if(m_oHidePivotFieldList.IsInit()) ptr->fHidePivotTableFList = m_oHidePivotFieldList->GetValue(); + if(m_oPromptedSolutions.IsInit()) ptr->fBuggedUserAboutSolution = m_oPromptedSolutions->GetValue(); + if(m_oPublishItems.IsInit()) ptr->fPublishedBookItems = m_oPublishItems->GetValue(); + if(m_oRefreshAllConnections.IsInit()) ptr->fRefreshAll = m_oRefreshAllConnections->GetValue(); + if(m_oShowBorderUnselectedTables.IsInit()) ptr->fHideBorderUnselLists = m_oShowBorderUnselectedTables->GetValue(); + if(m_oShowInkAnnotation.IsInit()) ptr->fShowInkAnnotation = m_oShowInkAnnotation->GetValue(); + if(m_oShowObjects.IsInit()) ptr->mdDspObj = m_oShowObjects->GetValue() ? 1 : 2; + if(m_oShowPivotChartFilter.IsInit()) ptr->fShowPivotChartFilter = m_oShowPivotChartFilter->GetValue(); + if(m_oUpdateLinks.IsInit()) ptr->grbitUpdateLinks = m_oUpdateLinks->GetValue(); return objectPtr; @@ -218,44 +238,58 @@ namespace OOX ptr->ipdBookPasswordData.szAlgName = m_oWorkbookAlgorithmName->GetValue(); ptr->dwBookSpinCount = m_oWorkbookSpinCount->GetValue(); - auto len = 0; - auto bytes = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); - std::string strData = {m_oWorkbookHashValue.get().begin(), m_oWorkbookHashValue.get().end()}; - NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), - bytes, len); - ptr->ipdBookPasswordData.rgbHash.cbLength = len; - - - auto len1 = 0; - auto bytes1 = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); - std::string strData1 = {m_oWorkbookSaltValue.get().begin(), m_oWorkbookSaltValue.get().end()}; - NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), - bytes1, len1); - ptr->ipdBookPasswordData.rgbSalt.cbLength = len1; - - ptr->ipdRevPasswordData.szAlgName = m_oRevisionsAlgorithmName->GetValue(); - ptr->dwRevSpinCount = m_oRevisionsSpinCount->GetValue(); + if(m_oWorkbookHashValue.IsInit()) + { + auto len = 0; + auto bytes = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oWorkbookHashValue.get().begin(), m_oWorkbookHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + ptr->ipdBookPasswordData.rgbHash.cbLength = len; + } - auto len2 = 0; - auto bytes2 = ptr->ipdRevPasswordData.rgbHash.rgbData.data(); - std::string strData2 = {m_oRevisionsHashValue.get().begin(), m_oRevisionsHashValue.get().end()}; - NSFile::CBase64Converter::Decode(strData2.c_str(), strData2.size(), - bytes2, len2); - ptr->ipdRevPasswordData.rgbHash.cbLength = len2; + if(m_oWorkbookSaltValue.IsInit()) + { + auto len1 = 0; + auto bytes1 = ptr->ipdBookPasswordData.rgbHash.rgbData.data(); + std::string strData1 = {m_oWorkbookSaltValue.get().begin(), m_oWorkbookSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + ptr->ipdBookPasswordData.rgbSalt.cbLength = len1; + } + if(m_oRevisionsAlgorithmName.IsInit()) + ptr->ipdRevPasswordData.szAlgName = m_oRevisionsAlgorithmName->GetValue(); + if(m_oRevisionsSpinCount.IsInit()) + ptr->dwRevSpinCount = m_oRevisionsSpinCount->GetValue(); - auto len3 = 0; - auto bytes3 = ptr->ipdRevPasswordData.rgbSalt.rgbData.data(); - std::string strData3 = {m_oRevisionsSaltValue.get().begin(), m_oRevisionsSaltValue.get().end()}; - NSFile::CBase64Converter::Decode(strData3.c_str(), strData3.size(), - bytes3, len3); - ptr->ipdRevPasswordData.rgbSalt.cbLength = len3; + if(m_oRevisionsHashValue.IsInit()) + { + auto len2 = 0; + auto bytes2 = ptr->ipdRevPasswordData.rgbHash.rgbData.data(); + std::string strData2 = {m_oRevisionsHashValue.get().begin(), m_oRevisionsHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData2.c_str(), strData2.size(), + bytes2, len2); + ptr->ipdRevPasswordData.rgbHash.cbLength = len2; + } + if(m_oRevisionsSaltValue.IsInit()) + { + auto len3 = 0; + auto bytes3 = ptr->ipdRevPasswordData.rgbSalt.rgbData.data(); + std::string strData3 = {m_oRevisionsSaltValue.get().begin(), m_oRevisionsSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData3.c_str(), strData3.size(), + bytes3, len3); + ptr->ipdRevPasswordData.rgbSalt.cbLength = len3; + } } else { auto ptr(new XLSB::BookProtection); objectPtr = XLS::BaseObjectPtr{ptr}; + if(m_oLockRevision.IsInit()) ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + if(m_oLockStructure.IsInit()) ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + if(m_oLockWindows.IsInit()) ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); } return objectPtr; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 3fdf81143b3..d45534798ed 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -563,7 +563,7 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); if(m_oBlackAndWhite.IsInit()) ptr->fNoColor = m_oBlackAndWhite->m_eValue; - if (ptr->fNoColor) + if (ptr->fNoColor && m_oCellComments.IsInit()) { if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) ptr->fNotes = true; @@ -571,14 +571,29 @@ namespace OOX ptr->fNotes = false; } - ptr->iCopies = m_oCopies->m_eValue; - ptr->fDraft = m_oDraft->m_eValue; - ptr->iErrors = m_oErrors->m_eValue; - ptr->iPageStart = m_oFirstPageNumber->m_eValue; - ptr->iFitHeight = m_oFitToHeight->m_eValue; - ptr->iFitWidth = m_oFitToWidth->m_eValue; - ptr->iRes = m_oHorizontalDpi->m_eValue; - ptr->szRelID = m_oRId->GetValue(); + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; + + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; + + if (m_oErrors.IsInit()) + ptr->iErrors = m_oErrors->m_eValue; + + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + + if (m_oFitToHeight.IsInit()) + ptr->iFitHeight = m_oFitToHeight->m_eValue; + + if (m_oFitToWidth.IsInit()) + ptr->iFitWidth = m_oFitToWidth->m_eValue; + + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; + + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) ptr->fLandscape = true; @@ -590,10 +605,17 @@ namespace OOX else ptr->fLeftToRight = false; - ptr->iPaperSize = m_oPaperSize->m_eValue; - ptr->iScale = m_oScale->m_eValue; - ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; - ptr->iVRes = m_oVerticalDpi->m_eValue; + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; + + if (m_oScale.IsInit()) + ptr->iScale = m_oScale->m_eValue; + + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; return objectPtr; } @@ -612,20 +634,37 @@ namespace OOX ptr->fNotes = false; } - ptr->iCopies = m_oCopies->m_eValue; - ptr->fDraft = m_oDraft->m_eValue; - ptr->iPageStart = m_oFirstPageNumber->m_eValue; - ptr->iRes = m_oHorizontalDpi->m_eValue; - ptr->szRelID = m_oRId->GetValue(); + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; - if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) - ptr->fLandscape = true; - else - ptr->fLandscape = false; + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; + + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; + + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); - ptr->iPaperSize = m_oPaperSize->m_eValue; - ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; - ptr->iVRes = m_oVerticalDpi->m_eValue; + if (m_oOrientation.IsInit()) + { + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; + } + + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; + + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; return objectPtr; } } @@ -1215,33 +1254,55 @@ namespace OOX { auto pWsView(new XLSB::BeginWsView); XLS::BaseObjectPtr castedPtr(pWsView); - pWsView->icvHdr = m_oColorId->m_eValue; - pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; - pWsView->fRightToLeft = m_oRightToLeft->m_eValue; - pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; - pWsView->fDspGridRt = m_oShowGridLines->m_eValue; - pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; - pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; - pWsView->fDspRuler = m_oShowRuler->m_eValue; - pWsView->fWhitespaceHidden = m_oShowWhiteSpace->m_eValue; - pWsView->fDspZerosRt = m_oShowZeros->m_eValue; - pWsView->fSelected = m_oTabSelected->m_eValue; - pWsView->topLeftCell = m_oTopLeftCell.get(); - pWsView->xlView = m_oView->m_eValue; - pWsView->fWnProt = m_oWindowProtection->m_eValue; - pWsView->iWbkView = m_oWorkbookViewId->m_eValue; - pWsView->wScale = m_oZoomScale->m_eValue; - pWsView->wScaleNormal = m_oZoomScaleNormal->m_eValue; - pWsView->wScalePLV = m_oZoomScalePageLayoutView->m_eValue; - pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; + if (m_oColorId.IsInit()) + pWsView->icvHdr = m_oColorId->m_eValue; + if (m_oDefaultGridColor.IsInit()) + pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; + if (m_oRightToLeft.IsInit()) + pWsView->fRightToLeft = m_oRightToLeft->m_eValue; + if (m_oShowFormulas.IsInit()) + pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; + if (m_oShowGridLines.IsInit()) + pWsView->fDspGridRt = m_oShowGridLines->m_eValue; + if (m_oShowOutlineSymbols.IsInit()) + pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; + if (m_oShowRowColHeaders.IsInit()) + pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; + if (m_oShowRuler.IsInit()) + pWsView->fDspRuler = m_oShowRuler->m_eValue; + if (m_oShowWhiteSpace.IsInit()) + pWsView->fWhitespaceHidden = m_oShowWhiteSpace->m_eValue; + if (m_oShowZeros.IsInit()) + pWsView->fDspZerosRt = m_oShowZeros->m_eValue; + if (m_oTabSelected.IsInit()) + pWsView->fSelected = m_oTabSelected->m_eValue; + if(m_oTopLeftCell.IsInit()) + pWsView->topLeftCell = m_oTopLeftCell.get(); + if (m_oView.IsInit()) + pWsView->xlView = m_oView->m_eValue; + if (m_oWindowProtection.IsInit()) + pWsView->fWnProt = m_oWindowProtection->m_eValue; + if (m_oWorkbookViewId.IsInit()) + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + if (m_oZoomScale.IsInit()) + pWsView->wScale = m_oZoomScale->m_eValue; + if (m_oZoomScaleNormal.IsInit()) + pWsView->wScaleNormal = m_oZoomScaleNormal->m_eValue; + if (m_oZoomScalePageLayoutView.IsInit()) + pWsView->wScalePLV = m_oZoomScalePageLayoutView->m_eValue; + if (m_oZoomScaleSheetLayoutView.IsInit()) + pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; return castedPtr; } else { auto pWsView(new XLSB::BeginCsView); XLS::BaseObjectPtr castedPtr(pWsView); + if(m_oTabSelected.IsInit()) pWsView->fSelected = m_oTabSelected->m_eValue; + if(m_oWorkbookViewId.IsInit()) pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + if(m_oZoomScale.IsInit()) pWsView->wScale = m_oZoomScale->m_eValue; return castedPtr; } @@ -1852,9 +1913,13 @@ namespace OOX auto castedBegin(new XLSB::BeginHeaderFooter); ptr->m_BrtBeginHeaderFooter = XLS::BaseObjectPtr{castedBegin}; + if(m_oAlignWithMargins.IsInit()) castedBegin->fHFAlignMargins = m_oAlignWithMargins->m_eValue; + if(m_oDifferentFirst.IsInit()) castedBegin->fHFDiffFirst = m_oDifferentFirst->m_eValue; + if(m_oDifferentOddEven.IsInit()) castedBegin->fHFDiffOddEven = m_oDifferentOddEven->m_eValue; + if(m_oScaleWithDoc.IsInit()) castedBegin->fHFScaleWithDoc = m_oScaleWithDoc->m_eValue; if(m_oOddHeader.IsInit()) @@ -2339,24 +2404,56 @@ namespace OOX auto ptr(new XLSB::SheetProtection); XLS::BaseObjectPtr castedPtr(ptr); - ptr->protpwd = std::stoul(m_oPassword.get()); - ptr->fAutoFilter = m_oAutoFilter->GetValue(); + if (m_oPassword.IsInit()) + ptr->protpwd = std::stoul(m_oPassword.get()); + + if (m_oAutoFilter.IsInit()) + ptr->fAutoFilter = m_oAutoFilter->GetValue(); + + if (m_oDeleteColumns.IsInit()) + ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + + if (m_oDeleteRows.IsInit()) + ptr->fDeleteRows = m_oDeleteRows->GetValue(); + + if (m_oFormatCells.IsInit()) + ptr->fFormatCells = m_oFormatCells->GetValue(); + + if (m_oFormatColumns.IsInit()) + ptr->fFormatColumns = m_oFormatColumns->GetValue(); + + if (m_oFormatRows.IsInit()) + ptr->fFormatRows = m_oFormatRows->GetValue(); + + if (m_oInsertColumns.IsInit()) + ptr->fInsertColumns = m_oInsertColumns->GetValue(); + + if (m_oInsertHyperlinks.IsInit()) + ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); - ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); - ptr->fDeleteRows = m_oDeleteRows->GetValue(); - ptr->fFormatCells = m_oFormatCells->GetValue(); - ptr->fFormatColumns = m_oFormatColumns->GetValue(); - ptr->fFormatRows = m_oFormatRows->GetValue(); - ptr->fInsertColumns = m_oInsertColumns->GetValue(); - ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); - ptr->fInsertRows = m_oInsertRows->GetValue(); - ptr->fObjects = m_oObjects->GetValue(); - ptr->fPivotTables = m_oPivotTables->GetValue(); - ptr->fScenarios = m_oScenarios->GetValue(); - ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); - ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); - ptr->fLocked = m_oSheet->GetValue(); - ptr->fSort = m_oSort->GetValue(); + if (m_oInsertRows.IsInit()) + ptr->fInsertRows = m_oInsertRows->GetValue(); + + if (m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + + if (m_oPivotTables.IsInit()) + ptr->fPivotTables = m_oPivotTables->GetValue(); + + if (m_oScenarios.IsInit()) + ptr->fScenarios = m_oScenarios->GetValue(); + + if (m_oSelectLockedCells.IsInit()) + ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + + if (m_oSelectUnlockedCells.IsInit()) + ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + + if (m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + + if (m_oSort.IsInit()) + ptr->fSort = m_oSort->GetValue(); return castedPtr; } @@ -2364,38 +2461,76 @@ namespace OOX { auto ptr(new XLSB::SheetProtectionIso); XLS::BaseObjectPtr castedPtr(ptr); - - ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); - ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oHashValue.IsInit()) + { byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); auto tempSize = 0; NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + } - byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); - auto tempSize2 = 0; - NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), - m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); - ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + if(m_oSaltValue.IsInit()) + { + byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + if(m_oAutoFilter.IsInit()) ptr->fAutoFilter = m_oAutoFilter->GetValue(); - ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); - ptr->fDeleteRows = m_oDeleteRows->GetValue(); - ptr->fFormatCells = m_oFormatCells->GetValue(); - ptr->fFormatColumns = m_oFormatColumns->GetValue(); - ptr->fFormatRows = m_oFormatRows->GetValue(); - ptr->fInsertColumns = m_oInsertColumns->GetValue(); - ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); - ptr->fInsertRows = m_oInsertRows->GetValue(); - ptr->fObjects = m_oObjects->GetValue(); - ptr->fPivotTables = m_oPivotTables->GetValue(); - ptr->fScenarios = m_oScenarios->GetValue(); - ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); - ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); - ptr->fLocked = m_oSheet->GetValue(); - ptr->fSort = m_oSort->GetValue(); + if (m_oDeleteColumns.IsInit()) + ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + + if (m_oDeleteRows.IsInit()) + ptr->fDeleteRows = m_oDeleteRows->GetValue(); + + if (m_oFormatCells.IsInit()) + ptr->fFormatCells = m_oFormatCells->GetValue(); + + if (m_oFormatColumns.IsInit()) + ptr->fFormatColumns = m_oFormatColumns->GetValue(); + + if (m_oFormatRows.IsInit()) + ptr->fFormatRows = m_oFormatRows->GetValue(); + + if (m_oInsertColumns.IsInit()) + ptr->fInsertColumns = m_oInsertColumns->GetValue(); + + if (m_oInsertHyperlinks.IsInit()) + ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + + if (m_oInsertRows.IsInit()) + ptr->fInsertRows = m_oInsertRows->GetValue(); + + if (m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + + if (m_oPivotTables.IsInit()) + ptr->fPivotTables = m_oPivotTables->GetValue(); + + if (m_oScenarios.IsInit()) + ptr->fScenarios = m_oScenarios->GetValue(); + + if (m_oSelectLockedCells.IsInit()) + ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + + if (m_oSelectUnlockedCells.IsInit()) + ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + + if (m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + + if (m_oSort.IsInit()) + ptr->fSort = m_oSort->GetValue(); + return castedPtr; } } From 6a26c7881630b91807bda067a1daf9be24d04f08 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 3 Aug 2023 15:12:20 +0300 Subject: [PATCH 095/794] . --- OOXML/XlsxFormat/Styles/rPr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index 3596e3de2a1..c88feb4b4fa 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -33,7 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" -#include "../../XlsbFormat/Biff12_records/Color.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/Color.h" namespace NSBinPptxRW { From 65675e2c54a0c85f341cc1343429470a13a0aa69 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 4 Aug 2023 11:52:15 +0300 Subject: [PATCH 096/794] . --- OOXML/SystemUtility/SystemUtility.cpp | 17 +++++++++++-- OOXML/SystemUtility/SystemUtility.h | 3 ++- OOXML/XlsbFormat/Xlsb.cpp | 15 ++++++++++- OOXML/XlsbFormat/Xlsb.h | 12 ++++++--- OOXML/XlsxFormat/Workbook/Workbook.cpp | 35 ++++++++++++++++++++------ OOXML/XlsxFormat/Workbook/Workbook.h | 2 +- X2tConverter/src/ASCConverters.cpp | 9 ++++--- 7 files changed, 72 insertions(+), 21 deletions(-) diff --git a/OOXML/SystemUtility/SystemUtility.cpp b/OOXML/SystemUtility/SystemUtility.cpp index 03280da835c..a95f833b2fc 100644 --- a/OOXML/SystemUtility/SystemUtility.cpp +++ b/OOXML/SystemUtility/SystemUtility.cpp @@ -242,8 +242,8 @@ namespace OOX } std::wstring CPath::GetExtention(bool bIsPoint) const { - int nFind = (int)m_strFilename.rfind('.'); - if (-1 == nFind) + size_t nFind = m_strFilename.rfind('.'); + if (std::wstring::npos == nFind) return L""; if (!bIsPoint) @@ -251,6 +251,19 @@ namespace OOX return m_strFilename.substr(nFind); } + void CPath::SetExtention(const std::wstring& ext) + { + size_t nFind = m_strFilename.rfind('.'); + if (std::wstring::npos == nFind) + { + m_strFilename += L"." + ext; + } + else + { + m_strFilename = m_strFilename.substr(nFind + 1) + ext; + } + + } std::wstring CPath::GetDirectory(bool bIsSlash) const { int nPos = (int)m_strFilename.rfind(FILE_SEPARATOR_CHAR); diff --git a/OOXML/SystemUtility/SystemUtility.h b/OOXML/SystemUtility/SystemUtility.h index 279e113a4c0..ad13efc14aa 100644 --- a/OOXML/SystemUtility/SystemUtility.h +++ b/OOXML/SystemUtility/SystemUtility.h @@ -42,7 +42,6 @@ namespace OOX //флаг введен, чтобы отличать относительные и абсолютные пути в rels bool m_bIsRoot; - public: CPath(); CPath(const std::wstring& sName, bool bIsNorm = true); CPath(const char*& sName, bool bIsNorm = true); @@ -70,6 +69,8 @@ namespace OOX std::wstring GetPath() const; std::wstring GetFilename() const; + void SetExtention(const std::wstring & ext); + void Normalize(); void SetName(std::wstring sName, bool bNormalize); diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 32a2ae4c924..442a9dcdef1 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -30,6 +30,8 @@ * */ #include "Xlsb.h" +#include "../DocxFormat/App.h" +#include "../DocxFormat/Core.h" #include "../XlsxFormat/Workbook/Workbook.h" #include "../XlsxFormat/SharedStrings/SharedStrings.h" @@ -93,7 +95,17 @@ bool OOX::Spreadsheet::CXlsb::ReadBin(const CPath& oFilePath, XLS::BaseObject* o return true; } +bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oDirPath, OOX::CContentTypes& oContentTypes) +{ + if (NULL == m_pWorkbook) + return false; + + m_bWriteToXlsb = true; + IFileContainer::Write(oDirPath / L"", OOX::CPath(_T("")), oContentTypes); + oContentTypes.Write(oDirPath); + return true; +} bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* objStream) { if (m_binaryWriter->CreateFileW(oFilePath.GetPath()) == false) @@ -102,7 +114,8 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* XLS::StreamCacheWriterPtr writer(new XLS::BinaryStreamCacheWriter(m_binaryWriter, xls_global_info)); XLS::BinWriterProcessor proc(writer, objStream); proc.mandatory(*objStream); - m_binaryWriter->WriteFile(m_binaryWriter->GetBuffer(), (static_cast(m_binaryWriter.get()))->GetPosition()); + + m_binaryWriter->WriteFile(m_binaryWriter->GetBuffer(), (static_cast(m_binaryWriter.get()))->GetPosition()); m_binaryWriter->CloseFile(); return true; diff --git a/OOXML/XlsbFormat/Xlsb.h b/OOXML/XlsbFormat/Xlsb.h index 0757d40c05e..065dc60d28b 100644 --- a/OOXML/XlsbFormat/Xlsb.h +++ b/OOXML/XlsbFormat/Xlsb.h @@ -60,9 +60,12 @@ namespace OOX init(); } ~CXlsb(); - + bool ReadBin(const CPath& oFilePath, XLS::BaseObject* objStream); bool WriteBin(const CPath& oFilePath, XLS::BaseObject* objStream); + + bool WriteBin(const CPath& oDirPath, OOX::CContentTypes& oContentTypes); + XLS::GlobalWorkbookInfo* GetGlobalinfo(); void PrepareSi(); void PrepareTableFormula(); @@ -72,8 +75,10 @@ namespace OOX bool IsWriteToXlsx(); void WriteToXlsx(bool isXlsx); - + std::unordered_map m_mapSheetNameSheetData; + + bool m_bWriteToXlsb = false; private: void init(); @@ -85,8 +90,7 @@ namespace OOX std::wstring m_sPath; OOX::CContentTypes m_oContentTypes; - bool m_bWriteToXlsx; - + bool m_bWriteToXlsx = false; }; } //Spreadsheet diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 91c3cedf14c..077845f7fd6 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -32,6 +32,7 @@ #pragma once #include "Workbook.h" +#include "../../XlsbFormat/Xlsb.h" #include "../../XlsbFormat/WorkBookStream.h" @@ -273,7 +274,7 @@ namespace OOX } } - XLS::BaseObjectPtr CWorkbook::WriteBin() + XLS::BaseObjectPtr CWorkbook::WriteBin() const { XLSB::WorkBookStreamPtr workBookStream(new XLSB::WorkBookStream); @@ -464,15 +465,23 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> } void CWorkbook::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - toXML(sXml); + sXml.WriteString(L""); - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); + toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); IFileContainer::Write(oPath, oDirectory, oContent); } @@ -487,7 +496,17 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> } const CPath CWorkbook::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } EElementType CWorkbook::getType () const { diff --git a/OOXML/XlsxFormat/Workbook/Workbook.h b/OOXML/XlsxFormat/Workbook/Workbook.h index 433dbefb452..a3b31d97db8 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -122,7 +122,7 @@ namespace OOX virtual ~CWorkbook(); void readBin(const CPath& oPath); - XLS::BaseObjectPtr WriteBin(); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void fromXML(XmlUtils::CXmlNode& node); diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 58633b4a778..63c1d555aee 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1155,11 +1155,12 @@ namespace NExtractTools //--------------------------------------------------------------------- const OOX::CPath oox_path(sFrom); - OOX::Spreadsheet::CXlsx xlsx(oox_path); - OOX::Spreadsheet::CXlsb xlsb; + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.Read(oox_path); + + OOX::CContentTypes oContentTypes; + nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - //XLS::BaseObjectPtr object = xlsx.toBin(); - //xlsb.WriteBin(sTempUnpackedXLSB, object.get()); //--------------------------------------------------------------------- if (SUCCEEDED_X2T(nRes)) { From dc95b8a92c29bdc4db12f148b621f662aa839294 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 4 Aug 2023 12:04:07 +0300 Subject: [PATCH 097/794] . --- OOXML/SystemUtility/SystemUtility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/SystemUtility/SystemUtility.cpp b/OOXML/SystemUtility/SystemUtility.cpp index a95f833b2fc..ac6d93af756 100644 --- a/OOXML/SystemUtility/SystemUtility.cpp +++ b/OOXML/SystemUtility/SystemUtility.cpp @@ -260,7 +260,7 @@ namespace OOX } else { - m_strFilename = m_strFilename.substr(nFind + 1) + ext; + m_strFilename = m_strFilename.substr(0, nFind + 1) + ext; } } From eef5b9b9cc7b29d2386abddd70caed6521157e34 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 4 Aug 2023 12:08:47 +0300 Subject: [PATCH 098/794] . --- X2tConverter/src/ASCConverters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 63c1d555aee..e4996a4d3e7 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1159,7 +1159,7 @@ namespace NExtractTools oXlsb.Read(oox_path); OOX::CContentTypes oContentTypes; - nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + nRes = oXlsb.WriteBin(sTempUnpackedXLSB, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; //--------------------------------------------------------------------- if (SUCCEEDED_X2T(nRes)) From 9cfb0ee82ad5296231b41c16432683d73f44e68a Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 4 Aug 2023 20:59:20 +0600 Subject: [PATCH 099/794] addede worksheet writing --- OOXML/SystemUtility/SystemUtility.cpp | 2 +- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 91 ++++++++++++++--------- OOXML/XlsxFormat/Worksheets/Worksheet.h | 2 +- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/OOXML/SystemUtility/SystemUtility.cpp b/OOXML/SystemUtility/SystemUtility.cpp index a95f833b2fc..cab07df2268 100644 --- a/OOXML/SystemUtility/SystemUtility.cpp +++ b/OOXML/SystemUtility/SystemUtility.cpp @@ -260,7 +260,7 @@ namespace OOX } else { - m_strFilename = m_strFilename.substr(nFind + 1) + ext; + m_strFilename = m_strFilename.substr(0, nFind + 1 ) + ext; } } diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index fd68ac31100..edffbe2b46f 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -229,7 +229,7 @@ namespace OOX } } - XLS::BaseObjectPtr CWorksheet::writeBin() + XLS::BaseObjectPtr CWorksheet::WriteBin() const { if(m_bIsChartSheet) { @@ -255,6 +255,9 @@ namespace OOX if (m_oMergeCells.IsInit()) workSheetStream->m_MERGECELLS = m_oMergeCells->toBin(); + if ( m_oSheetData.IsInit()) + workSheetStream->m_CELLTABLE = m_oSheetData->toBin(); + if (m_oSheetFormatPr.IsInit()) workSheetStream->m_BrtWsFmtInfo = m_oSheetFormatPr->toBin(); if (m_oSheetViews.IsInit()) @@ -674,52 +677,61 @@ namespace OOX if (bIsWritten) return; bIsWritten = true; + if (!m_bWriteDirectlyToFile) { - NSStringUtils::CStringBuilder sXml; + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - toXMLStart(sXml); - toXML(sXml); - toXMLEnd(sXml); + toXMLStart(sXml); + toXML(sXml); + toXMLEnd(sXml); - //NSFile::CFileBinary::SaveToFile(oPath.GetPath(), sXml.GetData()); - //for memory optimization for large files + //NSFile::CFileBinary::SaveToFile(oPath.GetPath(), sXml.GetData()); + //for memory optimization for large files - wchar_t* pXmlData = sXml.GetBuffer(); - LONG lwcharLen = (LONG)sXml.GetCurSize(); - const LONG lcurrentLen = 10485760; //10 Mbyte - LONG nCycles = lwcharLen / lcurrentLen; + wchar_t* pXmlData = sXml.GetBuffer(); + LONG lwcharLen = (LONG)sXml.GetCurSize(); + const LONG lcurrentLen = 10485760; //10 Mbyte + LONG nCycles = lwcharLen / lcurrentLen; - LONG lLen = 0; - BYTE* pData = NULL; - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); + LONG lLen = 0; + BYTE* pData = NULL; + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); - while(nCycles--) - { - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lcurrentLen, pData, lLen); + while(nCycles--) + { + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lcurrentLen, pData, lLen); - oFile.WriteFile(pData, lLen); + oFile.WriteFile(pData, lLen); - pXmlData += lcurrentLen; + pXmlData += lcurrentLen; - RELEASEARRAYOBJECTS(pData); - } + RELEASEARRAYOBJECTS(pData); + } - if(lwcharLen % lcurrentLen > 0) - { - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lwcharLen % lcurrentLen, pData, lLen); + if(lwcharLen % lcurrentLen > 0) + { + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pXmlData, lwcharLen % lcurrentLen, pData, lLen); - oFile.WriteFile(pData, lLen); + oFile.WriteFile(pData, lLen); - RELEASEARRAYOBJECTS(pData); - } - - oFile.CloseFile(); + RELEASEARRAYOBJECTS(pData); + } - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); - } + oFile.CloseFile(); + } + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } else { CPath oRealPath(oPath.GetDirectory() + FILE_SEPARATOR_STR + m_sOutputFilename); @@ -819,7 +831,18 @@ mc:Ignorable=\"x14ac\">"); } const CPath CWorksheet::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CWorksheet::GetReadPath() const { diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.h b/OOXML/XlsxFormat/Worksheets/Worksheet.h index e472137843d..38a3ed1f65c 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.h +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.h @@ -76,7 +76,7 @@ namespace OOX virtual ~CWorksheet(); void readBin(const CPath& oPath); - XLS::BaseObjectPtr writeBin(); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); From 3f75431018f966d6c0311e17f1029b812edb5b55 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 4 Aug 2023 21:49:02 +0600 Subject: [PATCH 100/794] started sheet data conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 242 ++++++++++++++++------ OOXML/XlsxFormat/Worksheets/SheetData.h | 13 +- 2 files changed, 187 insertions(+), 68 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 0fe3b4d841a..e533ec0d150 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -73,23 +73,23 @@ namespace OOX { namespace Spreadsheet { - static const wchar_t* m_aLetters[] = - { - L"A", L"B", L"C", L"D", L"E", L"F", L"G", L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", L"X", L"Y", L"Z", L"AA", L"AB", L"AC", L"AD", L"AE", L"AF", L"AG", L"AH", L"AI", L"AJ", L"AK", L"AL", L"AM", L"AN", L"AO", L"AP", L"AQ", L"AR", L"AS", L"AT", L"AU", L"AV", L"AW", L"AX", L"AY", L"AZ", L"BA", L"BB", L"BC", L"BD", L"BE", L"BF", L"BG", L"BH", L"BI", L"BJ", L"BK", L"BL", L"BM", L"BN", L"BO", L"BP", L"BQ", L"BR", L"BS", L"BT", L"BU", L"BV", L"BW", L"BX", L"BY", L"BZ", L"CA", L"CB", L"CC", L"CD", L"CE", L"CF", L"CG", L"CH", L"CI", L"CJ", L"CK", L"CL", L"CM", L"CN", L"CO", L"CP", L"CQ", L"CR", L"CS", L"CT", L"CU", L"CV", L"CW", L"CX", L"CY", L"CZ", L"DA", L"DB", L"DC", L"DD", L"DE", L"DF", L"DG", L"DH", L"DI", L"DJ", L"DK", L"DL", L"DM", L"DN", L"DO", L"DP", L"DQ", L"DR", L"DS", L"DT", L"DU", L"DV", L"DW", L"DX", L"DY", L"DZ", L"EA", L"EB", L"EC", L"ED", L"EE", L"EF", L"EG", L"EH", L"EI", L"EJ", L"EK", L"EL", L"EM", L"EN", L"EO", L"EP", L"EQ", L"ER", L"ES", L"ET", L"EU", L"EV", L"EW", L"EX", L"EY", L"EZ", L"FA", L"FB", L"FC", L"FD", L"FE", L"FF", L"FG", L"FH", L"FI", L"FJ", L"FK", L"FL", L"FM", L"FN", L"FO", L"FP", L"FQ", L"FR", L"FS", L"FT", L"FU", L"FV", L"FW", L"FX", L"FY", L"FZ", L"GA", L"GB", L"GC", L"GD", L"GE", L"GF", L"GG", L"GH", L"GI", L"GJ", L"GK", L"GL", L"GM", L"GN", L"GO", L"GP", L"GQ", L"GR", L"GS", L"GT", L"GU", L"GV", L"GW", L"GX", L"GY", L"GZ", L"HA", L"HB", L"HC", L"HD", L"HE", L"HF", L"HG", L"HH", L"HI", L"HJ", L"HK", L"HL", L"HM", L"HN", L"HO", L"HP", L"HQ", L"HR", L"HS", L"HT", L"HU", L"HV", L"HW", L"HX", L"HY", L"HZ", L"IA", L"IB", L"IC", L"ID", L"IE", L"IF", L"IG", L"IH", L"II", L"IJ", L"IK", L"IL", L"IM", L"IN", L"IO", L"IP", L"IQ", L"IR", L"IS", L"IT", L"IU", L"IV", L"IW", L"IX", L"IY", L"IZ", L"JA", L"JB", L"JC", L"JD", L"JE", L"JF", L"JG", L"JH", L"JI", L"JJ", L"JK", L"JL", L"JM", L"JN", L"JO", L"JP", L"JQ", L"JR", L"JS", L"JT", L"JU", L"JV", L"JW", L"JX", L"JY", L"JZ", L"KA", L"KB", L"KC", L"KD", L"KE", L"KF", L"KG", L"KH", L"KI", L"KJ", L"KK", L"KL", L"KM", L"KN", L"KO", L"KP", L"KQ", L"KR", L"KS", L"KT", L"KU", L"KV", L"KW", L"KX", L"KY", L"KZ", L"LA", L"LB", L"LC", L"LD", L"LE", L"LF", L"LG", L"LH", L"LI", L"LJ", L"LK", L"LL", L"LM", L"LN", L"LO", L"LP", L"LQ", L"LR", L"LS", L"LT", L"LU", L"LV", L"LW", L"LX", L"LY", L"LZ", L"MA", L"MB", L"MC", L"MD", L"ME", L"MF", L"MG", L"MH", L"MI", L"MJ", L"MK", L"ML", L"MM", L"MN", L"MO", L"MP", L"MQ", L"MR", L"MS", L"MT", L"MU", L"MV", L"MW", L"MX", L"MY", L"MZ", L"NA", L"NB", L"NC", L"ND", L"NE", L"NF", L"NG", L"NH", L"NI", L"NJ", L"NK", L"NL", L"NM", L"NN", L"NO", L"NP", L"NQ", L"NR", L"NS", L"NT", L"NU", L"NV", L"NW", L"NX", L"NY", L"NZ", L"OA", L"OB", L"OC", L"OD", L"OE", L"OF", L"OG", L"OH", L"OI", L"OJ", L"OK", L"OL", L"OM", L"ON", L"OO", L"OP", L"OQ", L"OR", L"OS", L"OT", L"OU", L"OV", L"OW", L"OX", L"OY", L"OZ", L"PA", L"PB", L"PC", L"PD", L"PE", L"PF", L"PG", L"PH", L"PI", L"PJ", L"PK", L"PL", L"PM", L"PN", L"PO", L"PP", L"PQ", L"PR", L"PS", L"PT", L"PU", L"PV", L"PW", L"PX", L"PY", L"PZ", L"QA", L"QB", L"QC", L"QD", L"QE", L"QF", L"QG", L"QH", L"QI", L"QJ", L"QK", L"QL", L"QM", L"QN", L"QO", L"QP", L"QQ", L"QR", L"QS", L"QT", L"QU", L"QV", L"QW", L"QX", L"QY", L"QZ", L"RA", L"RB", L"RC", L"RD", L"RE", L"RF", L"RG", L"RH", L"RI", L"RJ", L"RK", L"RL", L"RM", L"RN", L"RO", L"RP", L"RQ", L"RR", L"RS", L"RT", L"RU", L"RV", L"RW", L"RX", L"RY", L"RZ", L"SA", L"SB", L"SC", L"SD", L"SE", L"SF", L"SG", L"SH", L"SI", L"SJ", L"SK", L"SL", L"SM", L"SN", L"SO", L"SP", L"SQ", L"SR", L"SS", L"ST", L"SU", L"SV", L"SW", L"SX", L"SY", L"SZ", L"TA", L"TB", L"TC", L"TD", L"TE", L"TF", L"TG", L"TH", L"TI", L"TJ", L"TK", L"TL", L"TM", L"TN", L"TO", L"TP", L"TQ", L"TR", L"TS", L"TT", L"TU", L"TV", L"TW", L"TX", L"TY", L"TZ", L"UA", L"UB", L"UC", L"UD", L"UE", L"UF", L"UG", L"UH", L"UI", L"UJ", L"UK", L"UL", L"UM", L"UN", L"UO", L"UP", L"UQ", L"UR", L"US", L"UT", L"UU", L"UV", L"UW", L"UX", L"UY", L"UZ", L"VA", L"VB", L"VC", L"VD", L"VE", L"VF", L"VG", L"VH", L"VI", L"VJ", L"VK", L"VL", L"VM", L"VN", L"VO", L"VP", L"VQ", L"VR", L"VS", L"VT", L"VU", L"VV", L"VW", L"VX", L"VY", L"VZ", L"WA", L"WB", L"WC", L"WD", L"WE", L"WF", L"WG", L"WH", L"WI", L"WJ", L"WK", L"WL", L"WM", L"WN", L"WO", L"WP", L"WQ", L"WR", L"WS", L"WT", L"WU", L"WV", L"WW", L"WX", L"WY", - L"WZ", L"XA", L"XB", L"XC", L"XD", L"XE", L"XF", L"XG", L"XH", L"XI", L"XJ", L"XK", L"XL", L"XM", L"XN", L"XO", L"XP", L"XQ", L"XR", L"XS", L"XT", L"XU", L"XV", L"XW", L"XX", L"XY", L"XZ", L"YA", L"YB", L"YC", L"YD", L"YE", L"YF", L"YG", L"YH", L"YI", L"YJ", L"YK", L"YL", L"YM", L"YN", L"YO", L"YP", L"YQ", L"YR", L"YS", L"YT", L"YU", L"YV", L"YW", L"YX", L"YY", L"YZ", L"ZA", L"ZB", L"ZC", L"ZD", L"ZE", L"ZF", L"ZG", L"ZH", L"ZI", L"ZJ", L"ZK", L"ZL", L"ZM", L"ZN", L"ZO", L"ZP", L"ZQ", L"ZR", L"ZS", L"ZT", L"ZU", L"ZV", L"ZW", L"ZX", L"ZY", L"ZZ", L"AAA", L"AAB", L"AAC", L"AAD", L"AAE", L"AAF", L"AAG", L"AAH", L"AAI", L"AAJ", L"AAK", L"AAL", L"AAM", L"AAN", L"AAO", L"AAP", L"AAQ", L"AAR", L"AAS", L"AAT", L"AAU", L"AAV", L"AAW", L"AAX", L"AAY", L"AAZ", L"ABA", L"ABB", L"ABC", L"ABD", L"ABE", L"ABF", L"ABG", L"ABH", L"ABI", L"ABJ", L"ABK", L"ABL", L"ABM", L"ABN", L"ABO", L"ABP", L"ABQ", L"ABR", L"ABS", L"ABT", L"ABU", L"ABV", L"ABW", L"ABX", L"ABY", L"ABZ", L"ACA", L"ACB", L"ACC", L"ACD", L"ACE", L"ACF", L"ACG", L"ACH", L"ACI", L"ACJ", L"ACK", L"ACL", L"ACM", L"ACN", L"ACO", L"ACP", L"ACQ", L"ACR", L"ACS", L"ACT", L"ACU", L"ACV", L"ACW", L"ACX", L"ACY", L"ACZ", L"ADA", L"ADB", L"ADC", L"ADD", L"ADE", L"ADF", L"ADG", L"ADH", L"ADI", L"ADJ", L"ADK", L"ADL", L"ADM", L"ADN", L"ADO", L"ADP", L"ADQ", L"ADR", L"ADS", L"ADT", L"ADU", L"ADV", L"ADW", L"ADX", L"ADY", L"ADZ", L"AEA", L"AEB", L"AEC", L"AED", L"AEE", L"AEF", L"AEG", L"AEH", L"AEI", L"AEJ", L"AEK", L"AEL", L"AEM", L"AEN", L"AEO", L"AEP", L"AEQ", L"AER", L"AES", L"AET", L"AEU", L"AEV", L"AEW", L"AEX", L"AEY", L"AEZ", L"AFA", L"AFB", L"AFC", L"AFD", L"AFE", L"AFF", L"AFG", L"AFH", L"AFI", L"AFJ", L"AFK", L"AFL", L"AFM", L"AFN", L"AFO", L"AFP", L"AFQ", L"AFR", L"AFS", L"AFT", L"AFU", L"AFV", L"AFW", L"AFX", L"AFY", L"AFZ", L"AGA", L"AGB", L"AGC", L"AGD", L"AGE", L"AGF", L"AGG", L"AGH", L"AGI", L"AGJ", L"AGK", L"AGL", L"AGM", L"AGN", L"AGO", L"AGP", L"AGQ", L"AGR", L"AGS", L"AGT", L"AGU", L"AGV", L"AGW", L"AGX", L"AGY", L"AGZ", L"AHA", L"AHB", L"AHC", L"AHD", L"AHE", L"AHF", L"AHG", L"AHH", L"AHI", L"AHJ", L"AHK", L"AHL", L"AHM", L"AHN", L"AHO", L"AHP", L"AHQ", L"AHR", L"AHS", L"AHT", L"AHU", L"AHV", + static const wchar_t* m_aLetters[] = + { + L"A", L"B", L"C", L"D", L"E", L"F", L"G", L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", L"X", L"Y", L"Z", L"AA", L"AB", L"AC", L"AD", L"AE", L"AF", L"AG", L"AH", L"AI", L"AJ", L"AK", L"AL", L"AM", L"AN", L"AO", L"AP", L"AQ", L"AR", L"AS", L"AT", L"AU", L"AV", L"AW", L"AX", L"AY", L"AZ", L"BA", L"BB", L"BC", L"BD", L"BE", L"BF", L"BG", L"BH", L"BI", L"BJ", L"BK", L"BL", L"BM", L"BN", L"BO", L"BP", L"BQ", L"BR", L"BS", L"BT", L"BU", L"BV", L"BW", L"BX", L"BY", L"BZ", L"CA", L"CB", L"CC", L"CD", L"CE", L"CF", L"CG", L"CH", L"CI", L"CJ", L"CK", L"CL", L"CM", L"CN", L"CO", L"CP", L"CQ", L"CR", L"CS", L"CT", L"CU", L"CV", L"CW", L"CX", L"CY", L"CZ", L"DA", L"DB", L"DC", L"DD", L"DE", L"DF", L"DG", L"DH", L"DI", L"DJ", L"DK", L"DL", L"DM", L"DN", L"DO", L"DP", L"DQ", L"DR", L"DS", L"DT", L"DU", L"DV", L"DW", L"DX", L"DY", L"DZ", L"EA", L"EB", L"EC", L"ED", L"EE", L"EF", L"EG", L"EH", L"EI", L"EJ", L"EK", L"EL", L"EM", L"EN", L"EO", L"EP", L"EQ", L"ER", L"ES", L"ET", L"EU", L"EV", L"EW", L"EX", L"EY", L"EZ", L"FA", L"FB", L"FC", L"FD", L"FE", L"FF", L"FG", L"FH", L"FI", L"FJ", L"FK", L"FL", L"FM", L"FN", L"FO", L"FP", L"FQ", L"FR", L"FS", L"FT", L"FU", L"FV", L"FW", L"FX", L"FY", L"FZ", L"GA", L"GB", L"GC", L"GD", L"GE", L"GF", L"GG", L"GH", L"GI", L"GJ", L"GK", L"GL", L"GM", L"GN", L"GO", L"GP", L"GQ", L"GR", L"GS", L"GT", L"GU", L"GV", L"GW", L"GX", L"GY", L"GZ", L"HA", L"HB", L"HC", L"HD", L"HE", L"HF", L"HG", L"HH", L"HI", L"HJ", L"HK", L"HL", L"HM", L"HN", L"HO", L"HP", L"HQ", L"HR", L"HS", L"HT", L"HU", L"HV", L"HW", L"HX", L"HY", L"HZ", L"IA", L"IB", L"IC", L"ID", L"IE", L"IF", L"IG", L"IH", L"II", L"IJ", L"IK", L"IL", L"IM", L"IN", L"IO", L"IP", L"IQ", L"IR", L"IS", L"IT", L"IU", L"IV", L"IW", L"IX", L"IY", L"IZ", L"JA", L"JB", L"JC", L"JD", L"JE", L"JF", L"JG", L"JH", L"JI", L"JJ", L"JK", L"JL", L"JM", L"JN", L"JO", L"JP", L"JQ", L"JR", L"JS", L"JT", L"JU", L"JV", L"JW", L"JX", L"JY", L"JZ", L"KA", L"KB", L"KC", L"KD", L"KE", L"KF", L"KG", L"KH", L"KI", L"KJ", L"KK", L"KL", L"KM", L"KN", L"KO", L"KP", L"KQ", L"KR", L"KS", L"KT", L"KU", L"KV", L"KW", L"KX", L"KY", L"KZ", L"LA", L"LB", L"LC", L"LD", L"LE", L"LF", L"LG", L"LH", L"LI", L"LJ", L"LK", L"LL", L"LM", L"LN", L"LO", L"LP", L"LQ", L"LR", L"LS", L"LT", L"LU", L"LV", L"LW", L"LX", L"LY", L"LZ", L"MA", L"MB", L"MC", L"MD", L"ME", L"MF", L"MG", L"MH", L"MI", L"MJ", L"MK", L"ML", L"MM", L"MN", L"MO", L"MP", L"MQ", L"MR", L"MS", L"MT", L"MU", L"MV", L"MW", L"MX", L"MY", L"MZ", L"NA", L"NB", L"NC", L"ND", L"NE", L"NF", L"NG", L"NH", L"NI", L"NJ", L"NK", L"NL", L"NM", L"NN", L"NO", L"NP", L"NQ", L"NR", L"NS", L"NT", L"NU", L"NV", L"NW", L"NX", L"NY", L"NZ", L"OA", L"OB", L"OC", L"OD", L"OE", L"OF", L"OG", L"OH", L"OI", L"OJ", L"OK", L"OL", L"OM", L"ON", L"OO", L"OP", L"OQ", L"OR", L"OS", L"OT", L"OU", L"OV", L"OW", L"OX", L"OY", L"OZ", L"PA", L"PB", L"PC", L"PD", L"PE", L"PF", L"PG", L"PH", L"PI", L"PJ", L"PK", L"PL", L"PM", L"PN", L"PO", L"PP", L"PQ", L"PR", L"PS", L"PT", L"PU", L"PV", L"PW", L"PX", L"PY", L"PZ", L"QA", L"QB", L"QC", L"QD", L"QE", L"QF", L"QG", L"QH", L"QI", L"QJ", L"QK", L"QL", L"QM", L"QN", L"QO", L"QP", L"QQ", L"QR", L"QS", L"QT", L"QU", L"QV", L"QW", L"QX", L"QY", L"QZ", L"RA", L"RB", L"RC", L"RD", L"RE", L"RF", L"RG", L"RH", L"RI", L"RJ", L"RK", L"RL", L"RM", L"RN", L"RO", L"RP", L"RQ", L"RR", L"RS", L"RT", L"RU", L"RV", L"RW", L"RX", L"RY", L"RZ", L"SA", L"SB", L"SC", L"SD", L"SE", L"SF", L"SG", L"SH", L"SI", L"SJ", L"SK", L"SL", L"SM", L"SN", L"SO", L"SP", L"SQ", L"SR", L"SS", L"ST", L"SU", L"SV", L"SW", L"SX", L"SY", L"SZ", L"TA", L"TB", L"TC", L"TD", L"TE", L"TF", L"TG", L"TH", L"TI", L"TJ", L"TK", L"TL", L"TM", L"TN", L"TO", L"TP", L"TQ", L"TR", L"TS", L"TT", L"TU", L"TV", L"TW", L"TX", L"TY", L"TZ", L"UA", L"UB", L"UC", L"UD", L"UE", L"UF", L"UG", L"UH", L"UI", L"UJ", L"UK", L"UL", L"UM", L"UN", L"UO", L"UP", L"UQ", L"UR", L"US", L"UT", L"UU", L"UV", L"UW", L"UX", L"UY", L"UZ", L"VA", L"VB", L"VC", L"VD", L"VE", L"VF", L"VG", L"VH", L"VI", L"VJ", L"VK", L"VL", L"VM", L"VN", L"VO", L"VP", L"VQ", L"VR", L"VS", L"VT", L"VU", L"VV", L"VW", L"VX", L"VY", L"VZ", L"WA", L"WB", L"WC", L"WD", L"WE", L"WF", L"WG", L"WH", L"WI", L"WJ", L"WK", L"WL", L"WM", L"WN", L"WO", L"WP", L"WQ", L"WR", L"WS", L"WT", L"WU", L"WV", L"WW", L"WX", L"WY", + L"WZ", L"XA", L"XB", L"XC", L"XD", L"XE", L"XF", L"XG", L"XH", L"XI", L"XJ", L"XK", L"XL", L"XM", L"XN", L"XO", L"XP", L"XQ", L"XR", L"XS", L"XT", L"XU", L"XV", L"XW", L"XX", L"XY", L"XZ", L"YA", L"YB", L"YC", L"YD", L"YE", L"YF", L"YG", L"YH", L"YI", L"YJ", L"YK", L"YL", L"YM", L"YN", L"YO", L"YP", L"YQ", L"YR", L"YS", L"YT", L"YU", L"YV", L"YW", L"YX", L"YY", L"YZ", L"ZA", L"ZB", L"ZC", L"ZD", L"ZE", L"ZF", L"ZG", L"ZH", L"ZI", L"ZJ", L"ZK", L"ZL", L"ZM", L"ZN", L"ZO", L"ZP", L"ZQ", L"ZR", L"ZS", L"ZT", L"ZU", L"ZV", L"ZW", L"ZX", L"ZY", L"ZZ", L"AAA", L"AAB", L"AAC", L"AAD", L"AAE", L"AAF", L"AAG", L"AAH", L"AAI", L"AAJ", L"AAK", L"AAL", L"AAM", L"AAN", L"AAO", L"AAP", L"AAQ", L"AAR", L"AAS", L"AAT", L"AAU", L"AAV", L"AAW", L"AAX", L"AAY", L"AAZ", L"ABA", L"ABB", L"ABC", L"ABD", L"ABE", L"ABF", L"ABG", L"ABH", L"ABI", L"ABJ", L"ABK", L"ABL", L"ABM", L"ABN", L"ABO", L"ABP", L"ABQ", L"ABR", L"ABS", L"ABT", L"ABU", L"ABV", L"ABW", L"ABX", L"ABY", L"ABZ", L"ACA", L"ACB", L"ACC", L"ACD", L"ACE", L"ACF", L"ACG", L"ACH", L"ACI", L"ACJ", L"ACK", L"ACL", L"ACM", L"ACN", L"ACO", L"ACP", L"ACQ", L"ACR", L"ACS", L"ACT", L"ACU", L"ACV", L"ACW", L"ACX", L"ACY", L"ACZ", L"ADA", L"ADB", L"ADC", L"ADD", L"ADE", L"ADF", L"ADG", L"ADH", L"ADI", L"ADJ", L"ADK", L"ADL", L"ADM", L"ADN", L"ADO", L"ADP", L"ADQ", L"ADR", L"ADS", L"ADT", L"ADU", L"ADV", L"ADW", L"ADX", L"ADY", L"ADZ", L"AEA", L"AEB", L"AEC", L"AED", L"AEE", L"AEF", L"AEG", L"AEH", L"AEI", L"AEJ", L"AEK", L"AEL", L"AEM", L"AEN", L"AEO", L"AEP", L"AEQ", L"AER", L"AES", L"AET", L"AEU", L"AEV", L"AEW", L"AEX", L"AEY", L"AEZ", L"AFA", L"AFB", L"AFC", L"AFD", L"AFE", L"AFF", L"AFG", L"AFH", L"AFI", L"AFJ", L"AFK", L"AFL", L"AFM", L"AFN", L"AFO", L"AFP", L"AFQ", L"AFR", L"AFS", L"AFT", L"AFU", L"AFV", L"AFW", L"AFX", L"AFY", L"AFZ", L"AGA", L"AGB", L"AGC", L"AGD", L"AGE", L"AGF", L"AGG", L"AGH", L"AGI", L"AGJ", L"AGK", L"AGL", L"AGM", L"AGN", L"AGO", L"AGP", L"AGQ", L"AGR", L"AGS", L"AGT", L"AGU", L"AGV", L"AGW", L"AGX", L"AGY", L"AGZ", L"AHA", L"AHB", L"AHC", L"AHD", L"AHE", L"AHF", L"AHG", L"AHH", L"AHI", L"AHJ", L"AHK", L"AHL", L"AHM", L"AHN", L"AHO", L"AHP", L"AHQ", L"AHR", L"AHS", L"AHT", L"AHU", L"AHV", L"AHW", L"AHX", L"AHY", L"AHZ", L"AIA", L"AIB", L"AIC", L"AID", L"AIE", L"AIF", L"AIG", L"AIH", L"AII", L"AIJ", L"AIK", L"AIL", L"AIM", L"AIN", L"AIO", L"AIP", L"AIQ", L"AIR", L"AIS", L"AIT", L"AIU", L"AIV", L"AIW", L"AIX", L"AIY", L"AIZ", L"AJA", L"AJB", L"AJC", L"AJD", L"AJE", L"AJF", L"AJG", L"AJH", L"AJI", L"AJJ", L"AJK", L"AJL", L"AJM", L"AJN", L"AJO", L"AJP", L"AJQ", L"AJR", L"AJS", L"AJT", L"AJU", L"AJV", L"AJW", L"AJX", L"AJY", L"AJZ", L"AKA", L"AKB", L"AKC", L"AKD", L"AKE", L"AKF", L"AKG", L"AKH", L"AKI", L"AKJ", L"AKK", L"AKL", L"AKM", L"AKN", L"AKO", L"AKP", L"AKQ", L"AKR", L"AKS", L"AKT", L"AKU", L"AKV", L"AKW", L"AKX", L"AKY", L"AKZ", L"ALA", L"ALB", L"ALC", L"ALD", L"ALE", L"ALF", L"ALG", L"ALH", L"ALI", L"ALJ", L"ALK", L"ALL", L"ALM", L"ALN", L"ALO", L"ALP", L"ALQ", L"ALR", L"ALS", L"ALT", L"ALU", L"ALV", L"ALW", L"ALX", L"ALY", L"ALZ", L"AMA", L"AMB", L"AMC", L"AMD", L"AME", L"AMF", L"AMG", L"AMH", L"AMI", L"AMJ", L"AMK", L"AML", L"AMM", L"AMN", L"AMO", L"AMP", L"AMQ", L"AMR", L"AMS", L"AMT", L"AMU", L"AMV", L"AMW", L"AMX", L"AMY", L"AMZ", L"ANA", L"ANB", L"ANC", L"AND", L"ANE", L"ANF", L"ANG", L"ANH", L"ANI", L"ANJ", L"ANK", L"ANL", L"ANM", L"ANN", L"ANO", L"ANP", L"ANQ", L"ANR", L"ANS", L"ANT", L"ANU", L"ANV", L"ANW", L"ANX", L"ANY", L"ANZ", L"AOA", L"AOB", L"AOC", L"AOD", L"AOE", L"AOF", L"AOG", L"AOH", L"AOI", L"AOJ", L"AOK", L"AOL", L"AOM", L"AON", L"AOO", L"AOP", L"AOQ", L"AOR", L"AOS", L"AOT", L"AOU", L"AOV", L"AOW", L"AOX", L"AOY", L"AOZ", L"APA", L"APB", L"APC", L"APD", L"APE", L"APF", L"APG", L"APH", L"API", L"APJ", L"APK", L"APL", L"APM", L"APN", L"APO", L"APP", L"APQ", L"APR", L"APS", L"APT", L"APU", L"APV", L"APW", L"APX", L"APY", L"APZ", L"AQA", L"AQB", L"AQC", L"AQD", L"AQE", L"AQF", L"AQG", L"AQH", L"AQI", L"AQJ", L"AQK", L"AQL", L"AQM", L"AQN", L"AQO", L"AQP", L"AQQ", L"AQR", L"AQS", L"AQT", L"AQU", L"AQV", L"AQW", L"AQX", L"AQY", L"AQZ", L"ARA", L"ARB", L"ARC", L"ARD", L"ARE", L"ARF", L"ARG", L"ARH", L"ARI", L"ARJ", L"ARK", L"ARL", L"ARM", L"ARN", L"ARO", L"ARP", L"ARQ", L"ARR", L"ARS", L"ART", L"ARU", L"ARV", L"ARW", L"ARX", L"ARY", L"ARZ", L"ASA", L"ASB", L"ASC", L"ASD", L"ASE", L"ASF", L"ASG", L"ASH", L"ASI", L"ASJ", L"ASK", L"ASL", L"ASM", L"ASN", L"ASO", L"ASP", L"ASQ", L"ASR", L"ASS", L"AST", L"ASU", L"ASV", L"ASW", L"ASX", L"ASY", L"ASZ", L"ATA", L"ATB", L"ATC", L"ATD", L"ATE", L"ATF", L"ATG", L"ATH", L"ATI", L"ATJ", L"ATK", L"ATL", L"ATM", L"ATN", L"ATO", L"ATP", L"ATQ", L"ATR", L"ATS", L"ATT", L"ATU", L"ATV", L"ATW", L"ATX", L"ATY", L"ATZ", L"AUA", L"AUB", L"AUC", L"AUD", L"AUE", L"AUF", L"AUG", L"AUH", L"AUI", L"AUJ", L"AUK", L"AUL", L"AUM", L"AUN", L"AUO", L"AUP", L"AUQ", L"AUR", L"AUS", L"AUT", L"AUU", L"AUV", L"AUW", L"AUX", L"AUY", L"AUZ", L"AVA", L"AVB", L"AVC", L"AVD", L"AVE", L"AVF", L"AVG", L"AVH", L"AVI", L"AVJ", L"AVK", L"AVL", L"AVM", L"AVN", L"AVO", L"AVP", L"AVQ", L"AVR", L"AVS", L"AVT", L"AVU", L"AVV", L"AVW", L"AVX", L"AVY", L"AVZ", L"AWA", L"AWB", L"AWC", L"AWD", L"AWE", L"AWF", L"AWG", L"AWH", L"AWI", L"AWJ", L"AWK", L"AWL", L"AWM", L"AWN", L"AWO", L"AWP", L"AWQ", L"AWR", L"AWS", L"AWT", L"AWU", L"AWV", L"AWW", L"AWX", L"AWY", L"AWZ", L"AXA", L"AXB", L"AXC", L"AXD", L"AXE", L"AXF", L"AXG", L"AXH", L"AXI", L"AXJ", L"AXK", L"AXL", L"AXM", L"AXN", L"AXO", L"AXP", L"AXQ", L"AXR", L"AXS", L"AXT", L"AXU", L"AXV", L"AXW", L"AXX", L"AXY", L"AXZ", L"AYA", L"AYB", L"AYC", L"AYD", L"AYE", L"AYF", L"AYG", L"AYH", L"AYI", L"AYJ", L"AYK", L"AYL", L"AYM", L"AYN", L"AYO", L"AYP", L"AYQ", L"AYR", L"AYS", L"AYT", L"AYU", L"AYV", L"AYW", L"AYX", L"AYY", L"AYZ", L"AZA", L"AZB", L"AZC", L"AZD", L"AZE", L"AZF", L"AZG", L"AZH", L"AZI", L"AZJ", L"AZK", L"AZL", L"AZM", L"AZN", L"AZO", L"AZP", L"AZQ", L"AZR", L"AZS", L"AZT", L"AZU", L"AZV", L"AZW", L"AZX", L"AZY", L"AZZ", L"BAA", L"BAB", L"BAC", L"BAD", L"BAE", L"BAF", L"BAG", L"BAH", L"BAI", L"BAJ", L"BAK", L"BAL", L"BAM", L"BAN", L"BAO", L"BAP", L"BAQ", L"BAR", L"BAS", L"BAT", L"BAU", L"BAV", L"BAW", L"BAX", L"BAY", L"BAZ", L"BBA", L"BBB", L"BBC", L"BBD", L"BBE", L"BBF", L"BBG", L"BBH", L"BBI", L"BBJ", L"BBK", L"BBL", L"BBM", L"BBN", L"BBO", L"BBP", L"BBQ", L"BBR", L"BBS", L"BBT", L"BBU", L"BBV", L"BBW", L"BBX", L"BBY", L"BBZ", L"BCA", L"BCB", L"BCC", L"BCD", L"BCE", L"BCF", L"BCG", L"BCH", L"BCI", L"BCJ", L"BCK", L"BCL", L"BCM", L"BCN", L"BCO", L"BCP", L"BCQ", L"BCR", L"BCS", L"BCT", L"BCU", L"BCV", L"BCW", L"BCX", L"BCY", L"BCZ", L"BDA", L"BDB", L"BDC", L"BDD", L"BDE", L"BDF", L"BDG", L"BDH", L"BDI", L"BDJ", L"BDK", L"BDL", L"BDM", L"BDN", L"BDO", L"BDP", L"BDQ", L"BDR", L"BDS", L"BDT", L"BDU", L"BDV", L"BDW", L"BDX", L"BDY", L"BDZ", L"BEA", L"BEB", L"BEC", L"BED", L"BEE", L"BEF", L"BEG", L"BEH", L"BEI", L"BEJ", L"BEK", L"BEL", L"BEM", L"BEN", L"BEO", L"BEP", L"BEQ", L"BER", L"BES", L"BET", L"BEU", L"BEV", L"BEW", L"BEX", L"BEY", L"BEZ", L"BFA", L"BFB", L"BFC", L"BFD", L"BFE", L"BFF", L"BFG", L"BFH", L"BFI", L"BFJ", L"BFK", L"BFL", L"BFM", L"BFN", L"BFO", L"BFP", L"BFQ", L"BFR", L"BFS", L"BFT", L"BFU", L"BFV", L"BFW", L"BFX", L"BFY", L"BFZ", L"BGA", L"BGB", L"BGC", L"BGD", L"BGE", L"BGF", L"BGG", L"BGH", L"BGI", L"BGJ", L"BGK", L"BGL", L"BGM", L"BGN", L"BGO", L"BGP", L"BGQ", L"BGR", L"BGS", L"BGT", L"BGU", L"BGV", L"BGW", L"BGX", L"BGY", L"BGZ", L"BHA", L"BHB", L"BHC", L"BHD", L"BHE", L"BHF", L"BHG", L"BHH", L"BHI", L"BHJ", L"BHK", L"BHL", L"BHM", L"BHN", L"BHO", L"BHP", L"BHQ", L"BHR", L"BHS", L"BHT", L"BHU", L"BHV", L"BHW", L"BHX", L"BHY", L"BHZ", L"BIA", L"BIB", L"BIC", L"BID", L"BIE", L"BIF", L"BIG", L"BIH", L"BII", L"BIJ", L"BIK", L"BIL", L"BIM", L"BIN", L"BIO", L"BIP", L"BIQ", L"BIR", L"BIS", L"BIT", L"BIU", L"BIV", L"BIW", L"BIX", L"BIY", L"BIZ", L"BJA", L"BJB", L"BJC", L"BJD", L"BJE", L"BJF", L"BJG", L"BJH", L"BJI", L"BJJ", L"BJK", L"BJL", L"BJM", L"BJN", L"BJO", L"BJP", L"BJQ", L"BJR", L"BJS", L"BJT", L"BJU", L"BJV", L"BJW", L"BJX", L"BJY", L"BJZ", L"BKA", L"BKB", L"BKC", L"BKD", L"BKE", L"BKF", L"BKG", L"BKH", L"BKI", L"BKJ", L"BKK", L"BKL", L"BKM", L"BKN", L"BKO", L"BKP", L"BKQ", L"BKR", L"BKS", L"BKT", L"BKU", L"BKV", L"BKW", L"BKX", L"BKY", L"BKZ", L"BLA", L"BLB", L"BLC", L"BLD", L"BLE", L"BLF", L"BLG", L"BLH", L"BLI", L"BLJ", L"BLK", L"BLL", L"BLM", L"BLN", L"BLO", L"BLP", L"BLQ", L"BLR", L"BLS", L"BLT", L"BLU", L"BLV", L"BLW", L"BLX", L"BLY", L"BLZ", L"BMA", L"BMB", L"BMC", L"BMD", L"BME", L"BMF", L"BMG", L"BMH", L"BMI", L"BMJ", L"BMK", L"BML", L"BMM", L"BMN", L"BMO", L"BMP", L"BMQ", L"BMR", L"BMS", L"BMT", L"BMU", L"BMV", L"BMW", L"BMX", L"BMY", L"BMZ", L"BNA", L"BNB", L"BNC", L"BND", L"BNE", L"BNF", L"BNG", L"BNH", L"BNI", L"BNJ", L"BNK", L"BNL", L"BNM", L"BNN", L"BNO", L"BNP", L"BNQ", L"BNR", L"BNS", L"BNT", L"BNU", L"BNV", L"BNW", L"BNX", L"BNY", L"BNZ", L"BOA", L"BOB", L"BOC", L"BOD", L"BOE", L"BOF", L"BOG", L"BOH", L"BOI", L"BOJ", L"BOK", L"BOL", L"BOM", L"BON", L"BOO", L"BOP", L"BOQ", L"BOR", L"BOS", L"BOT", L"BOU", L"BOV", L"BOW", L"BOX", L"BOY", L"BOZ", L"BPA", L"BPB", L"BPC", L"BPD", L"BPE", L"BPF", L"BPG", L"BPH", L"BPI", L"BPJ", L"BPK", L"BPL", L"BPM", L"BPN", L"BPO", L"BPP", L"BPQ", L"BPR", L"BPS", L"BPT", L"BPU", L"BPV", L"BPW", L"BPX", L"BPY", L"BPZ", L"BQA", L"BQB", L"BQC", L"BQD", L"BQE", L"BQF", L"BQG", L"BQH", L"BQI", L"BQJ", L"BQK", L"BQL", L"BQM", L"BQN", L"BQO", L"BQP", L"BQQ", L"BQR", L"BQS", L"BQT", L"BQU", L"BQV", L"BQW", L"BQX", L"BQY", L"BQZ", L"BRA", L"BRB", L"BRC", L"BRD", L"BRE", L"BRF", L"BRG", L"BRH", L"BRI", L"BRJ", L"BRK", L"BRL", L"BRM", L"BRN", L"BRO", L"BRP", L"BRQ", L"BRR", L"BRS", L"BRT", L"BRU", L"BRV", L"BRW", L"BRX", L"BRY", L"BRZ", L"BSA", L"BSB", L"BSC", L"BSD", L"BSE", L"BSF", L"BSG", L"BSH", L"BSI", L"BSJ", L"BSK", L"BSL", L"BSM", L"BSN", L"BSO", L"BSP", L"BSQ", L"BSR", L"BSS", L"BST", L"BSU", L"BSV", L"BSW", L"BSX", L"BSY", L"BSZ", L"BTA", L"BTB", L"BTC", L"BTD", L"BTE", L"BTF", L"BTG", L"BTH", L"BTI", L"BTJ", L"BTK", L"BTL", L"BTM", L"BTN", L"BTO", L"BTP", L"BTQ", L"BTR", L"BTS", L"BTT", L"BTU", L"BTV", L"BTW", L"BTX", L"BTY", L"BTZ", L"BUA", L"BUB", L"BUC", L"BUD", L"BUE", L"BUF", L"BUG", L"BUH", L"BUI", L"BUJ", L"BUK", L"BUL", L"BUM", L"BUN", L"BUO", L"BUP", L"BUQ", L"BUR", L"BUS", L"BUT", L"BUU", L"BUV", L"BUW", L"BUX", L"BUY", L"BUZ", L"BVA", L"BVB", L"BVC", L"BVD", L"BVE", L"BVF", L"BVG", L"BVH", L"BVI", L"BVJ", L"BVK", L"BVL", L"BVM", L"BVN", L"BVO", L"BVP", L"BVQ", L"BVR", L"BVS", L"BVT", L"BVU", L"BVV", L"BVW", L"BVX", L"BVY", L"BVZ", L"BWA", L"BWB", L"BWC", L"BWD", L"BWE", L"BWF", L"BWG", L"BWH", L"BWI", L"BWJ", L"BWK", L"BWL", L"BWM", L"BWN", L"BWO", L"BWP", L"BWQ", L"BWR", L"BWS", L"BWT", L"BWU", L"BWV", L"BWW", L"BWX", L"BWY", L"BWZ", L"BXA", L"BXB", L"BXC", L"BXD", L"BXE", L"BXF", L"BXG", L"BXH", L"BXI", L"BXJ", L"BXK", L"BXL", L"BXM", L"BXN", L"BXO", L"BXP", L"BXQ", L"BXR", L"BXS", L"BXT", L"BXU", L"BXV", L"BXW", L"BXX", L"BXY", L"BXZ", L"BYA", L"BYB", L"BYC", L"BYD", L"BYE", L"BYF", L"BYG", L"BYH", L"BYI", L"BYJ", L"BYK", L"BYL", L"BYM", L"BYN", L"BYO", L"BYP", L"BYQ", L"BYR", L"BYS", L"BYT", L"BYU", L"BYV", L"BYW", L"BYX", L"BYY", L"BYZ", L"BZA", L"BZB", L"BZC", L"BZD", L"BZE", L"BZF", L"BZG", L"BZH", L"BZI", L"BZJ", L"BZK", L"BZL", L"BZM", L"BZN", L"BZO", L"BZP", L"BZQ", L"BZR", L"BZS", L"BZT", L"BZU", L"BZV", L"BZW", L"BZX", L"BZY", L"BZZ", L"CAA", L"CAB", L"CAC", L"CAD", L"CAE", L"CAF", L"CAG", L"CAH", L"CAI", L"CAJ", L"CAK", L"CAL", L"CAM", L"CAN", L"CAO", L"CAP", L"CAQ", L"CAR", L"CAS", L"CAT", L"CAU", L"CAV", L"CAW", L"CAX", L"CAY", L"CAZ", L"CBA", L"CBB", L"CBC", L"CBD", L"CBE", L"CBF", L"CBG", L"CBH", L"CBI", L"CBJ", L"CBK", L"CBL", L"CBM", L"CBN", L"CBO", L"CBP", L"CBQ", L"CBR", L"CBS", L"CBT", L"CBU", L"CBV", L"CBW", L"CBX", L"CBY", L"CBZ", L"CCA", L"CCB", L"CCC", L"CCD", L"CCE", L"CCF", L"CCG", L"CCH", L"CCI", L"CCJ", L"CCK", L"CCL", L"CCM", L"CCN", L"CCO", L"CCP", L"CCQ", L"CCR", L"CCS", L"CCT", L"CCU", L"CCV", L"CCW", L"CCX", L"CCY", L"CCZ", L"CDA", L"CDB", L"CDC", L"CDD", L"CDE", L"CDF", L"CDG", L"CDH", L"CDI", L"CDJ", L"CDK", L"CDL", L"CDM", L"CDN", L"CDO", L"CDP", L"CDQ", L"CDR", L"CDS", L"CDT", L"CDU", L"CDV", L"CDW", L"CDX", L"CDY", L"CDZ", L"CEA", L"CEB", L"CEC", L"CED", L"CEE", L"CEF", L"CEG", L"CEH", L"CEI", L"CEJ", L"CEK", L"CEL", L"CEM", L"CEN", L"CEO", L"CEP", L"CEQ", L"CER", L"CES", L"CET", L"CEU", L"CEV", L"CEW", L"CEX", L"CEY", L"CEZ", L"CFA", L"CFB", L"CFC", L"CFD", L"CFE", L"CFF", L"CFG", L"CFH", L"CFI", L"CFJ", L"CFK", L"CFL", L"CFM", L"CFN", L"CFO", L"CFP", L"CFQ", L"CFR", L"CFS", L"CFT", L"CFU", L"CFV", L"CFW", L"CFX", L"CFY", L"CFZ", L"CGA", L"CGB", L"CGC", L"CGD", L"CGE", L"CGF", L"CGG", L"CGH", L"CGI", L"CGJ", L"CGK", L"CGL", L"CGM", L"CGN", L"CGO", L"CGP", L"CGQ", L"CGR", L"CGS", L"CGT", L"CGU", L"CGV", L"CGW", L"CGX", L"CGY", L"CGZ", L"CHA", L"CHB", L"CHC", L"CHD", L"CHE", L"CHF", L"CHG", L"CHH", L"CHI", L"CHJ", L"CHK", L"CHL", L"CHM", L"CHN", L"CHO", L"CHP", L"CHQ", L"CHR", L"CHS", L"CHT", L"CHU", L"CHV", L"CHW", L"CHX", L"CHY", L"CHZ", L"CIA", L"CIB", L"CIC", L"CID", L"CIE", L"CIF", L"CIG", L"CIH", L"CII", L"CIJ", L"CIK", L"CIL", L"CIM", L"CIN", L"CIO", L"CIP", L"CIQ", L"CIR", L"CIS", L"CIT", L"CIU", L"CIV", L"CIW", L"CIX", L"CIY", L"CIZ", L"CJA", L"CJB", L"CJC", L"CJD", L"CJE", L"CJF", L"CJG", L"CJH", L"CJI", L"CJJ", L"CJK", L"CJL", L"CJM", L"CJN", L"CJO", L"CJP", L"CJQ", L"CJR", L"CJS", L"CJT", L"CJU", L"CJV", L"CJW", L"CJX", L"CJY", L"CJZ", L"CKA", L"CKB", L"CKC", L"CKD", L"CKE", L"CKF", L"CKG", L"CKH", L"CKI", L"CKJ", L"CKK", L"CKL", L"CKM", L"CKN", L"CKO", L"CKP", L"CKQ", L"CKR", L"CKS", L"CKT", L"CKU", L"CKV", L"CKW", L"CKX", L"CKY", L"CKZ", L"CLA", L"CLB", L"CLC", L"CLD", L"CLE", L"CLF", L"CLG", L"CLH", L"CLI", L"CLJ", L"CLK", L"CLL", L"CLM", L"CLN", L"CLO", L"CLP", L"CLQ", L"CLR", L"CLS", L"CLT", L"CLU", L"CLV", L"CLW", L"CLX", L"CLY", L"CLZ", L"CMA", L"CMB", L"CMC", L"CMD", L"CME", L"CMF", L"CMG", L"CMH", L"CMI", L"CMJ", L"CMK", L"CML", L"CMM", L"CMN", L"CMO", L"CMP", L"CMQ", L"CMR", L"CMS", L"CMT", L"CMU", L"CMV", L"CMW", L"CMX", L"CMY", L"CMZ", L"CNA", L"CNB", L"CNC", L"CND", L"CNE", L"CNF", L"CNG", L"CNH", L"CNI", L"CNJ", L"CNK", L"CNL", L"CNM", L"CNN", L"CNO", L"CNP", L"CNQ", L"CNR", L"CNS", L"CNT", L"CNU", L"CNV", L"CNW", L"CNX", L"CNY", L"CNZ", L"COA", L"COB", L"COC", L"COD", L"COE", L"COF", L"COG", L"COH", L"COI", L"COJ", L"COK", L"COL", L"COM", L"CON", L"COO", L"COP", L"COQ", L"COR", L"COS", L"COT", L"COU", L"COV", L"COW", L"COX", L"COY", L"COZ", L"CPA", L"CPB", L"CPC", L"CPD", L"CPE", L"CPF", L"CPG", L"CPH", L"CPI", L"CPJ", L"CPK", L"CPL", L"CPM", L"CPN", L"CPO", L"CPP", L"CPQ", L"CPR", L"CPS", L"CPT", L"CPU", L"CPV", L"CPW", L"CPX", L"CPY", L"CPZ", L"CQA", L"CQB", L"CQC", L"CQD", L"CQE", L"CQF", L"CQG", L"CQH", L"CQI", L"CQJ", L"CQK", L"CQL", L"CQM", L"CQN", L"CQO", L"CQP", L"CQQ", L"CQR", L"CQS", L"CQT", L"CQU", L"CQV", L"CQW", L"CQX", L"CQY", L"CQZ", L"CRA", L"CRB", L"CRC", L"CRD", L"CRE", L"CRF", L"CRG", L"CRH", L"CRI", L"CRJ", L"CRK", L"CRL", L"CRM", L"CRN", L"CRO", L"CRP", L"CRQ", L"CRR", L"CRS", L"CRT", L"CRU", L"CRV", L"CRW", L"CRX", L"CRY", L"CRZ", L"CSA", L"CSB", L"CSC", L"CSD", L"CSE", L"CSF", L"CSG", L"CSH", L"CSI", L"CSJ", L"CSK", L"CSL", L"CSM", L"CSN", L"CSO", L"CSP", L"CSQ", L"CSR", L"CSS", L"CST", L"CSU", L"CSV", L"CSW", L"CSX", L"CSY", L"CSZ", L"CTA", L"CTB", L"CTC", L"CTD", L"CTE", L"CTF", L"CTG", L"CTH", L"CTI", L"CTJ", L"CTK", L"CTL", L"CTM", L"CTN", L"CTO", L"CTP", L"CTQ", L"CTR", L"CTS", L"CTT", L"CTU", L"CTV", L"CTW", L"CTX", L"CTY", L"CTZ", L"CUA", L"CUB", L"CUC", L"CUD", L"CUE", L"CUF", L"CUG", L"CUH", L"CUI", L"CUJ", L"CUK", L"CUL", L"CUM", L"CUN", L"CUO", L"CUP", L"CUQ", L"CUR", L"CUS", L"CUT", L"CUU", L"CUV", L"CUW", L"CUX", L"CUY", L"CUZ", L"CVA", L"CVB", L"CVC", L"CVD", L"CVE", L"CVF", L"CVG", L"CVH", L"CVI", L"CVJ", L"CVK", L"CVL", L"CVM", L"CVN", L"CVO", L"CVP", L"CVQ", L"CVR", L"CVS", L"CVT", L"CVU", L"CVV", L"CVW", L"CVX", L"CVY", L"CVZ", L"CWA", L"CWB", L"CWC", L"CWD", L"CWE", L"CWF", L"CWG", L"CWH", L"CWI", L"CWJ", L"CWK", L"CWL", L"CWM", L"CWN", L"CWO", L"CWP", L"CWQ", L"CWR", L"CWS", L"CWT", L"CWU", L"CWV", L"CWW", L"CWX", L"CWY", L"CWZ", L"CXA", L"CXB", L"CXC", L"CXD", L"CXE", L"CXF", L"CXG", L"CXH", L"CXI", L"CXJ", L"CXK", L"CXL", L"CXM", L"CXN", L"CXO", L"CXP", L"CXQ", L"CXR", L"CXS", L"CXT", L"CXU", L"CXV", L"CXW", L"CXX", L"CXY", L"CXZ", L"CYA", L"CYB", L"CYC", L"CYD", L"CYE", L"CYF", L"CYG", L"CYH", L"CYI", L"CYJ", L"CYK", L"CYL", L"CYM", L"CYN", L"CYO", L"CYP", L"CYQ", L"CYR", L"CYS", L"CYT", L"CYU", L"CYV", L"CYW", L"CYX", L"CYY", L"CYZ", L"CZA", L"CZB", L"CZC", L"CZD", L"CZE", L"CZF", L"CZG", L"CZH", L"CZI", L"CZJ", L"CZK", L"CZL", L"CZM", L"CZN", L"CZO", L"CZP", L"CZQ", L"CZR", L"CZS", L"CZT", L"CZU", L"CZV", L"CZW", L"CZX", L"CZY", L"CZZ", L"DAA", L"DAB", L"DAC", L"DAD", L"DAE", L"DAF", L"DAG", L"DAH", L"DAI", L"DAJ", L"DAK", L"DAL", L"DAM", L"DAN", L"DAO", L"DAP", L"DAQ", L"DAR", L"DAS", L"DAT", L"DAU", L"DAV", L"DAW", L"DAX", L"DAY", L"DAZ", L"DBA", L"DBB", L"DBC", L"DBD", L"DBE", L"DBF", L"DBG", L"DBH", L"DBI", L"DBJ", L"DBK", L"DBL", L"DBM", L"DBN", L"DBO", L"DBP", L"DBQ", L"DBR", L"DBS", L"DBT", L"DBU", L"DBV", L"DBW", L"DBX", L"DBY", L"DBZ", L"DCA", L"DCB", L"DCC", L"DCD", L"DCE", L"DCF", L"DCG", L"DCH", L"DCI", L"DCJ", L"DCK", L"DCL", L"DCM", L"DCN", L"DCO", L"DCP", L"DCQ", L"DCR", L"DCS", L"DCT", L"DCU", L"DCV", L"DCW", L"DCX", L"DCY", L"DCZ", L"DDA", - L"DDB", L"DDC", L"DDD", L"DDE", L"DDF", L"DDG", L"DDH", L"DDI", L"DDJ", L"DDK", L"DDL", L"DDM", L"DDN", L"DDO", L"DDP", L"DDQ", L"DDR", L"DDS", L"DDT", L"DDU", L"DDV", L"DDW", L"DDX", L"DDY", L"DDZ", L"DEA", L"DEB", L"DEC", L"DED", L"DEE", L"DEF", L"DEG", L"DEH", L"DEI", L"DEJ", L"DEK", L"DEL", L"DEM", L"DEN", L"DEO", L"DEP", L"DEQ", L"DER", L"DES", L"DET", L"DEU", L"DEV", L"DEW", L"DEX", L"DEY", L"DEZ", L"DFA", L"DFB", L"DFC", L"DFD", L"DFE", L"DFF", L"DFG", L"DFH", L"DFI", L"DFJ", L"DFK", L"DFL", L"DFM", L"DFN", L"DFO", L"DFP", L"DFQ", L"DFR", L"DFS", L"DFT", L"DFU", L"DFV", L"DFW", L"DFX", L"DFY", L"DFZ", L"DGA", L"DGB", L"DGC", L"DGD", L"DGE", L"DGF", L"DGG", L"DGH", L"DGI", L"DGJ", L"DGK", L"DGL", L"DGM", L"DGN", L"DGO", L"DGP", L"DGQ", L"DGR", L"DGS", L"DGT", L"DGU", L"DGV", L"DGW", L"DGX", L"DGY", L"DGZ", L"DHA", L"DHB", L"DHC", L"DHD", L"DHE", L"DHF", L"DHG", L"DHH", L"DHI", L"DHJ", L"DHK", L"DHL", L"DHM", L"DHN", L"DHO", L"DHP", L"DHQ", L"DHR", L"DHS", L"DHT", L"DHU", L"DHV", L"DHW", L"DHX", L"DHY", L"DHZ", L"DIA", L"DIB", L"DIC", L"DID", L"DIE", L"DIF", L"DIG", L"DIH", L"DII", L"DIJ", L"DIK", L"DIL", L"DIM", L"DIN", L"DIO", L"DIP", L"DIQ", L"DIR", L"DIS", L"DIT", L"DIU", L"DIV", L"DIW", L"DIX", L"DIY", L"DIZ", L"DJA", L"DJB", L"DJC", L"DJD", L"DJE", L"DJF", L"DJG", L"DJH", L"DJI", L"DJJ", L"DJK", L"DJL", L"DJM", L"DJN", L"DJO", L"DJP", L"DJQ", L"DJR", L"DJS", L"DJT", L"DJU", L"DJV", L"DJW", L"DJX", L"DJY", L"DJZ", L"DKA", L"DKB", L"DKC", L"DKD", L"DKE", L"DKF", L"DKG", L"DKH", L"DKI", L"DKJ", L"DKK", L"DKL", L"DKM", L"DKN", L"DKO", L"DKP", L"DKQ", L"DKR", L"DKS", L"DKT", L"DKU", L"DKV", L"DKW", L"DKX", L"DKY", L"DKZ", L"DLA", L"DLB", L"DLC", L"DLD", L"DLE", L"DLF", L"DLG", L"DLH", L"DLI", L"DLJ", L"DLK", L"DLL", L"DLM", L"DLN", L"DLO", L"DLP", L"DLQ", L"DLR", L"DLS", L"DLT", L"DLU", L"DLV", L"DLW", L"DLX", L"DLY", L"DLZ", L"DMA", L"DMB", L"DMC", L"DMD", L"DME", L"DMF", L"DMG", L"DMH", L"DMI", L"DMJ", L"DMK", L"DML", L"DMM", L"DMN", L"DMO", L"DMP", L"DMQ", L"DMR", L"DMS", L"DMT", L"DMU", L"DMV", L"DMW", L"DMX", L"DMY", L"DMZ", L"DNA", L"DNB", L"DNC", L"DND", L"DNE", L"DNF", L"DNG", L"DNH", L"DNI", L"DNJ", L"DNK", L"DNL", L"DNM", L"DNN", L"DNO", L"DNP", L"DNQ", L"DNR", L"DNS", L"DNT", L"DNU", L"DNV", L"DNW", L"DNX", L"DNY", L"DNZ", L"DOA", L"DOB", L"DOC", L"DOD", L"DOE", L"DOF", L"DOG", L"DOH", L"DOI", L"DOJ", L"DOK", L"DOL", L"DOM", L"DON", L"DOO", L"DOP", L"DOQ", L"DOR", L"DOS", L"DOT", L"DOU", L"DOV", L"DOW", L"DOX", L"DOY", L"DOZ", L"DPA", L"DPB", L"DPC", L"DPD", L"DPE", L"DPF", L"DPG", L"DPH", L"DPI", L"DPJ", L"DPK", L"DPL", L"DPM", L"DPN", L"DPO", L"DPP", L"DPQ", L"DPR", L"DPS", L"DPT", L"DPU", L"DPV", L"DPW", L"DPX", L"DPY", L"DPZ", L"DQA", L"DQB", L"DQC", L"DQD", L"DQE", L"DQF", L"DQG", L"DQH", L"DQI", L"DQJ", L"DQK", L"DQL", L"DQM", L"DQN", L"DQO", L"DQP", L"DQQ", L"DQR", L"DQS", L"DQT", L"DQU", L"DQV", L"DQW", L"DQX", L"DQY", L"DQZ", L"DRA", L"DRB", L"DRC", L"DRD", L"DRE", L"DRF", L"DRG", L"DRH", L"DRI", L"DRJ", L"DRK", L"DRL", L"DRM", L"DRN", L"DRO", L"DRP", L"DRQ", L"DRR", L"DRS", L"DRT", L"DRU", L"DRV", L"DRW", L"DRX", L"DRY", L"DRZ", L"DSA", L"DSB", L"DSC", L"DSD", L"DSE", L"DSF", L"DSG", L"DSH", L"DSI", L"DSJ", L"DSK", L"DSL", L"DSM", L"DSN", L"DSO", L"DSP", L"DSQ", L"DSR", L"DSS", L"DST", L"DSU", L"DSV", L"DSW", L"DSX", L"DSY", L"DSZ", L"DTA", L"DTB", L"DTC", L"DTD", L"DTE", L"DTF", L"DTG", L"DTH", L"DTI", L"DTJ", L"DTK", L"DTL", L"DTM", L"DTN", L"DTO", L"DTP", L"DTQ", L"DTR", L"DTS", L"DTT", L"DTU", L"DTV", L"DTW", L"DTX", L"DTY", L"DTZ", L"DUA", L"DUB", L"DUC", L"DUD", L"DUE", L"DUF", L"DUG", L"DUH", L"DUI", L"DUJ", L"DUK", L"DUL", L"DUM", L"DUN", L"DUO", L"DUP", L"DUQ", L"DUR", L"DUS", L"DUT", L"DUU", L"DUV", L"DUW", L"DUX", L"DUY", L"DUZ", L"DVA", L"DVB", L"DVC", L"DVD", L"DVE", L"DVF", L"DVG", L"DVH", L"DVI", L"DVJ", L"DVK", L"DVL", L"DVM", L"DVN", L"DVO", L"DVP", L"DVQ", L"DVR", L"DVS", L"DVT", L"DVU", L"DVV", L"DVW", L"DVX", L"DVY", L"DVZ", L"DWA", L"DWB", L"DWC", L"DWD", L"DWE", L"DWF", L"DWG", L"DWH", L"DWI", L"DWJ", L"DWK", L"DWL", L"DWM", L"DWN", L"DWO", L"DWP", L"DWQ", L"DWR", L"DWS", L"DWT", L"DWU", L"DWV", L"DWW", L"DWX", L"DWY", L"DWZ", L"DXA", L"DXB", L"DXC", L"DXD", L"DXE", L"DXF", L"DXG", L"DXH", L"DXI", L"DXJ", L"DXK", L"DXL", L"DXM", L"DXN", L"DXO", L"DXP", L"DXQ", L"DXR", L"DXS", - L"DXT", L"DXU", L"DXV", L"DXW", L"DXX", L"DXY", L"DXZ", L"DYA", L"DYB", L"DYC", L"DYD", L"DYE", L"DYF", L"DYG", L"DYH", L"DYI", L"DYJ", L"DYK", L"DYL", L"DYM", L"DYN", L"DYO", L"DYP", L"DYQ", L"DYR", L"DYS", L"DYT", L"DYU", L"DYV", L"DYW", L"DYX", L"DYY", L"DYZ", L"DZA", L"DZB", L"DZC", L"DZD", L"DZE", L"DZF", L"DZG", L"DZH", L"DZI", L"DZJ", L"DZK", L"DZL", L"DZM", L"DZN", L"DZO", L"DZP", L"DZQ", L"DZR", L"DZS", L"DZT", L"DZU", L"DZV", L"DZW", L"DZX", L"DZY", L"DZZ", L"EAA", L"EAB", L"EAC", L"EAD", L"EAE", L"EAF", L"EAG", L"EAH", L"EAI", L"EAJ", L"EAK", L"EAL", L"EAM", L"EAN", L"EAO", L"EAP", L"EAQ", L"EAR", L"EAS", L"EAT", L"EAU", L"EAV", L"EAW", L"EAX", L"EAY", L"EAZ", L"EBA", L"EBB", L"EBC", L"EBD", L"EBE", L"EBF", L"EBG", L"EBH", L"EBI", L"EBJ", L"EBK", L"EBL", L"EBM", L"EBN", L"EBO", L"EBP", L"EBQ", L"EBR", L"EBS", L"EBT", L"EBU", L"EBV", L"EBW", L"EBX", L"EBY", L"EBZ", L"ECA", L"ECB", L"ECC", L"ECD", L"ECE", L"ECF", L"ECG", L"ECH", L"ECI", L"ECJ", L"ECK", L"ECL", L"ECM", L"ECN", L"ECO", L"ECP", L"ECQ", L"ECR", L"ECS", L"ECT", L"ECU", L"ECV", L"ECW", L"ECX", L"ECY", L"ECZ", L"EDA", L"EDB", L"EDC", L"EDD", L"EDE", L"EDF", L"EDG", L"EDH", L"EDI", L"EDJ", L"EDK", L"EDL", L"EDM", L"EDN", L"EDO", L"EDP", L"EDQ", L"EDR", L"EDS", L"EDT", L"EDU", L"EDV", L"EDW", L"EDX", L"EDY", L"EDZ", L"EEA", L"EEB", L"EEC", L"EED", L"EEE", L"EEF", L"EEG", L"EEH", L"EEI", L"EEJ", L"EEK", L"EEL", L"EEM", L"EEN", L"EEO", L"EEP", L"EEQ", L"EER", L"EES", L"EET", L"EEU", L"EEV", L"EEW", L"EEX", L"EEY", L"EEZ", L"EFA", L"EFB", L"EFC", L"EFD", L"EFE", L"EFF", L"EFG", L"EFH", L"EFI", L"EFJ", L"EFK", L"EFL", L"EFM", L"EFN", L"EFO", L"EFP", L"EFQ", L"EFR", L"EFS", L"EFT", L"EFU", L"EFV", L"EFW", L"EFX", L"EFY", L"EFZ", L"EGA", L"EGB", L"EGC", L"EGD", L"EGE", L"EGF", L"EGG", L"EGH", L"EGI", L"EGJ", L"EGK", L"EGL", L"EGM", L"EGN", L"EGO", L"EGP", L"EGQ", L"EGR", L"EGS", L"EGT", L"EGU", L"EGV", L"EGW", L"EGX", L"EGY", L"EGZ", L"EHA", L"EHB", L"EHC", L"EHD", L"EHE", L"EHF", L"EHG", L"EHH", L"EHI", L"EHJ", L"EHK", L"EHL", L"EHM", L"EHN", L"EHO", L"EHP", L"EHQ", L"EHR", L"EHS", L"EHT", L"EHU", L"EHV", L"EHW", L"EHX", L"EHY", L"EHZ", L"EIA", L"EIB", L"EIC", L"EID", L"EIE", L"EIF", L"EIG", L"EIH", L"EII", L"EIJ", L"EIK", L"EIL", L"EIM", L"EIN", L"EIO", L"EIP", L"EIQ", L"EIR", L"EIS", L"EIT", L"EIU", L"EIV", L"EIW", L"EIX", L"EIY", L"EIZ", L"EJA", L"EJB", L"EJC", L"EJD", L"EJE", L"EJF", L"EJG", L"EJH", L"EJI", L"EJJ", L"EJK", L"EJL", L"EJM", L"EJN", L"EJO", L"EJP", L"EJQ", L"EJR", L"EJS", L"EJT", L"EJU", L"EJV", L"EJW", L"EJX", L"EJY", L"EJZ", L"EKA", L"EKB", L"EKC", L"EKD", L"EKE", L"EKF", L"EKG", L"EKH", L"EKI", L"EKJ", L"EKK", L"EKL", L"EKM", L"EKN", L"EKO", L"EKP", L"EKQ", L"EKR", L"EKS", L"EKT", L"EKU", L"EKV", L"EKW", L"EKX", L"EKY", L"EKZ", L"ELA", L"ELB", L"ELC", L"ELD", L"ELE", L"ELF", L"ELG", L"ELH", L"ELI", L"ELJ", L"ELK", L"ELL", L"ELM", L"ELN", L"ELO", L"ELP", L"ELQ", L"ELR", L"ELS", L"ELT", L"ELU", L"ELV", L"ELW", L"ELX", L"ELY", L"ELZ", L"EMA", L"EMB", L"EMC", L"EMD", L"EME", L"EMF", L"EMG", L"EMH", L"EMI", L"EMJ", L"EMK", L"EML", L"EMM", L"EMN", L"EMO", L"EMP", L"EMQ", L"EMR", L"EMS", L"EMT", L"EMU", L"EMV", L"EMW", L"EMX", L"EMY", L"EMZ", L"ENA", L"ENB", L"ENC", L"END", L"ENE", L"ENF", L"ENG", L"ENH", L"ENI", L"ENJ", L"ENK", L"ENL", L"ENM", L"ENN", L"ENO", L"ENP", L"ENQ", L"ENR", L"ENS", L"ENT", L"ENU", L"ENV", L"ENW", L"ENX", L"ENY", L"ENZ", L"EOA", L"EOB", L"EOC", L"EOD", L"EOE", L"EOF", L"EOG", L"EOH", L"EOI", L"EOJ", L"EOK", L"EOL", L"EOM", L"EON", L"EOO", L"EOP", L"EOQ", L"EOR", L"EOS", L"EOT", L"EOU", L"EOV", L"EOW", L"EOX", L"EOY", L"EOZ", L"EPA", L"EPB", L"EPC", L"EPD", L"EPE", L"EPF", L"EPG", L"EPH", L"EPI", L"EPJ", L"EPK", L"EPL", L"EPM", L"EPN", L"EPO", L"EPP", L"EPQ", L"EPR", L"EPS", L"EPT", L"EPU", L"EPV", L"EPW", L"EPX", L"EPY", L"EPZ", L"EQA", L"EQB", L"EQC", L"EQD", L"EQE", L"EQF", L"EQG", L"EQH", L"EQI", L"EQJ", L"EQK", L"EQL", L"EQM", L"EQN", L"EQO", L"EQP", L"EQQ", L"EQR", L"EQS", L"EQT", L"EQU", L"EQV", L"EQW", L"EQX", L"EQY", L"EQZ", L"ERA", L"ERB", L"ERC", L"ERD", L"ERE", L"ERF", L"ERG", L"ERH", L"ERI", L"ERJ", L"ERK", L"ERL", L"ERM", L"ERN", L"ERO", L"ERP", L"ERQ", L"ERR", L"ERS", L"ERT", L"ERU", L"ERV", L"ERW", L"ERX", L"ERY", L"ERZ", L"ESA", L"ESB", L"ESC", L"ESD", L"ESE", L"ESF", L"ESG", L"ESH", L"ESI", L"ESJ", L"ESK", + L"DDB", L"DDC", L"DDD", L"DDE", L"DDF", L"DDG", L"DDH", L"DDI", L"DDJ", L"DDK", L"DDL", L"DDM", L"DDN", L"DDO", L"DDP", L"DDQ", L"DDR", L"DDS", L"DDT", L"DDU", L"DDV", L"DDW", L"DDX", L"DDY", L"DDZ", L"DEA", L"DEB", L"DEC", L"DED", L"DEE", L"DEF", L"DEG", L"DEH", L"DEI", L"DEJ", L"DEK", L"DEL", L"DEM", L"DEN", L"DEO", L"DEP", L"DEQ", L"DER", L"DES", L"DET", L"DEU", L"DEV", L"DEW", L"DEX", L"DEY", L"DEZ", L"DFA", L"DFB", L"DFC", L"DFD", L"DFE", L"DFF", L"DFG", L"DFH", L"DFI", L"DFJ", L"DFK", L"DFL", L"DFM", L"DFN", L"DFO", L"DFP", L"DFQ", L"DFR", L"DFS", L"DFT", L"DFU", L"DFV", L"DFW", L"DFX", L"DFY", L"DFZ", L"DGA", L"DGB", L"DGC", L"DGD", L"DGE", L"DGF", L"DGG", L"DGH", L"DGI", L"DGJ", L"DGK", L"DGL", L"DGM", L"DGN", L"DGO", L"DGP", L"DGQ", L"DGR", L"DGS", L"DGT", L"DGU", L"DGV", L"DGW", L"DGX", L"DGY", L"DGZ", L"DHA", L"DHB", L"DHC", L"DHD", L"DHE", L"DHF", L"DHG", L"DHH", L"DHI", L"DHJ", L"DHK", L"DHL", L"DHM", L"DHN", L"DHO", L"DHP", L"DHQ", L"DHR", L"DHS", L"DHT", L"DHU", L"DHV", L"DHW", L"DHX", L"DHY", L"DHZ", L"DIA", L"DIB", L"DIC", L"DID", L"DIE", L"DIF", L"DIG", L"DIH", L"DII", L"DIJ", L"DIK", L"DIL", L"DIM", L"DIN", L"DIO", L"DIP", L"DIQ", L"DIR", L"DIS", L"DIT", L"DIU", L"DIV", L"DIW", L"DIX", L"DIY", L"DIZ", L"DJA", L"DJB", L"DJC", L"DJD", L"DJE", L"DJF", L"DJG", L"DJH", L"DJI", L"DJJ", L"DJK", L"DJL", L"DJM", L"DJN", L"DJO", L"DJP", L"DJQ", L"DJR", L"DJS", L"DJT", L"DJU", L"DJV", L"DJW", L"DJX", L"DJY", L"DJZ", L"DKA", L"DKB", L"DKC", L"DKD", L"DKE", L"DKF", L"DKG", L"DKH", L"DKI", L"DKJ", L"DKK", L"DKL", L"DKM", L"DKN", L"DKO", L"DKP", L"DKQ", L"DKR", L"DKS", L"DKT", L"DKU", L"DKV", L"DKW", L"DKX", L"DKY", L"DKZ", L"DLA", L"DLB", L"DLC", L"DLD", L"DLE", L"DLF", L"DLG", L"DLH", L"DLI", L"DLJ", L"DLK", L"DLL", L"DLM", L"DLN", L"DLO", L"DLP", L"DLQ", L"DLR", L"DLS", L"DLT", L"DLU", L"DLV", L"DLW", L"DLX", L"DLY", L"DLZ", L"DMA", L"DMB", L"DMC", L"DMD", L"DME", L"DMF", L"DMG", L"DMH", L"DMI", L"DMJ", L"DMK", L"DML", L"DMM", L"DMN", L"DMO", L"DMP", L"DMQ", L"DMR", L"DMS", L"DMT", L"DMU", L"DMV", L"DMW", L"DMX", L"DMY", L"DMZ", L"DNA", L"DNB", L"DNC", L"DND", L"DNE", L"DNF", L"DNG", L"DNH", L"DNI", L"DNJ", L"DNK", L"DNL", L"DNM", L"DNN", L"DNO", L"DNP", L"DNQ", L"DNR", L"DNS", L"DNT", L"DNU", L"DNV", L"DNW", L"DNX", L"DNY", L"DNZ", L"DOA", L"DOB", L"DOC", L"DOD", L"DOE", L"DOF", L"DOG", L"DOH", L"DOI", L"DOJ", L"DOK", L"DOL", L"DOM", L"DON", L"DOO", L"DOP", L"DOQ", L"DOR", L"DOS", L"DOT", L"DOU", L"DOV", L"DOW", L"DOX", L"DOY", L"DOZ", L"DPA", L"DPB", L"DPC", L"DPD", L"DPE", L"DPF", L"DPG", L"DPH", L"DPI", L"DPJ", L"DPK", L"DPL", L"DPM", L"DPN", L"DPO", L"DPP", L"DPQ", L"DPR", L"DPS", L"DPT", L"DPU", L"DPV", L"DPW", L"DPX", L"DPY", L"DPZ", L"DQA", L"DQB", L"DQC", L"DQD", L"DQE", L"DQF", L"DQG", L"DQH", L"DQI", L"DQJ", L"DQK", L"DQL", L"DQM", L"DQN", L"DQO", L"DQP", L"DQQ", L"DQR", L"DQS", L"DQT", L"DQU", L"DQV", L"DQW", L"DQX", L"DQY", L"DQZ", L"DRA", L"DRB", L"DRC", L"DRD", L"DRE", L"DRF", L"DRG", L"DRH", L"DRI", L"DRJ", L"DRK", L"DRL", L"DRM", L"DRN", L"DRO", L"DRP", L"DRQ", L"DRR", L"DRS", L"DRT", L"DRU", L"DRV", L"DRW", L"DRX", L"DRY", L"DRZ", L"DSA", L"DSB", L"DSC", L"DSD", L"DSE", L"DSF", L"DSG", L"DSH", L"DSI", L"DSJ", L"DSK", L"DSL", L"DSM", L"DSN", L"DSO", L"DSP", L"DSQ", L"DSR", L"DSS", L"DST", L"DSU", L"DSV", L"DSW", L"DSX", L"DSY", L"DSZ", L"DTA", L"DTB", L"DTC", L"DTD", L"DTE", L"DTF", L"DTG", L"DTH", L"DTI", L"DTJ", L"DTK", L"DTL", L"DTM", L"DTN", L"DTO", L"DTP", L"DTQ", L"DTR", L"DTS", L"DTT", L"DTU", L"DTV", L"DTW", L"DTX", L"DTY", L"DTZ", L"DUA", L"DUB", L"DUC", L"DUD", L"DUE", L"DUF", L"DUG", L"DUH", L"DUI", L"DUJ", L"DUK", L"DUL", L"DUM", L"DUN", L"DUO", L"DUP", L"DUQ", L"DUR", L"DUS", L"DUT", L"DUU", L"DUV", L"DUW", L"DUX", L"DUY", L"DUZ", L"DVA", L"DVB", L"DVC", L"DVD", L"DVE", L"DVF", L"DVG", L"DVH", L"DVI", L"DVJ", L"DVK", L"DVL", L"DVM", L"DVN", L"DVO", L"DVP", L"DVQ", L"DVR", L"DVS", L"DVT", L"DVU", L"DVV", L"DVW", L"DVX", L"DVY", L"DVZ", L"DWA", L"DWB", L"DWC", L"DWD", L"DWE", L"DWF", L"DWG", L"DWH", L"DWI", L"DWJ", L"DWK", L"DWL", L"DWM", L"DWN", L"DWO", L"DWP", L"DWQ", L"DWR", L"DWS", L"DWT", L"DWU", L"DWV", L"DWW", L"DWX", L"DWY", L"DWZ", L"DXA", L"DXB", L"DXC", L"DXD", L"DXE", L"DXF", L"DXG", L"DXH", L"DXI", L"DXJ", L"DXK", L"DXL", L"DXM", L"DXN", L"DXO", L"DXP", L"DXQ", L"DXR", L"DXS", + L"DXT", L"DXU", L"DXV", L"DXW", L"DXX", L"DXY", L"DXZ", L"DYA", L"DYB", L"DYC", L"DYD", L"DYE", L"DYF", L"DYG", L"DYH", L"DYI", L"DYJ", L"DYK", L"DYL", L"DYM", L"DYN", L"DYO", L"DYP", L"DYQ", L"DYR", L"DYS", L"DYT", L"DYU", L"DYV", L"DYW", L"DYX", L"DYY", L"DYZ", L"DZA", L"DZB", L"DZC", L"DZD", L"DZE", L"DZF", L"DZG", L"DZH", L"DZI", L"DZJ", L"DZK", L"DZL", L"DZM", L"DZN", L"DZO", L"DZP", L"DZQ", L"DZR", L"DZS", L"DZT", L"DZU", L"DZV", L"DZW", L"DZX", L"DZY", L"DZZ", L"EAA", L"EAB", L"EAC", L"EAD", L"EAE", L"EAF", L"EAG", L"EAH", L"EAI", L"EAJ", L"EAK", L"EAL", L"EAM", L"EAN", L"EAO", L"EAP", L"EAQ", L"EAR", L"EAS", L"EAT", L"EAU", L"EAV", L"EAW", L"EAX", L"EAY", L"EAZ", L"EBA", L"EBB", L"EBC", L"EBD", L"EBE", L"EBF", L"EBG", L"EBH", L"EBI", L"EBJ", L"EBK", L"EBL", L"EBM", L"EBN", L"EBO", L"EBP", L"EBQ", L"EBR", L"EBS", L"EBT", L"EBU", L"EBV", L"EBW", L"EBX", L"EBY", L"EBZ", L"ECA", L"ECB", L"ECC", L"ECD", L"ECE", L"ECF", L"ECG", L"ECH", L"ECI", L"ECJ", L"ECK", L"ECL", L"ECM", L"ECN", L"ECO", L"ECP", L"ECQ", L"ECR", L"ECS", L"ECT", L"ECU", L"ECV", L"ECW", L"ECX", L"ECY", L"ECZ", L"EDA", L"EDB", L"EDC", L"EDD", L"EDE", L"EDF", L"EDG", L"EDH", L"EDI", L"EDJ", L"EDK", L"EDL", L"EDM", L"EDN", L"EDO", L"EDP", L"EDQ", L"EDR", L"EDS", L"EDT", L"EDU", L"EDV", L"EDW", L"EDX", L"EDY", L"EDZ", L"EEA", L"EEB", L"EEC", L"EED", L"EEE", L"EEF", L"EEG", L"EEH", L"EEI", L"EEJ", L"EEK", L"EEL", L"EEM", L"EEN", L"EEO", L"EEP", L"EEQ", L"EER", L"EES", L"EET", L"EEU", L"EEV", L"EEW", L"EEX", L"EEY", L"EEZ", L"EFA", L"EFB", L"EFC", L"EFD", L"EFE", L"EFF", L"EFG", L"EFH", L"EFI", L"EFJ", L"EFK", L"EFL", L"EFM", L"EFN", L"EFO", L"EFP", L"EFQ", L"EFR", L"EFS", L"EFT", L"EFU", L"EFV", L"EFW", L"EFX", L"EFY", L"EFZ", L"EGA", L"EGB", L"EGC", L"EGD", L"EGE", L"EGF", L"EGG", L"EGH", L"EGI", L"EGJ", L"EGK", L"EGL", L"EGM", L"EGN", L"EGO", L"EGP", L"EGQ", L"EGR", L"EGS", L"EGT", L"EGU", L"EGV", L"EGW", L"EGX", L"EGY", L"EGZ", L"EHA", L"EHB", L"EHC", L"EHD", L"EHE", L"EHF", L"EHG", L"EHH", L"EHI", L"EHJ", L"EHK", L"EHL", L"EHM", L"EHN", L"EHO", L"EHP", L"EHQ", L"EHR", L"EHS", L"EHT", L"EHU", L"EHV", L"EHW", L"EHX", L"EHY", L"EHZ", L"EIA", L"EIB", L"EIC", L"EID", L"EIE", L"EIF", L"EIG", L"EIH", L"EII", L"EIJ", L"EIK", L"EIL", L"EIM", L"EIN", L"EIO", L"EIP", L"EIQ", L"EIR", L"EIS", L"EIT", L"EIU", L"EIV", L"EIW", L"EIX", L"EIY", L"EIZ", L"EJA", L"EJB", L"EJC", L"EJD", L"EJE", L"EJF", L"EJG", L"EJH", L"EJI", L"EJJ", L"EJK", L"EJL", L"EJM", L"EJN", L"EJO", L"EJP", L"EJQ", L"EJR", L"EJS", L"EJT", L"EJU", L"EJV", L"EJW", L"EJX", L"EJY", L"EJZ", L"EKA", L"EKB", L"EKC", L"EKD", L"EKE", L"EKF", L"EKG", L"EKH", L"EKI", L"EKJ", L"EKK", L"EKL", L"EKM", L"EKN", L"EKO", L"EKP", L"EKQ", L"EKR", L"EKS", L"EKT", L"EKU", L"EKV", L"EKW", L"EKX", L"EKY", L"EKZ", L"ELA", L"ELB", L"ELC", L"ELD", L"ELE", L"ELF", L"ELG", L"ELH", L"ELI", L"ELJ", L"ELK", L"ELL", L"ELM", L"ELN", L"ELO", L"ELP", L"ELQ", L"ELR", L"ELS", L"ELT", L"ELU", L"ELV", L"ELW", L"ELX", L"ELY", L"ELZ", L"EMA", L"EMB", L"EMC", L"EMD", L"EME", L"EMF", L"EMG", L"EMH", L"EMI", L"EMJ", L"EMK", L"EML", L"EMM", L"EMN", L"EMO", L"EMP", L"EMQ", L"EMR", L"EMS", L"EMT", L"EMU", L"EMV", L"EMW", L"EMX", L"EMY", L"EMZ", L"ENA", L"ENB", L"ENC", L"END", L"ENE", L"ENF", L"ENG", L"ENH", L"ENI", L"ENJ", L"ENK", L"ENL", L"ENM", L"ENN", L"ENO", L"ENP", L"ENQ", L"ENR", L"ENS", L"ENT", L"ENU", L"ENV", L"ENW", L"ENX", L"ENY", L"ENZ", L"EOA", L"EOB", L"EOC", L"EOD", L"EOE", L"EOF", L"EOG", L"EOH", L"EOI", L"EOJ", L"EOK", L"EOL", L"EOM", L"EON", L"EOO", L"EOP", L"EOQ", L"EOR", L"EOS", L"EOT", L"EOU", L"EOV", L"EOW", L"EOX", L"EOY", L"EOZ", L"EPA", L"EPB", L"EPC", L"EPD", L"EPE", L"EPF", L"EPG", L"EPH", L"EPI", L"EPJ", L"EPK", L"EPL", L"EPM", L"EPN", L"EPO", L"EPP", L"EPQ", L"EPR", L"EPS", L"EPT", L"EPU", L"EPV", L"EPW", L"EPX", L"EPY", L"EPZ", L"EQA", L"EQB", L"EQC", L"EQD", L"EQE", L"EQF", L"EQG", L"EQH", L"EQI", L"EQJ", L"EQK", L"EQL", L"EQM", L"EQN", L"EQO", L"EQP", L"EQQ", L"EQR", L"EQS", L"EQT", L"EQU", L"EQV", L"EQW", L"EQX", L"EQY", L"EQZ", L"ERA", L"ERB", L"ERC", L"ERD", L"ERE", L"ERF", L"ERG", L"ERH", L"ERI", L"ERJ", L"ERK", L"ERL", L"ERM", L"ERN", L"ERO", L"ERP", L"ERQ", L"ERR", L"ERS", L"ERT", L"ERU", L"ERV", L"ERW", L"ERX", L"ERY", L"ERZ", L"ESA", L"ESB", L"ESC", L"ESD", L"ESE", L"ESF", L"ESG", L"ESH", L"ESI", L"ESJ", L"ESK", L"ESL", L"ESM", L"ESN", L"ESO", L"ESP", L"ESQ", L"ESR", L"ESS", L"EST", L"ESU", L"ESV", L"ESW", L"ESX", L"ESY", L"ESZ", L"ETA", L"ETB", L"ETC", L"ETD", L"ETE", L"ETF", L"ETG", L"ETH", L"ETI", L"ETJ", L"ETK", L"ETL", L"ETM", L"ETN", L"ETO", L"ETP", L"ETQ", L"ETR", L"ETS", L"ETT", L"ETU", L"ETV", L"ETW", L"ETX", L"ETY", L"ETZ", L"EUA", L"EUB", L"EUC", L"EUD", L"EUE", L"EUF", L"EUG", L"EUH", L"EUI", L"EUJ", L"EUK", L"EUL", L"EUM", L"EUN", L"EUO", L"EUP", L"EUQ", L"EUR", L"EUS", L"EUT", L"EUU", L"EUV", L"EUW", L"EUX", L"EUY", L"EUZ", L"EVA", L"EVB", L"EVC", L"EVD", L"EVE", L"EVF", L"EVG", L"EVH", L"EVI", L"EVJ", L"EVK", L"EVL", L"EVM", L"EVN", L"EVO", L"EVP", L"EVQ", L"EVR", L"EVS", L"EVT", L"EVU", L"EVV", L"EVW", L"EVX", L"EVY", L"EVZ", L"EWA", L"EWB", L"EWC", L"EWD", L"EWE", L"EWF", L"EWG", L"EWH", L"EWI", L"EWJ", L"EWK", L"EWL", L"EWM", L"EWN", L"EWO", L"EWP", L"EWQ", L"EWR", L"EWS", L"EWT", L"EWU", L"EWV", L"EWW", L"EWX", L"EWY", L"EWZ", L"EXA", L"EXB", L"EXC", L"EXD", L"EXE", L"EXF", L"EXG", L"EXH", L"EXI", L"EXJ", L"EXK", L"EXL", L"EXM", L"EXN", L"EXO", L"EXP", L"EXQ", L"EXR", L"EXS", L"EXT", L"EXU", L"EXV", L"EXW", L"EXX", L"EXY", L"EXZ", L"EYA", L"EYB", L"EYC", L"EYD", L"EYE", L"EYF", L"EYG", L"EYH", L"EYI", L"EYJ", L"EYK", L"EYL", L"EYM", L"EYN", L"EYO", L"EYP", L"EYQ", L"EYR", L"EYS", L"EYT", L"EYU", L"EYV", L"EYW", L"EYX", L"EYY", L"EYZ", L"EZA", L"EZB", L"EZC", L"EZD", L"EZE", L"EZF", L"EZG", L"EZH", L"EZI", L"EZJ", L"EZK", L"EZL", L"EZM", L"EZN", L"EZO", L"EZP", L"EZQ", L"EZR", L"EZS", L"EZT", L"EZU", L"EZV", L"EZW", L"EZX", L"EZY", L"EZZ", L"FAA", L"FAB", L"FAC", L"FAD", L"FAE", L"FAF", L"FAG", L"FAH", L"FAI", L"FAJ", L"FAK", L"FAL", L"FAM", L"FAN", L"FAO", L"FAP", L"FAQ", L"FAR", L"FAS", L"FAT", L"FAU", L"FAV", L"FAW", L"FAX", L"FAY", L"FAZ", L"FBA", L"FBB", L"FBC", L"FBD", L"FBE", L"FBF", L"FBG", L"FBH", L"FBI", L"FBJ", L"FBK", L"FBL", L"FBM", L"FBN", L"FBO", L"FBP", L"FBQ", L"FBR", L"FBS", L"FBT", L"FBU", L"FBV", L"FBW", L"FBX", L"FBY", L"FBZ", L"FCA", L"FCB", L"FCC", L"FCD", L"FCE", L"FCF", L"FCG", L"FCH", L"FCI", L"FCJ", L"FCK", L"FCL", L"FCM", L"FCN", L"FCO", L"FCP", L"FCQ", L"FCR", L"FCS", L"FCT", L"FCU", L"FCV", L"FCW", L"FCX", L"FCY", L"FCZ", L"FDA", L"FDB", L"FDC", L"FDD", L"FDE", L"FDF", - L"FDG", L"FDH", L"FDI", L"FDJ", L"FDK", L"FDL", L"FDM", L"FDN", L"FDO", L"FDP", L"FDQ", L"FDR", L"FDS", L"FDT", L"FDU", L"FDV", L"FDW", L"FDX", L"FDY", L"FDZ", L"FEA", L"FEB", L"FEC", L"FED", L"FEE", L"FEF", L"FEG", L"FEH", L"FEI", L"FEJ", L"FEK", L"FEL", L"FEM", L"FEN", L"FEO", L"FEP", L"FEQ", L"FER", L"FES", L"FET", L"FEU", L"FEV", L"FEW", L"FEX", L"FEY", L"FEZ", L"FFA", L"FFB", L"FFC", L"FFD", L"FFE", L"FFF", L"FFG", L"FFH", L"FFI", L"FFJ", L"FFK", L"FFL", L"FFM", L"FFN", L"FFO", L"FFP", L"FFQ", L"FFR", L"FFS", L"FFT", L"FFU", L"FFV", L"FFW", L"FFX", L"FFY", L"FFZ", L"FGA", L"FGB", L"FGC", L"FGD", L"FGE", L"FGF", L"FGG", L"FGH", L"FGI", L"FGJ", L"FGK", L"FGL", L"FGM", L"FGN", L"FGO", L"FGP", L"FGQ", L"FGR", L"FGS", L"FGT", L"FGU", L"FGV", L"FGW", L"FGX", L"FGY", L"FGZ", L"FHA", L"FHB", L"FHC", L"FHD", L"FHE", L"FHF", L"FHG", L"FHH", L"FHI", L"FHJ", L"FHK", L"FHL", L"FHM", L"FHN", L"FHO", L"FHP", L"FHQ", L"FHR", L"FHS", L"FHT", L"FHU", L"FHV", L"FHW", L"FHX", L"FHY", L"FHZ", L"FIA", L"FIB", L"FIC", L"FID", L"FIE", L"FIF", L"FIG", L"FIH", L"FII", L"FIJ", L"FIK", L"FIL", L"FIM", L"FIN", L"FIO", L"FIP", L"FIQ", L"FIR", L"FIS", L"FIT", L"FIU", L"FIV", L"FIW", L"FIX", L"FIY", L"FIZ", L"FJA", L"FJB", L"FJC", L"FJD", L"FJE", L"FJF", L"FJG", L"FJH", L"FJI", L"FJJ", L"FJK", L"FJL", L"FJM", L"FJN", L"FJO", L"FJP", L"FJQ", L"FJR", L"FJS", L"FJT", L"FJU", L"FJV", L"FJW", L"FJX", L"FJY", L"FJZ", L"FKA", L"FKB", L"FKC", L"FKD", L"FKE", L"FKF", L"FKG", L"FKH", L"FKI", L"FKJ", L"FKK", L"FKL", L"FKM", L"FKN", L"FKO", L"FKP", L"FKQ", L"FKR", L"FKS", L"FKT", L"FKU", L"FKV", L"FKW", L"FKX", L"FKY", L"FKZ", L"FLA", L"FLB", L"FLC", L"FLD", L"FLE", L"FLF", L"FLG", L"FLH", L"FLI", L"FLJ", L"FLK", L"FLL", L"FLM", L"FLN", L"FLO", L"FLP", L"FLQ", L"FLR", L"FLS", L"FLT", L"FLU", L"FLV", L"FLW", L"FLX", L"FLY", L"FLZ", L"FMA", L"FMB", L"FMC", L"FMD", L"FME", L"FMF", L"FMG", L"FMH", L"FMI", L"FMJ", L"FMK", L"FML", L"FMM", L"FMN", L"FMO", L"FMP", L"FMQ", L"FMR", L"FMS", L"FMT", L"FMU", L"FMV", L"FMW", L"FMX", L"FMY", L"FMZ", L"FNA", L"FNB", L"FNC", L"FND", L"FNE", L"FNF", L"FNG", L"FNH", L"FNI", L"FNJ", L"FNK", L"FNL", L"FNM", L"FNN", L"FNO", L"FNP", L"FNQ", L"FNR", L"FNS", L"FNT", L"FNU", L"FNV", L"FNW", L"FNX", L"FNY", L"FNZ", L"FOA", L"FOB", L"FOC", L"FOD", L"FOE", L"FOF", L"FOG", L"FOH", L"FOI", L"FOJ", L"FOK", L"FOL", L"FOM", L"FON", L"FOO", L"FOP", L"FOQ", L"FOR", L"FOS", L"FOT", L"FOU", L"FOV", L"FOW", L"FOX", L"FOY", L"FOZ", L"FPA", L"FPB", L"FPC", L"FPD", L"FPE", L"FPF", L"FPG", L"FPH", L"FPI", L"FPJ", L"FPK", L"FPL", L"FPM", L"FPN", L"FPO", L"FPP", L"FPQ", L"FPR", L"FPS", L"FPT", L"FPU", L"FPV", L"FPW", L"FPX", L"FPY", L"FPZ", L"FQA", L"FQB", L"FQC", L"FQD", L"FQE", L"FQF", L"FQG", L"FQH", L"FQI", L"FQJ", L"FQK", L"FQL", L"FQM", L"FQN", L"FQO", L"FQP", L"FQQ", L"FQR", L"FQS", L"FQT", L"FQU", L"FQV", L"FQW", L"FQX", L"FQY", L"FQZ", L"FRA", L"FRB", L"FRC", L"FRD", L"FRE", L"FRF", L"FRG", L"FRH", L"FRI", L"FRJ", L"FRK", L"FRL", L"FRM", L"FRN", L"FRO", L"FRP", L"FRQ", L"FRR", L"FRS", L"FRT", L"FRU", L"FRV", L"FRW", L"FRX", L"FRY", L"FRZ", L"FSA", L"FSB", L"FSC", L"FSD", L"FSE", L"FSF", L"FSG", L"FSH", L"FSI", L"FSJ", L"FSK", L"FSL", L"FSM", L"FSN", L"FSO", L"FSP", L"FSQ", L"FSR", L"FSS", L"FST", L"FSU", L"FSV", L"FSW", L"FSX", L"FSY", L"FSZ", L"FTA", L"FTB", L"FTC", L"FTD", L"FTE", L"FTF", L"FTG", L"FTH", L"FTI", L"FTJ", L"FTK", L"FTL", L"FTM", L"FTN", L"FTO", L"FTP", L"FTQ", L"FTR", L"FTS", L"FTT", L"FTU", L"FTV", L"FTW", L"FTX", L"FTY", L"FTZ", L"FUA", L"FUB", L"FUC", L"FUD", L"FUE", L"FUF", L"FUG", L"FUH", L"FUI", L"FUJ", L"FUK", L"FUL", L"FUM", L"FUN", L"FUO", L"FUP", L"FUQ", L"FUR", L"FUS", L"FUT", L"FUU", L"FUV", L"FUW", L"FUX", L"FUY", L"FUZ", L"FVA", L"FVB", L"FVC", L"FVD", L"FVE", L"FVF", L"FVG", L"FVH", L"FVI", L"FVJ", L"FVK", L"FVL", L"FVM", L"FVN", L"FVO", L"FVP", L"FVQ", L"FVR", L"FVS", L"FVT", L"FVU", L"FVV", L"FVW", L"FVX", L"FVY", L"FVZ", L"FWA", L"FWB", L"FWC", L"FWD", L"FWE", L"FWF", L"FWG", L"FWH", L"FWI", L"FWJ", L"FWK", L"FWL", L"FWM", L"FWN", L"FWO", L"FWP", L"FWQ", L"FWR", L"FWS", L"FWT", L"FWU", L"FWV", L"FWW", L"FWX", L"FWY", L"FWZ", L"FXA", L"FXB", L"FXC", L"FXD", L"FXE", L"FXF", L"FXG", L"FXH", L"FXI", L"FXJ", L"FXK", L"FXL", L"FXM", L"FXN", L"FXO", L"FXP", L"FXQ", L"FXR", L"FXS", L"FXT", L"FXU", L"FXV", L"FXW", L"FXX", + L"FDG", L"FDH", L"FDI", L"FDJ", L"FDK", L"FDL", L"FDM", L"FDN", L"FDO", L"FDP", L"FDQ", L"FDR", L"FDS", L"FDT", L"FDU", L"FDV", L"FDW", L"FDX", L"FDY", L"FDZ", L"FEA", L"FEB", L"FEC", L"FED", L"FEE", L"FEF", L"FEG", L"FEH", L"FEI", L"FEJ", L"FEK", L"FEL", L"FEM", L"FEN", L"FEO", L"FEP", L"FEQ", L"FER", L"FES", L"FET", L"FEU", L"FEV", L"FEW", L"FEX", L"FEY", L"FEZ", L"FFA", L"FFB", L"FFC", L"FFD", L"FFE", L"FFF", L"FFG", L"FFH", L"FFI", L"FFJ", L"FFK", L"FFL", L"FFM", L"FFN", L"FFO", L"FFP", L"FFQ", L"FFR", L"FFS", L"FFT", L"FFU", L"FFV", L"FFW", L"FFX", L"FFY", L"FFZ", L"FGA", L"FGB", L"FGC", L"FGD", L"FGE", L"FGF", L"FGG", L"FGH", L"FGI", L"FGJ", L"FGK", L"FGL", L"FGM", L"FGN", L"FGO", L"FGP", L"FGQ", L"FGR", L"FGS", L"FGT", L"FGU", L"FGV", L"FGW", L"FGX", L"FGY", L"FGZ", L"FHA", L"FHB", L"FHC", L"FHD", L"FHE", L"FHF", L"FHG", L"FHH", L"FHI", L"FHJ", L"FHK", L"FHL", L"FHM", L"FHN", L"FHO", L"FHP", L"FHQ", L"FHR", L"FHS", L"FHT", L"FHU", L"FHV", L"FHW", L"FHX", L"FHY", L"FHZ", L"FIA", L"FIB", L"FIC", L"FID", L"FIE", L"FIF", L"FIG", L"FIH", L"FII", L"FIJ", L"FIK", L"FIL", L"FIM", L"FIN", L"FIO", L"FIP", L"FIQ", L"FIR", L"FIS", L"FIT", L"FIU", L"FIV", L"FIW", L"FIX", L"FIY", L"FIZ", L"FJA", L"FJB", L"FJC", L"FJD", L"FJE", L"FJF", L"FJG", L"FJH", L"FJI", L"FJJ", L"FJK", L"FJL", L"FJM", L"FJN", L"FJO", L"FJP", L"FJQ", L"FJR", L"FJS", L"FJT", L"FJU", L"FJV", L"FJW", L"FJX", L"FJY", L"FJZ", L"FKA", L"FKB", L"FKC", L"FKD", L"FKE", L"FKF", L"FKG", L"FKH", L"FKI", L"FKJ", L"FKK", L"FKL", L"FKM", L"FKN", L"FKO", L"FKP", L"FKQ", L"FKR", L"FKS", L"FKT", L"FKU", L"FKV", L"FKW", L"FKX", L"FKY", L"FKZ", L"FLA", L"FLB", L"FLC", L"FLD", L"FLE", L"FLF", L"FLG", L"FLH", L"FLI", L"FLJ", L"FLK", L"FLL", L"FLM", L"FLN", L"FLO", L"FLP", L"FLQ", L"FLR", L"FLS", L"FLT", L"FLU", L"FLV", L"FLW", L"FLX", L"FLY", L"FLZ", L"FMA", L"FMB", L"FMC", L"FMD", L"FME", L"FMF", L"FMG", L"FMH", L"FMI", L"FMJ", L"FMK", L"FML", L"FMM", L"FMN", L"FMO", L"FMP", L"FMQ", L"FMR", L"FMS", L"FMT", L"FMU", L"FMV", L"FMW", L"FMX", L"FMY", L"FMZ", L"FNA", L"FNB", L"FNC", L"FND", L"FNE", L"FNF", L"FNG", L"FNH", L"FNI", L"FNJ", L"FNK", L"FNL", L"FNM", L"FNN", L"FNO", L"FNP", L"FNQ", L"FNR", L"FNS", L"FNT", L"FNU", L"FNV", L"FNW", L"FNX", L"FNY", L"FNZ", L"FOA", L"FOB", L"FOC", L"FOD", L"FOE", L"FOF", L"FOG", L"FOH", L"FOI", L"FOJ", L"FOK", L"FOL", L"FOM", L"FON", L"FOO", L"FOP", L"FOQ", L"FOR", L"FOS", L"FOT", L"FOU", L"FOV", L"FOW", L"FOX", L"FOY", L"FOZ", L"FPA", L"FPB", L"FPC", L"FPD", L"FPE", L"FPF", L"FPG", L"FPH", L"FPI", L"FPJ", L"FPK", L"FPL", L"FPM", L"FPN", L"FPO", L"FPP", L"FPQ", L"FPR", L"FPS", L"FPT", L"FPU", L"FPV", L"FPW", L"FPX", L"FPY", L"FPZ", L"FQA", L"FQB", L"FQC", L"FQD", L"FQE", L"FQF", L"FQG", L"FQH", L"FQI", L"FQJ", L"FQK", L"FQL", L"FQM", L"FQN", L"FQO", L"FQP", L"FQQ", L"FQR", L"FQS", L"FQT", L"FQU", L"FQV", L"FQW", L"FQX", L"FQY", L"FQZ", L"FRA", L"FRB", L"FRC", L"FRD", L"FRE", L"FRF", L"FRG", L"FRH", L"FRI", L"FRJ", L"FRK", L"FRL", L"FRM", L"FRN", L"FRO", L"FRP", L"FRQ", L"FRR", L"FRS", L"FRT", L"FRU", L"FRV", L"FRW", L"FRX", L"FRY", L"FRZ", L"FSA", L"FSB", L"FSC", L"FSD", L"FSE", L"FSF", L"FSG", L"FSH", L"FSI", L"FSJ", L"FSK", L"FSL", L"FSM", L"FSN", L"FSO", L"FSP", L"FSQ", L"FSR", L"FSS", L"FST", L"FSU", L"FSV", L"FSW", L"FSX", L"FSY", L"FSZ", L"FTA", L"FTB", L"FTC", L"FTD", L"FTE", L"FTF", L"FTG", L"FTH", L"FTI", L"FTJ", L"FTK", L"FTL", L"FTM", L"FTN", L"FTO", L"FTP", L"FTQ", L"FTR", L"FTS", L"FTT", L"FTU", L"FTV", L"FTW", L"FTX", L"FTY", L"FTZ", L"FUA", L"FUB", L"FUC", L"FUD", L"FUE", L"FUF", L"FUG", L"FUH", L"FUI", L"FUJ", L"FUK", L"FUL", L"FUM", L"FUN", L"FUO", L"FUP", L"FUQ", L"FUR", L"FUS", L"FUT", L"FUU", L"FUV", L"FUW", L"FUX", L"FUY", L"FUZ", L"FVA", L"FVB", L"FVC", L"FVD", L"FVE", L"FVF", L"FVG", L"FVH", L"FVI", L"FVJ", L"FVK", L"FVL", L"FVM", L"FVN", L"FVO", L"FVP", L"FVQ", L"FVR", L"FVS", L"FVT", L"FVU", L"FVV", L"FVW", L"FVX", L"FVY", L"FVZ", L"FWA", L"FWB", L"FWC", L"FWD", L"FWE", L"FWF", L"FWG", L"FWH", L"FWI", L"FWJ", L"FWK", L"FWL", L"FWM", L"FWN", L"FWO", L"FWP", L"FWQ", L"FWR", L"FWS", L"FWT", L"FWU", L"FWV", L"FWW", L"FWX", L"FWY", L"FWZ", L"FXA", L"FXB", L"FXC", L"FXD", L"FXE", L"FXF", L"FXG", L"FXH", L"FXI", L"FXJ", L"FXK", L"FXL", L"FXM", L"FXN", L"FXO", L"FXP", L"FXQ", L"FXR", L"FXS", L"FXT", L"FXU", L"FXV", L"FXW", L"FXX", L"FXY", L"FXZ", L"FYA", L"FYB", L"FYC", L"FYD", L"FYE", L"FYF", L"FYG", L"FYH", L"FYI", L"FYJ", L"FYK", L"FYL", L"FYM", L"FYN", L"FYO", L"FYP", L"FYQ", L"FYR", L"FYS", L"FYT", L"FYU", L"FYV", L"FYW", L"FYX", L"FYY", L"FYZ", L"FZA", L"FZB", L"FZC", L"FZD", L"FZE", L"FZF", L"FZG", L"FZH", L"FZI", L"FZJ", L"FZK", L"FZL", L"FZM", L"FZN", L"FZO", L"FZP", L"FZQ", L"FZR", L"FZS", L"FZT", L"FZU", L"FZV", L"FZW", L"FZX", L"FZY", L"FZZ", L"GAA", L"GAB", L"GAC", L"GAD", L"GAE", L"GAF", L"GAG", L"GAH", L"GAI", L"GAJ", L"GAK", L"GAL", L"GAM", L"GAN", L"GAO", L"GAP", L"GAQ", L"GAR", L"GAS", L"GAT", L"GAU", L"GAV", L"GAW", L"GAX", L"GAY", L"GAZ", L"GBA", L"GBB", L"GBC", L"GBD", L"GBE", L"GBF", L"GBG", L"GBH", L"GBI", L"GBJ", L"GBK", L"GBL", L"GBM", L"GBN", L"GBO", L"GBP", L"GBQ", L"GBR", L"GBS", L"GBT", L"GBU", L"GBV", L"GBW", L"GBX", L"GBY", L"GBZ", L"GCA", L"GCB", L"GCC", L"GCD", L"GCE", L"GCF", L"GCG", L"GCH", L"GCI", L"GCJ", L"GCK", L"GCL", L"GCM", L"GCN", L"GCO", L"GCP", L"GCQ", L"GCR", L"GCS", L"GCT", L"GCU", L"GCV", L"GCW", L"GCX", L"GCY", L"GCZ", L"GDA", L"GDB", L"GDC", L"GDD", L"GDE", L"GDF", L"GDG", L"GDH", L"GDI", L"GDJ", L"GDK", L"GDL", L"GDM", L"GDN", L"GDO", L"GDP", L"GDQ", L"GDR", L"GDS", L"GDT", L"GDU", L"GDV", L"GDW", L"GDX", L"GDY", L"GDZ", L"GEA", L"GEB", L"GEC", L"GED", L"GEE", L"GEF", L"GEG", L"GEH", L"GEI", L"GEJ", L"GEK", L"GEL", L"GEM", L"GEN", L"GEO", L"GEP", L"GEQ", L"GER", L"GES", L"GET", L"GEU", L"GEV", L"GEW", L"GEX", L"GEY", L"GEZ", L"GFA", L"GFB", L"GFC", L"GFD", L"GFE", L"GFF", L"GFG", L"GFH", L"GFI", L"GFJ", L"GFK", L"GFL", L"GFM", L"GFN", L"GFO", L"GFP", L"GFQ", L"GFR", L"GFS", L"GFT", L"GFU", L"GFV", L"GFW", L"GFX", L"GFY", L"GFZ", L"GGA", L"GGB", L"GGC", L"GGD", L"GGE", L"GGF", L"GGG", L"GGH", L"GGI", L"GGJ", L"GGK", L"GGL", L"GGM", L"GGN", L"GGO", L"GGP", L"GGQ", L"GGR", L"GGS", L"GGT", L"GGU", L"GGV", L"GGW", L"GGX", L"GGY", L"GGZ", L"GHA", L"GHB", L"GHC", L"GHD", L"GHE", L"GHF", L"GHG", L"GHH", L"GHI", L"GHJ", L"GHK", L"GHL", L"GHM", L"GHN", L"GHO", L"GHP", L"GHQ", L"GHR", L"GHS", L"GHT", L"GHU", L"GHV", L"GHW", L"GHX", L"GHY", L"GHZ", L"GIA", L"GIB", L"GIC", L"GID", L"GIE", L"GIF", L"GIG", L"GIH", L"GII", L"GIJ", L"GIK", L"GIL", L"GIM", L"GIN", L"GIO", L"GIP", L"GIQ", L"GIR", L"GIS", - L"GIT", L"GIU", L"GIV", L"GIW", L"GIX", L"GIY", L"GIZ", L"GJA", L"GJB", L"GJC", L"GJD", L"GJE", L"GJF", L"GJG", L"GJH", L"GJI", L"GJJ", L"GJK", L"GJL", L"GJM", L"GJN", L"GJO", L"GJP", L"GJQ", L"GJR", L"GJS", L"GJT", L"GJU", L"GJV", L"GJW", L"GJX", L"GJY", L"GJZ", L"GKA", L"GKB", L"GKC", L"GKD", L"GKE", L"GKF", L"GKG", L"GKH", L"GKI", L"GKJ", L"GKK", L"GKL", L"GKM", L"GKN", L"GKO", L"GKP", L"GKQ", L"GKR", L"GKS", L"GKT", L"GKU", L"GKV", L"GKW", L"GKX", L"GKY", L"GKZ", L"GLA", L"GLB", L"GLC", L"GLD", L"GLE", L"GLF", L"GLG", L"GLH", L"GLI", L"GLJ", L"GLK", L"GLL", L"GLM", L"GLN", L"GLO", L"GLP", L"GLQ", L"GLR", L"GLS", L"GLT", L"GLU", L"GLV", L"GLW", L"GLX", L"GLY", L"GLZ", L"GMA", L"GMB", L"GMC", L"GMD", L"GME", L"GMF", L"GMG", L"GMH", L"GMI", L"GMJ", L"GMK", L"GML", L"GMM", L"GMN", L"GMO", L"GMP", L"GMQ", L"GMR", L"GMS", L"GMT", L"GMU", L"GMV", L"GMW", L"GMX", L"GMY", L"GMZ", L"GNA", L"GNB", L"GNC", L"GND", L"GNE", L"GNF", L"GNG", L"GNH", L"GNI", L"GNJ", L"GNK", L"GNL", L"GNM", L"GNN", L"GNO", L"GNP", L"GNQ", L"GNR", L"GNS", L"GNT", L"GNU", L"GNV", L"GNW", L"GNX", L"GNY", L"GNZ", L"GOA", L"GOB", L"GOC", L"GOD", L"GOE", L"GOF", L"GOG", L"GOH", L"GOI", L"GOJ", L"GOK", L"GOL", L"GOM", L"GON", L"GOO", L"GOP", L"GOQ", L"GOR", L"GOS", L"GOT", L"GOU", L"GOV", L"GOW", L"GOX", L"GOY", L"GOZ", L"GPA", L"GPB", L"GPC", L"GPD", L"GPE", L"GPF", L"GPG", L"GPH", L"GPI", L"GPJ", L"GPK", L"GPL", L"GPM", L"GPN", L"GPO", L"GPP", L"GPQ", L"GPR", L"GPS", L"GPT", L"GPU", L"GPV", L"GPW", L"GPX", L"GPY", L"GPZ", L"GQA", L"GQB", L"GQC", L"GQD", L"GQE", L"GQF", L"GQG", L"GQH", L"GQI", L"GQJ", L"GQK", L"GQL", L"GQM", L"GQN", L"GQO", L"GQP", L"GQQ", L"GQR", L"GQS", L"GQT", L"GQU", L"GQV", L"GQW", L"GQX", L"GQY", L"GQZ", L"GRA", L"GRB", L"GRC", L"GRD", L"GRE", L"GRF", L"GRG", L"GRH", L"GRI", L"GRJ", L"GRK", L"GRL", L"GRM", L"GRN", L"GRO", L"GRP", L"GRQ", L"GRR", L"GRS", L"GRT", L"GRU", L"GRV", L"GRW", L"GRX", L"GRY", L"GRZ", L"GSA", L"GSB", L"GSC", L"GSD", L"GSE", L"GSF", L"GSG", L"GSH", L"GSI", L"GSJ", L"GSK", L"GSL", L"GSM", L"GSN", L"GSO", L"GSP", L"GSQ", L"GSR", L"GSS", L"GST", L"GSU", L"GSV", L"GSW", L"GSX", L"GSY", L"GSZ", L"GTA", L"GTB", L"GTC", L"GTD", L"GTE", L"GTF", - L"GTG", L"GTH", L"GTI", L"GTJ", L"GTK", L"GTL", L"GTM", L"GTN", L"GTO", L"GTP", L"GTQ", L"GTR", L"GTS", L"GTT", L"GTU", L"GTV", L"GTW", L"GTX", L"GTY", L"GTZ", L"GUA", L"GUB", L"GUC", L"GUD", L"GUE", L"GUF", L"GUG", L"GUH", L"GUI", L"GUJ", L"GUK", L"GUL", L"GUM", L"GUN", L"GUO", L"GUP", L"GUQ", L"GUR", L"GUS", L"GUT", L"GUU", L"GUV", L"GUW", L"GUX", L"GUY", L"GUZ", L"GVA", L"GVB", L"GVC", L"GVD", L"GVE", L"GVF", L"GVG", L"GVH", L"GVI", L"GVJ", L"GVK", L"GVL", L"GVM", L"GVN", L"GVO", L"GVP", L"GVQ", L"GVR", L"GVS", L"GVT", L"GVU", L"GVV", L"GVW", L"GVX", L"GVY", L"GVZ", L"GWA", L"GWB", L"GWC", L"GWD", L"GWE", L"GWF", L"GWG", L"GWH", L"GWI", L"GWJ", L"GWK", L"GWL", L"GWM", L"GWN", L"GWO", L"GWP", L"GWQ", L"GWR", L"GWS", L"GWT", L"GWU", L"GWV", L"GWW", L"GWX", L"GWY", L"GWZ", L"GXA", L"GXB", L"GXC", L"GXD", L"GXE", L"GXF", L"GXG", L"GXH", L"GXI", L"GXJ", L"GXK", L"GXL", L"GXM", L"GXN", L"GXO", L"GXP", L"GXQ", L"GXR", L"GXS", L"GXT", L"GXU", L"GXV", L"GXW", L"GXX", L"GXY", L"GXZ", L"GYA", L"GYB", L"GYC", L"GYD", L"GYE", L"GYF", L"GYG", L"GYH", L"GYI", L"GYJ", L"GYK", L"GYL", L"GYM", L"GYN", L"GYO", L"GYP", L"GYQ", L"GYR", L"GYS", L"GYT", L"GYU", L"GYV", L"GYW", L"GYX", L"GYY", L"GYZ", L"GZA", L"GZB", L"GZC", L"GZD", L"GZE", L"GZF", L"GZG", L"GZH", L"GZI", L"GZJ", L"GZK", L"GZL", L"GZM", L"GZN", L"GZO", L"GZP", L"GZQ", L"GZR", L"GZS", L"GZT", L"GZU", L"GZV", L"GZW", L"GZX", L"GZY", L"GZZ", L"HAA", L"HAB", L"HAC", L"HAD", L"HAE", L"HAF", L"HAG", L"HAH", L"HAI", L"HAJ", L"HAK", L"HAL", L"HAM", L"HAN", L"HAO", L"HAP", L"HAQ", L"HAR", L"HAS", L"HAT", L"HAU", L"HAV", L"HAW", L"HAX", L"HAY", L"HAZ", L"HBA", L"HBB", L"HBC", L"HBD", L"HBE", L"HBF", L"HBG", L"HBH", L"HBI", L"HBJ", L"HBK", L"HBL", L"HBM", L"HBN", L"HBO", L"HBP", L"HBQ", L"HBR", L"HBS", L"HBT", L"HBU", L"HBV", L"HBW", L"HBX", L"HBY", L"HBZ", L"HCA", L"HCB", L"HCC", L"HCD", L"HCE", L"HCF", L"HCG", L"HCH", L"HCI", L"HCJ", L"HCK", L"HCL", L"HCM", L"HCN", L"HCO", L"HCP", L"HCQ", L"HCR", L"HCS", L"HCT", L"HCU", L"HCV", L"HCW", L"HCX", L"HCY", L"HCZ", L"HDA", L"HDB", L"HDC", L"HDD", L"HDE", L"HDF", L"HDG", L"HDH", L"HDI", L"HDJ", L"HDK", L"HDL", L"HDM", L"HDN", L"HDO", L"HDP", L"HDQ", L"HDR", L"HDS", - L"HDT", L"HDU", L"HDV", L"HDW", L"HDX", L"HDY", L"HDZ", L"HEA", L"HEB", L"HEC", L"HED", L"HEE", L"HEF", L"HEG", L"HEH", L"HEI", L"HEJ", L"HEK", L"HEL", L"HEM", L"HEN", L"HEO", L"HEP", L"HEQ", L"HER", L"HES", L"HET", L"HEU", L"HEV", L"HEW", L"HEX", L"HEY", L"HEZ", L"HFA", L"HFB", L"HFC", L"HFD", L"HFE", L"HFF", L"HFG", L"HFH", L"HFI", L"HFJ", L"HFK", L"HFL", L"HFM", L"HFN", L"HFO", L"HFP", L"HFQ", L"HFR", L"HFS", L"HFT", L"HFU", L"HFV", L"HFW", L"HFX", L"HFY", L"HFZ", L"HGA", L"HGB", L"HGC", L"HGD", L"HGE", L"HGF", L"HGG", L"HGH", L"HGI", L"HGJ", L"HGK", L"HGL", L"HGM", L"HGN", L"HGO", L"HGP", L"HGQ", L"HGR", L"HGS", L"HGT", L"HGU", L"HGV", L"HGW", L"HGX", L"HGY", L"HGZ", L"HHA", L"HHB", L"HHC", L"HHD", L"HHE", L"HHF", L"HHG", L"HHH", L"HHI", L"HHJ", L"HHK", L"HHL", L"HHM", L"HHN", L"HHO", L"HHP", L"HHQ", L"HHR", L"HHS", L"HHT", L"HHU", L"HHV", L"HHW", L"HHX", L"HHY", L"HHZ", L"HIA", L"HIB", L"HIC", L"HID", L"HIE", L"HIF", L"HIG", L"HIH", L"HII", L"HIJ", L"HIK", L"HIL", L"HIM", L"HIN", L"HIO", L"HIP", L"HIQ", L"HIR", L"HIS", L"HIT", L"HIU", L"HIV", L"HIW", L"HIX", L"HIY", L"HIZ", L"HJA", L"HJB", L"HJC", L"HJD", L"HJE", L"HJF", L"HJG", L"HJH", L"HJI", L"HJJ", L"HJK", L"HJL", L"HJM", L"HJN", L"HJO", L"HJP", L"HJQ", L"HJR", L"HJS", L"HJT", L"HJU", L"HJV", L"HJW", L"HJX", L"HJY", L"HJZ", L"HKA", L"HKB", L"HKC", L"HKD", L"HKE", L"HKF", L"HKG", L"HKH", L"HKI", L"HKJ", L"HKK", L"HKL", L"HKM", L"HKN", L"HKO", L"HKP", L"HKQ", L"HKR", L"HKS", L"HKT", L"HKU", L"HKV", L"HKW", L"HKX", L"HKY", L"HKZ", L"HLA", L"HLB", L"HLC", L"HLD", L"HLE", L"HLF", L"HLG", L"HLH", L"HLI", L"HLJ", L"HLK", L"HLL", L"HLM", L"HLN", L"HLO", L"HLP", L"HLQ", L"HLR", L"HLS", L"HLT", L"HLU", L"HLV", L"HLW", L"HLX", L"HLY", L"HLZ", L"HMA", L"HMB", L"HMC", L"HMD", L"HME", L"HMF", L"HMG", L"HMH", L"HMI", L"HMJ", L"HMK", L"HML", L"HMM", L"HMN", L"HMO", L"HMP", L"HMQ", L"HMR", L"HMS", L"HMT", L"HMU", L"HMV", L"HMW", L"HMX", L"HMY", L"HMZ", L"HNA", L"HNB", L"HNC", L"HND", L"HNE", L"HNF", L"HNG", L"HNH", L"HNI", L"HNJ", L"HNK", L"HNL", L"HNM", L"HNN", L"HNO", L"HNP", L"HNQ", L"HNR", L"HNS", L"HNT", L"HNU", L"HNV", L"HNW", L"HNX", L"HNY", L"HNZ", L"HOA", L"HOB", L"HOC", L"HOD", L"HOE", L"HOF", + L"GIT", L"GIU", L"GIV", L"GIW", L"GIX", L"GIY", L"GIZ", L"GJA", L"GJB", L"GJC", L"GJD", L"GJE", L"GJF", L"GJG", L"GJH", L"GJI", L"GJJ", L"GJK", L"GJL", L"GJM", L"GJN", L"GJO", L"GJP", L"GJQ", L"GJR", L"GJS", L"GJT", L"GJU", L"GJV", L"GJW", L"GJX", L"GJY", L"GJZ", L"GKA", L"GKB", L"GKC", L"GKD", L"GKE", L"GKF", L"GKG", L"GKH", L"GKI", L"GKJ", L"GKK", L"GKL", L"GKM", L"GKN", L"GKO", L"GKP", L"GKQ", L"GKR", L"GKS", L"GKT", L"GKU", L"GKV", L"GKW", L"GKX", L"GKY", L"GKZ", L"GLA", L"GLB", L"GLC", L"GLD", L"GLE", L"GLF", L"GLG", L"GLH", L"GLI", L"GLJ", L"GLK", L"GLL", L"GLM", L"GLN", L"GLO", L"GLP", L"GLQ", L"GLR", L"GLS", L"GLT", L"GLU", L"GLV", L"GLW", L"GLX", L"GLY", L"GLZ", L"GMA", L"GMB", L"GMC", L"GMD", L"GME", L"GMF", L"GMG", L"GMH", L"GMI", L"GMJ", L"GMK", L"GML", L"GMM", L"GMN", L"GMO", L"GMP", L"GMQ", L"GMR", L"GMS", L"GMT", L"GMU", L"GMV", L"GMW", L"GMX", L"GMY", L"GMZ", L"GNA", L"GNB", L"GNC", L"GND", L"GNE", L"GNF", L"GNG", L"GNH", L"GNI", L"GNJ", L"GNK", L"GNL", L"GNM", L"GNN", L"GNO", L"GNP", L"GNQ", L"GNR", L"GNS", L"GNT", L"GNU", L"GNV", L"GNW", L"GNX", L"GNY", L"GNZ", L"GOA", L"GOB", L"GOC", L"GOD", L"GOE", L"GOF", L"GOG", L"GOH", L"GOI", L"GOJ", L"GOK", L"GOL", L"GOM", L"GON", L"GOO", L"GOP", L"GOQ", L"GOR", L"GOS", L"GOT", L"GOU", L"GOV", L"GOW", L"GOX", L"GOY", L"GOZ", L"GPA", L"GPB", L"GPC", L"GPD", L"GPE", L"GPF", L"GPG", L"GPH", L"GPI", L"GPJ", L"GPK", L"GPL", L"GPM", L"GPN", L"GPO", L"GPP", L"GPQ", L"GPR", L"GPS", L"GPT", L"GPU", L"GPV", L"GPW", L"GPX", L"GPY", L"GPZ", L"GQA", L"GQB", L"GQC", L"GQD", L"GQE", L"GQF", L"GQG", L"GQH", L"GQI", L"GQJ", L"GQK", L"GQL", L"GQM", L"GQN", L"GQO", L"GQP", L"GQQ", L"GQR", L"GQS", L"GQT", L"GQU", L"GQV", L"GQW", L"GQX", L"GQY", L"GQZ", L"GRA", L"GRB", L"GRC", L"GRD", L"GRE", L"GRF", L"GRG", L"GRH", L"GRI", L"GRJ", L"GRK", L"GRL", L"GRM", L"GRN", L"GRO", L"GRP", L"GRQ", L"GRR", L"GRS", L"GRT", L"GRU", L"GRV", L"GRW", L"GRX", L"GRY", L"GRZ", L"GSA", L"GSB", L"GSC", L"GSD", L"GSE", L"GSF", L"GSG", L"GSH", L"GSI", L"GSJ", L"GSK", L"GSL", L"GSM", L"GSN", L"GSO", L"GSP", L"GSQ", L"GSR", L"GSS", L"GST", L"GSU", L"GSV", L"GSW", L"GSX", L"GSY", L"GSZ", L"GTA", L"GTB", L"GTC", L"GTD", L"GTE", L"GTF", + L"GTG", L"GTH", L"GTI", L"GTJ", L"GTK", L"GTL", L"GTM", L"GTN", L"GTO", L"GTP", L"GTQ", L"GTR", L"GTS", L"GTT", L"GTU", L"GTV", L"GTW", L"GTX", L"GTY", L"GTZ", L"GUA", L"GUB", L"GUC", L"GUD", L"GUE", L"GUF", L"GUG", L"GUH", L"GUI", L"GUJ", L"GUK", L"GUL", L"GUM", L"GUN", L"GUO", L"GUP", L"GUQ", L"GUR", L"GUS", L"GUT", L"GUU", L"GUV", L"GUW", L"GUX", L"GUY", L"GUZ", L"GVA", L"GVB", L"GVC", L"GVD", L"GVE", L"GVF", L"GVG", L"GVH", L"GVI", L"GVJ", L"GVK", L"GVL", L"GVM", L"GVN", L"GVO", L"GVP", L"GVQ", L"GVR", L"GVS", L"GVT", L"GVU", L"GVV", L"GVW", L"GVX", L"GVY", L"GVZ", L"GWA", L"GWB", L"GWC", L"GWD", L"GWE", L"GWF", L"GWG", L"GWH", L"GWI", L"GWJ", L"GWK", L"GWL", L"GWM", L"GWN", L"GWO", L"GWP", L"GWQ", L"GWR", L"GWS", L"GWT", L"GWU", L"GWV", L"GWW", L"GWX", L"GWY", L"GWZ", L"GXA", L"GXB", L"GXC", L"GXD", L"GXE", L"GXF", L"GXG", L"GXH", L"GXI", L"GXJ", L"GXK", L"GXL", L"GXM", L"GXN", L"GXO", L"GXP", L"GXQ", L"GXR", L"GXS", L"GXT", L"GXU", L"GXV", L"GXW", L"GXX", L"GXY", L"GXZ", L"GYA", L"GYB", L"GYC", L"GYD", L"GYE", L"GYF", L"GYG", L"GYH", L"GYI", L"GYJ", L"GYK", L"GYL", L"GYM", L"GYN", L"GYO", L"GYP", L"GYQ", L"GYR", L"GYS", L"GYT", L"GYU", L"GYV", L"GYW", L"GYX", L"GYY", L"GYZ", L"GZA", L"GZB", L"GZC", L"GZD", L"GZE", L"GZF", L"GZG", L"GZH", L"GZI", L"GZJ", L"GZK", L"GZL", L"GZM", L"GZN", L"GZO", L"GZP", L"GZQ", L"GZR", L"GZS", L"GZT", L"GZU", L"GZV", L"GZW", L"GZX", L"GZY", L"GZZ", L"HAA", L"HAB", L"HAC", L"HAD", L"HAE", L"HAF", L"HAG", L"HAH", L"HAI", L"HAJ", L"HAK", L"HAL", L"HAM", L"HAN", L"HAO", L"HAP", L"HAQ", L"HAR", L"HAS", L"HAT", L"HAU", L"HAV", L"HAW", L"HAX", L"HAY", L"HAZ", L"HBA", L"HBB", L"HBC", L"HBD", L"HBE", L"HBF", L"HBG", L"HBH", L"HBI", L"HBJ", L"HBK", L"HBL", L"HBM", L"HBN", L"HBO", L"HBP", L"HBQ", L"HBR", L"HBS", L"HBT", L"HBU", L"HBV", L"HBW", L"HBX", L"HBY", L"HBZ", L"HCA", L"HCB", L"HCC", L"HCD", L"HCE", L"HCF", L"HCG", L"HCH", L"HCI", L"HCJ", L"HCK", L"HCL", L"HCM", L"HCN", L"HCO", L"HCP", L"HCQ", L"HCR", L"HCS", L"HCT", L"HCU", L"HCV", L"HCW", L"HCX", L"HCY", L"HCZ", L"HDA", L"HDB", L"HDC", L"HDD", L"HDE", L"HDF", L"HDG", L"HDH", L"HDI", L"HDJ", L"HDK", L"HDL", L"HDM", L"HDN", L"HDO", L"HDP", L"HDQ", L"HDR", L"HDS", + L"HDT", L"HDU", L"HDV", L"HDW", L"HDX", L"HDY", L"HDZ", L"HEA", L"HEB", L"HEC", L"HED", L"HEE", L"HEF", L"HEG", L"HEH", L"HEI", L"HEJ", L"HEK", L"HEL", L"HEM", L"HEN", L"HEO", L"HEP", L"HEQ", L"HER", L"HES", L"HET", L"HEU", L"HEV", L"HEW", L"HEX", L"HEY", L"HEZ", L"HFA", L"HFB", L"HFC", L"HFD", L"HFE", L"HFF", L"HFG", L"HFH", L"HFI", L"HFJ", L"HFK", L"HFL", L"HFM", L"HFN", L"HFO", L"HFP", L"HFQ", L"HFR", L"HFS", L"HFT", L"HFU", L"HFV", L"HFW", L"HFX", L"HFY", L"HFZ", L"HGA", L"HGB", L"HGC", L"HGD", L"HGE", L"HGF", L"HGG", L"HGH", L"HGI", L"HGJ", L"HGK", L"HGL", L"HGM", L"HGN", L"HGO", L"HGP", L"HGQ", L"HGR", L"HGS", L"HGT", L"HGU", L"HGV", L"HGW", L"HGX", L"HGY", L"HGZ", L"HHA", L"HHB", L"HHC", L"HHD", L"HHE", L"HHF", L"HHG", L"HHH", L"HHI", L"HHJ", L"HHK", L"HHL", L"HHM", L"HHN", L"HHO", L"HHP", L"HHQ", L"HHR", L"HHS", L"HHT", L"HHU", L"HHV", L"HHW", L"HHX", L"HHY", L"HHZ", L"HIA", L"HIB", L"HIC", L"HID", L"HIE", L"HIF", L"HIG", L"HIH", L"HII", L"HIJ", L"HIK", L"HIL", L"HIM", L"HIN", L"HIO", L"HIP", L"HIQ", L"HIR", L"HIS", L"HIT", L"HIU", L"HIV", L"HIW", L"HIX", L"HIY", L"HIZ", L"HJA", L"HJB", L"HJC", L"HJD", L"HJE", L"HJF", L"HJG", L"HJH", L"HJI", L"HJJ", L"HJK", L"HJL", L"HJM", L"HJN", L"HJO", L"HJP", L"HJQ", L"HJR", L"HJS", L"HJT", L"HJU", L"HJV", L"HJW", L"HJX", L"HJY", L"HJZ", L"HKA", L"HKB", L"HKC", L"HKD", L"HKE", L"HKF", L"HKG", L"HKH", L"HKI", L"HKJ", L"HKK", L"HKL", L"HKM", L"HKN", L"HKO", L"HKP", L"HKQ", L"HKR", L"HKS", L"HKT", L"HKU", L"HKV", L"HKW", L"HKX", L"HKY", L"HKZ", L"HLA", L"HLB", L"HLC", L"HLD", L"HLE", L"HLF", L"HLG", L"HLH", L"HLI", L"HLJ", L"HLK", L"HLL", L"HLM", L"HLN", L"HLO", L"HLP", L"HLQ", L"HLR", L"HLS", L"HLT", L"HLU", L"HLV", L"HLW", L"HLX", L"HLY", L"HLZ", L"HMA", L"HMB", L"HMC", L"HMD", L"HME", L"HMF", L"HMG", L"HMH", L"HMI", L"HMJ", L"HMK", L"HML", L"HMM", L"HMN", L"HMO", L"HMP", L"HMQ", L"HMR", L"HMS", L"HMT", L"HMU", L"HMV", L"HMW", L"HMX", L"HMY", L"HMZ", L"HNA", L"HNB", L"HNC", L"HND", L"HNE", L"HNF", L"HNG", L"HNH", L"HNI", L"HNJ", L"HNK", L"HNL", L"HNM", L"HNN", L"HNO", L"HNP", L"HNQ", L"HNR", L"HNS", L"HNT", L"HNU", L"HNV", L"HNW", L"HNX", L"HNY", L"HNZ", L"HOA", L"HOB", L"HOC", L"HOD", L"HOE", L"HOF", L"HOG", L"HOH", L"HOI", L"HOJ", L"HOK", L"HOL", L"HOM", L"HON", L"HOO", L"HOP", L"HOQ", L"HOR", L"HOS", L"HOT", L"HOU", L"HOV", L"HOW", L"HOX", L"HOY", L"HOZ", L"HPA", L"HPB", L"HPC", L"HPD", L"HPE", L"HPF", L"HPG", L"HPH", L"HPI", L"HPJ", L"HPK", L"HPL", L"HPM", L"HPN", L"HPO", L"HPP", L"HPQ", L"HPR", L"HPS", L"HPT", L"HPU", L"HPV", L"HPW", L"HPX", L"HPY", L"HPZ", L"HQA", L"HQB", L"HQC", L"HQD", L"HQE", L"HQF", L"HQG", L"HQH", L"HQI", L"HQJ", L"HQK", L"HQL", L"HQM", L"HQN", L"HQO", L"HQP", L"HQQ", L"HQR", L"HQS", L"HQT", L"HQU", L"HQV", L"HQW", L"HQX", L"HQY", L"HQZ", L"HRA", L"HRB", L"HRC", L"HRD", L"HRE", L"HRF", L"HRG", L"HRH", L"HRI", L"HRJ", L"HRK", L"HRL", L"HRM", L"HRN", L"HRO", L"HRP", L"HRQ", L"HRR", L"HRS", L"HRT", L"HRU", L"HRV", L"HRW", L"HRX", L"HRY", L"HRZ", L"HSA", L"HSB", L"HSC", L"HSD", L"HSE", L"HSF", L"HSG", L"HSH", L"HSI", L"HSJ", L"HSK", L"HSL", L"HSM", L"HSN", L"HSO", L"HSP", L"HSQ", L"HSR", L"HSS", L"HST", L"HSU", L"HSV", L"HSW", L"HSX", L"HSY", L"HSZ", L"HTA", L"HTB", L"HTC", L"HTD", L"HTE", L"HTF", L"HTG", L"HTH", L"HTI", L"HTJ", L"HTK", L"HTL", L"HTM", L"HTN", L"HTO", L"HTP", L"HTQ", L"HTR", L"HTS", L"HTT", L"HTU", L"HTV", L"HTW", L"HTX", L"HTY", L"HTZ", L"HUA", L"HUB", L"HUC", L"HUD", L"HUE", L"HUF", L"HUG", L"HUH", L"HUI", L"HUJ", L"HUK", L"HUL", L"HUM", L"HUN", L"HUO", L"HUP", L"HUQ", L"HUR", L"HUS", L"HUT", L"HUU", L"HUV", L"HUW", L"HUX", L"HUY", L"HUZ", L"HVA", L"HVB", L"HVC", L"HVD", L"HVE", L"HVF", L"HVG", L"HVH", L"HVI", L"HVJ", L"HVK", L"HVL", L"HVM", L"HVN", L"HVO", L"HVP", L"HVQ", L"HVR", L"HVS", L"HVT", L"HVU", L"HVV", L"HVW", L"HVX", L"HVY", L"HVZ", L"HWA", L"HWB", L"HWC", L"HWD", L"HWE", L"HWF", L"HWG", L"HWH", L"HWI", L"HWJ", L"HWK", L"HWL", L"HWM", L"HWN", L"HWO", L"HWP", L"HWQ", L"HWR", L"HWS", L"HWT", L"HWU", L"HWV", L"HWW", L"HWX", L"HWY", L"HWZ", L"HXA", L"HXB", L"HXC", L"HXD", L"HXE", L"HXF", L"HXG", L"HXH", L"HXI", L"HXJ", L"HXK", L"HXL", L"HXM", L"HXN", L"HXO", L"HXP", L"HXQ", L"HXR", L"HXS", L"HXT", L"HXU", L"HXV", L"HXW", L"HXX", L"HXY", L"HXZ", L"HYA", L"HYB", L"HYC", L"HYD", L"HYE", L"HYF", L"HYG", L"HYH", L"HYI", L"HYJ", L"HYK", L"HYL", L"HYM", L"HYN", L"HYO", L"HYP", L"HYQ", L"HYR", L"HYS", L"HYT", L"HYU", L"HYV", L"HYW", L"HYX", L"HYY", L"HYZ", L"HZA", L"HZB", L"HZC", L"HZD", L"HZE", L"HZF", L"HZG", L"HZH", L"HZI", L"HZJ", L"HZK", L"HZL", L"HZM", L"HZN", L"HZO", L"HZP", L"HZQ", L"HZR", L"HZS", L"HZT", L"HZU", L"HZV", L"HZW", L"HZX", L"HZY", L"HZZ", L"IAA", L"IAB", L"IAC", L"IAD", L"IAE", L"IAF", L"IAG", L"IAH", L"IAI", L"IAJ", L"IAK", L"IAL", L"IAM", L"IAN", L"IAO", L"IAP", L"IAQ", L"IAR", L"IAS", L"IAT", L"IAU", L"IAV", L"IAW", L"IAX", L"IAY", L"IAZ", L"IBA", L"IBB", L"IBC", L"IBD", L"IBE", L"IBF", L"IBG", L"IBH", L"IBI", L"IBJ", L"IBK", L"IBL", L"IBM", L"IBN", L"IBO", L"IBP", L"IBQ", L"IBR", L"IBS", L"IBT", L"IBU", L"IBV", L"IBW", L"IBX", L"IBY", L"IBZ", L"ICA", L"ICB", L"ICC", L"ICD", L"ICE", L"ICF", L"ICG", L"ICH", L"ICI", L"ICJ", L"ICK", L"ICL", L"ICM", L"ICN", L"ICO", L"ICP", L"ICQ", L"ICR", L"ICS", L"ICT", L"ICU", L"ICV", L"ICW", L"ICX", L"ICY", L"ICZ", L"IDA", L"IDB", L"IDC", L"IDD", L"IDE", L"IDF", L"IDG", L"IDH", L"IDI", L"IDJ", L"IDK", L"IDL", L"IDM", L"IDN", L"IDO", L"IDP", L"IDQ", L"IDR", L"IDS", L"IDT", L"IDU", L"IDV", L"IDW", L"IDX", L"IDY", L"IDZ", L"IEA", L"IEB", L"IEC", L"IED", L"IEE", L"IEF", L"IEG", L"IEH", L"IEI", L"IEJ", L"IEK", L"IEL", L"IEM", L"IEN", L"IEO", L"IEP", L"IEQ", L"IER", L"IES", L"IET", L"IEU", L"IEV", L"IEW", L"IEX", L"IEY", L"IEZ", L"IFA", L"IFB", L"IFC", L"IFD", L"IFE", L"IFF", L"IFG", L"IFH", L"IFI", L"IFJ", L"IFK", L"IFL", L"IFM", L"IFN", L"IFO", L"IFP", L"IFQ", L"IFR", L"IFS", L"IFT", L"IFU", L"IFV", L"IFW", L"IFX", L"IFY", L"IFZ", L"IGA", L"IGB", L"IGC", L"IGD", L"IGE", L"IGF", L"IGG", L"IGH", L"IGI", L"IGJ", L"IGK", L"IGL", L"IGM", L"IGN", L"IGO", L"IGP", L"IGQ", L"IGR", L"IGS", L"IGT", L"IGU", L"IGV", L"IGW", L"IGX", L"IGY", L"IGZ", L"IHA", L"IHB", L"IHC", L"IHD", L"IHE", L"IHF", L"IHG", L"IHH", L"IHI", L"IHJ", L"IHK", L"IHL", L"IHM", L"IHN", L"IHO", L"IHP", L"IHQ", L"IHR", L"IHS", L"IHT", L"IHU", L"IHV", L"IHW", L"IHX", L"IHY", L"IHZ", L"IIA", L"IIB", L"IIC", L"IID", L"IIE", L"IIF", L"IIG", L"IIH", L"III", L"IIJ", L"IIK", L"IIL", L"IIM", L"IIN", L"IIO", L"IIP", L"IIQ", L"IIR", L"IIS", L"IIT", L"IIU", L"IIV", L"IIW", L"IIX", L"IIY", L"IIZ", L"IJA", L"IJB", L"IJC", L"IJD", L"IJE", L"IJF", L"IJG", L"IJH", L"IJI", L"IJJ", L"IJK", L"IJL", L"IJM", L"IJN", L"IJO", L"IJP", L"IJQ", L"IJR", L"IJS", L"IJT", L"IJU", L"IJV", L"IJW", L"IJX", L"IJY", L"IJZ", L"IKA", L"IKB", L"IKC", L"IKD", L"IKE", L"IKF", L"IKG", L"IKH", L"IKI", L"IKJ", L"IKK", L"IKL", L"IKM", L"IKN", L"IKO", L"IKP", L"IKQ", L"IKR", L"IKS", L"IKT", L"IKU", L"IKV", L"IKW", L"IKX", L"IKY", L"IKZ", L"ILA", L"ILB", L"ILC", L"ILD", L"ILE", L"ILF", L"ILG", L"ILH", L"ILI", L"ILJ", L"ILK", L"ILL", L"ILM", L"ILN", L"ILO", L"ILP", L"ILQ", L"ILR", L"ILS", L"ILT", L"ILU", L"ILV", L"ILW", L"ILX", L"ILY", L"ILZ", L"IMA", L"IMB", L"IMC", L"IMD", L"IME", L"IMF", L"IMG", L"IMH", L"IMI", L"IMJ", L"IMK", L"IML", L"IMM", L"IMN", L"IMO", L"IMP", L"IMQ", L"IMR", L"IMS", L"IMT", L"IMU", L"IMV", L"IMW", L"IMX", L"IMY", L"IMZ", L"INA", L"INB", L"INC", L"IND", L"INE", L"INF", L"ING", L"INH", L"INI", L"INJ", L"INK", L"INL", L"INM", L"INN", L"INO", L"INP", L"INQ", L"INR", L"INS", L"INT", L"INU", L"INV", L"INW", L"INX", L"INY", L"INZ", L"IOA", L"IOB", L"IOC", L"IOD", L"IOE", L"IOF", L"IOG", L"IOH", L"IOI", L"IOJ", L"IOK", L"IOL", L"IOM", L"ION", L"IOO", L"IOP", L"IOQ", L"IOR", L"IOS", L"IOT", L"IOU", L"IOV", L"IOW", L"IOX", L"IOY", L"IOZ", L"IPA", L"IPB", L"IPC", L"IPD", L"IPE", L"IPF", L"IPG", L"IPH", L"IPI", L"IPJ", L"IPK", L"IPL", L"IPM", L"IPN", L"IPO", L"IPP", L"IPQ", L"IPR", L"IPS", L"IPT", L"IPU", L"IPV", L"IPW", L"IPX", L"IPY", L"IPZ", L"IQA", L"IQB", L"IQC", L"IQD", L"IQE", L"IQF", L"IQG", L"IQH", L"IQI", L"IQJ", L"IQK", L"IQL", L"IQM", L"IQN", L"IQO", L"IQP", L"IQQ", L"IQR", L"IQS", L"IQT", L"IQU", L"IQV", L"IQW", L"IQX", L"IQY", L"IQZ", L"IRA", L"IRB", L"IRC", L"IRD", L"IRE", L"IRF", L"IRG", L"IRH", L"IRI", L"IRJ", L"IRK", L"IRL", L"IRM", L"IRN", L"IRO", L"IRP", L"IRQ", L"IRR", L"IRS", L"IRT", L"IRU", L"IRV", L"IRW", L"IRX", L"IRY", L"IRZ", L"ISA", L"ISB", L"ISC", L"ISD", L"ISE", L"ISF", L"ISG", L"ISH", L"ISI", L"ISJ", L"ISK", L"ISL", L"ISM", L"ISN", L"ISO", L"ISP", L"ISQ", L"ISR", L"ISS", L"IST", L"ISU", L"ISV", L"ISW", L"ISX", L"ISY", L"ISZ", L"ITA", L"ITB", L"ITC", L"ITD", L"ITE", L"ITF", L"ITG", L"ITH", L"ITI", L"ITJ", L"ITK", @@ -97,37 +97,37 @@ namespace OOX L"JDY", L"JDZ", L"JEA", L"JEB", L"JEC", L"JED", L"JEE", L"JEF", L"JEG", L"JEH", L"JEI", L"JEJ", L"JEK", L"JEL", L"JEM", L"JEN", L"JEO", L"JEP", L"JEQ", L"JER", L"JES", L"JET", L"JEU", L"JEV", L"JEW", L"JEX", L"JEY", L"JEZ", L"JFA", L"JFB", L"JFC", L"JFD", L"JFE", L"JFF", L"JFG", L"JFH", L"JFI", L"JFJ", L"JFK", L"JFL", L"JFM", L"JFN", L"JFO", L"JFP", L"JFQ", L"JFR", L"JFS", L"JFT", L"JFU", L"JFV", L"JFW", L"JFX", L"JFY", L"JFZ", L"JGA", L"JGB", L"JGC", L"JGD", L"JGE", L"JGF", L"JGG", L"JGH", L"JGI", L"JGJ", L"JGK", L"JGL", L"JGM", L"JGN", L"JGO", L"JGP", L"JGQ", L"JGR", L"JGS", L"JGT", L"JGU", L"JGV", L"JGW", L"JGX", L"JGY", L"JGZ", L"JHA", L"JHB", L"JHC", L"JHD", L"JHE", L"JHF", L"JHG", L"JHH", L"JHI", L"JHJ", L"JHK", L"JHL", L"JHM", L"JHN", L"JHO", L"JHP", L"JHQ", L"JHR", L"JHS", L"JHT", L"JHU", L"JHV", L"JHW", L"JHX", L"JHY", L"JHZ", L"JIA", L"JIB", L"JIC", L"JID", L"JIE", L"JIF", L"JIG", L"JIH", L"JII", L"JIJ", L"JIK", L"JIL", L"JIM", L"JIN", L"JIO", L"JIP", L"JIQ", L"JIR", L"JIS", L"JIT", L"JIU", L"JIV", L"JIW", L"JIX", L"JIY", L"JIZ", L"JJA", L"JJB", L"JJC", L"JJD", L"JJE", L"JJF", L"JJG", L"JJH", L"JJI", L"JJJ", L"JJK", L"JJL", L"JJM", L"JJN", L"JJO", L"JJP", L"JJQ", L"JJR", L"JJS", L"JJT", L"JJU", L"JJV", L"JJW", L"JJX", L"JJY", L"JJZ", L"JKA", L"JKB", L"JKC", L"JKD", L"JKE", L"JKF", L"JKG", L"JKH", L"JKI", L"JKJ", L"JKK", L"JKL", L"JKM", L"JKN", L"JKO", L"JKP", L"JKQ", L"JKR", L"JKS", L"JKT", L"JKU", L"JKV", L"JKW", L"JKX", L"JKY", L"JKZ", L"JLA", L"JLB", L"JLC", L"JLD", L"JLE", L"JLF", L"JLG", L"JLH", L"JLI", L"JLJ", L"JLK", L"JLL", L"JLM", L"JLN", L"JLO", L"JLP", L"JLQ", L"JLR", L"JLS", L"JLT", L"JLU", L"JLV", L"JLW", L"JLX", L"JLY", L"JLZ", L"JMA", L"JMB", L"JMC", L"JMD", L"JME", L"JMF", L"JMG", L"JMH", L"JMI", L"JMJ", L"JMK", L"JML", L"JMM", L"JMN", L"JMO", L"JMP", L"JMQ", L"JMR", L"JMS", L"JMT", L"JMU", L"JMV", L"JMW", L"JMX", L"JMY", L"JMZ", L"JNA", L"JNB", L"JNC", L"JND", L"JNE", L"JNF", L"JNG", L"JNH", L"JNI", L"JNJ", L"JNK", L"JNL", L"JNM", L"JNN", L"JNO", L"JNP", L"JNQ", L"JNR", L"JNS", L"JNT", L"JNU", L"JNV", L"JNW", L"JNX", L"JNY", L"JNZ", L"JOA", L"JOB", L"JOC", L"JOD", L"JOE", L"JOF", L"JOG", L"JOH", L"JOI", L"JOJ", L"JOK", L"JOL", L"JOM", L"JON", L"JOO", L"JOP", L"JOQ", L"JOR", L"JOS", L"JOT", L"JOU", L"JOV", L"JOW", L"JOX", L"JOY", L"JOZ", L"JPA", L"JPB", L"JPC", L"JPD", L"JPE", L"JPF", L"JPG", L"JPH", L"JPI", L"JPJ", L"JPK", L"JPL", L"JPM", L"JPN", L"JPO", L"JPP", L"JPQ", L"JPR", L"JPS", L"JPT", L"JPU", L"JPV", L"JPW", L"JPX", L"JPY", L"JPZ", L"JQA", L"JQB", L"JQC", L"JQD", L"JQE", L"JQF", L"JQG", L"JQH", L"JQI", L"JQJ", L"JQK", L"JQL", L"JQM", L"JQN", L"JQO", L"JQP", L"JQQ", L"JQR", L"JQS", L"JQT", L"JQU", L"JQV", L"JQW", L"JQX", L"JQY", L"JQZ", L"JRA", L"JRB", L"JRC", L"JRD", L"JRE", L"JRF", L"JRG", L"JRH", L"JRI", L"JRJ", L"JRK", L"JRL", L"JRM", L"JRN", L"JRO", L"JRP", L"JRQ", L"JRR", L"JRS", L"JRT", L"JRU", L"JRV", L"JRW", L"JRX", L"JRY", L"JRZ", L"JSA", L"JSB", L"JSC", L"JSD", L"JSE", L"JSF", L"JSG", L"JSH", L"JSI", L"JSJ", L"JSK", L"JSL", L"JSM", L"JSN", L"JSO", L"JSP", L"JSQ", L"JSR", L"JSS", L"JST", L"JSU", L"JSV", L"JSW", L"JSX", L"JSY", L"JSZ", L"JTA", L"JTB", L"JTC", L"JTD", L"JTE", L"JTF", L"JTG", L"JTH", L"JTI", L"JTJ", L"JTK", L"JTL", L"JTM", L"JTN", L"JTO", L"JTP", L"JTQ", L"JTR", L"JTS", L"JTT", L"JTU", L"JTV", L"JTW", L"JTX", L"JTY", L"JTZ", L"JUA", L"JUB", L"JUC", L"JUD", L"JUE", L"JUF", L"JUG", L"JUH", L"JUI", L"JUJ", L"JUK", L"JUL", L"JUM", L"JUN", L"JUO", L"JUP", L"JUQ", L"JUR", L"JUS", L"JUT", L"JUU", L"JUV", L"JUW", L"JUX", L"JUY", L"JUZ", L"JVA", L"JVB", L"JVC", L"JVD", L"JVE", L"JVF", L"JVG", L"JVH", L"JVI", L"JVJ", L"JVK", L"JVL", L"JVM", L"JVN", L"JVO", L"JVP", L"JVQ", L"JVR", L"JVS", L"JVT", L"JVU", L"JVV", L"JVW", L"JVX", L"JVY", L"JVZ", L"JWA", L"JWB", L"JWC", L"JWD", L"JWE", L"JWF", L"JWG", L"JWH", L"JWI", L"JWJ", L"JWK", L"JWL", L"JWM", L"JWN", L"JWO", L"JWP", L"JWQ", L"JWR", L"JWS", L"JWT", L"JWU", L"JWV", L"JWW", L"JWX", L"JWY", L"JWZ", L"JXA", L"JXB", L"JXC", L"JXD", L"JXE", L"JXF", L"JXG", L"JXH", L"JXI", L"JXJ", L"JXK", L"JXL", L"JXM", L"JXN", L"JXO", L"JXP", L"JXQ", L"JXR", L"JXS", L"JXT", L"JXU", L"JXV", L"JXW", L"JXX", L"JXY", L"JXZ", L"JYA", L"JYB", L"JYC", L"JYD", L"JYE", L"JYF", L"JYG", L"JYH", L"JYI", L"JYJ", L"JYK", L"JYL", L"JYM", L"JYN", L"JYO", L"JYP", L"JYQ", L"JYR", L"JYS", L"JYT", L"JYU", L"JYV", L"JYW", L"JYX", L"JYY", L"JYZ", L"JZA", L"JZB", L"JZC", L"JZD", L"JZE", L"JZF", L"JZG", L"JZH", L"JZI", L"JZJ", L"JZK", L"JZL", L"JZM", L"JZN", L"JZO", L"JZP", L"JZQ", L"JZR", L"JZS", L"JZT", L"JZU", L"JZV", L"JZW", L"JZX", L"JZY", L"JZZ", L"KAA", L"KAB", L"KAC", L"KAD", L"KAE", L"KAF", L"KAG", L"KAH", L"KAI", L"KAJ", L"KAK", L"KAL", L"KAM", L"KAN", L"KAO", L"KAP", L"KAQ", L"KAR", L"KAS", L"KAT", L"KAU", L"KAV", L"KAW", L"KAX", L"KAY", L"KAZ", L"KBA", L"KBB", L"KBC", L"KBD", L"KBE", L"KBF", L"KBG", L"KBH", L"KBI", L"KBJ", L"KBK", L"KBL", L"KBM", L"KBN", L"KBO", L"KBP", L"KBQ", L"KBR", L"KBS", L"KBT", L"KBU", L"KBV", L"KBW", L"KBX", L"KBY", L"KBZ", L"KCA", L"KCB", L"KCC", L"KCD", L"KCE", L"KCF", L"KCG", L"KCH", L"KCI", L"KCJ", L"KCK", L"KCL", L"KCM", L"KCN", L"KCO", L"KCP", L"KCQ", L"KCR", L"KCS", L"KCT", L"KCU", L"KCV", L"KCW", L"KCX", L"KCY", L"KCZ", L"KDA", L"KDB", L"KDC", L"KDD", L"KDE", L"KDF", L"KDG", L"KDH", L"KDI", L"KDJ", L"KDK", L"KDL", L"KDM", L"KDN", L"KDO", L"KDP", L"KDQ", L"KDR", L"KDS", L"KDT", L"KDU", L"KDV", L"KDW", L"KDX", L"KDY", L"KDZ", L"KEA", L"KEB", L"KEC", L"KED", L"KEE", L"KEF", L"KEG", L"KEH", L"KEI", L"KEJ", L"KEK", L"KEL", L"KEM", L"KEN", L"KEO", L"KEP", L"KEQ", L"KER", L"KES", L"KET", L"KEU", L"KEV", L"KEW", L"KEX", L"KEY", L"KEZ", L"KFA", L"KFB", L"KFC", L"KFD", L"KFE", L"KFF", L"KFG", L"KFH", L"KFI", L"KFJ", L"KFK", L"KFL", L"KFM", L"KFN", L"KFO", L"KFP", L"KFQ", L"KFR", L"KFS", L"KFT", L"KFU", L"KFV", L"KFW", L"KFX", L"KFY", L"KFZ", L"KGA", L"KGB", L"KGC", L"KGD", L"KGE", L"KGF", L"KGG", L"KGH", L"KGI", L"KGJ", L"KGK", L"KGL", L"KGM", L"KGN", L"KGO", L"KGP", L"KGQ", L"KGR", L"KGS", L"KGT", L"KGU", L"KGV", L"KGW", L"KGX", L"KGY", L"KGZ", L"KHA", L"KHB", L"KHC", L"KHD", L"KHE", L"KHF", L"KHG", L"KHH", L"KHI", L"KHJ", L"KHK", L"KHL", L"KHM", L"KHN", L"KHO", L"KHP", L"KHQ", L"KHR", L"KHS", L"KHT", L"KHU", L"KHV", L"KHW", L"KHX", L"KHY", L"KHZ", L"KIA", L"KIB", L"KIC", L"KID", L"KIE", L"KIF", L"KIG", L"KIH", L"KII", L"KIJ", L"KIK", L"KIL", L"KIM", L"KIN", L"KIO", L"KIP", L"KIQ", L"KIR", L"KIS", L"KIT", L"KIU", L"KIV", L"KIW", L"KIX", L"KIY", L"KIZ", L"KJA", L"KJB", L"KJC", L"KJD", L"KJE", L"KJF", L"KJG", L"KJH", L"KJI", L"KJJ", L"KJK", - L"KJL", L"KJM", L"KJN", L"KJO", L"KJP", L"KJQ", L"KJR", L"KJS", L"KJT", L"KJU", L"KJV", L"KJW", L"KJX", L"KJY", L"KJZ", L"KKA", L"KKB", L"KKC", L"KKD", L"KKE", L"KKF", L"KKG", L"KKH", L"KKI", L"KKJ", L"KKK", L"KKL", L"KKM", L"KKN", L"KKO", L"KKP", L"KKQ", L"KKR", L"KKS", L"KKT", L"KKU", L"KKV", L"KKW", L"KKX", L"KKY", L"KKZ", L"KLA", L"KLB", L"KLC", L"KLD", L"KLE", L"KLF", L"KLG", L"KLH", L"KLI", L"KLJ", L"KLK", L"KLL", L"KLM", L"KLN", L"KLO", L"KLP", L"KLQ", L"KLR", L"KLS", L"KLT", L"KLU", L"KLV", L"KLW", L"KLX", L"KLY", L"KLZ", L"KMA", L"KMB", L"KMC", L"KMD", L"KME", L"KMF", L"KMG", L"KMH", L"KMI", L"KMJ", L"KMK", L"KML", L"KMM", L"KMN", L"KMO", L"KMP", L"KMQ", L"KMR", L"KMS", L"KMT", L"KMU", L"KMV", L"KMW", L"KMX", L"KMY", L"KMZ", L"KNA", L"KNB", L"KNC", L"KND", L"KNE", L"KNF", L"KNG", L"KNH", L"KNI", L"KNJ", L"KNK", L"KNL", L"KNM", L"KNN", L"KNO", L"KNP", L"KNQ", L"KNR", L"KNS", L"KNT", L"KNU", L"KNV", L"KNW", L"KNX", L"KNY", L"KNZ", L"KOA", L"KOB", L"KOC", L"KOD", L"KOE", L"KOF", L"KOG", L"KOH", L"KOI", L"KOJ", L"KOK", L"KOL", L"KOM", L"KON", L"KOO", L"KOP", L"KOQ", L"KOR", L"KOS", L"KOT", L"KOU", L"KOV", L"KOW", L"KOX", L"KOY", L"KOZ", L"KPA", L"KPB", L"KPC", L"KPD", L"KPE", L"KPF", L"KPG", L"KPH", L"KPI", L"KPJ", L"KPK", L"KPL", L"KPM", L"KPN", L"KPO", L"KPP", L"KPQ", L"KPR", L"KPS", L"KPT", L"KPU", L"KPV", L"KPW", L"KPX", L"KPY", L"KPZ", L"KQA", L"KQB", L"KQC", L"KQD", L"KQE", L"KQF", L"KQG", L"KQH", L"KQI", L"KQJ", L"KQK", L"KQL", L"KQM", L"KQN", L"KQO", L"KQP", L"KQQ", L"KQR", L"KQS", L"KQT", L"KQU", L"KQV", L"KQW", L"KQX", L"KQY", L"KQZ", L"KRA", L"KRB", L"KRC", L"KRD", L"KRE", L"KRF", L"KRG", L"KRH", L"KRI", L"KRJ", L"KRK", L"KRL", L"KRM", L"KRN", L"KRO", L"KRP", L"KRQ", L"KRR", L"KRS", L"KRT", L"KRU", L"KRV", L"KRW", L"KRX", L"KRY", L"KRZ", L"KSA", L"KSB", L"KSC", L"KSD", L"KSE", L"KSF", L"KSG", L"KSH", L"KSI", L"KSJ", L"KSK", L"KSL", L"KSM", L"KSN", L"KSO", L"KSP", L"KSQ", L"KSR", L"KSS", L"KST", L"KSU", L"KSV", L"KSW", L"KSX", L"KSY", L"KSZ", L"KTA", L"KTB", L"KTC", L"KTD", L"KTE", L"KTF", L"KTG", L"KTH", L"KTI", L"KTJ", L"KTK", L"KTL", L"KTM", L"KTN", L"KTO", L"KTP", L"KTQ", L"KTR", L"KTS", L"KTT", L"KTU", L"KTV", L"KTW", L"KTX", - L"KTY", L"KTZ", L"KUA", L"KUB", L"KUC", L"KUD", L"KUE", L"KUF", L"KUG", L"KUH", L"KUI", L"KUJ", L"KUK", L"KUL", L"KUM", L"KUN", L"KUO", L"KUP", L"KUQ", L"KUR", L"KUS", L"KUT", L"KUU", L"KUV", L"KUW", L"KUX", L"KUY", L"KUZ", L"KVA", L"KVB", L"KVC", L"KVD", L"KVE", L"KVF", L"KVG", L"KVH", L"KVI", L"KVJ", L"KVK", L"KVL", L"KVM", L"KVN", L"KVO", L"KVP", L"KVQ", L"KVR", L"KVS", L"KVT", L"KVU", L"KVV", L"KVW", L"KVX", L"KVY", L"KVZ", L"KWA", L"KWB", L"KWC", L"KWD", L"KWE", L"KWF", L"KWG", L"KWH", L"KWI", L"KWJ", L"KWK", L"KWL", L"KWM", L"KWN", L"KWO", L"KWP", L"KWQ", L"KWR", L"KWS", L"KWT", L"KWU", L"KWV", L"KWW", L"KWX", L"KWY", L"KWZ", L"KXA", L"KXB", L"KXC", L"KXD", L"KXE", L"KXF", L"KXG", L"KXH", L"KXI", L"KXJ", L"KXK", L"KXL", L"KXM", L"KXN", L"KXO", L"KXP", L"KXQ", L"KXR", L"KXS", L"KXT", L"KXU", L"KXV", L"KXW", L"KXX", L"KXY", L"KXZ", L"KYA", L"KYB", L"KYC", L"KYD", L"KYE", L"KYF", L"KYG", L"KYH", L"KYI", L"KYJ", L"KYK", L"KYL", L"KYM", L"KYN", L"KYO", L"KYP", L"KYQ", L"KYR", L"KYS", L"KYT", L"KYU", L"KYV", L"KYW", L"KYX", L"KYY", L"KYZ", L"KZA", L"KZB", L"KZC", L"KZD", L"KZE", L"KZF", L"KZG", L"KZH", L"KZI", L"KZJ", L"KZK", L"KZL", L"KZM", L"KZN", L"KZO", L"KZP", L"KZQ", L"KZR", L"KZS", L"KZT", L"KZU", L"KZV", L"KZW", L"KZX", L"KZY", L"KZZ", L"LAA", L"LAB", L"LAC", L"LAD", L"LAE", L"LAF", L"LAG", L"LAH", L"LAI", L"LAJ", L"LAK", L"LAL", L"LAM", L"LAN", L"LAO", L"LAP", L"LAQ", L"LAR", L"LAS", L"LAT", L"LAU", L"LAV", L"LAW", L"LAX", L"LAY", L"LAZ", L"LBA", L"LBB", L"LBC", L"LBD", L"LBE", L"LBF", L"LBG", L"LBH", L"LBI", L"LBJ", L"LBK", L"LBL", L"LBM", L"LBN", L"LBO", L"LBP", L"LBQ", L"LBR", L"LBS", L"LBT", L"LBU", L"LBV", L"LBW", L"LBX", L"LBY", L"LBZ", L"LCA", L"LCB", L"LCC", L"LCD", L"LCE", L"LCF", L"LCG", L"LCH", L"LCI", L"LCJ", L"LCK", L"LCL", L"LCM", L"LCN", L"LCO", L"LCP", L"LCQ", L"LCR", L"LCS", L"LCT", L"LCU", L"LCV", L"LCW", L"LCX", L"LCY", L"LCZ", L"LDA", L"LDB", L"LDC", L"LDD", L"LDE", L"LDF", L"LDG", L"LDH", L"LDI", L"LDJ", L"LDK", L"LDL", L"LDM", L"LDN", L"LDO", L"LDP", L"LDQ", L"LDR", L"LDS", L"LDT", L"LDU", L"LDV", L"LDW", L"LDX", L"LDY", L"LDZ", L"LEA", L"LEB", L"LEC", L"LED", L"LEE", L"LEF", L"LEG", L"LEH", L"LEI", L"LEJ", L"LEK", - L"LEL", L"LEM", L"LEN", L"LEO", L"LEP", L"LEQ", L"LER", L"LES", L"LET", L"LEU", L"LEV", L"LEW", L"LEX", L"LEY", L"LEZ", L"LFA", L"LFB", L"LFC", L"LFD", L"LFE", L"LFF", L"LFG", L"LFH", L"LFI", L"LFJ", L"LFK", L"LFL", L"LFM", L"LFN", L"LFO", L"LFP", L"LFQ", L"LFR", L"LFS", L"LFT", L"LFU", L"LFV", L"LFW", L"LFX", L"LFY", L"LFZ", L"LGA", L"LGB", L"LGC", L"LGD", L"LGE", L"LGF", L"LGG", L"LGH", L"LGI", L"LGJ", L"LGK", L"LGL", L"LGM", L"LGN", L"LGO", L"LGP", L"LGQ", L"LGR", L"LGS", L"LGT", L"LGU", L"LGV", L"LGW", L"LGX", L"LGY", L"LGZ", L"LHA", L"LHB", L"LHC", L"LHD", L"LHE", L"LHF", L"LHG", L"LHH", L"LHI", L"LHJ", L"LHK", L"LHL", L"LHM", L"LHN", L"LHO", L"LHP", L"LHQ", L"LHR", L"LHS", L"LHT", L"LHU", L"LHV", L"LHW", L"LHX", L"LHY", L"LHZ", L"LIA", L"LIB", L"LIC", L"LID", L"LIE", L"LIF", L"LIG", L"LIH", L"LII", L"LIJ", L"LIK", L"LIL", L"LIM", L"LIN", L"LIO", L"LIP", L"LIQ", L"LIR", L"LIS", L"LIT", L"LIU", L"LIV", L"LIW", L"LIX", L"LIY", L"LIZ", L"LJA", L"LJB", L"LJC", L"LJD", L"LJE", L"LJF", L"LJG", L"LJH", L"LJI", L"LJJ", L"LJK", L"LJL", L"LJM", L"LJN", L"LJO", L"LJP", L"LJQ", L"LJR", L"LJS", L"LJT", L"LJU", L"LJV", L"LJW", L"LJX", L"LJY", L"LJZ", L"LKA", L"LKB", L"LKC", L"LKD", L"LKE", L"LKF", L"LKG", L"LKH", L"LKI", L"LKJ", L"LKK", L"LKL", L"LKM", L"LKN", L"LKO", L"LKP", L"LKQ", L"LKR", L"LKS", L"LKT", L"LKU", L"LKV", L"LKW", L"LKX", L"LKY", L"LKZ", L"LLA", L"LLB", L"LLC", L"LLD", L"LLE", L"LLF", L"LLG", L"LLH", L"LLI", L"LLJ", L"LLK", L"LLL", L"LLM", L"LLN", L"LLO", L"LLP", L"LLQ", L"LLR", L"LLS", L"LLT", L"LLU", L"LLV", L"LLW", L"LLX", L"LLY", L"LLZ", L"LMA", L"LMB", L"LMC", L"LMD", L"LME", L"LMF", L"LMG", L"LMH", L"LMI", L"LMJ", L"LMK", L"LML", L"LMM", L"LMN", L"LMO", L"LMP", L"LMQ", L"LMR", L"LMS", L"LMT", L"LMU", L"LMV", L"LMW", L"LMX", L"LMY", L"LMZ", L"LNA", L"LNB", L"LNC", L"LND", L"LNE", L"LNF", L"LNG", L"LNH", L"LNI", L"LNJ", L"LNK", L"LNL", L"LNM", L"LNN", L"LNO", L"LNP", L"LNQ", L"LNR", L"LNS", L"LNT", L"LNU", L"LNV", L"LNW", L"LNX", L"LNY", L"LNZ", L"LOA", L"LOB", L"LOC", L"LOD", L"LOE", L"LOF", L"LOG", L"LOH", L"LOI", L"LOJ", L"LOK", L"LOL", L"LOM", L"LON", L"LOO", L"LOP", L"LOQ", L"LOR", L"LOS", L"LOT", L"LOU", L"LOV", L"LOW", L"LOX", + L"KJL", L"KJM", L"KJN", L"KJO", L"KJP", L"KJQ", L"KJR", L"KJS", L"KJT", L"KJU", L"KJV", L"KJW", L"KJX", L"KJY", L"KJZ", L"KKA", L"KKB", L"KKC", L"KKD", L"KKE", L"KKF", L"KKG", L"KKH", L"KKI", L"KKJ", L"KKK", L"KKL", L"KKM", L"KKN", L"KKO", L"KKP", L"KKQ", L"KKR", L"KKS", L"KKT", L"KKU", L"KKV", L"KKW", L"KKX", L"KKY", L"KKZ", L"KLA", L"KLB", L"KLC", L"KLD", L"KLE", L"KLF", L"KLG", L"KLH", L"KLI", L"KLJ", L"KLK", L"KLL", L"KLM", L"KLN", L"KLO", L"KLP", L"KLQ", L"KLR", L"KLS", L"KLT", L"KLU", L"KLV", L"KLW", L"KLX", L"KLY", L"KLZ", L"KMA", L"KMB", L"KMC", L"KMD", L"KME", L"KMF", L"KMG", L"KMH", L"KMI", L"KMJ", L"KMK", L"KML", L"KMM", L"KMN", L"KMO", L"KMP", L"KMQ", L"KMR", L"KMS", L"KMT", L"KMU", L"KMV", L"KMW", L"KMX", L"KMY", L"KMZ", L"KNA", L"KNB", L"KNC", L"KND", L"KNE", L"KNF", L"KNG", L"KNH", L"KNI", L"KNJ", L"KNK", L"KNL", L"KNM", L"KNN", L"KNO", L"KNP", L"KNQ", L"KNR", L"KNS", L"KNT", L"KNU", L"KNV", L"KNW", L"KNX", L"KNY", L"KNZ", L"KOA", L"KOB", L"KOC", L"KOD", L"KOE", L"KOF", L"KOG", L"KOH", L"KOI", L"KOJ", L"KOK", L"KOL", L"KOM", L"KON", L"KOO", L"KOP", L"KOQ", L"KOR", L"KOS", L"KOT", L"KOU", L"KOV", L"KOW", L"KOX", L"KOY", L"KOZ", L"KPA", L"KPB", L"KPC", L"KPD", L"KPE", L"KPF", L"KPG", L"KPH", L"KPI", L"KPJ", L"KPK", L"KPL", L"KPM", L"KPN", L"KPO", L"KPP", L"KPQ", L"KPR", L"KPS", L"KPT", L"KPU", L"KPV", L"KPW", L"KPX", L"KPY", L"KPZ", L"KQA", L"KQB", L"KQC", L"KQD", L"KQE", L"KQF", L"KQG", L"KQH", L"KQI", L"KQJ", L"KQK", L"KQL", L"KQM", L"KQN", L"KQO", L"KQP", L"KQQ", L"KQR", L"KQS", L"KQT", L"KQU", L"KQV", L"KQW", L"KQX", L"KQY", L"KQZ", L"KRA", L"KRB", L"KRC", L"KRD", L"KRE", L"KRF", L"KRG", L"KRH", L"KRI", L"KRJ", L"KRK", L"KRL", L"KRM", L"KRN", L"KRO", L"KRP", L"KRQ", L"KRR", L"KRS", L"KRT", L"KRU", L"KRV", L"KRW", L"KRX", L"KRY", L"KRZ", L"KSA", L"KSB", L"KSC", L"KSD", L"KSE", L"KSF", L"KSG", L"KSH", L"KSI", L"KSJ", L"KSK", L"KSL", L"KSM", L"KSN", L"KSO", L"KSP", L"KSQ", L"KSR", L"KSS", L"KST", L"KSU", L"KSV", L"KSW", L"KSX", L"KSY", L"KSZ", L"KTA", L"KTB", L"KTC", L"KTD", L"KTE", L"KTF", L"KTG", L"KTH", L"KTI", L"KTJ", L"KTK", L"KTL", L"KTM", L"KTN", L"KTO", L"KTP", L"KTQ", L"KTR", L"KTS", L"KTT", L"KTU", L"KTV", L"KTW", L"KTX", + L"KTY", L"KTZ", L"KUA", L"KUB", L"KUC", L"KUD", L"KUE", L"KUF", L"KUG", L"KUH", L"KUI", L"KUJ", L"KUK", L"KUL", L"KUM", L"KUN", L"KUO", L"KUP", L"KUQ", L"KUR", L"KUS", L"KUT", L"KUU", L"KUV", L"KUW", L"KUX", L"KUY", L"KUZ", L"KVA", L"KVB", L"KVC", L"KVD", L"KVE", L"KVF", L"KVG", L"KVH", L"KVI", L"KVJ", L"KVK", L"KVL", L"KVM", L"KVN", L"KVO", L"KVP", L"KVQ", L"KVR", L"KVS", L"KVT", L"KVU", L"KVV", L"KVW", L"KVX", L"KVY", L"KVZ", L"KWA", L"KWB", L"KWC", L"KWD", L"KWE", L"KWF", L"KWG", L"KWH", L"KWI", L"KWJ", L"KWK", L"KWL", L"KWM", L"KWN", L"KWO", L"KWP", L"KWQ", L"KWR", L"KWS", L"KWT", L"KWU", L"KWV", L"KWW", L"KWX", L"KWY", L"KWZ", L"KXA", L"KXB", L"KXC", L"KXD", L"KXE", L"KXF", L"KXG", L"KXH", L"KXI", L"KXJ", L"KXK", L"KXL", L"KXM", L"KXN", L"KXO", L"KXP", L"KXQ", L"KXR", L"KXS", L"KXT", L"KXU", L"KXV", L"KXW", L"KXX", L"KXY", L"KXZ", L"KYA", L"KYB", L"KYC", L"KYD", L"KYE", L"KYF", L"KYG", L"KYH", L"KYI", L"KYJ", L"KYK", L"KYL", L"KYM", L"KYN", L"KYO", L"KYP", L"KYQ", L"KYR", L"KYS", L"KYT", L"KYU", L"KYV", L"KYW", L"KYX", L"KYY", L"KYZ", L"KZA", L"KZB", L"KZC", L"KZD", L"KZE", L"KZF", L"KZG", L"KZH", L"KZI", L"KZJ", L"KZK", L"KZL", L"KZM", L"KZN", L"KZO", L"KZP", L"KZQ", L"KZR", L"KZS", L"KZT", L"KZU", L"KZV", L"KZW", L"KZX", L"KZY", L"KZZ", L"LAA", L"LAB", L"LAC", L"LAD", L"LAE", L"LAF", L"LAG", L"LAH", L"LAI", L"LAJ", L"LAK", L"LAL", L"LAM", L"LAN", L"LAO", L"LAP", L"LAQ", L"LAR", L"LAS", L"LAT", L"LAU", L"LAV", L"LAW", L"LAX", L"LAY", L"LAZ", L"LBA", L"LBB", L"LBC", L"LBD", L"LBE", L"LBF", L"LBG", L"LBH", L"LBI", L"LBJ", L"LBK", L"LBL", L"LBM", L"LBN", L"LBO", L"LBP", L"LBQ", L"LBR", L"LBS", L"LBT", L"LBU", L"LBV", L"LBW", L"LBX", L"LBY", L"LBZ", L"LCA", L"LCB", L"LCC", L"LCD", L"LCE", L"LCF", L"LCG", L"LCH", L"LCI", L"LCJ", L"LCK", L"LCL", L"LCM", L"LCN", L"LCO", L"LCP", L"LCQ", L"LCR", L"LCS", L"LCT", L"LCU", L"LCV", L"LCW", L"LCX", L"LCY", L"LCZ", L"LDA", L"LDB", L"LDC", L"LDD", L"LDE", L"LDF", L"LDG", L"LDH", L"LDI", L"LDJ", L"LDK", L"LDL", L"LDM", L"LDN", L"LDO", L"LDP", L"LDQ", L"LDR", L"LDS", L"LDT", L"LDU", L"LDV", L"LDW", L"LDX", L"LDY", L"LDZ", L"LEA", L"LEB", L"LEC", L"LED", L"LEE", L"LEF", L"LEG", L"LEH", L"LEI", L"LEJ", L"LEK", + L"LEL", L"LEM", L"LEN", L"LEO", L"LEP", L"LEQ", L"LER", L"LES", L"LET", L"LEU", L"LEV", L"LEW", L"LEX", L"LEY", L"LEZ", L"LFA", L"LFB", L"LFC", L"LFD", L"LFE", L"LFF", L"LFG", L"LFH", L"LFI", L"LFJ", L"LFK", L"LFL", L"LFM", L"LFN", L"LFO", L"LFP", L"LFQ", L"LFR", L"LFS", L"LFT", L"LFU", L"LFV", L"LFW", L"LFX", L"LFY", L"LFZ", L"LGA", L"LGB", L"LGC", L"LGD", L"LGE", L"LGF", L"LGG", L"LGH", L"LGI", L"LGJ", L"LGK", L"LGL", L"LGM", L"LGN", L"LGO", L"LGP", L"LGQ", L"LGR", L"LGS", L"LGT", L"LGU", L"LGV", L"LGW", L"LGX", L"LGY", L"LGZ", L"LHA", L"LHB", L"LHC", L"LHD", L"LHE", L"LHF", L"LHG", L"LHH", L"LHI", L"LHJ", L"LHK", L"LHL", L"LHM", L"LHN", L"LHO", L"LHP", L"LHQ", L"LHR", L"LHS", L"LHT", L"LHU", L"LHV", L"LHW", L"LHX", L"LHY", L"LHZ", L"LIA", L"LIB", L"LIC", L"LID", L"LIE", L"LIF", L"LIG", L"LIH", L"LII", L"LIJ", L"LIK", L"LIL", L"LIM", L"LIN", L"LIO", L"LIP", L"LIQ", L"LIR", L"LIS", L"LIT", L"LIU", L"LIV", L"LIW", L"LIX", L"LIY", L"LIZ", L"LJA", L"LJB", L"LJC", L"LJD", L"LJE", L"LJF", L"LJG", L"LJH", L"LJI", L"LJJ", L"LJK", L"LJL", L"LJM", L"LJN", L"LJO", L"LJP", L"LJQ", L"LJR", L"LJS", L"LJT", L"LJU", L"LJV", L"LJW", L"LJX", L"LJY", L"LJZ", L"LKA", L"LKB", L"LKC", L"LKD", L"LKE", L"LKF", L"LKG", L"LKH", L"LKI", L"LKJ", L"LKK", L"LKL", L"LKM", L"LKN", L"LKO", L"LKP", L"LKQ", L"LKR", L"LKS", L"LKT", L"LKU", L"LKV", L"LKW", L"LKX", L"LKY", L"LKZ", L"LLA", L"LLB", L"LLC", L"LLD", L"LLE", L"LLF", L"LLG", L"LLH", L"LLI", L"LLJ", L"LLK", L"LLL", L"LLM", L"LLN", L"LLO", L"LLP", L"LLQ", L"LLR", L"LLS", L"LLT", L"LLU", L"LLV", L"LLW", L"LLX", L"LLY", L"LLZ", L"LMA", L"LMB", L"LMC", L"LMD", L"LME", L"LMF", L"LMG", L"LMH", L"LMI", L"LMJ", L"LMK", L"LML", L"LMM", L"LMN", L"LMO", L"LMP", L"LMQ", L"LMR", L"LMS", L"LMT", L"LMU", L"LMV", L"LMW", L"LMX", L"LMY", L"LMZ", L"LNA", L"LNB", L"LNC", L"LND", L"LNE", L"LNF", L"LNG", L"LNH", L"LNI", L"LNJ", L"LNK", L"LNL", L"LNM", L"LNN", L"LNO", L"LNP", L"LNQ", L"LNR", L"LNS", L"LNT", L"LNU", L"LNV", L"LNW", L"LNX", L"LNY", L"LNZ", L"LOA", L"LOB", L"LOC", L"LOD", L"LOE", L"LOF", L"LOG", L"LOH", L"LOI", L"LOJ", L"LOK", L"LOL", L"LOM", L"LON", L"LOO", L"LOP", L"LOQ", L"LOR", L"LOS", L"LOT", L"LOU", L"LOV", L"LOW", L"LOX", L"LOY", L"LOZ", L"LPA", L"LPB", L"LPC", L"LPD", L"LPE", L"LPF", L"LPG", L"LPH", L"LPI", L"LPJ", L"LPK", L"LPL", L"LPM", L"LPN", L"LPO", L"LPP", L"LPQ", L"LPR", L"LPS", L"LPT", L"LPU", L"LPV", L"LPW", L"LPX", L"LPY", L"LPZ", L"LQA", L"LQB", L"LQC", L"LQD", L"LQE", L"LQF", L"LQG", L"LQH", L"LQI", L"LQJ", L"LQK", L"LQL", L"LQM", L"LQN", L"LQO", L"LQP", L"LQQ", L"LQR", L"LQS", L"LQT", L"LQU", L"LQV", L"LQW", L"LQX", L"LQY", L"LQZ", L"LRA", L"LRB", L"LRC", L"LRD", L"LRE", L"LRF", L"LRG", L"LRH", L"LRI", L"LRJ", L"LRK", L"LRL", L"LRM", L"LRN", L"LRO", L"LRP", L"LRQ", L"LRR", L"LRS", L"LRT", L"LRU", L"LRV", L"LRW", L"LRX", L"LRY", L"LRZ", L"LSA", L"LSB", L"LSC", L"LSD", L"LSE", L"LSF", L"LSG", L"LSH", L"LSI", L"LSJ", L"LSK", L"LSL", L"LSM", L"LSN", L"LSO", L"LSP", L"LSQ", L"LSR", L"LSS", L"LST", L"LSU", L"LSV", L"LSW", L"LSX", L"LSY", L"LSZ", L"LTA", L"LTB", L"LTC", L"LTD", L"LTE", L"LTF", L"LTG", L"LTH", L"LTI", L"LTJ", L"LTK", L"LTL", L"LTM", L"LTN", L"LTO", L"LTP", L"LTQ", L"LTR", L"LTS", L"LTT", L"LTU", L"LTV", L"LTW", L"LTX", L"LTY", L"LTZ", L"LUA", L"LUB", L"LUC", L"LUD", L"LUE", L"LUF", L"LUG", L"LUH", L"LUI", L"LUJ", L"LUK", L"LUL", L"LUM", L"LUN", L"LUO", L"LUP", L"LUQ", L"LUR", L"LUS", L"LUT", L"LUU", L"LUV", L"LUW", L"LUX", L"LUY", L"LUZ", L"LVA", L"LVB", L"LVC", L"LVD", L"LVE", L"LVF", L"LVG", L"LVH", L"LVI", L"LVJ", L"LVK", L"LVL", L"LVM", L"LVN", L"LVO", L"LVP", L"LVQ", L"LVR", L"LVS", L"LVT", L"LVU", L"LVV", L"LVW", L"LVX", L"LVY", L"LVZ", L"LWA", L"LWB", L"LWC", L"LWD", L"LWE", L"LWF", L"LWG", L"LWH", L"LWI", L"LWJ", L"LWK", L"LWL", L"LWM", L"LWN", L"LWO", L"LWP", L"LWQ", L"LWR", L"LWS", L"LWT", L"LWU", L"LWV", L"LWW", L"LWX", L"LWY", L"LWZ", L"LXA", L"LXB", L"LXC", L"LXD", L"LXE", L"LXF", L"LXG", L"LXH", L"LXI", L"LXJ", L"LXK", L"LXL", L"LXM", L"LXN", L"LXO", L"LXP", L"LXQ", L"LXR", L"LXS", L"LXT", L"LXU", L"LXV", L"LXW", L"LXX", L"LXY", L"LXZ", L"LYA", L"LYB", L"LYC", L"LYD", L"LYE", L"LYF", L"LYG", L"LYH", L"LYI", L"LYJ", L"LYK", L"LYL", L"LYM", L"LYN", L"LYO", L"LYP", L"LYQ", L"LYR", L"LYS", L"LYT", L"LYU", L"LYV", L"LYW", L"LYX", L"LYY", L"LYZ", L"LZA", L"LZB", L"LZC", L"LZD", L"LZE", L"LZF", L"LZG", L"LZH", L"LZI", L"LZJ", L"LZK", L"LZL", L"LZM", L"LZN", L"LZO", L"LZP", L"LZQ", L"LZR", L"LZS", L"LZT", L"LZU", L"LZV", L"LZW", L"LZX", L"LZY", L"LZZ", L"MAA", L"MAB", L"MAC", L"MAD", L"MAE", L"MAF", L"MAG", L"MAH", L"MAI", L"MAJ", L"MAK", L"MAL", L"MAM", L"MAN", L"MAO", L"MAP", L"MAQ", L"MAR", L"MAS", L"MAT", L"MAU", L"MAV", L"MAW", L"MAX", L"MAY", L"MAZ", L"MBA", L"MBB", L"MBC", L"MBD", L"MBE", L"MBF", L"MBG", L"MBH", L"MBI", L"MBJ", L"MBK", L"MBL", L"MBM", L"MBN", L"MBO", L"MBP", L"MBQ", L"MBR", L"MBS", L"MBT", L"MBU", L"MBV", L"MBW", L"MBX", L"MBY", L"MBZ", L"MCA", L"MCB", L"MCC", L"MCD", L"MCE", L"MCF", L"MCG", L"MCH", L"MCI", L"MCJ", L"MCK", L"MCL", L"MCM", L"MCN", L"MCO", L"MCP", L"MCQ", L"MCR", L"MCS", L"MCT", L"MCU", L"MCV", L"MCW", L"MCX", L"MCY", L"MCZ", L"MDA", L"MDB", L"MDC", L"MDD", L"MDE", L"MDF", L"MDG", L"MDH", L"MDI", L"MDJ", L"MDK", L"MDL", L"MDM", L"MDN", L"MDO", L"MDP", L"MDQ", L"MDR", L"MDS", L"MDT", L"MDU", L"MDV", L"MDW", L"MDX", L"MDY", L"MDZ", L"MEA", L"MEB", L"MEC", L"MED", L"MEE", L"MEF", L"MEG", L"MEH", L"MEI", L"MEJ", L"MEK", L"MEL", L"MEM", L"MEN", L"MEO", L"MEP", L"MEQ", L"MER", L"MES", L"MET", L"MEU", L"MEV", L"MEW", L"MEX", L"MEY", L"MEZ", L"MFA", L"MFB", L"MFC", L"MFD", L"MFE", L"MFF", L"MFG", L"MFH", L"MFI", L"MFJ", L"MFK", L"MFL", L"MFM", L"MFN", L"MFO", L"MFP", L"MFQ", L"MFR", L"MFS", L"MFT", L"MFU", L"MFV", L"MFW", L"MFX", L"MFY", L"MFZ", L"MGA", L"MGB", L"MGC", L"MGD", L"MGE", L"MGF", L"MGG", L"MGH", L"MGI", L"MGJ", L"MGK", L"MGL", L"MGM", L"MGN", L"MGO", L"MGP", L"MGQ", L"MGR", L"MGS", L"MGT", L"MGU", L"MGV", L"MGW", L"MGX", L"MGY", L"MGZ", L"MHA", L"MHB", L"MHC", L"MHD", L"MHE", L"MHF", L"MHG", L"MHH", L"MHI", L"MHJ", L"MHK", L"MHL", L"MHM", L"MHN", L"MHO", L"MHP", L"MHQ", L"MHR", L"MHS", L"MHT", L"MHU", L"MHV", L"MHW", L"MHX", L"MHY", L"MHZ", L"MIA", L"MIB", L"MIC", L"MID", L"MIE", L"MIF", L"MIG", L"MIH", L"MII", L"MIJ", L"MIK", L"MIL", L"MIM", L"MIN", L"MIO", L"MIP", L"MIQ", L"MIR", L"MIS", L"MIT", L"MIU", L"MIV", L"MIW", L"MIX", L"MIY", L"MIZ", L"MJA", L"MJB", L"MJC", L"MJD", L"MJE", L"MJF", L"MJG", L"MJH", L"MJI", L"MJJ", L"MJK", L"MJL", L"MJM", L"MJN", L"MJO", L"MJP", L"MJQ", L"MJR", L"MJS", L"MJT", L"MJU", L"MJV", L"MJW", L"MJX", L"MJY", L"MJZ", L"MKA", L"MKB", L"MKC", L"MKD", L"MKE", L"MKF", L"MKG", L"MKH", L"MKI", L"MKJ", L"MKK", L"MKL", L"MKM", L"MKN", L"MKO", L"MKP", L"MKQ", L"MKR", L"MKS", L"MKT", L"MKU", L"MKV", L"MKW", L"MKX", L"MKY", L"MKZ", L"MLA", L"MLB", L"MLC", L"MLD", L"MLE", L"MLF", L"MLG", L"MLH", L"MLI", L"MLJ", L"MLK", L"MLL", L"MLM", L"MLN", L"MLO", L"MLP", L"MLQ", L"MLR", L"MLS", L"MLT", L"MLU", L"MLV", L"MLW", L"MLX", L"MLY", L"MLZ", L"MMA", L"MMB", L"MMC", L"MMD", L"MME", L"MMF", L"MMG", L"MMH", L"MMI", L"MMJ", L"MMK", L"MML", L"MMM", L"MMN", L"MMO", L"MMP", L"MMQ", L"MMR", L"MMS", L"MMT", L"MMU", L"MMV", L"MMW", L"MMX", L"MMY", L"MMZ", L"MNA", L"MNB", L"MNC", L"MND", L"MNE", L"MNF", L"MNG", L"MNH", L"MNI", L"MNJ", L"MNK", L"MNL", L"MNM", L"MNN", L"MNO", L"MNP", L"MNQ", L"MNR", L"MNS", L"MNT", L"MNU", L"MNV", L"MNW", L"MNX", L"MNY", L"MNZ", L"MOA", L"MOB", L"MOC", L"MOD", L"MOE", L"MOF", L"MOG", L"MOH", L"MOI", L"MOJ", L"MOK", L"MOL", L"MOM", L"MON", L"MOO", L"MOP", L"MOQ", L"MOR", L"MOS", L"MOT", L"MOU", L"MOV", L"MOW", L"MOX", L"MOY", L"MOZ", L"MPA", L"MPB", L"MPC", L"MPD", L"MPE", L"MPF", L"MPG", L"MPH", L"MPI", L"MPJ", L"MPK", L"MPL", L"MPM", L"MPN", L"MPO", L"MPP", L"MPQ", L"MPR", L"MPS", L"MPT", L"MPU", L"MPV", L"MPW", L"MPX", L"MPY", L"MPZ", L"MQA", L"MQB", L"MQC", L"MQD", L"MQE", L"MQF", L"MQG", L"MQH", L"MQI", L"MQJ", L"MQK", L"MQL", L"MQM", L"MQN", L"MQO", L"MQP", L"MQQ", L"MQR", L"MQS", L"MQT", L"MQU", L"MQV", L"MQW", L"MQX", L"MQY", L"MQZ", L"MRA", L"MRB", L"MRC", L"MRD", L"MRE", L"MRF", L"MRG", L"MRH", L"MRI", L"MRJ", L"MRK", L"MRL", L"MRM", L"MRN", L"MRO", L"MRP", L"MRQ", L"MRR", L"MRS", L"MRT", L"MRU", L"MRV", L"MRW", L"MRX", L"MRY", L"MRZ", L"MSA", L"MSB", L"MSC", L"MSD", L"MSE", L"MSF", L"MSG", L"MSH", L"MSI", L"MSJ", L"MSK", L"MSL", L"MSM", L"MSN", L"MSO", L"MSP", L"MSQ", L"MSR", L"MSS", L"MST", L"MSU", L"MSV", L"MSW", L"MSX", L"MSY", L"MSZ", L"MTA", L"MTB", L"MTC", L"MTD", L"MTE", L"MTF", L"MTG", L"MTH", L"MTI", L"MTJ", L"MTK", L"MTL", L"MTM", L"MTN", L"MTO", L"MTP", L"MTQ", L"MTR", L"MTS", L"MTT", L"MTU", L"MTV", L"MTW", L"MTX", L"MTY", L"MTZ", L"MUA", L"MUB", L"MUC", - L"MUD", L"MUE", L"MUF", L"MUG", L"MUH", L"MUI", L"MUJ", L"MUK", L"MUL", L"MUM", L"MUN", L"MUO", L"MUP", L"MUQ", L"MUR", L"MUS", L"MUT", L"MUU", L"MUV", L"MUW", L"MUX", L"MUY", L"MUZ", L"MVA", L"MVB", L"MVC", L"MVD", L"MVE", L"MVF", L"MVG", L"MVH", L"MVI", L"MVJ", L"MVK", L"MVL", L"MVM", L"MVN", L"MVO", L"MVP", L"MVQ", L"MVR", L"MVS", L"MVT", L"MVU", L"MVV", L"MVW", L"MVX", L"MVY", L"MVZ", L"MWA", L"MWB", L"MWC", L"MWD", L"MWE", L"MWF", L"MWG", L"MWH", L"MWI", L"MWJ", L"MWK", L"MWL", L"MWM", L"MWN", L"MWO", L"MWP", L"MWQ", L"MWR", L"MWS", L"MWT", L"MWU", L"MWV", L"MWW", L"MWX", L"MWY", L"MWZ", L"MXA", L"MXB", L"MXC", L"MXD", L"MXE", L"MXF", L"MXG", L"MXH", L"MXI", L"MXJ", L"MXK", L"MXL", L"MXM", L"MXN", L"MXO", L"MXP", L"MXQ", L"MXR", L"MXS", L"MXT", L"MXU", L"MXV", L"MXW", L"MXX", L"MXY", L"MXZ", L"MYA", L"MYB", L"MYC", L"MYD", L"MYE", L"MYF", L"MYG", L"MYH", L"MYI", L"MYJ", L"MYK", L"MYL", L"MYM", L"MYN", L"MYO", L"MYP", L"MYQ", L"MYR", L"MYS", L"MYT", L"MYU", L"MYV", L"MYW", L"MYX", L"MYY", L"MYZ", L"MZA", L"MZB", L"MZC", L"MZD", L"MZE", L"MZF", L"MZG", L"MZH", L"MZI", L"MZJ", L"MZK", L"MZL", L"MZM", L"MZN", L"MZO", L"MZP", L"MZQ", L"MZR", L"MZS", L"MZT", L"MZU", L"MZV", L"MZW", L"MZX", L"MZY", L"MZZ", L"NAA", L"NAB", L"NAC", L"NAD", L"NAE", L"NAF", L"NAG", L"NAH", L"NAI", L"NAJ", L"NAK", L"NAL", L"NAM", L"NAN", L"NAO", L"NAP", L"NAQ", L"NAR", L"NAS", L"NAT", L"NAU", L"NAV", L"NAW", L"NAX", L"NAY", L"NAZ", L"NBA", L"NBB", L"NBC", L"NBD", L"NBE", L"NBF", L"NBG", L"NBH", L"NBI", L"NBJ", L"NBK", L"NBL", L"NBM", L"NBN", L"NBO", L"NBP", L"NBQ", L"NBR", L"NBS", L"NBT", L"NBU", L"NBV", L"NBW", L"NBX", L"NBY", L"NBZ", L"NCA", L"NCB", L"NCC", L"NCD", L"NCE", L"NCF", L"NCG", L"NCH", L"NCI", L"NCJ", L"NCK", L"NCL", L"NCM", L"NCN", L"NCO", L"NCP", L"NCQ", L"NCR", L"NCS", L"NCT", L"NCU", L"NCV", L"NCW", L"NCX", L"NCY", L"NCZ", L"NDA", L"NDB", L"NDC", L"NDD", L"NDE", L"NDF", L"NDG", L"NDH", L"NDI", L"NDJ", L"NDK", L"NDL", L"NDM", L"NDN", L"NDO", L"NDP", L"NDQ", L"NDR", L"NDS", L"NDT", L"NDU", L"NDV", L"NDW", L"NDX", L"NDY", L"NDZ", L"NEA", L"NEB", L"NEC", L"NED", L"NEE", L"NEF", L"NEG", L"NEH", L"NEI", L"NEJ", L"NEK", L"NEL", L"NEM", L"NEN", L"NEO", L"NEP", - L"NEQ", L"NER", L"NES", L"NET", L"NEU", L"NEV", L"NEW", L"NEX", L"NEY", L"NEZ", L"NFA", L"NFB", L"NFC", L"NFD", L"NFE", L"NFF", L"NFG", L"NFH", L"NFI", L"NFJ", L"NFK", L"NFL", L"NFM", L"NFN", L"NFO", L"NFP", L"NFQ", L"NFR", L"NFS", L"NFT", L"NFU", L"NFV", L"NFW", L"NFX", L"NFY", L"NFZ", L"NGA", L"NGB", L"NGC", L"NGD", L"NGE", L"NGF", L"NGG", L"NGH", L"NGI", L"NGJ", L"NGK", L"NGL", L"NGM", L"NGN", L"NGO", L"NGP", L"NGQ", L"NGR", L"NGS", L"NGT", L"NGU", L"NGV", L"NGW", L"NGX", L"NGY", L"NGZ", L"NHA", L"NHB", L"NHC", L"NHD", L"NHE", L"NHF", L"NHG", L"NHH", L"NHI", L"NHJ", L"NHK", L"NHL", L"NHM", L"NHN", L"NHO", L"NHP", L"NHQ", L"NHR", L"NHS", L"NHT", L"NHU", L"NHV", L"NHW", L"NHX", L"NHY", L"NHZ", L"NIA", L"NIB", L"NIC", L"NID", L"NIE", L"NIF", L"NIG", L"NIH", L"NII", L"NIJ", L"NIK", L"NIL", L"NIM", L"NIN", L"NIO", L"NIP", L"NIQ", L"NIR", L"NIS", L"NIT", L"NIU", L"NIV", L"NIW", L"NIX", L"NIY", L"NIZ", L"NJA", L"NJB", L"NJC", L"NJD", L"NJE", L"NJF", L"NJG", L"NJH", L"NJI", L"NJJ", L"NJK", L"NJL", L"NJM", L"NJN", L"NJO", L"NJP", L"NJQ", L"NJR", L"NJS", L"NJT", L"NJU", L"NJV", L"NJW", L"NJX", L"NJY", L"NJZ", L"NKA", L"NKB", L"NKC", L"NKD", L"NKE", L"NKF", L"NKG", L"NKH", L"NKI", L"NKJ", L"NKK", L"NKL", L"NKM", L"NKN", L"NKO", L"NKP", L"NKQ", L"NKR", L"NKS", L"NKT", L"NKU", L"NKV", L"NKW", L"NKX", L"NKY", L"NKZ", L"NLA", L"NLB", L"NLC", L"NLD", L"NLE", L"NLF", L"NLG", L"NLH", L"NLI", L"NLJ", L"NLK", L"NLL", L"NLM", L"NLN", L"NLO", L"NLP", L"NLQ", L"NLR", L"NLS", L"NLT", L"NLU", L"NLV", L"NLW", L"NLX", L"NLY", L"NLZ", L"NMA", L"NMB", L"NMC", L"NMD", L"NME", L"NMF", L"NMG", L"NMH", L"NMI", L"NMJ", L"NMK", L"NML", L"NMM", L"NMN", L"NMO", L"NMP", L"NMQ", L"NMR", L"NMS", L"NMT", L"NMU", L"NMV", L"NMW", L"NMX", L"NMY", L"NMZ", L"NNA", L"NNB", L"NNC", L"NND", L"NNE", L"NNF", L"NNG", L"NNH", L"NNI", L"NNJ", L"NNK", L"NNL", L"NNM", L"NNN", L"NNO", L"NNP", L"NNQ", L"NNR", L"NNS", L"NNT", L"NNU", L"NNV", L"NNW", L"NNX", L"NNY", L"NNZ", L"NOA", L"NOB", L"NOC", L"NOD", L"NOE", L"NOF", L"NOG", L"NOH", L"NOI", L"NOJ", L"NOK", L"NOL", L"NOM", L"NON", L"NOO", L"NOP", L"NOQ", L"NOR", L"NOS", L"NOT", L"NOU", L"NOV", L"NOW", L"NOX", L"NOY", L"NOZ", L"NPA", L"NPB", L"NPC", - L"NPD", L"NPE", L"NPF", L"NPG", L"NPH", L"NPI", L"NPJ", L"NPK", L"NPL", L"NPM", L"NPN", L"NPO", L"NPP", L"NPQ", L"NPR", L"NPS", L"NPT", L"NPU", L"NPV", L"NPW", L"NPX", L"NPY", L"NPZ", L"NQA", L"NQB", L"NQC", L"NQD", L"NQE", L"NQF", L"NQG", L"NQH", L"NQI", L"NQJ", L"NQK", L"NQL", L"NQM", L"NQN", L"NQO", L"NQP", L"NQQ", L"NQR", L"NQS", L"NQT", L"NQU", L"NQV", L"NQW", L"NQX", L"NQY", L"NQZ", L"NRA", L"NRB", L"NRC", L"NRD", L"NRE", L"NRF", L"NRG", L"NRH", L"NRI", L"NRJ", L"NRK", L"NRL", L"NRM", L"NRN", L"NRO", L"NRP", L"NRQ", L"NRR", L"NRS", L"NRT", L"NRU", L"NRV", L"NRW", L"NRX", L"NRY", L"NRZ", L"NSA", L"NSB", L"NSC", L"NSD", L"NSE", L"NSF", L"NSG", L"NSH", L"NSI", L"NSJ", L"NSK", L"NSL", L"NSM", L"NSN", L"NSO", L"NSP", L"NSQ", L"NSR", L"NSS", L"NST", L"NSU", L"NSV", L"NSW", L"NSX", L"NSY", L"NSZ", L"NTA", L"NTB", L"NTC", L"NTD", L"NTE", L"NTF", L"NTG", L"NTH", L"NTI", L"NTJ", L"NTK", L"NTL", L"NTM", L"NTN", L"NTO", L"NTP", L"NTQ", L"NTR", L"NTS", L"NTT", L"NTU", L"NTV", L"NTW", L"NTX", L"NTY", L"NTZ", L"NUA", L"NUB", L"NUC", L"NUD", L"NUE", L"NUF", L"NUG", L"NUH", L"NUI", L"NUJ", L"NUK", L"NUL", L"NUM", L"NUN", L"NUO", L"NUP", L"NUQ", L"NUR", L"NUS", L"NUT", L"NUU", L"NUV", L"NUW", L"NUX", L"NUY", L"NUZ", L"NVA", L"NVB", L"NVC", L"NVD", L"NVE", L"NVF", L"NVG", L"NVH", L"NVI", L"NVJ", L"NVK", L"NVL", L"NVM", L"NVN", L"NVO", L"NVP", L"NVQ", L"NVR", L"NVS", L"NVT", L"NVU", L"NVV", L"NVW", L"NVX", L"NVY", L"NVZ", L"NWA", L"NWB", L"NWC", L"NWD", L"NWE", L"NWF", L"NWG", L"NWH", L"NWI", L"NWJ", L"NWK", L"NWL", L"NWM", L"NWN", L"NWO", L"NWP", L"NWQ", L"NWR", L"NWS", L"NWT", L"NWU", L"NWV", L"NWW", L"NWX", L"NWY", L"NWZ", L"NXA", L"NXB", L"NXC", L"NXD", L"NXE", L"NXF", L"NXG", L"NXH", L"NXI", L"NXJ", L"NXK", L"NXL", L"NXM", L"NXN", L"NXO", L"NXP", L"NXQ", L"NXR", L"NXS", L"NXT", L"NXU", L"NXV", L"NXW", L"NXX", L"NXY", L"NXZ", L"NYA", L"NYB", L"NYC", L"NYD", L"NYE", L"NYF", L"NYG", L"NYH", L"NYI", L"NYJ", L"NYK", L"NYL", L"NYM", L"NYN", L"NYO", L"NYP", L"NYQ", L"NYR", L"NYS", L"NYT", L"NYU", L"NYV", L"NYW", L"NYX", L"NYY", L"NYZ", L"NZA", L"NZB", L"NZC", L"NZD", L"NZE", L"NZF", L"NZG", L"NZH", L"NZI", L"NZJ", L"NZK", L"NZL", L"NZM", L"NZN", L"NZO", L"NZP", - L"NZQ", L"NZR", L"NZS", L"NZT", L"NZU", L"NZV", L"NZW", L"NZX", L"NZY", L"NZZ", L"OAA", L"OAB", L"OAC", L"OAD", L"OAE", L"OAF", L"OAG", L"OAH", L"OAI", L"OAJ", L"OAK", L"OAL", L"OAM", L"OAN", L"OAO", L"OAP", L"OAQ", L"OAR", L"OAS", L"OAT", L"OAU", L"OAV", L"OAW", L"OAX", L"OAY", L"OAZ", L"OBA", L"OBB", L"OBC", L"OBD", L"OBE", L"OBF", L"OBG", L"OBH", L"OBI", L"OBJ", L"OBK", L"OBL", L"OBM", L"OBN", L"OBO", L"OBP", L"OBQ", L"OBR", L"OBS", L"OBT", L"OBU", L"OBV", L"OBW", L"OBX", L"OBY", L"OBZ", L"OCA", L"OCB", L"OCC", L"OCD", L"OCE", L"OCF", L"OCG", L"OCH", L"OCI", L"OCJ", L"OCK", L"OCL", L"OCM", L"OCN", L"OCO", L"OCP", L"OCQ", L"OCR", L"OCS", L"OCT", L"OCU", L"OCV", L"OCW", L"OCX", L"OCY", L"OCZ", L"ODA", L"ODB", L"ODC", L"ODD", L"ODE", L"ODF", L"ODG", L"ODH", L"ODI", L"ODJ", L"ODK", L"ODL", L"ODM", L"ODN", L"ODO", L"ODP", L"ODQ", L"ODR", L"ODS", L"ODT", L"ODU", L"ODV", L"ODW", L"ODX", L"ODY", L"ODZ", L"OEA", L"OEB", L"OEC", L"OED", L"OEE", L"OEF", L"OEG", L"OEH", L"OEI", L"OEJ", L"OEK", L"OEL", L"OEM", L"OEN", L"OEO", L"OEP", L"OEQ", L"OER", L"OES", L"OET", L"OEU", L"OEV", L"OEW", L"OEX", L"OEY", L"OEZ", L"OFA", L"OFB", L"OFC", L"OFD", L"OFE", L"OFF", L"OFG", L"OFH", L"OFI", L"OFJ", L"OFK", L"OFL", L"OFM", L"OFN", L"OFO", L"OFP", L"OFQ", L"OFR", L"OFS", L"OFT", L"OFU", L"OFV", L"OFW", L"OFX", L"OFY", L"OFZ", L"OGA", L"OGB", L"OGC", L"OGD", L"OGE", L"OGF", L"OGG", L"OGH", L"OGI", L"OGJ", L"OGK", L"OGL", L"OGM", L"OGN", L"OGO", L"OGP", L"OGQ", L"OGR", L"OGS", L"OGT", L"OGU", L"OGV", L"OGW", L"OGX", L"OGY", L"OGZ", L"OHA", L"OHB", L"OHC", L"OHD", L"OHE", L"OHF", L"OHG", L"OHH", L"OHI", L"OHJ", L"OHK", L"OHL", L"OHM", L"OHN", L"OHO", L"OHP", L"OHQ", L"OHR", L"OHS", L"OHT", L"OHU", L"OHV", L"OHW", L"OHX", L"OHY", L"OHZ", L"OIA", L"OIB", L"OIC", L"OID", L"OIE", L"OIF", L"OIG", L"OIH", L"OII", L"OIJ", L"OIK", L"OIL", L"OIM", L"OIN", L"OIO", L"OIP", L"OIQ", L"OIR", L"OIS", L"OIT", L"OIU", L"OIV", L"OIW", L"OIX", L"OIY", L"OIZ", L"OJA", L"OJB", L"OJC", L"OJD", L"OJE", L"OJF", L"OJG", L"OJH", L"OJI", L"OJJ", L"OJK", L"OJL", L"OJM", L"OJN", L"OJO", L"OJP", L"OJQ", L"OJR", L"OJS", L"OJT", L"OJU", L"OJV", L"OJW", L"OJX", L"OJY", L"OJZ", L"OKA", L"OKB", L"OKC", - L"OKD", L"OKE", L"OKF", L"OKG", L"OKH", L"OKI", L"OKJ", L"OKK", L"OKL", L"OKM", L"OKN", L"OKO", L"OKP", L"OKQ", L"OKR", L"OKS", L"OKT", L"OKU", L"OKV", L"OKW", L"OKX", L"OKY", L"OKZ", L"OLA", L"OLB", L"OLC", L"OLD", L"OLE", L"OLF", L"OLG", L"OLH", L"OLI", L"OLJ", L"OLK", L"OLL", L"OLM", L"OLN", L"OLO", L"OLP", L"OLQ", L"OLR", L"OLS", L"OLT", L"OLU", L"OLV", L"OLW", L"OLX", L"OLY", L"OLZ", L"OMA", L"OMB", L"OMC", L"OMD", L"OME", L"OMF", L"OMG", L"OMH", L"OMI", L"OMJ", L"OMK", L"OML", L"OMM", L"OMN", L"OMO", L"OMP", L"OMQ", L"OMR", L"OMS", L"OMT", L"OMU", L"OMV", L"OMW", L"OMX", L"OMY", L"OMZ", L"ONA", L"ONB", L"ONC", L"OND", L"ONE", L"ONF", L"ONG", L"ONH", L"ONI", L"ONJ", L"ONK", L"ONL", L"ONM", L"ONN", L"ONO", L"ONP", L"ONQ", L"ONR", L"ONS", L"ONT", L"ONU", L"ONV", L"ONW", L"ONX", L"ONY", L"ONZ", L"OOA", L"OOB", L"OOC", L"OOD", L"OOE", L"OOF", L"OOG", L"OOH", L"OOI", L"OOJ", L"OOK", L"OOL", L"OOM", L"OON", L"OOO", L"OOP", L"OOQ", L"OOR", L"OOS", L"OOT", L"OOU", L"OOV", L"OOW", L"OOX", L"OOY", L"OOZ", L"OPA", L"OPB", L"OPC", L"OPD", L"OPE", L"OPF", L"OPG", L"OPH", L"OPI", L"OPJ", L"OPK", L"OPL", L"OPM", L"OPN", L"OPO", L"OPP", L"OPQ", L"OPR", L"OPS", L"OPT", L"OPU", L"OPV", L"OPW", L"OPX", L"OPY", L"OPZ", L"OQA", L"OQB", L"OQC", L"OQD", L"OQE", L"OQF", L"OQG", L"OQH", L"OQI", L"OQJ", L"OQK", L"OQL", L"OQM", L"OQN", L"OQO", L"OQP", L"OQQ", L"OQR", L"OQS", L"OQT", L"OQU", L"OQV", L"OQW", L"OQX", L"OQY", L"OQZ", L"ORA", L"ORB", L"ORC", L"ORD", L"ORE", L"ORF", L"ORG", L"ORH", L"ORI", L"ORJ", L"ORK", L"ORL", L"ORM", L"ORN", L"ORO", L"ORP", L"ORQ", L"ORR", L"ORS", L"ORT", L"ORU", L"ORV", L"ORW", L"ORX", L"ORY", L"ORZ", L"OSA", L"OSB", L"OSC", L"OSD", L"OSE", L"OSF", L"OSG", L"OSH", L"OSI", L"OSJ", L"OSK", L"OSL", L"OSM", L"OSN", L"OSO", L"OSP", L"OSQ", L"OSR", L"OSS", L"OST", L"OSU", L"OSV", L"OSW", L"OSX", L"OSY", L"OSZ", L"OTA", L"OTB", L"OTC", L"OTD", L"OTE", L"OTF", L"OTG", L"OTH", L"OTI", L"OTJ", L"OTK", L"OTL", L"OTM", L"OTN", L"OTO", L"OTP", L"OTQ", L"OTR", L"OTS", L"OTT", L"OTU", L"OTV", L"OTW", L"OTX", L"OTY", L"OTZ", L"OUA", L"OUB", L"OUC", L"OUD", L"OUE", L"OUF", L"OUG", L"OUH", L"OUI", L"OUJ", L"OUK", L"OUL", L"OUM", L"OUN", L"OUO", L"OUP", - L"OUQ", L"OUR", L"OUS", L"OUT", L"OUU", L"OUV", L"OUW", L"OUX", L"OUY", L"OUZ", L"OVA", L"OVB", L"OVC", L"OVD", L"OVE", L"OVF", L"OVG", L"OVH", L"OVI", L"OVJ", L"OVK", L"OVL", L"OVM", L"OVN", L"OVO", L"OVP", L"OVQ", L"OVR", L"OVS", L"OVT", L"OVU", L"OVV", L"OVW", L"OVX", L"OVY", L"OVZ", L"OWA", L"OWB", L"OWC", L"OWD", L"OWE", L"OWF", L"OWG", L"OWH", L"OWI", L"OWJ", L"OWK", L"OWL", L"OWM", L"OWN", L"OWO", L"OWP", L"OWQ", L"OWR", L"OWS", L"OWT", L"OWU", L"OWV", L"OWW", L"OWX", L"OWY", L"OWZ", L"OXA", L"OXB", L"OXC", L"OXD", L"OXE", L"OXF", L"OXG", L"OXH", L"OXI", L"OXJ", L"OXK", L"OXL", L"OXM", L"OXN", L"OXO", L"OXP", L"OXQ", L"OXR", L"OXS", L"OXT", L"OXU", L"OXV", L"OXW", L"OXX", L"OXY", L"OXZ", L"OYA", L"OYB", L"OYC", L"OYD", L"OYE", L"OYF", L"OYG", L"OYH", L"OYI", L"OYJ", L"OYK", L"OYL", L"OYM", L"OYN", L"OYO", L"OYP", L"OYQ", L"OYR", L"OYS", L"OYT", L"OYU", L"OYV", L"OYW", L"OYX", L"OYY", L"OYZ", L"OZA", L"OZB", L"OZC", L"OZD", L"OZE", L"OZF", L"OZG", L"OZH", L"OZI", L"OZJ", L"OZK", L"OZL", L"OZM", L"OZN", L"OZO", L"OZP", L"OZQ", L"OZR", L"OZS", L"OZT", L"OZU", L"OZV", L"OZW", L"OZX", L"OZY", L"OZZ", L"PAA", L"PAB", L"PAC", L"PAD", L"PAE", L"PAF", L"PAG", L"PAH", L"PAI", L"PAJ", L"PAK", L"PAL", L"PAM", L"PAN", L"PAO", L"PAP", L"PAQ", L"PAR", L"PAS", L"PAT", L"PAU", L"PAV", L"PAW", L"PAX", L"PAY", L"PAZ", L"PBA", L"PBB", L"PBC", L"PBD", L"PBE", L"PBF", L"PBG", L"PBH", L"PBI", L"PBJ", L"PBK", L"PBL", L"PBM", L"PBN", L"PBO", L"PBP", L"PBQ", L"PBR", L"PBS", L"PBT", L"PBU", L"PBV", L"PBW", L"PBX", L"PBY", L"PBZ", L"PCA", L"PCB", L"PCC", L"PCD", L"PCE", L"PCF", L"PCG", L"PCH", L"PCI", L"PCJ", L"PCK", L"PCL", L"PCM", L"PCN", L"PCO", L"PCP", L"PCQ", L"PCR", L"PCS", L"PCT", L"PCU", L"PCV", L"PCW", L"PCX", L"PCY", L"PCZ", L"PDA", L"PDB", L"PDC", L"PDD", L"PDE", L"PDF", L"PDG", L"PDH", L"PDI", L"PDJ", L"PDK", L"PDL", L"PDM", L"PDN", L"PDO", L"PDP", L"PDQ", L"PDR", L"PDS", L"PDT", L"PDU", L"PDV", L"PDW", L"PDX", L"PDY", L"PDZ", L"PEA", L"PEB", L"PEC", L"PED", L"PEE", L"PEF", L"PEG", L"PEH", L"PEI", L"PEJ", L"PEK", L"PEL", L"PEM", L"PEN", L"PEO", L"PEP", L"PEQ", L"PER", L"PES", L"PET", L"PEU", L"PEV", L"PEW", L"PEX", L"PEY", L"PEZ", L"PFA", L"PFB", L"PFC", + L"MUD", L"MUE", L"MUF", L"MUG", L"MUH", L"MUI", L"MUJ", L"MUK", L"MUL", L"MUM", L"MUN", L"MUO", L"MUP", L"MUQ", L"MUR", L"MUS", L"MUT", L"MUU", L"MUV", L"MUW", L"MUX", L"MUY", L"MUZ", L"MVA", L"MVB", L"MVC", L"MVD", L"MVE", L"MVF", L"MVG", L"MVH", L"MVI", L"MVJ", L"MVK", L"MVL", L"MVM", L"MVN", L"MVO", L"MVP", L"MVQ", L"MVR", L"MVS", L"MVT", L"MVU", L"MVV", L"MVW", L"MVX", L"MVY", L"MVZ", L"MWA", L"MWB", L"MWC", L"MWD", L"MWE", L"MWF", L"MWG", L"MWH", L"MWI", L"MWJ", L"MWK", L"MWL", L"MWM", L"MWN", L"MWO", L"MWP", L"MWQ", L"MWR", L"MWS", L"MWT", L"MWU", L"MWV", L"MWW", L"MWX", L"MWY", L"MWZ", L"MXA", L"MXB", L"MXC", L"MXD", L"MXE", L"MXF", L"MXG", L"MXH", L"MXI", L"MXJ", L"MXK", L"MXL", L"MXM", L"MXN", L"MXO", L"MXP", L"MXQ", L"MXR", L"MXS", L"MXT", L"MXU", L"MXV", L"MXW", L"MXX", L"MXY", L"MXZ", L"MYA", L"MYB", L"MYC", L"MYD", L"MYE", L"MYF", L"MYG", L"MYH", L"MYI", L"MYJ", L"MYK", L"MYL", L"MYM", L"MYN", L"MYO", L"MYP", L"MYQ", L"MYR", L"MYS", L"MYT", L"MYU", L"MYV", L"MYW", L"MYX", L"MYY", L"MYZ", L"MZA", L"MZB", L"MZC", L"MZD", L"MZE", L"MZF", L"MZG", L"MZH", L"MZI", L"MZJ", L"MZK", L"MZL", L"MZM", L"MZN", L"MZO", L"MZP", L"MZQ", L"MZR", L"MZS", L"MZT", L"MZU", L"MZV", L"MZW", L"MZX", L"MZY", L"MZZ", L"NAA", L"NAB", L"NAC", L"NAD", L"NAE", L"NAF", L"NAG", L"NAH", L"NAI", L"NAJ", L"NAK", L"NAL", L"NAM", L"NAN", L"NAO", L"NAP", L"NAQ", L"NAR", L"NAS", L"NAT", L"NAU", L"NAV", L"NAW", L"NAX", L"NAY", L"NAZ", L"NBA", L"NBB", L"NBC", L"NBD", L"NBE", L"NBF", L"NBG", L"NBH", L"NBI", L"NBJ", L"NBK", L"NBL", L"NBM", L"NBN", L"NBO", L"NBP", L"NBQ", L"NBR", L"NBS", L"NBT", L"NBU", L"NBV", L"NBW", L"NBX", L"NBY", L"NBZ", L"NCA", L"NCB", L"NCC", L"NCD", L"NCE", L"NCF", L"NCG", L"NCH", L"NCI", L"NCJ", L"NCK", L"NCL", L"NCM", L"NCN", L"NCO", L"NCP", L"NCQ", L"NCR", L"NCS", L"NCT", L"NCU", L"NCV", L"NCW", L"NCX", L"NCY", L"NCZ", L"NDA", L"NDB", L"NDC", L"NDD", L"NDE", L"NDF", L"NDG", L"NDH", L"NDI", L"NDJ", L"NDK", L"NDL", L"NDM", L"NDN", L"NDO", L"NDP", L"NDQ", L"NDR", L"NDS", L"NDT", L"NDU", L"NDV", L"NDW", L"NDX", L"NDY", L"NDZ", L"NEA", L"NEB", L"NEC", L"NED", L"NEE", L"NEF", L"NEG", L"NEH", L"NEI", L"NEJ", L"NEK", L"NEL", L"NEM", L"NEN", L"NEO", L"NEP", + L"NEQ", L"NER", L"NES", L"NET", L"NEU", L"NEV", L"NEW", L"NEX", L"NEY", L"NEZ", L"NFA", L"NFB", L"NFC", L"NFD", L"NFE", L"NFF", L"NFG", L"NFH", L"NFI", L"NFJ", L"NFK", L"NFL", L"NFM", L"NFN", L"NFO", L"NFP", L"NFQ", L"NFR", L"NFS", L"NFT", L"NFU", L"NFV", L"NFW", L"NFX", L"NFY", L"NFZ", L"NGA", L"NGB", L"NGC", L"NGD", L"NGE", L"NGF", L"NGG", L"NGH", L"NGI", L"NGJ", L"NGK", L"NGL", L"NGM", L"NGN", L"NGO", L"NGP", L"NGQ", L"NGR", L"NGS", L"NGT", L"NGU", L"NGV", L"NGW", L"NGX", L"NGY", L"NGZ", L"NHA", L"NHB", L"NHC", L"NHD", L"NHE", L"NHF", L"NHG", L"NHH", L"NHI", L"NHJ", L"NHK", L"NHL", L"NHM", L"NHN", L"NHO", L"NHP", L"NHQ", L"NHR", L"NHS", L"NHT", L"NHU", L"NHV", L"NHW", L"NHX", L"NHY", L"NHZ", L"NIA", L"NIB", L"NIC", L"NID", L"NIE", L"NIF", L"NIG", L"NIH", L"NII", L"NIJ", L"NIK", L"NIL", L"NIM", L"NIN", L"NIO", L"NIP", L"NIQ", L"NIR", L"NIS", L"NIT", L"NIU", L"NIV", L"NIW", L"NIX", L"NIY", L"NIZ", L"NJA", L"NJB", L"NJC", L"NJD", L"NJE", L"NJF", L"NJG", L"NJH", L"NJI", L"NJJ", L"NJK", L"NJL", L"NJM", L"NJN", L"NJO", L"NJP", L"NJQ", L"NJR", L"NJS", L"NJT", L"NJU", L"NJV", L"NJW", L"NJX", L"NJY", L"NJZ", L"NKA", L"NKB", L"NKC", L"NKD", L"NKE", L"NKF", L"NKG", L"NKH", L"NKI", L"NKJ", L"NKK", L"NKL", L"NKM", L"NKN", L"NKO", L"NKP", L"NKQ", L"NKR", L"NKS", L"NKT", L"NKU", L"NKV", L"NKW", L"NKX", L"NKY", L"NKZ", L"NLA", L"NLB", L"NLC", L"NLD", L"NLE", L"NLF", L"NLG", L"NLH", L"NLI", L"NLJ", L"NLK", L"NLL", L"NLM", L"NLN", L"NLO", L"NLP", L"NLQ", L"NLR", L"NLS", L"NLT", L"NLU", L"NLV", L"NLW", L"NLX", L"NLY", L"NLZ", L"NMA", L"NMB", L"NMC", L"NMD", L"NME", L"NMF", L"NMG", L"NMH", L"NMI", L"NMJ", L"NMK", L"NML", L"NMM", L"NMN", L"NMO", L"NMP", L"NMQ", L"NMR", L"NMS", L"NMT", L"NMU", L"NMV", L"NMW", L"NMX", L"NMY", L"NMZ", L"NNA", L"NNB", L"NNC", L"NND", L"NNE", L"NNF", L"NNG", L"NNH", L"NNI", L"NNJ", L"NNK", L"NNL", L"NNM", L"NNN", L"NNO", L"NNP", L"NNQ", L"NNR", L"NNS", L"NNT", L"NNU", L"NNV", L"NNW", L"NNX", L"NNY", L"NNZ", L"NOA", L"NOB", L"NOC", L"NOD", L"NOE", L"NOF", L"NOG", L"NOH", L"NOI", L"NOJ", L"NOK", L"NOL", L"NOM", L"NON", L"NOO", L"NOP", L"NOQ", L"NOR", L"NOS", L"NOT", L"NOU", L"NOV", L"NOW", L"NOX", L"NOY", L"NOZ", L"NPA", L"NPB", L"NPC", + L"NPD", L"NPE", L"NPF", L"NPG", L"NPH", L"NPI", L"NPJ", L"NPK", L"NPL", L"NPM", L"NPN", L"NPO", L"NPP", L"NPQ", L"NPR", L"NPS", L"NPT", L"NPU", L"NPV", L"NPW", L"NPX", L"NPY", L"NPZ", L"NQA", L"NQB", L"NQC", L"NQD", L"NQE", L"NQF", L"NQG", L"NQH", L"NQI", L"NQJ", L"NQK", L"NQL", L"NQM", L"NQN", L"NQO", L"NQP", L"NQQ", L"NQR", L"NQS", L"NQT", L"NQU", L"NQV", L"NQW", L"NQX", L"NQY", L"NQZ", L"NRA", L"NRB", L"NRC", L"NRD", L"NRE", L"NRF", L"NRG", L"NRH", L"NRI", L"NRJ", L"NRK", L"NRL", L"NRM", L"NRN", L"NRO", L"NRP", L"NRQ", L"NRR", L"NRS", L"NRT", L"NRU", L"NRV", L"NRW", L"NRX", L"NRY", L"NRZ", L"NSA", L"NSB", L"NSC", L"NSD", L"NSE", L"NSF", L"NSG", L"NSH", L"NSI", L"NSJ", L"NSK", L"NSL", L"NSM", L"NSN", L"NSO", L"NSP", L"NSQ", L"NSR", L"NSS", L"NST", L"NSU", L"NSV", L"NSW", L"NSX", L"NSY", L"NSZ", L"NTA", L"NTB", L"NTC", L"NTD", L"NTE", L"NTF", L"NTG", L"NTH", L"NTI", L"NTJ", L"NTK", L"NTL", L"NTM", L"NTN", L"NTO", L"NTP", L"NTQ", L"NTR", L"NTS", L"NTT", L"NTU", L"NTV", L"NTW", L"NTX", L"NTY", L"NTZ", L"NUA", L"NUB", L"NUC", L"NUD", L"NUE", L"NUF", L"NUG", L"NUH", L"NUI", L"NUJ", L"NUK", L"NUL", L"NUM", L"NUN", L"NUO", L"NUP", L"NUQ", L"NUR", L"NUS", L"NUT", L"NUU", L"NUV", L"NUW", L"NUX", L"NUY", L"NUZ", L"NVA", L"NVB", L"NVC", L"NVD", L"NVE", L"NVF", L"NVG", L"NVH", L"NVI", L"NVJ", L"NVK", L"NVL", L"NVM", L"NVN", L"NVO", L"NVP", L"NVQ", L"NVR", L"NVS", L"NVT", L"NVU", L"NVV", L"NVW", L"NVX", L"NVY", L"NVZ", L"NWA", L"NWB", L"NWC", L"NWD", L"NWE", L"NWF", L"NWG", L"NWH", L"NWI", L"NWJ", L"NWK", L"NWL", L"NWM", L"NWN", L"NWO", L"NWP", L"NWQ", L"NWR", L"NWS", L"NWT", L"NWU", L"NWV", L"NWW", L"NWX", L"NWY", L"NWZ", L"NXA", L"NXB", L"NXC", L"NXD", L"NXE", L"NXF", L"NXG", L"NXH", L"NXI", L"NXJ", L"NXK", L"NXL", L"NXM", L"NXN", L"NXO", L"NXP", L"NXQ", L"NXR", L"NXS", L"NXT", L"NXU", L"NXV", L"NXW", L"NXX", L"NXY", L"NXZ", L"NYA", L"NYB", L"NYC", L"NYD", L"NYE", L"NYF", L"NYG", L"NYH", L"NYI", L"NYJ", L"NYK", L"NYL", L"NYM", L"NYN", L"NYO", L"NYP", L"NYQ", L"NYR", L"NYS", L"NYT", L"NYU", L"NYV", L"NYW", L"NYX", L"NYY", L"NYZ", L"NZA", L"NZB", L"NZC", L"NZD", L"NZE", L"NZF", L"NZG", L"NZH", L"NZI", L"NZJ", L"NZK", L"NZL", L"NZM", L"NZN", L"NZO", L"NZP", + L"NZQ", L"NZR", L"NZS", L"NZT", L"NZU", L"NZV", L"NZW", L"NZX", L"NZY", L"NZZ", L"OAA", L"OAB", L"OAC", L"OAD", L"OAE", L"OAF", L"OAG", L"OAH", L"OAI", L"OAJ", L"OAK", L"OAL", L"OAM", L"OAN", L"OAO", L"OAP", L"OAQ", L"OAR", L"OAS", L"OAT", L"OAU", L"OAV", L"OAW", L"OAX", L"OAY", L"OAZ", L"OBA", L"OBB", L"OBC", L"OBD", L"OBE", L"OBF", L"OBG", L"OBH", L"OBI", L"OBJ", L"OBK", L"OBL", L"OBM", L"OBN", L"OBO", L"OBP", L"OBQ", L"OBR", L"OBS", L"OBT", L"OBU", L"OBV", L"OBW", L"OBX", L"OBY", L"OBZ", L"OCA", L"OCB", L"OCC", L"OCD", L"OCE", L"OCF", L"OCG", L"OCH", L"OCI", L"OCJ", L"OCK", L"OCL", L"OCM", L"OCN", L"OCO", L"OCP", L"OCQ", L"OCR", L"OCS", L"OCT", L"OCU", L"OCV", L"OCW", L"OCX", L"OCY", L"OCZ", L"ODA", L"ODB", L"ODC", L"ODD", L"ODE", L"ODF", L"ODG", L"ODH", L"ODI", L"ODJ", L"ODK", L"ODL", L"ODM", L"ODN", L"ODO", L"ODP", L"ODQ", L"ODR", L"ODS", L"ODT", L"ODU", L"ODV", L"ODW", L"ODX", L"ODY", L"ODZ", L"OEA", L"OEB", L"OEC", L"OED", L"OEE", L"OEF", L"OEG", L"OEH", L"OEI", L"OEJ", L"OEK", L"OEL", L"OEM", L"OEN", L"OEO", L"OEP", L"OEQ", L"OER", L"OES", L"OET", L"OEU", L"OEV", L"OEW", L"OEX", L"OEY", L"OEZ", L"OFA", L"OFB", L"OFC", L"OFD", L"OFE", L"OFF", L"OFG", L"OFH", L"OFI", L"OFJ", L"OFK", L"OFL", L"OFM", L"OFN", L"OFO", L"OFP", L"OFQ", L"OFR", L"OFS", L"OFT", L"OFU", L"OFV", L"OFW", L"OFX", L"OFY", L"OFZ", L"OGA", L"OGB", L"OGC", L"OGD", L"OGE", L"OGF", L"OGG", L"OGH", L"OGI", L"OGJ", L"OGK", L"OGL", L"OGM", L"OGN", L"OGO", L"OGP", L"OGQ", L"OGR", L"OGS", L"OGT", L"OGU", L"OGV", L"OGW", L"OGX", L"OGY", L"OGZ", L"OHA", L"OHB", L"OHC", L"OHD", L"OHE", L"OHF", L"OHG", L"OHH", L"OHI", L"OHJ", L"OHK", L"OHL", L"OHM", L"OHN", L"OHO", L"OHP", L"OHQ", L"OHR", L"OHS", L"OHT", L"OHU", L"OHV", L"OHW", L"OHX", L"OHY", L"OHZ", L"OIA", L"OIB", L"OIC", L"OID", L"OIE", L"OIF", L"OIG", L"OIH", L"OII", L"OIJ", L"OIK", L"OIL", L"OIM", L"OIN", L"OIO", L"OIP", L"OIQ", L"OIR", L"OIS", L"OIT", L"OIU", L"OIV", L"OIW", L"OIX", L"OIY", L"OIZ", L"OJA", L"OJB", L"OJC", L"OJD", L"OJE", L"OJF", L"OJG", L"OJH", L"OJI", L"OJJ", L"OJK", L"OJL", L"OJM", L"OJN", L"OJO", L"OJP", L"OJQ", L"OJR", L"OJS", L"OJT", L"OJU", L"OJV", L"OJW", L"OJX", L"OJY", L"OJZ", L"OKA", L"OKB", L"OKC", + L"OKD", L"OKE", L"OKF", L"OKG", L"OKH", L"OKI", L"OKJ", L"OKK", L"OKL", L"OKM", L"OKN", L"OKO", L"OKP", L"OKQ", L"OKR", L"OKS", L"OKT", L"OKU", L"OKV", L"OKW", L"OKX", L"OKY", L"OKZ", L"OLA", L"OLB", L"OLC", L"OLD", L"OLE", L"OLF", L"OLG", L"OLH", L"OLI", L"OLJ", L"OLK", L"OLL", L"OLM", L"OLN", L"OLO", L"OLP", L"OLQ", L"OLR", L"OLS", L"OLT", L"OLU", L"OLV", L"OLW", L"OLX", L"OLY", L"OLZ", L"OMA", L"OMB", L"OMC", L"OMD", L"OME", L"OMF", L"OMG", L"OMH", L"OMI", L"OMJ", L"OMK", L"OML", L"OMM", L"OMN", L"OMO", L"OMP", L"OMQ", L"OMR", L"OMS", L"OMT", L"OMU", L"OMV", L"OMW", L"OMX", L"OMY", L"OMZ", L"ONA", L"ONB", L"ONC", L"OND", L"ONE", L"ONF", L"ONG", L"ONH", L"ONI", L"ONJ", L"ONK", L"ONL", L"ONM", L"ONN", L"ONO", L"ONP", L"ONQ", L"ONR", L"ONS", L"ONT", L"ONU", L"ONV", L"ONW", L"ONX", L"ONY", L"ONZ", L"OOA", L"OOB", L"OOC", L"OOD", L"OOE", L"OOF", L"OOG", L"OOH", L"OOI", L"OOJ", L"OOK", L"OOL", L"OOM", L"OON", L"OOO", L"OOP", L"OOQ", L"OOR", L"OOS", L"OOT", L"OOU", L"OOV", L"OOW", L"OOX", L"OOY", L"OOZ", L"OPA", L"OPB", L"OPC", L"OPD", L"OPE", L"OPF", L"OPG", L"OPH", L"OPI", L"OPJ", L"OPK", L"OPL", L"OPM", L"OPN", L"OPO", L"OPP", L"OPQ", L"OPR", L"OPS", L"OPT", L"OPU", L"OPV", L"OPW", L"OPX", L"OPY", L"OPZ", L"OQA", L"OQB", L"OQC", L"OQD", L"OQE", L"OQF", L"OQG", L"OQH", L"OQI", L"OQJ", L"OQK", L"OQL", L"OQM", L"OQN", L"OQO", L"OQP", L"OQQ", L"OQR", L"OQS", L"OQT", L"OQU", L"OQV", L"OQW", L"OQX", L"OQY", L"OQZ", L"ORA", L"ORB", L"ORC", L"ORD", L"ORE", L"ORF", L"ORG", L"ORH", L"ORI", L"ORJ", L"ORK", L"ORL", L"ORM", L"ORN", L"ORO", L"ORP", L"ORQ", L"ORR", L"ORS", L"ORT", L"ORU", L"ORV", L"ORW", L"ORX", L"ORY", L"ORZ", L"OSA", L"OSB", L"OSC", L"OSD", L"OSE", L"OSF", L"OSG", L"OSH", L"OSI", L"OSJ", L"OSK", L"OSL", L"OSM", L"OSN", L"OSO", L"OSP", L"OSQ", L"OSR", L"OSS", L"OST", L"OSU", L"OSV", L"OSW", L"OSX", L"OSY", L"OSZ", L"OTA", L"OTB", L"OTC", L"OTD", L"OTE", L"OTF", L"OTG", L"OTH", L"OTI", L"OTJ", L"OTK", L"OTL", L"OTM", L"OTN", L"OTO", L"OTP", L"OTQ", L"OTR", L"OTS", L"OTT", L"OTU", L"OTV", L"OTW", L"OTX", L"OTY", L"OTZ", L"OUA", L"OUB", L"OUC", L"OUD", L"OUE", L"OUF", L"OUG", L"OUH", L"OUI", L"OUJ", L"OUK", L"OUL", L"OUM", L"OUN", L"OUO", L"OUP", + L"OUQ", L"OUR", L"OUS", L"OUT", L"OUU", L"OUV", L"OUW", L"OUX", L"OUY", L"OUZ", L"OVA", L"OVB", L"OVC", L"OVD", L"OVE", L"OVF", L"OVG", L"OVH", L"OVI", L"OVJ", L"OVK", L"OVL", L"OVM", L"OVN", L"OVO", L"OVP", L"OVQ", L"OVR", L"OVS", L"OVT", L"OVU", L"OVV", L"OVW", L"OVX", L"OVY", L"OVZ", L"OWA", L"OWB", L"OWC", L"OWD", L"OWE", L"OWF", L"OWG", L"OWH", L"OWI", L"OWJ", L"OWK", L"OWL", L"OWM", L"OWN", L"OWO", L"OWP", L"OWQ", L"OWR", L"OWS", L"OWT", L"OWU", L"OWV", L"OWW", L"OWX", L"OWY", L"OWZ", L"OXA", L"OXB", L"OXC", L"OXD", L"OXE", L"OXF", L"OXG", L"OXH", L"OXI", L"OXJ", L"OXK", L"OXL", L"OXM", L"OXN", L"OXO", L"OXP", L"OXQ", L"OXR", L"OXS", L"OXT", L"OXU", L"OXV", L"OXW", L"OXX", L"OXY", L"OXZ", L"OYA", L"OYB", L"OYC", L"OYD", L"OYE", L"OYF", L"OYG", L"OYH", L"OYI", L"OYJ", L"OYK", L"OYL", L"OYM", L"OYN", L"OYO", L"OYP", L"OYQ", L"OYR", L"OYS", L"OYT", L"OYU", L"OYV", L"OYW", L"OYX", L"OYY", L"OYZ", L"OZA", L"OZB", L"OZC", L"OZD", L"OZE", L"OZF", L"OZG", L"OZH", L"OZI", L"OZJ", L"OZK", L"OZL", L"OZM", L"OZN", L"OZO", L"OZP", L"OZQ", L"OZR", L"OZS", L"OZT", L"OZU", L"OZV", L"OZW", L"OZX", L"OZY", L"OZZ", L"PAA", L"PAB", L"PAC", L"PAD", L"PAE", L"PAF", L"PAG", L"PAH", L"PAI", L"PAJ", L"PAK", L"PAL", L"PAM", L"PAN", L"PAO", L"PAP", L"PAQ", L"PAR", L"PAS", L"PAT", L"PAU", L"PAV", L"PAW", L"PAX", L"PAY", L"PAZ", L"PBA", L"PBB", L"PBC", L"PBD", L"PBE", L"PBF", L"PBG", L"PBH", L"PBI", L"PBJ", L"PBK", L"PBL", L"PBM", L"PBN", L"PBO", L"PBP", L"PBQ", L"PBR", L"PBS", L"PBT", L"PBU", L"PBV", L"PBW", L"PBX", L"PBY", L"PBZ", L"PCA", L"PCB", L"PCC", L"PCD", L"PCE", L"PCF", L"PCG", L"PCH", L"PCI", L"PCJ", L"PCK", L"PCL", L"PCM", L"PCN", L"PCO", L"PCP", L"PCQ", L"PCR", L"PCS", L"PCT", L"PCU", L"PCV", L"PCW", L"PCX", L"PCY", L"PCZ", L"PDA", L"PDB", L"PDC", L"PDD", L"PDE", L"PDF", L"PDG", L"PDH", L"PDI", L"PDJ", L"PDK", L"PDL", L"PDM", L"PDN", L"PDO", L"PDP", L"PDQ", L"PDR", L"PDS", L"PDT", L"PDU", L"PDV", L"PDW", L"PDX", L"PDY", L"PDZ", L"PEA", L"PEB", L"PEC", L"PED", L"PEE", L"PEF", L"PEG", L"PEH", L"PEI", L"PEJ", L"PEK", L"PEL", L"PEM", L"PEN", L"PEO", L"PEP", L"PEQ", L"PER", L"PES", L"PET", L"PEU", L"PEV", L"PEW", L"PEX", L"PEY", L"PEZ", L"PFA", L"PFB", L"PFC", L"PFD", L"PFE", L"PFF", L"PFG", L"PFH", L"PFI", L"PFJ", L"PFK", L"PFL", L"PFM", L"PFN", L"PFO", L"PFP", L"PFQ", L"PFR", L"PFS", L"PFT", L"PFU", L"PFV", L"PFW", L"PFX", L"PFY", L"PFZ", L"PGA", L"PGB", L"PGC", L"PGD", L"PGE", L"PGF", L"PGG", L"PGH", L"PGI", L"PGJ", L"PGK", L"PGL", L"PGM", L"PGN", L"PGO", L"PGP", L"PGQ", L"PGR", L"PGS", L"PGT", L"PGU", L"PGV", L"PGW", L"PGX", L"PGY", L"PGZ", L"PHA", L"PHB", L"PHC", L"PHD", L"PHE", L"PHF", L"PHG", L"PHH", L"PHI", L"PHJ", L"PHK", L"PHL", L"PHM", L"PHN", L"PHO", L"PHP", L"PHQ", L"PHR", L"PHS", L"PHT", L"PHU", L"PHV", L"PHW", L"PHX", L"PHY", L"PHZ", L"PIA", L"PIB", L"PIC", L"PID", L"PIE", L"PIF", L"PIG", L"PIH", L"PII", L"PIJ", L"PIK", L"PIL", L"PIM", L"PIN", L"PIO", L"PIP", L"PIQ", L"PIR", L"PIS", L"PIT", L"PIU", L"PIV", L"PIW", L"PIX", L"PIY", L"PIZ", L"PJA", L"PJB", L"PJC", L"PJD", L"PJE", L"PJF", L"PJG", L"PJH", L"PJI", L"PJJ", L"PJK", L"PJL", L"PJM", L"PJN", L"PJO", L"PJP", L"PJQ", L"PJR", L"PJS", L"PJT", L"PJU", L"PJV", L"PJW", L"PJX", L"PJY", L"PJZ", L"PKA", L"PKB", L"PKC", L"PKD", L"PKE", L"PKF", L"PKG", L"PKH", L"PKI", L"PKJ", L"PKK", L"PKL", L"PKM", L"PKN", L"PKO", L"PKP", L"PKQ", L"PKR", L"PKS", L"PKT", L"PKU", L"PKV", L"PKW", L"PKX", L"PKY", L"PKZ", L"PLA", L"PLB", L"PLC", L"PLD", L"PLE", L"PLF", L"PLG", L"PLH", L"PLI", L"PLJ", L"PLK", L"PLL", L"PLM", L"PLN", L"PLO", L"PLP", L"PLQ", L"PLR", L"PLS", L"PLT", L"PLU", L"PLV", L"PLW", L"PLX", L"PLY", L"PLZ", L"PMA", L"PMB", L"PMC", L"PMD", L"PME", L"PMF", L"PMG", L"PMH", L"PMI", L"PMJ", L"PMK", L"PML", L"PMM", L"PMN", L"PMO", L"PMP", L"PMQ", L"PMR", L"PMS", L"PMT", L"PMU", L"PMV", L"PMW", L"PMX", L"PMY", L"PMZ", L"PNA", L"PNB", L"PNC", L"PND", L"PNE", L"PNF", L"PNG", L"PNH", L"PNI", L"PNJ", L"PNK", L"PNL", L"PNM", L"PNN", L"PNO", L"PNP", L"PNQ", L"PNR", L"PNS", L"PNT", L"PNU", L"PNV", L"PNW", L"PNX", L"PNY", L"PNZ", L"POA", L"POB", L"POC", L"POD", L"POE", L"POF", L"POG", L"POH", L"POI", L"POJ", L"POK", L"POL", L"POM", L"PON", L"POO", L"POP", L"POQ", L"POR", L"POS", L"POT", L"POU", L"POV", L"POW", L"POX", L"POY", L"POZ", L"PPA", L"PPB", L"PPC", L"PPD", L"PPE", L"PPF", L"PPG", L"PPH", - L"PPI", L"PPJ", L"PPK", L"PPL", L"PPM", L"PPN", L"PPO", L"PPP", L"PPQ", L"PPR", L"PPS", L"PPT", L"PPU", L"PPV", L"PPW", L"PPX", L"PPY", L"PPZ", L"PQA", L"PQB", L"PQC", L"PQD", L"PQE", L"PQF", L"PQG", L"PQH", L"PQI", L"PQJ", L"PQK", L"PQL", L"PQM", L"PQN", L"PQO", L"PQP", L"PQQ", L"PQR", L"PQS", L"PQT", L"PQU", L"PQV", L"PQW", L"PQX", L"PQY", L"PQZ", L"PRA", L"PRB", L"PRC", L"PRD", L"PRE", L"PRF", L"PRG", L"PRH", L"PRI", L"PRJ", L"PRK", L"PRL", L"PRM", L"PRN", L"PRO", L"PRP", L"PRQ", L"PRR", L"PRS", L"PRT", L"PRU", L"PRV", L"PRW", L"PRX", L"PRY", L"PRZ", L"PSA", L"PSB", L"PSC", L"PSD", L"PSE", L"PSF", L"PSG", L"PSH", L"PSI", L"PSJ", L"PSK", L"PSL", L"PSM", L"PSN", L"PSO", L"PSP", L"PSQ", L"PSR", L"PSS", L"PST", L"PSU", L"PSV", L"PSW", L"PSX", L"PSY", L"PSZ", L"PTA", L"PTB", L"PTC", L"PTD", L"PTE", L"PTF", L"PTG", L"PTH", L"PTI", L"PTJ", L"PTK", L"PTL", L"PTM", L"PTN", L"PTO", L"PTP", L"PTQ", L"PTR", L"PTS", L"PTT", L"PTU", L"PTV", L"PTW", L"PTX", L"PTY", L"PTZ", L"PUA", L"PUB", L"PUC", L"PUD", L"PUE", L"PUF", L"PUG", L"PUH", L"PUI", L"PUJ", L"PUK", L"PUL", L"PUM", L"PUN", L"PUO", L"PUP", L"PUQ", L"PUR", L"PUS", L"PUT", L"PUU", L"PUV", L"PUW", L"PUX", L"PUY", L"PUZ", L"PVA", L"PVB", L"PVC", L"PVD", L"PVE", L"PVF", L"PVG", L"PVH", L"PVI", L"PVJ", L"PVK", L"PVL", L"PVM", L"PVN", L"PVO", L"PVP", L"PVQ", L"PVR", L"PVS", L"PVT", L"PVU", L"PVV", L"PVW", L"PVX", L"PVY", L"PVZ", L"PWA", L"PWB", L"PWC", L"PWD", L"PWE", L"PWF", L"PWG", L"PWH", L"PWI", L"PWJ", L"PWK", L"PWL", L"PWM", L"PWN", L"PWO", L"PWP", L"PWQ", L"PWR", L"PWS", L"PWT", L"PWU", L"PWV", L"PWW", L"PWX", L"PWY", L"PWZ", L"PXA", L"PXB", L"PXC", L"PXD", L"PXE", L"PXF", L"PXG", L"PXH", L"PXI", L"PXJ", L"PXK", L"PXL", L"PXM", L"PXN", L"PXO", L"PXP", L"PXQ", L"PXR", L"PXS", L"PXT", L"PXU", L"PXV", L"PXW", L"PXX", L"PXY", L"PXZ", L"PYA", L"PYB", L"PYC", L"PYD", L"PYE", L"PYF", L"PYG", L"PYH", L"PYI", L"PYJ", L"PYK", L"PYL", L"PYM", L"PYN", L"PYO", L"PYP", L"PYQ", L"PYR", L"PYS", L"PYT", L"PYU", L"PYV", L"PYW", L"PYX", L"PYY", L"PYZ", L"PZA", L"PZB", L"PZC", L"PZD", L"PZE", L"PZF", L"PZG", L"PZH", L"PZI", L"PZJ", L"PZK", L"PZL", L"PZM", L"PZN", L"PZO", L"PZP", L"PZQ", L"PZR", L"PZS", L"PZT", L"PZU", + L"PPI", L"PPJ", L"PPK", L"PPL", L"PPM", L"PPN", L"PPO", L"PPP", L"PPQ", L"PPR", L"PPS", L"PPT", L"PPU", L"PPV", L"PPW", L"PPX", L"PPY", L"PPZ", L"PQA", L"PQB", L"PQC", L"PQD", L"PQE", L"PQF", L"PQG", L"PQH", L"PQI", L"PQJ", L"PQK", L"PQL", L"PQM", L"PQN", L"PQO", L"PQP", L"PQQ", L"PQR", L"PQS", L"PQT", L"PQU", L"PQV", L"PQW", L"PQX", L"PQY", L"PQZ", L"PRA", L"PRB", L"PRC", L"PRD", L"PRE", L"PRF", L"PRG", L"PRH", L"PRI", L"PRJ", L"PRK", L"PRL", L"PRM", L"PRN", L"PRO", L"PRP", L"PRQ", L"PRR", L"PRS", L"PRT", L"PRU", L"PRV", L"PRW", L"PRX", L"PRY", L"PRZ", L"PSA", L"PSB", L"PSC", L"PSD", L"PSE", L"PSF", L"PSG", L"PSH", L"PSI", L"PSJ", L"PSK", L"PSL", L"PSM", L"PSN", L"PSO", L"PSP", L"PSQ", L"PSR", L"PSS", L"PST", L"PSU", L"PSV", L"PSW", L"PSX", L"PSY", L"PSZ", L"PTA", L"PTB", L"PTC", L"PTD", L"PTE", L"PTF", L"PTG", L"PTH", L"PTI", L"PTJ", L"PTK", L"PTL", L"PTM", L"PTN", L"PTO", L"PTP", L"PTQ", L"PTR", L"PTS", L"PTT", L"PTU", L"PTV", L"PTW", L"PTX", L"PTY", L"PTZ", L"PUA", L"PUB", L"PUC", L"PUD", L"PUE", L"PUF", L"PUG", L"PUH", L"PUI", L"PUJ", L"PUK", L"PUL", L"PUM", L"PUN", L"PUO", L"PUP", L"PUQ", L"PUR", L"PUS", L"PUT", L"PUU", L"PUV", L"PUW", L"PUX", L"PUY", L"PUZ", L"PVA", L"PVB", L"PVC", L"PVD", L"PVE", L"PVF", L"PVG", L"PVH", L"PVI", L"PVJ", L"PVK", L"PVL", L"PVM", L"PVN", L"PVO", L"PVP", L"PVQ", L"PVR", L"PVS", L"PVT", L"PVU", L"PVV", L"PVW", L"PVX", L"PVY", L"PVZ", L"PWA", L"PWB", L"PWC", L"PWD", L"PWE", L"PWF", L"PWG", L"PWH", L"PWI", L"PWJ", L"PWK", L"PWL", L"PWM", L"PWN", L"PWO", L"PWP", L"PWQ", L"PWR", L"PWS", L"PWT", L"PWU", L"PWV", L"PWW", L"PWX", L"PWY", L"PWZ", L"PXA", L"PXB", L"PXC", L"PXD", L"PXE", L"PXF", L"PXG", L"PXH", L"PXI", L"PXJ", L"PXK", L"PXL", L"PXM", L"PXN", L"PXO", L"PXP", L"PXQ", L"PXR", L"PXS", L"PXT", L"PXU", L"PXV", L"PXW", L"PXX", L"PXY", L"PXZ", L"PYA", L"PYB", L"PYC", L"PYD", L"PYE", L"PYF", L"PYG", L"PYH", L"PYI", L"PYJ", L"PYK", L"PYL", L"PYM", L"PYN", L"PYO", L"PYP", L"PYQ", L"PYR", L"PYS", L"PYT", L"PYU", L"PYV", L"PYW", L"PYX", L"PYY", L"PYZ", L"PZA", L"PZB", L"PZC", L"PZD", L"PZE", L"PZF", L"PZG", L"PZH", L"PZI", L"PZJ", L"PZK", L"PZL", L"PZM", L"PZN", L"PZO", L"PZP", L"PZQ", L"PZR", L"PZS", L"PZT", L"PZU", L"PZV", L"PZW", L"PZX", L"PZY", L"PZZ", L"QAA", L"QAB", L"QAC", L"QAD", L"QAE", L"QAF", L"QAG", L"QAH", L"QAI", L"QAJ", L"QAK", L"QAL", L"QAM", L"QAN", L"QAO", L"QAP", L"QAQ", L"QAR", L"QAS", L"QAT", L"QAU", L"QAV", L"QAW", L"QAX", L"QAY", L"QAZ", L"QBA", L"QBB", L"QBC", L"QBD", L"QBE", L"QBF", L"QBG", L"QBH", L"QBI", L"QBJ", L"QBK", L"QBL", L"QBM", L"QBN", L"QBO", L"QBP", L"QBQ", L"QBR", L"QBS", L"QBT", L"QBU", L"QBV", L"QBW", L"QBX", L"QBY", L"QBZ", L"QCA", L"QCB", L"QCC", L"QCD", L"QCE", L"QCF", L"QCG", L"QCH", L"QCI", L"QCJ", L"QCK", L"QCL", L"QCM", L"QCN", L"QCO", L"QCP", L"QCQ", L"QCR", L"QCS", L"QCT", L"QCU", L"QCV", L"QCW", L"QCX", L"QCY", L"QCZ", L"QDA", L"QDB", L"QDC", L"QDD", L"QDE", L"QDF", L"QDG", L"QDH", L"QDI", L"QDJ", L"QDK", L"QDL", L"QDM", L"QDN", L"QDO", L"QDP", L"QDQ", L"QDR", L"QDS", L"QDT", L"QDU", L"QDV", L"QDW", L"QDX", L"QDY", L"QDZ", L"QEA", L"QEB", L"QEC", L"QED", L"QEE", L"QEF", L"QEG", L"QEH", L"QEI", L"QEJ", L"QEK", L"QEL", L"QEM", L"QEN", L"QEO", L"QEP", L"QEQ", L"QER", L"QES", L"QET", L"QEU", L"QEV", L"QEW", L"QEX", L"QEY", L"QEZ", L"QFA", L"QFB", L"QFC", L"QFD", L"QFE", L"QFF", L"QFG", L"QFH", L"QFI", L"QFJ", L"QFK", L"QFL", L"QFM", L"QFN", L"QFO", L"QFP", L"QFQ", L"QFR", L"QFS", L"QFT", L"QFU", L"QFV", L"QFW", L"QFX", L"QFY", L"QFZ", L"QGA", L"QGB", L"QGC", L"QGD", L"QGE", L"QGF", L"QGG", L"QGH", L"QGI", L"QGJ", L"QGK", L"QGL", L"QGM", L"QGN", L"QGO", L"QGP", L"QGQ", L"QGR", L"QGS", L"QGT", L"QGU", L"QGV", L"QGW", L"QGX", L"QGY", L"QGZ", L"QHA", L"QHB", L"QHC", L"QHD", L"QHE", L"QHF", L"QHG", L"QHH", L"QHI", L"QHJ", L"QHK", L"QHL", L"QHM", L"QHN", L"QHO", L"QHP", L"QHQ", L"QHR", L"QHS", L"QHT", L"QHU", L"QHV", L"QHW", L"QHX", L"QHY", L"QHZ", L"QIA", L"QIB", L"QIC", L"QID", L"QIE", L"QIF", L"QIG", L"QIH", L"QII", L"QIJ", L"QIK", L"QIL", L"QIM", L"QIN", L"QIO", L"QIP", L"QIQ", L"QIR", L"QIS", L"QIT", L"QIU", L"QIV", L"QIW", L"QIX", L"QIY", L"QIZ", L"QJA", L"QJB", L"QJC", L"QJD", L"QJE", L"QJF", L"QJG", L"QJH", L"QJI", L"QJJ", L"QJK", L"QJL", L"QJM", L"QJN", L"QJO", L"QJP", L"QJQ", L"QJR", L"QJS", L"QJT", L"QJU", L"QJV", L"QJW", L"QJX", L"QJY", L"QJZ", L"QKA", L"QKB", L"QKC", L"QKD", L"QKE", L"QKF", L"QKG", L"QKH", - L"QKI", L"QKJ", L"QKK", L"QKL", L"QKM", L"QKN", L"QKO", L"QKP", L"QKQ", L"QKR", L"QKS", L"QKT", L"QKU", L"QKV", L"QKW", L"QKX", L"QKY", L"QKZ", L"QLA", L"QLB", L"QLC", L"QLD", L"QLE", L"QLF", L"QLG", L"QLH", L"QLI", L"QLJ", L"QLK", L"QLL", L"QLM", L"QLN", L"QLO", L"QLP", L"QLQ", L"QLR", L"QLS", L"QLT", L"QLU", L"QLV", L"QLW", L"QLX", L"QLY", L"QLZ", L"QMA", L"QMB", L"QMC", L"QMD", L"QME", L"QMF", L"QMG", L"QMH", L"QMI", L"QMJ", L"QMK", L"QML", L"QMM", L"QMN", L"QMO", L"QMP", L"QMQ", L"QMR", L"QMS", L"QMT", L"QMU", L"QMV", L"QMW", L"QMX", L"QMY", L"QMZ", L"QNA", L"QNB", L"QNC", L"QND", L"QNE", L"QNF", L"QNG", L"QNH", L"QNI", L"QNJ", L"QNK", L"QNL", L"QNM", L"QNN", L"QNO", L"QNP", L"QNQ", L"QNR", L"QNS", L"QNT", L"QNU", L"QNV", L"QNW", L"QNX", L"QNY", L"QNZ", L"QOA", L"QOB", L"QOC", L"QOD", L"QOE", L"QOF", L"QOG", L"QOH", L"QOI", L"QOJ", L"QOK", L"QOL", L"QOM", L"QON", L"QOO", L"QOP", L"QOQ", L"QOR", L"QOS", L"QOT", L"QOU", L"QOV", L"QOW", L"QOX", L"QOY", L"QOZ", L"QPA", L"QPB", L"QPC", L"QPD", L"QPE", L"QPF", L"QPG", L"QPH", L"QPI", L"QPJ", L"QPK", L"QPL", L"QPM", L"QPN", L"QPO", L"QPP", L"QPQ", L"QPR", L"QPS", L"QPT", L"QPU", L"QPV", L"QPW", L"QPX", L"QPY", L"QPZ", L"QQA", L"QQB", L"QQC", L"QQD", L"QQE", L"QQF", L"QQG", L"QQH", L"QQI", L"QQJ", L"QQK", L"QQL", L"QQM", L"QQN", L"QQO", L"QQP", L"QQQ", L"QQR", L"QQS", L"QQT", L"QQU", L"QQV", L"QQW", L"QQX", L"QQY", L"QQZ", L"QRA", L"QRB", L"QRC", L"QRD", L"QRE", L"QRF", L"QRG", L"QRH", L"QRI", L"QRJ", L"QRK", L"QRL", L"QRM", L"QRN", L"QRO", L"QRP", L"QRQ", L"QRR", L"QRS", L"QRT", L"QRU", L"QRV", L"QRW", L"QRX", L"QRY", L"QRZ", L"QSA", L"QSB", L"QSC", L"QSD", L"QSE", L"QSF", L"QSG", L"QSH", L"QSI", L"QSJ", L"QSK", L"QSL", L"QSM", L"QSN", L"QSO", L"QSP", L"QSQ", L"QSR", L"QSS", L"QST", L"QSU", L"QSV", L"QSW", L"QSX", L"QSY", L"QSZ", L"QTA", L"QTB", L"QTC", L"QTD", L"QTE", L"QTF", L"QTG", L"QTH", L"QTI", L"QTJ", L"QTK", L"QTL", L"QTM", L"QTN", L"QTO", L"QTP", L"QTQ", L"QTR", L"QTS", L"QTT", L"QTU", L"QTV", L"QTW", L"QTX", L"QTY", L"QTZ", L"QUA", L"QUB", L"QUC", L"QUD", L"QUE", L"QUF", L"QUG", L"QUH", L"QUI", L"QUJ", L"QUK", L"QUL", L"QUM", L"QUN", L"QUO", L"QUP", L"QUQ", L"QUR", L"QUS", L"QUT", L"QUU", - L"QUV", L"QUW", L"QUX", L"QUY", L"QUZ", L"QVA", L"QVB", L"QVC", L"QVD", L"QVE", L"QVF", L"QVG", L"QVH", L"QVI", L"QVJ", L"QVK", L"QVL", L"QVM", L"QVN", L"QVO", L"QVP", L"QVQ", L"QVR", L"QVS", L"QVT", L"QVU", L"QVV", L"QVW", L"QVX", L"QVY", L"QVZ", L"QWA", L"QWB", L"QWC", L"QWD", L"QWE", L"QWF", L"QWG", L"QWH", L"QWI", L"QWJ", L"QWK", L"QWL", L"QWM", L"QWN", L"QWO", L"QWP", L"QWQ", L"QWR", L"QWS", L"QWT", L"QWU", L"QWV", L"QWW", L"QWX", L"QWY", L"QWZ", L"QXA", L"QXB", L"QXC", L"QXD", L"QXE", L"QXF", L"QXG", L"QXH", L"QXI", L"QXJ", L"QXK", L"QXL", L"QXM", L"QXN", L"QXO", L"QXP", L"QXQ", L"QXR", L"QXS", L"QXT", L"QXU", L"QXV", L"QXW", L"QXX", L"QXY", L"QXZ", L"QYA", L"QYB", L"QYC", L"QYD", L"QYE", L"QYF", L"QYG", L"QYH", L"QYI", L"QYJ", L"QYK", L"QYL", L"QYM", L"QYN", L"QYO", L"QYP", L"QYQ", L"QYR", L"QYS", L"QYT", L"QYU", L"QYV", L"QYW", L"QYX", L"QYY", L"QYZ", L"QZA", L"QZB", L"QZC", L"QZD", L"QZE", L"QZF", L"QZG", L"QZH", L"QZI", L"QZJ", L"QZK", L"QZL", L"QZM", L"QZN", L"QZO", L"QZP", L"QZQ", L"QZR", L"QZS", L"QZT", L"QZU", L"QZV", L"QZW", L"QZX", L"QZY", L"QZZ", L"RAA", L"RAB", L"RAC", L"RAD", L"RAE", L"RAF", L"RAG", L"RAH", L"RAI", L"RAJ", L"RAK", L"RAL", L"RAM", L"RAN", L"RAO", L"RAP", L"RAQ", L"RAR", L"RAS", L"RAT", L"RAU", L"RAV", L"RAW", L"RAX", L"RAY", L"RAZ", L"RBA", L"RBB", L"RBC", L"RBD", L"RBE", L"RBF", L"RBG", L"RBH", L"RBI", L"RBJ", L"RBK", L"RBL", L"RBM", L"RBN", L"RBO", L"RBP", L"RBQ", L"RBR", L"RBS", L"RBT", L"RBU", L"RBV", L"RBW", L"RBX", L"RBY", L"RBZ", L"RCA", L"RCB", L"RCC", L"RCD", L"RCE", L"RCF", L"RCG", L"RCH", L"RCI", L"RCJ", L"RCK", L"RCL", L"RCM", L"RCN", L"RCO", L"RCP", L"RCQ", L"RCR", L"RCS", L"RCT", L"RCU", L"RCV", L"RCW", L"RCX", L"RCY", L"RCZ", L"RDA", L"RDB", L"RDC", L"RDD", L"RDE", L"RDF", L"RDG", L"RDH", L"RDI", L"RDJ", L"RDK", L"RDL", L"RDM", L"RDN", L"RDO", L"RDP", L"RDQ", L"RDR", L"RDS", L"RDT", L"RDU", L"RDV", L"RDW", L"RDX", L"RDY", L"RDZ", L"REA", L"REB", L"REC", L"RED", L"REE", L"REF", L"REG", L"REH", L"REI", L"REJ", L"REK", L"REL", L"REM", L"REN", L"REO", L"REP", L"REQ", L"RER", L"RES", L"RET", L"REU", L"REV", L"REW", L"REX", L"REY", L"REZ", L"RFA", L"RFB", L"RFC", L"RFD", L"RFE", L"RFF", L"RFG", L"RFH", - L"RFI", L"RFJ", L"RFK", L"RFL", L"RFM", L"RFN", L"RFO", L"RFP", L"RFQ", L"RFR", L"RFS", L"RFT", L"RFU", L"RFV", L"RFW", L"RFX", L"RFY", L"RFZ", L"RGA", L"RGB", L"RGC", L"RGD", L"RGE", L"RGF", L"RGG", L"RGH", L"RGI", L"RGJ", L"RGK", L"RGL", L"RGM", L"RGN", L"RGO", L"RGP", L"RGQ", L"RGR", L"RGS", L"RGT", L"RGU", L"RGV", L"RGW", L"RGX", L"RGY", L"RGZ", L"RHA", L"RHB", L"RHC", L"RHD", L"RHE", L"RHF", L"RHG", L"RHH", L"RHI", L"RHJ", L"RHK", L"RHL", L"RHM", L"RHN", L"RHO", L"RHP", L"RHQ", L"RHR", L"RHS", L"RHT", L"RHU", L"RHV", L"RHW", L"RHX", L"RHY", L"RHZ", L"RIA", L"RIB", L"RIC", L"RID", L"RIE", L"RIF", L"RIG", L"RIH", L"RII", L"RIJ", L"RIK", L"RIL", L"RIM", L"RIN", L"RIO", L"RIP", L"RIQ", L"RIR", L"RIS", L"RIT", L"RIU", L"RIV", L"RIW", L"RIX", L"RIY", L"RIZ", L"RJA", L"RJB", L"RJC", L"RJD", L"RJE", L"RJF", L"RJG", L"RJH", L"RJI", L"RJJ", L"RJK", L"RJL", L"RJM", L"RJN", L"RJO", L"RJP", L"RJQ", L"RJR", L"RJS", L"RJT", L"RJU", L"RJV", L"RJW", L"RJX", L"RJY", L"RJZ", L"RKA", L"RKB", L"RKC", L"RKD", L"RKE", L"RKF", L"RKG", L"RKH", L"RKI", L"RKJ", L"RKK", L"RKL", L"RKM", L"RKN", L"RKO", L"RKP", L"RKQ", L"RKR", L"RKS", L"RKT", L"RKU", L"RKV", L"RKW", L"RKX", L"RKY", L"RKZ", L"RLA", L"RLB", L"RLC", L"RLD", L"RLE", L"RLF", L"RLG", L"RLH", L"RLI", L"RLJ", L"RLK", L"RLL", L"RLM", L"RLN", L"RLO", L"RLP", L"RLQ", L"RLR", L"RLS", L"RLT", L"RLU", L"RLV", L"RLW", L"RLX", L"RLY", L"RLZ", L"RMA", L"RMB", L"RMC", L"RMD", L"RME", L"RMF", L"RMG", L"RMH", L"RMI", L"RMJ", L"RMK", L"RML", L"RMM", L"RMN", L"RMO", L"RMP", L"RMQ", L"RMR", L"RMS", L"RMT", L"RMU", L"RMV", L"RMW", L"RMX", L"RMY", L"RMZ", L"RNA", L"RNB", L"RNC", L"RND", L"RNE", L"RNF", L"RNG", L"RNH", L"RNI", L"RNJ", L"RNK", L"RNL", L"RNM", L"RNN", L"RNO", L"RNP", L"RNQ", L"RNR", L"RNS", L"RNT", L"RNU", L"RNV", L"RNW", L"RNX", L"RNY", L"RNZ", L"ROA", L"ROB", L"ROC", L"ROD", L"ROE", L"ROF", L"ROG", L"ROH", L"ROI", L"ROJ", L"ROK", L"ROL", L"ROM", L"RON", L"ROO", L"ROP", L"ROQ", L"ROR", L"ROS", L"ROT", L"ROU", L"ROV", L"ROW", L"ROX", L"ROY", L"ROZ", L"RPA", L"RPB", L"RPC", L"RPD", L"RPE", L"RPF", L"RPG", L"RPH", L"RPI", L"RPJ", L"RPK", L"RPL", L"RPM", L"RPN", L"RPO", L"RPP", L"RPQ", L"RPR", L"RPS", L"RPT", L"RPU", - L"RPV", L"RPW", L"RPX", L"RPY", L"RPZ", L"RQA", L"RQB", L"RQC", L"RQD", L"RQE", L"RQF", L"RQG", L"RQH", L"RQI", L"RQJ", L"RQK", L"RQL", L"RQM", L"RQN", L"RQO", L"RQP", L"RQQ", L"RQR", L"RQS", L"RQT", L"RQU", L"RQV", L"RQW", L"RQX", L"RQY", L"RQZ", L"RRA", L"RRB", L"RRC", L"RRD", L"RRE", L"RRF", L"RRG", L"RRH", L"RRI", L"RRJ", L"RRK", L"RRL", L"RRM", L"RRN", L"RRO", L"RRP", L"RRQ", L"RRR", L"RRS", L"RRT", L"RRU", L"RRV", L"RRW", L"RRX", L"RRY", L"RRZ", L"RSA", L"RSB", L"RSC", L"RSD", L"RSE", L"RSF", L"RSG", L"RSH", L"RSI", L"RSJ", L"RSK", L"RSL", L"RSM", L"RSN", L"RSO", L"RSP", L"RSQ", L"RSR", L"RSS", L"RST", L"RSU", L"RSV", L"RSW", L"RSX", L"RSY", L"RSZ", L"RTA", L"RTB", L"RTC", L"RTD", L"RTE", L"RTF", L"RTG", L"RTH", L"RTI", L"RTJ", L"RTK", L"RTL", L"RTM", L"RTN", L"RTO", L"RTP", L"RTQ", L"RTR", L"RTS", L"RTT", L"RTU", L"RTV", L"RTW", L"RTX", L"RTY", L"RTZ", L"RUA", L"RUB", L"RUC", L"RUD", L"RUE", L"RUF", L"RUG", L"RUH", L"RUI", L"RUJ", L"RUK", L"RUL", L"RUM", L"RUN", L"RUO", L"RUP", L"RUQ", L"RUR", L"RUS", L"RUT", L"RUU", L"RUV", L"RUW", L"RUX", L"RUY", L"RUZ", L"RVA", L"RVB", L"RVC", L"RVD", L"RVE", L"RVF", L"RVG", L"RVH", L"RVI", L"RVJ", L"RVK", L"RVL", L"RVM", L"RVN", L"RVO", L"RVP", L"RVQ", L"RVR", L"RVS", L"RVT", L"RVU", L"RVV", L"RVW", L"RVX", L"RVY", L"RVZ", L"RWA", L"RWB", L"RWC", L"RWD", L"RWE", L"RWF", L"RWG", L"RWH", L"RWI", L"RWJ", L"RWK", L"RWL", L"RWM", L"RWN", L"RWO", L"RWP", L"RWQ", L"RWR", L"RWS", L"RWT", L"RWU", L"RWV", L"RWW", L"RWX", L"RWY", L"RWZ", L"RXA", L"RXB", L"RXC", L"RXD", L"RXE", L"RXF", L"RXG", L"RXH", L"RXI", L"RXJ", L"RXK", L"RXL", L"RXM", L"RXN", L"RXO", L"RXP", L"RXQ", L"RXR", L"RXS", L"RXT", L"RXU", L"RXV", L"RXW", L"RXX", L"RXY", L"RXZ", L"RYA", L"RYB", L"RYC", L"RYD", L"RYE", L"RYF", L"RYG", L"RYH", L"RYI", L"RYJ", L"RYK", L"RYL", L"RYM", L"RYN", L"RYO", L"RYP", L"RYQ", L"RYR", L"RYS", L"RYT", L"RYU", L"RYV", L"RYW", L"RYX", L"RYY", L"RYZ", L"RZA", L"RZB", L"RZC", L"RZD", L"RZE", L"RZF", L"RZG", L"RZH", L"RZI", L"RZJ", L"RZK", L"RZL", L"RZM", L"RZN", L"RZO", L"RZP", L"RZQ", L"RZR", L"RZS", L"RZT", L"RZU", L"RZV", L"RZW", L"RZX", L"RZY", L"RZZ", L"SAA", L"SAB", L"SAC", L"SAD", L"SAE", L"SAF", L"SAG", L"SAH", - L"SAI", L"SAJ", L"SAK", L"SAL", L"SAM", L"SAN", L"SAO", L"SAP", L"SAQ", L"SAR", L"SAS", L"SAT", L"SAU", L"SAV", L"SAW", L"SAX", L"SAY", L"SAZ", L"SBA", L"SBB", L"SBC", L"SBD", L"SBE", L"SBF", L"SBG", L"SBH", L"SBI", L"SBJ", L"SBK", L"SBL", L"SBM", L"SBN", L"SBO", L"SBP", L"SBQ", L"SBR", L"SBS", L"SBT", L"SBU", L"SBV", L"SBW", L"SBX", L"SBY", L"SBZ", L"SCA", L"SCB", L"SCC", L"SCD", L"SCE", L"SCF", L"SCG", L"SCH", L"SCI", L"SCJ", L"SCK", L"SCL", L"SCM", L"SCN", L"SCO", L"SCP", L"SCQ", L"SCR", L"SCS", L"SCT", L"SCU", L"SCV", L"SCW", L"SCX", L"SCY", L"SCZ", L"SDA", L"SDB", L"SDC", L"SDD", L"SDE", L"SDF", L"SDG", L"SDH", L"SDI", L"SDJ", L"SDK", L"SDL", L"SDM", L"SDN", L"SDO", L"SDP", L"SDQ", L"SDR", L"SDS", L"SDT", L"SDU", L"SDV", L"SDW", L"SDX", L"SDY", L"SDZ", L"SEA", L"SEB", L"SEC", L"SED", L"SEE", L"SEF", L"SEG", L"SEH", L"SEI", L"SEJ", L"SEK", L"SEL", L"SEM", L"SEN", L"SEO", L"SEP", L"SEQ", L"SER", L"SES", L"SET", L"SEU", L"SEV", L"SEW", L"SEX", L"SEY", L"SEZ", L"SFA", L"SFB", L"SFC", L"SFD", L"SFE", L"SFF", L"SFG", L"SFH", L"SFI", L"SFJ", L"SFK", L"SFL", L"SFM", L"SFN", L"SFO", L"SFP", L"SFQ", L"SFR", L"SFS", L"SFT", L"SFU", L"SFV", L"SFW", L"SFX", L"SFY", L"SFZ", L"SGA", L"SGB", L"SGC", L"SGD", L"SGE", L"SGF", L"SGG", L"SGH", L"SGI", L"SGJ", L"SGK", L"SGL", L"SGM", L"SGN", L"SGO", L"SGP", L"SGQ", L"SGR", L"SGS", L"SGT", L"SGU", L"SGV", L"SGW", L"SGX", L"SGY", L"SGZ", L"SHA", L"SHB", L"SHC", L"SHD", L"SHE", L"SHF", L"SHG", L"SHH", L"SHI", L"SHJ", L"SHK", L"SHL", L"SHM", L"SHN", L"SHO", L"SHP", L"SHQ", L"SHR", L"SHS", L"SHT", L"SHU", L"SHV", L"SHW", L"SHX", L"SHY", L"SHZ", L"SIA", L"SIB", L"SIC", L"SID", L"SIE", L"SIF", L"SIG", L"SIH", L"SII", L"SIJ", L"SIK", L"SIL", L"SIM", L"SIN", L"SIO", L"SIP", L"SIQ", L"SIR", L"SIS", L"SIT", L"SIU", L"SIV", L"SIW", L"SIX", L"SIY", L"SIZ", L"SJA", L"SJB", L"SJC", L"SJD", L"SJE", L"SJF", L"SJG", L"SJH", L"SJI", L"SJJ", L"SJK", L"SJL", L"SJM", L"SJN", L"SJO", L"SJP", L"SJQ", L"SJR", L"SJS", L"SJT", L"SJU", L"SJV", L"SJW", L"SJX", L"SJY", L"SJZ", L"SKA", L"SKB", L"SKC", L"SKD", L"SKE", L"SKF", L"SKG", L"SKH", L"SKI", L"SKJ", L"SKK", L"SKL", L"SKM", L"SKN", L"SKO", L"SKP", L"SKQ", L"SKR", L"SKS", L"SKT", L"SKU", - L"SKV", L"SKW", L"SKX", L"SKY", L"SKZ", L"SLA", L"SLB", L"SLC", L"SLD", L"SLE", L"SLF", L"SLG", L"SLH", L"SLI", L"SLJ", L"SLK", L"SLL", L"SLM", L"SLN", L"SLO", L"SLP", L"SLQ", L"SLR", L"SLS", L"SLT", L"SLU", L"SLV", L"SLW", L"SLX", L"SLY", L"SLZ", L"SMA", L"SMB", L"SMC", L"SMD", L"SME", L"SMF", L"SMG", L"SMH", L"SMI", L"SMJ", L"SMK", L"SML", L"SMM", L"SMN", L"SMO", L"SMP", L"SMQ", L"SMR", L"SMS", L"SMT", L"SMU", L"SMV", L"SMW", L"SMX", L"SMY", L"SMZ", L"SNA", L"SNB", L"SNC", L"SND", L"SNE", L"SNF", L"SNG", L"SNH", L"SNI", L"SNJ", L"SNK", L"SNL", L"SNM", L"SNN", L"SNO", L"SNP", L"SNQ", L"SNR", L"SNS", L"SNT", L"SNU", L"SNV", L"SNW", L"SNX", L"SNY", L"SNZ", L"SOA", L"SOB", L"SOC", L"SOD", L"SOE", L"SOF", L"SOG", L"SOH", L"SOI", L"SOJ", L"SOK", L"SOL", L"SOM", L"SON", L"SOO", L"SOP", L"SOQ", L"SOR", L"SOS", L"SOT", L"SOU", L"SOV", L"SOW", L"SOX", L"SOY", L"SOZ", L"SPA", L"SPB", L"SPC", L"SPD", L"SPE", L"SPF", L"SPG", L"SPH", L"SPI", L"SPJ", L"SPK", L"SPL", L"SPM", L"SPN", L"SPO", L"SPP", L"SPQ", L"SPR", L"SPS", L"SPT", L"SPU", L"SPV", L"SPW", L"SPX", L"SPY", L"SPZ", L"SQA", L"SQB", L"SQC", L"SQD", L"SQE", L"SQF", L"SQG", L"SQH", L"SQI", L"SQJ", L"SQK", L"SQL", L"SQM", L"SQN", L"SQO", L"SQP", L"SQQ", L"SQR", L"SQS", L"SQT", L"SQU", L"SQV", L"SQW", L"SQX", L"SQY", L"SQZ", L"SRA", L"SRB", L"SRC", L"SRD", L"SRE", L"SRF", L"SRG", L"SRH", L"SRI", L"SRJ", L"SRK", L"SRL", L"SRM", L"SRN", L"SRO", L"SRP", L"SRQ", L"SRR", L"SRS", L"SRT", L"SRU", L"SRV", L"SRW", L"SRX", L"SRY", L"SRZ", L"SSA", L"SSB", L"SSC", L"SSD", L"SSE", L"SSF", L"SSG", L"SSH", L"SSI", L"SSJ", L"SSK", L"SSL", L"SSM", L"SSN", L"SSO", L"SSP", L"SSQ", L"SSR", L"SSS", L"SST", L"SSU", L"SSV", L"SSW", L"SSX", L"SSY", L"SSZ", L"STA", L"STB", L"STC", L"STD", L"STE", L"STF", L"STG", L"STH", L"STI", L"STJ", L"STK", L"STL", L"STM", L"STN", L"STO", L"STP", L"STQ", L"STR", L"STS", L"STT", L"STU", L"STV", L"STW", L"STX", L"STY", L"STZ", L"SUA", L"SUB", L"SUC", L"SUD", L"SUE", L"SUF", L"SUG", L"SUH", L"SUI", L"SUJ", L"SUK", L"SUL", L"SUM", L"SUN", L"SUO", L"SUP", L"SUQ", L"SUR", L"SUS", L"SUT", L"SUU", L"SUV", L"SUW", L"SUX", L"SUY", - L"SUZ", L"SVA", L"SVB", L"SVC", L"SVD", L"SVE", L"SVF", L"SVG", L"SVH", L"SVI", L"SVJ", L"SVK", L"SVL", L"SVM", L"SVN", L"SVO", L"SVP", L"SVQ", L"SVR", L"SVS", L"SVT", L"SVU", L"SVV", L"SVW", L"SVX", L"SVY", L"SVZ", L"SWA", L"SWB", L"SWC", L"SWD", L"SWE", L"SWF", L"SWG", L"SWH", L"SWI", L"SWJ", L"SWK", L"SWL", L"SWM", L"SWN", L"SWO", L"SWP", L"SWQ", L"SWR", L"SWS", L"SWT", L"SWU", L"SWV", L"SWW", L"SWX", L"SWY", L"SWZ", L"SXA", L"SXB", L"SXC", L"SXD", L"SXE", L"SXF", L"SXG", L"SXH", L"SXI", L"SXJ", L"SXK", L"SXL", L"SXM", L"SXN", L"SXO", L"SXP", L"SXQ", L"SXR", L"SXS", L"SXT", L"SXU", L"SXV", L"SXW", L"SXX", L"SXY", L"SXZ", L"SYA", L"SYB", L"SYC", L"SYD", L"SYE", L"SYF", L"SYG", L"SYH", L"SYI", L"SYJ", L"SYK", L"SYL", L"SYM", L"SYN", L"SYO", L"SYP", L"SYQ", L"SYR", L"SYS", L"SYT", L"SYU", L"SYV", L"SYW", L"SYX", L"SYY", L"SYZ", L"SZA", L"SZB", L"SZC", L"SZD", L"SZE", L"SZF", L"SZG", L"SZH", L"SZI", L"SZJ", L"SZK", L"SZL", L"SZM", L"SZN", L"SZO", L"SZP", L"SZQ", L"SZR", L"SZS", L"SZT", L"SZU", L"SZV", L"SZW", L"SZX", L"SZY", L"SZZ", L"TAA", L"TAB", L"TAC", L"TAD", L"TAE", L"TAF", L"TAG", L"TAH", L"TAI", L"TAJ", L"TAK", L"TAL", L"TAM", L"TAN", L"TAO", L"TAP", L"TAQ", L"TAR", L"TAS", L"TAT", L"TAU", L"TAV", L"TAW", L"TAX", L"TAY", L"TAZ", L"TBA", L"TBB", L"TBC", L"TBD", L"TBE", L"TBF", L"TBG", L"TBH", L"TBI", L"TBJ", L"TBK", L"TBL", L"TBM", L"TBN", L"TBO", L"TBP", L"TBQ", L"TBR", L"TBS", L"TBT", L"TBU", L"TBV", L"TBW", L"TBX", L"TBY", L"TBZ", L"TCA", L"TCB", L"TCC", L"TCD", L"TCE", L"TCF", L"TCG", L"TCH", L"TCI", L"TCJ", L"TCK", L"TCL", L"TCM", L"TCN", L"TCO", L"TCP", L"TCQ", L"TCR", L"TCS", L"TCT", L"TCU", L"TCV", L"TCW", L"TCX", L"TCY", L"TCZ", L"TDA", L"TDB", L"TDC", L"TDD", L"TDE", L"TDF", L"TDG", L"TDH", L"TDI", L"TDJ", L"TDK", L"TDL", L"TDM", L"TDN", L"TDO", L"TDP", L"TDQ", L"TDR", L"TDS", L"TDT", L"TDU", L"TDV", L"TDW", L"TDX", L"TDY", L"TDZ", L"TEA", L"TEB", L"TEC", L"TED", L"TEE", L"TEF", L"TEG", L"TEH", L"TEI", L"TEJ", L"TEK", L"TEL", L"TEM", L"TEN", L"TEO", L"TEP", L"TEQ", L"TER", L"TES", L"TET", L"TEU", L"TEV", L"TEW", L"TEX", L"TEY", L"TEZ", L"TFA", L"TFB", L"TFC", L"TFD", L"TFE", L"TFF", L"TFG", L"TFH", L"TFI", L"TFJ", L"TFK", L"TFL", + L"QKI", L"QKJ", L"QKK", L"QKL", L"QKM", L"QKN", L"QKO", L"QKP", L"QKQ", L"QKR", L"QKS", L"QKT", L"QKU", L"QKV", L"QKW", L"QKX", L"QKY", L"QKZ", L"QLA", L"QLB", L"QLC", L"QLD", L"QLE", L"QLF", L"QLG", L"QLH", L"QLI", L"QLJ", L"QLK", L"QLL", L"QLM", L"QLN", L"QLO", L"QLP", L"QLQ", L"QLR", L"QLS", L"QLT", L"QLU", L"QLV", L"QLW", L"QLX", L"QLY", L"QLZ", L"QMA", L"QMB", L"QMC", L"QMD", L"QME", L"QMF", L"QMG", L"QMH", L"QMI", L"QMJ", L"QMK", L"QML", L"QMM", L"QMN", L"QMO", L"QMP", L"QMQ", L"QMR", L"QMS", L"QMT", L"QMU", L"QMV", L"QMW", L"QMX", L"QMY", L"QMZ", L"QNA", L"QNB", L"QNC", L"QND", L"QNE", L"QNF", L"QNG", L"QNH", L"QNI", L"QNJ", L"QNK", L"QNL", L"QNM", L"QNN", L"QNO", L"QNP", L"QNQ", L"QNR", L"QNS", L"QNT", L"QNU", L"QNV", L"QNW", L"QNX", L"QNY", L"QNZ", L"QOA", L"QOB", L"QOC", L"QOD", L"QOE", L"QOF", L"QOG", L"QOH", L"QOI", L"QOJ", L"QOK", L"QOL", L"QOM", L"QON", L"QOO", L"QOP", L"QOQ", L"QOR", L"QOS", L"QOT", L"QOU", L"QOV", L"QOW", L"QOX", L"QOY", L"QOZ", L"QPA", L"QPB", L"QPC", L"QPD", L"QPE", L"QPF", L"QPG", L"QPH", L"QPI", L"QPJ", L"QPK", L"QPL", L"QPM", L"QPN", L"QPO", L"QPP", L"QPQ", L"QPR", L"QPS", L"QPT", L"QPU", L"QPV", L"QPW", L"QPX", L"QPY", L"QPZ", L"QQA", L"QQB", L"QQC", L"QQD", L"QQE", L"QQF", L"QQG", L"QQH", L"QQI", L"QQJ", L"QQK", L"QQL", L"QQM", L"QQN", L"QQO", L"QQP", L"QQQ", L"QQR", L"QQS", L"QQT", L"QQU", L"QQV", L"QQW", L"QQX", L"QQY", L"QQZ", L"QRA", L"QRB", L"QRC", L"QRD", L"QRE", L"QRF", L"QRG", L"QRH", L"QRI", L"QRJ", L"QRK", L"QRL", L"QRM", L"QRN", L"QRO", L"QRP", L"QRQ", L"QRR", L"QRS", L"QRT", L"QRU", L"QRV", L"QRW", L"QRX", L"QRY", L"QRZ", L"QSA", L"QSB", L"QSC", L"QSD", L"QSE", L"QSF", L"QSG", L"QSH", L"QSI", L"QSJ", L"QSK", L"QSL", L"QSM", L"QSN", L"QSO", L"QSP", L"QSQ", L"QSR", L"QSS", L"QST", L"QSU", L"QSV", L"QSW", L"QSX", L"QSY", L"QSZ", L"QTA", L"QTB", L"QTC", L"QTD", L"QTE", L"QTF", L"QTG", L"QTH", L"QTI", L"QTJ", L"QTK", L"QTL", L"QTM", L"QTN", L"QTO", L"QTP", L"QTQ", L"QTR", L"QTS", L"QTT", L"QTU", L"QTV", L"QTW", L"QTX", L"QTY", L"QTZ", L"QUA", L"QUB", L"QUC", L"QUD", L"QUE", L"QUF", L"QUG", L"QUH", L"QUI", L"QUJ", L"QUK", L"QUL", L"QUM", L"QUN", L"QUO", L"QUP", L"QUQ", L"QUR", L"QUS", L"QUT", L"QUU", + L"QUV", L"QUW", L"QUX", L"QUY", L"QUZ", L"QVA", L"QVB", L"QVC", L"QVD", L"QVE", L"QVF", L"QVG", L"QVH", L"QVI", L"QVJ", L"QVK", L"QVL", L"QVM", L"QVN", L"QVO", L"QVP", L"QVQ", L"QVR", L"QVS", L"QVT", L"QVU", L"QVV", L"QVW", L"QVX", L"QVY", L"QVZ", L"QWA", L"QWB", L"QWC", L"QWD", L"QWE", L"QWF", L"QWG", L"QWH", L"QWI", L"QWJ", L"QWK", L"QWL", L"QWM", L"QWN", L"QWO", L"QWP", L"QWQ", L"QWR", L"QWS", L"QWT", L"QWU", L"QWV", L"QWW", L"QWX", L"QWY", L"QWZ", L"QXA", L"QXB", L"QXC", L"QXD", L"QXE", L"QXF", L"QXG", L"QXH", L"QXI", L"QXJ", L"QXK", L"QXL", L"QXM", L"QXN", L"QXO", L"QXP", L"QXQ", L"QXR", L"QXS", L"QXT", L"QXU", L"QXV", L"QXW", L"QXX", L"QXY", L"QXZ", L"QYA", L"QYB", L"QYC", L"QYD", L"QYE", L"QYF", L"QYG", L"QYH", L"QYI", L"QYJ", L"QYK", L"QYL", L"QYM", L"QYN", L"QYO", L"QYP", L"QYQ", L"QYR", L"QYS", L"QYT", L"QYU", L"QYV", L"QYW", L"QYX", L"QYY", L"QYZ", L"QZA", L"QZB", L"QZC", L"QZD", L"QZE", L"QZF", L"QZG", L"QZH", L"QZI", L"QZJ", L"QZK", L"QZL", L"QZM", L"QZN", L"QZO", L"QZP", L"QZQ", L"QZR", L"QZS", L"QZT", L"QZU", L"QZV", L"QZW", L"QZX", L"QZY", L"QZZ", L"RAA", L"RAB", L"RAC", L"RAD", L"RAE", L"RAF", L"RAG", L"RAH", L"RAI", L"RAJ", L"RAK", L"RAL", L"RAM", L"RAN", L"RAO", L"RAP", L"RAQ", L"RAR", L"RAS", L"RAT", L"RAU", L"RAV", L"RAW", L"RAX", L"RAY", L"RAZ", L"RBA", L"RBB", L"RBC", L"RBD", L"RBE", L"RBF", L"RBG", L"RBH", L"RBI", L"RBJ", L"RBK", L"RBL", L"RBM", L"RBN", L"RBO", L"RBP", L"RBQ", L"RBR", L"RBS", L"RBT", L"RBU", L"RBV", L"RBW", L"RBX", L"RBY", L"RBZ", L"RCA", L"RCB", L"RCC", L"RCD", L"RCE", L"RCF", L"RCG", L"RCH", L"RCI", L"RCJ", L"RCK", L"RCL", L"RCM", L"RCN", L"RCO", L"RCP", L"RCQ", L"RCR", L"RCS", L"RCT", L"RCU", L"RCV", L"RCW", L"RCX", L"RCY", L"RCZ", L"RDA", L"RDB", L"RDC", L"RDD", L"RDE", L"RDF", L"RDG", L"RDH", L"RDI", L"RDJ", L"RDK", L"RDL", L"RDM", L"RDN", L"RDO", L"RDP", L"RDQ", L"RDR", L"RDS", L"RDT", L"RDU", L"RDV", L"RDW", L"RDX", L"RDY", L"RDZ", L"REA", L"REB", L"REC", L"RED", L"REE", L"REF", L"REG", L"REH", L"REI", L"REJ", L"REK", L"REL", L"REM", L"REN", L"REO", L"REP", L"REQ", L"RER", L"RES", L"RET", L"REU", L"REV", L"REW", L"REX", L"REY", L"REZ", L"RFA", L"RFB", L"RFC", L"RFD", L"RFE", L"RFF", L"RFG", L"RFH", + L"RFI", L"RFJ", L"RFK", L"RFL", L"RFM", L"RFN", L"RFO", L"RFP", L"RFQ", L"RFR", L"RFS", L"RFT", L"RFU", L"RFV", L"RFW", L"RFX", L"RFY", L"RFZ", L"RGA", L"RGB", L"RGC", L"RGD", L"RGE", L"RGF", L"RGG", L"RGH", L"RGI", L"RGJ", L"RGK", L"RGL", L"RGM", L"RGN", L"RGO", L"RGP", L"RGQ", L"RGR", L"RGS", L"RGT", L"RGU", L"RGV", L"RGW", L"RGX", L"RGY", L"RGZ", L"RHA", L"RHB", L"RHC", L"RHD", L"RHE", L"RHF", L"RHG", L"RHH", L"RHI", L"RHJ", L"RHK", L"RHL", L"RHM", L"RHN", L"RHO", L"RHP", L"RHQ", L"RHR", L"RHS", L"RHT", L"RHU", L"RHV", L"RHW", L"RHX", L"RHY", L"RHZ", L"RIA", L"RIB", L"RIC", L"RID", L"RIE", L"RIF", L"RIG", L"RIH", L"RII", L"RIJ", L"RIK", L"RIL", L"RIM", L"RIN", L"RIO", L"RIP", L"RIQ", L"RIR", L"RIS", L"RIT", L"RIU", L"RIV", L"RIW", L"RIX", L"RIY", L"RIZ", L"RJA", L"RJB", L"RJC", L"RJD", L"RJE", L"RJF", L"RJG", L"RJH", L"RJI", L"RJJ", L"RJK", L"RJL", L"RJM", L"RJN", L"RJO", L"RJP", L"RJQ", L"RJR", L"RJS", L"RJT", L"RJU", L"RJV", L"RJW", L"RJX", L"RJY", L"RJZ", L"RKA", L"RKB", L"RKC", L"RKD", L"RKE", L"RKF", L"RKG", L"RKH", L"RKI", L"RKJ", L"RKK", L"RKL", L"RKM", L"RKN", L"RKO", L"RKP", L"RKQ", L"RKR", L"RKS", L"RKT", L"RKU", L"RKV", L"RKW", L"RKX", L"RKY", L"RKZ", L"RLA", L"RLB", L"RLC", L"RLD", L"RLE", L"RLF", L"RLG", L"RLH", L"RLI", L"RLJ", L"RLK", L"RLL", L"RLM", L"RLN", L"RLO", L"RLP", L"RLQ", L"RLR", L"RLS", L"RLT", L"RLU", L"RLV", L"RLW", L"RLX", L"RLY", L"RLZ", L"RMA", L"RMB", L"RMC", L"RMD", L"RME", L"RMF", L"RMG", L"RMH", L"RMI", L"RMJ", L"RMK", L"RML", L"RMM", L"RMN", L"RMO", L"RMP", L"RMQ", L"RMR", L"RMS", L"RMT", L"RMU", L"RMV", L"RMW", L"RMX", L"RMY", L"RMZ", L"RNA", L"RNB", L"RNC", L"RND", L"RNE", L"RNF", L"RNG", L"RNH", L"RNI", L"RNJ", L"RNK", L"RNL", L"RNM", L"RNN", L"RNO", L"RNP", L"RNQ", L"RNR", L"RNS", L"RNT", L"RNU", L"RNV", L"RNW", L"RNX", L"RNY", L"RNZ", L"ROA", L"ROB", L"ROC", L"ROD", L"ROE", L"ROF", L"ROG", L"ROH", L"ROI", L"ROJ", L"ROK", L"ROL", L"ROM", L"RON", L"ROO", L"ROP", L"ROQ", L"ROR", L"ROS", L"ROT", L"ROU", L"ROV", L"ROW", L"ROX", L"ROY", L"ROZ", L"RPA", L"RPB", L"RPC", L"RPD", L"RPE", L"RPF", L"RPG", L"RPH", L"RPI", L"RPJ", L"RPK", L"RPL", L"RPM", L"RPN", L"RPO", L"RPP", L"RPQ", L"RPR", L"RPS", L"RPT", L"RPU", + L"RPV", L"RPW", L"RPX", L"RPY", L"RPZ", L"RQA", L"RQB", L"RQC", L"RQD", L"RQE", L"RQF", L"RQG", L"RQH", L"RQI", L"RQJ", L"RQK", L"RQL", L"RQM", L"RQN", L"RQO", L"RQP", L"RQQ", L"RQR", L"RQS", L"RQT", L"RQU", L"RQV", L"RQW", L"RQX", L"RQY", L"RQZ", L"RRA", L"RRB", L"RRC", L"RRD", L"RRE", L"RRF", L"RRG", L"RRH", L"RRI", L"RRJ", L"RRK", L"RRL", L"RRM", L"RRN", L"RRO", L"RRP", L"RRQ", L"RRR", L"RRS", L"RRT", L"RRU", L"RRV", L"RRW", L"RRX", L"RRY", L"RRZ", L"RSA", L"RSB", L"RSC", L"RSD", L"RSE", L"RSF", L"RSG", L"RSH", L"RSI", L"RSJ", L"RSK", L"RSL", L"RSM", L"RSN", L"RSO", L"RSP", L"RSQ", L"RSR", L"RSS", L"RST", L"RSU", L"RSV", L"RSW", L"RSX", L"RSY", L"RSZ", L"RTA", L"RTB", L"RTC", L"RTD", L"RTE", L"RTF", L"RTG", L"RTH", L"RTI", L"RTJ", L"RTK", L"RTL", L"RTM", L"RTN", L"RTO", L"RTP", L"RTQ", L"RTR", L"RTS", L"RTT", L"RTU", L"RTV", L"RTW", L"RTX", L"RTY", L"RTZ", L"RUA", L"RUB", L"RUC", L"RUD", L"RUE", L"RUF", L"RUG", L"RUH", L"RUI", L"RUJ", L"RUK", L"RUL", L"RUM", L"RUN", L"RUO", L"RUP", L"RUQ", L"RUR", L"RUS", L"RUT", L"RUU", L"RUV", L"RUW", L"RUX", L"RUY", L"RUZ", L"RVA", L"RVB", L"RVC", L"RVD", L"RVE", L"RVF", L"RVG", L"RVH", L"RVI", L"RVJ", L"RVK", L"RVL", L"RVM", L"RVN", L"RVO", L"RVP", L"RVQ", L"RVR", L"RVS", L"RVT", L"RVU", L"RVV", L"RVW", L"RVX", L"RVY", L"RVZ", L"RWA", L"RWB", L"RWC", L"RWD", L"RWE", L"RWF", L"RWG", L"RWH", L"RWI", L"RWJ", L"RWK", L"RWL", L"RWM", L"RWN", L"RWO", L"RWP", L"RWQ", L"RWR", L"RWS", L"RWT", L"RWU", L"RWV", L"RWW", L"RWX", L"RWY", L"RWZ", L"RXA", L"RXB", L"RXC", L"RXD", L"RXE", L"RXF", L"RXG", L"RXH", L"RXI", L"RXJ", L"RXK", L"RXL", L"RXM", L"RXN", L"RXO", L"RXP", L"RXQ", L"RXR", L"RXS", L"RXT", L"RXU", L"RXV", L"RXW", L"RXX", L"RXY", L"RXZ", L"RYA", L"RYB", L"RYC", L"RYD", L"RYE", L"RYF", L"RYG", L"RYH", L"RYI", L"RYJ", L"RYK", L"RYL", L"RYM", L"RYN", L"RYO", L"RYP", L"RYQ", L"RYR", L"RYS", L"RYT", L"RYU", L"RYV", L"RYW", L"RYX", L"RYY", L"RYZ", L"RZA", L"RZB", L"RZC", L"RZD", L"RZE", L"RZF", L"RZG", L"RZH", L"RZI", L"RZJ", L"RZK", L"RZL", L"RZM", L"RZN", L"RZO", L"RZP", L"RZQ", L"RZR", L"RZS", L"RZT", L"RZU", L"RZV", L"RZW", L"RZX", L"RZY", L"RZZ", L"SAA", L"SAB", L"SAC", L"SAD", L"SAE", L"SAF", L"SAG", L"SAH", + L"SAI", L"SAJ", L"SAK", L"SAL", L"SAM", L"SAN", L"SAO", L"SAP", L"SAQ", L"SAR", L"SAS", L"SAT", L"SAU", L"SAV", L"SAW", L"SAX", L"SAY", L"SAZ", L"SBA", L"SBB", L"SBC", L"SBD", L"SBE", L"SBF", L"SBG", L"SBH", L"SBI", L"SBJ", L"SBK", L"SBL", L"SBM", L"SBN", L"SBO", L"SBP", L"SBQ", L"SBR", L"SBS", L"SBT", L"SBU", L"SBV", L"SBW", L"SBX", L"SBY", L"SBZ", L"SCA", L"SCB", L"SCC", L"SCD", L"SCE", L"SCF", L"SCG", L"SCH", L"SCI", L"SCJ", L"SCK", L"SCL", L"SCM", L"SCN", L"SCO", L"SCP", L"SCQ", L"SCR", L"SCS", L"SCT", L"SCU", L"SCV", L"SCW", L"SCX", L"SCY", L"SCZ", L"SDA", L"SDB", L"SDC", L"SDD", L"SDE", L"SDF", L"SDG", L"SDH", L"SDI", L"SDJ", L"SDK", L"SDL", L"SDM", L"SDN", L"SDO", L"SDP", L"SDQ", L"SDR", L"SDS", L"SDT", L"SDU", L"SDV", L"SDW", L"SDX", L"SDY", L"SDZ", L"SEA", L"SEB", L"SEC", L"SED", L"SEE", L"SEF", L"SEG", L"SEH", L"SEI", L"SEJ", L"SEK", L"SEL", L"SEM", L"SEN", L"SEO", L"SEP", L"SEQ", L"SER", L"SES", L"SET", L"SEU", L"SEV", L"SEW", L"SEX", L"SEY", L"SEZ", L"SFA", L"SFB", L"SFC", L"SFD", L"SFE", L"SFF", L"SFG", L"SFH", L"SFI", L"SFJ", L"SFK", L"SFL", L"SFM", L"SFN", L"SFO", L"SFP", L"SFQ", L"SFR", L"SFS", L"SFT", L"SFU", L"SFV", L"SFW", L"SFX", L"SFY", L"SFZ", L"SGA", L"SGB", L"SGC", L"SGD", L"SGE", L"SGF", L"SGG", L"SGH", L"SGI", L"SGJ", L"SGK", L"SGL", L"SGM", L"SGN", L"SGO", L"SGP", L"SGQ", L"SGR", L"SGS", L"SGT", L"SGU", L"SGV", L"SGW", L"SGX", L"SGY", L"SGZ", L"SHA", L"SHB", L"SHC", L"SHD", L"SHE", L"SHF", L"SHG", L"SHH", L"SHI", L"SHJ", L"SHK", L"SHL", L"SHM", L"SHN", L"SHO", L"SHP", L"SHQ", L"SHR", L"SHS", L"SHT", L"SHU", L"SHV", L"SHW", L"SHX", L"SHY", L"SHZ", L"SIA", L"SIB", L"SIC", L"SID", L"SIE", L"SIF", L"SIG", L"SIH", L"SII", L"SIJ", L"SIK", L"SIL", L"SIM", L"SIN", L"SIO", L"SIP", L"SIQ", L"SIR", L"SIS", L"SIT", L"SIU", L"SIV", L"SIW", L"SIX", L"SIY", L"SIZ", L"SJA", L"SJB", L"SJC", L"SJD", L"SJE", L"SJF", L"SJG", L"SJH", L"SJI", L"SJJ", L"SJK", L"SJL", L"SJM", L"SJN", L"SJO", L"SJP", L"SJQ", L"SJR", L"SJS", L"SJT", L"SJU", L"SJV", L"SJW", L"SJX", L"SJY", L"SJZ", L"SKA", L"SKB", L"SKC", L"SKD", L"SKE", L"SKF", L"SKG", L"SKH", L"SKI", L"SKJ", L"SKK", L"SKL", L"SKM", L"SKN", L"SKO", L"SKP", L"SKQ", L"SKR", L"SKS", L"SKT", L"SKU", + L"SKV", L"SKW", L"SKX", L"SKY", L"SKZ", L"SLA", L"SLB", L"SLC", L"SLD", L"SLE", L"SLF", L"SLG", L"SLH", L"SLI", L"SLJ", L"SLK", L"SLL", L"SLM", L"SLN", L"SLO", L"SLP", L"SLQ", L"SLR", L"SLS", L"SLT", L"SLU", L"SLV", L"SLW", L"SLX", L"SLY", L"SLZ", L"SMA", L"SMB", L"SMC", L"SMD", L"SME", L"SMF", L"SMG", L"SMH", L"SMI", L"SMJ", L"SMK", L"SML", L"SMM", L"SMN", L"SMO", L"SMP", L"SMQ", L"SMR", L"SMS", L"SMT", L"SMU", L"SMV", L"SMW", L"SMX", L"SMY", L"SMZ", L"SNA", L"SNB", L"SNC", L"SND", L"SNE", L"SNF", L"SNG", L"SNH", L"SNI", L"SNJ", L"SNK", L"SNL", L"SNM", L"SNN", L"SNO", L"SNP", L"SNQ", L"SNR", L"SNS", L"SNT", L"SNU", L"SNV", L"SNW", L"SNX", L"SNY", L"SNZ", L"SOA", L"SOB", L"SOC", L"SOD", L"SOE", L"SOF", L"SOG", L"SOH", L"SOI", L"SOJ", L"SOK", L"SOL", L"SOM", L"SON", L"SOO", L"SOP", L"SOQ", L"SOR", L"SOS", L"SOT", L"SOU", L"SOV", L"SOW", L"SOX", L"SOY", L"SOZ", L"SPA", L"SPB", L"SPC", L"SPD", L"SPE", L"SPF", L"SPG", L"SPH", L"SPI", L"SPJ", L"SPK", L"SPL", L"SPM", L"SPN", L"SPO", L"SPP", L"SPQ", L"SPR", L"SPS", L"SPT", L"SPU", L"SPV", L"SPW", L"SPX", L"SPY", L"SPZ", L"SQA", L"SQB", L"SQC", L"SQD", L"SQE", L"SQF", L"SQG", L"SQH", L"SQI", L"SQJ", L"SQK", L"SQL", L"SQM", L"SQN", L"SQO", L"SQP", L"SQQ", L"SQR", L"SQS", L"SQT", L"SQU", L"SQV", L"SQW", L"SQX", L"SQY", L"SQZ", L"SRA", L"SRB", L"SRC", L"SRD", L"SRE", L"SRF", L"SRG", L"SRH", L"SRI", L"SRJ", L"SRK", L"SRL", L"SRM", L"SRN", L"SRO", L"SRP", L"SRQ", L"SRR", L"SRS", L"SRT", L"SRU", L"SRV", L"SRW", L"SRX", L"SRY", L"SRZ", L"SSA", L"SSB", L"SSC", L"SSD", L"SSE", L"SSF", L"SSG", L"SSH", L"SSI", L"SSJ", L"SSK", L"SSL", L"SSM", L"SSN", L"SSO", L"SSP", L"SSQ", L"SSR", L"SSS", L"SST", L"SSU", L"SSV", L"SSW", L"SSX", L"SSY", L"SSZ", L"STA", L"STB", L"STC", L"STD", L"STE", L"STF", L"STG", L"STH", L"STI", L"STJ", L"STK", L"STL", L"STM", L"STN", L"STO", L"STP", L"STQ", L"STR", L"STS", L"STT", L"STU", L"STV", L"STW", L"STX", L"STY", L"STZ", L"SUA", L"SUB", L"SUC", L"SUD", L"SUE", L"SUF", L"SUG", L"SUH", L"SUI", L"SUJ", L"SUK", L"SUL", L"SUM", L"SUN", L"SUO", L"SUP", L"SUQ", L"SUR", L"SUS", L"SUT", L"SUU", L"SUV", L"SUW", L"SUX", L"SUY", + L"SUZ", L"SVA", L"SVB", L"SVC", L"SVD", L"SVE", L"SVF", L"SVG", L"SVH", L"SVI", L"SVJ", L"SVK", L"SVL", L"SVM", L"SVN", L"SVO", L"SVP", L"SVQ", L"SVR", L"SVS", L"SVT", L"SVU", L"SVV", L"SVW", L"SVX", L"SVY", L"SVZ", L"SWA", L"SWB", L"SWC", L"SWD", L"SWE", L"SWF", L"SWG", L"SWH", L"SWI", L"SWJ", L"SWK", L"SWL", L"SWM", L"SWN", L"SWO", L"SWP", L"SWQ", L"SWR", L"SWS", L"SWT", L"SWU", L"SWV", L"SWW", L"SWX", L"SWY", L"SWZ", L"SXA", L"SXB", L"SXC", L"SXD", L"SXE", L"SXF", L"SXG", L"SXH", L"SXI", L"SXJ", L"SXK", L"SXL", L"SXM", L"SXN", L"SXO", L"SXP", L"SXQ", L"SXR", L"SXS", L"SXT", L"SXU", L"SXV", L"SXW", L"SXX", L"SXY", L"SXZ", L"SYA", L"SYB", L"SYC", L"SYD", L"SYE", L"SYF", L"SYG", L"SYH", L"SYI", L"SYJ", L"SYK", L"SYL", L"SYM", L"SYN", L"SYO", L"SYP", L"SYQ", L"SYR", L"SYS", L"SYT", L"SYU", L"SYV", L"SYW", L"SYX", L"SYY", L"SYZ", L"SZA", L"SZB", L"SZC", L"SZD", L"SZE", L"SZF", L"SZG", L"SZH", L"SZI", L"SZJ", L"SZK", L"SZL", L"SZM", L"SZN", L"SZO", L"SZP", L"SZQ", L"SZR", L"SZS", L"SZT", L"SZU", L"SZV", L"SZW", L"SZX", L"SZY", L"SZZ", L"TAA", L"TAB", L"TAC", L"TAD", L"TAE", L"TAF", L"TAG", L"TAH", L"TAI", L"TAJ", L"TAK", L"TAL", L"TAM", L"TAN", L"TAO", L"TAP", L"TAQ", L"TAR", L"TAS", L"TAT", L"TAU", L"TAV", L"TAW", L"TAX", L"TAY", L"TAZ", L"TBA", L"TBB", L"TBC", L"TBD", L"TBE", L"TBF", L"TBG", L"TBH", L"TBI", L"TBJ", L"TBK", L"TBL", L"TBM", L"TBN", L"TBO", L"TBP", L"TBQ", L"TBR", L"TBS", L"TBT", L"TBU", L"TBV", L"TBW", L"TBX", L"TBY", L"TBZ", L"TCA", L"TCB", L"TCC", L"TCD", L"TCE", L"TCF", L"TCG", L"TCH", L"TCI", L"TCJ", L"TCK", L"TCL", L"TCM", L"TCN", L"TCO", L"TCP", L"TCQ", L"TCR", L"TCS", L"TCT", L"TCU", L"TCV", L"TCW", L"TCX", L"TCY", L"TCZ", L"TDA", L"TDB", L"TDC", L"TDD", L"TDE", L"TDF", L"TDG", L"TDH", L"TDI", L"TDJ", L"TDK", L"TDL", L"TDM", L"TDN", L"TDO", L"TDP", L"TDQ", L"TDR", L"TDS", L"TDT", L"TDU", L"TDV", L"TDW", L"TDX", L"TDY", L"TDZ", L"TEA", L"TEB", L"TEC", L"TED", L"TEE", L"TEF", L"TEG", L"TEH", L"TEI", L"TEJ", L"TEK", L"TEL", L"TEM", L"TEN", L"TEO", L"TEP", L"TEQ", L"TER", L"TES", L"TET", L"TEU", L"TEV", L"TEW", L"TEX", L"TEY", L"TEZ", L"TFA", L"TFB", L"TFC", L"TFD", L"TFE", L"TFF", L"TFG", L"TFH", L"TFI", L"TFJ", L"TFK", L"TFL", L"TFM", L"TFN", L"TFO", L"TFP", L"TFQ", L"TFR", L"TFS", L"TFT", L"TFU", L"TFV", L"TFW", L"TFX", L"TFY", L"TFZ", L"TGA", L"TGB", L"TGC", L"TGD", L"TGE", L"TGF", L"TGG", L"TGH", L"TGI", L"TGJ", L"TGK", L"TGL", L"TGM", L"TGN", L"TGO", L"TGP", L"TGQ", L"TGR", L"TGS", L"TGT", L"TGU", L"TGV", L"TGW", L"TGX", L"TGY", L"TGZ", L"THA", L"THB", L"THC", L"THD", L"THE", L"THF", L"THG", L"THH", L"THI", L"THJ", L"THK", L"THL", L"THM", L"THN", L"THO", L"THP", L"THQ", L"THR", L"THS", L"THT", L"THU", L"THV", L"THW", L"THX", L"THY", L"THZ", L"TIA", L"TIB", L"TIC", L"TID", L"TIE", L"TIF", L"TIG", L"TIH", L"TII", L"TIJ", L"TIK", L"TIL", L"TIM", L"TIN", L"TIO", L"TIP", L"TIQ", L"TIR", L"TIS", L"TIT", L"TIU", L"TIV", L"TIW", L"TIX", L"TIY", L"TIZ", L"TJA", L"TJB", L"TJC", L"TJD", L"TJE", L"TJF", L"TJG", L"TJH", L"TJI", L"TJJ", L"TJK", L"TJL", L"TJM", L"TJN", L"TJO", L"TJP", L"TJQ", L"TJR", L"TJS", L"TJT", L"TJU", L"TJV", L"TJW", L"TJX", L"TJY", L"TJZ", L"TKA", L"TKB", L"TKC", L"TKD", L"TKE", L"TKF", L"TKG", L"TKH", L"TKI", L"TKJ", L"TKK", L"TKL", L"TKM", L"TKN", L"TKO", L"TKP", L"TKQ", L"TKR", L"TKS", L"TKT", L"TKU", L"TKV", L"TKW", L"TKX", L"TKY", L"TKZ", L"TLA", L"TLB", L"TLC", L"TLD", L"TLE", L"TLF", L"TLG", L"TLH", L"TLI", L"TLJ", L"TLK", L"TLL", L"TLM", L"TLN", L"TLO", L"TLP", L"TLQ", L"TLR", L"TLS", L"TLT", L"TLU", L"TLV", L"TLW", L"TLX", L"TLY", L"TLZ", L"TMA", L"TMB", L"TMC", L"TMD", L"TME", L"TMF", L"TMG", L"TMH", L"TMI", L"TMJ", L"TMK", L"TML", L"TMM", L"TMN", L"TMO", L"TMP", L"TMQ", L"TMR", L"TMS", L"TMT", L"TMU", L"TMV", L"TMW", L"TMX", L"TMY", L"TMZ", L"TNA", L"TNB", L"TNC", L"TND", L"TNE", L"TNF", L"TNG", L"TNH", L"TNI", L"TNJ", L"TNK", L"TNL", L"TNM", L"TNN", L"TNO", L"TNP", L"TNQ", L"TNR", L"TNS", L"TNT", L"TNU", L"TNV", L"TNW", L"TNX", L"TNY", L"TNZ", L"TOA", L"TOB", L"TOC", L"TOD", L"TOE", L"TOF", L"TOG", L"TOH", L"TOI", L"TOJ", L"TOK", L"TOL", L"TOM", L"TON", L"TOO", L"TOP", L"TOQ", L"TOR", L"TOS", L"TOT", L"TOU", L"TOV", L"TOW", L"TOX", L"TOY", L"TOZ", L"TPA", L"TPB", L"TPC", L"TPD", L"TPE", L"TPF", L"TPG", L"TPH", L"TPI", L"TPJ", L"TPK", L"TPL", L"TPM", L"TPN", L"TPO", L"TPP", L"TPQ", L"TPR", L"TPS", L"TPT", L"TPU", L"TPV", L"TPW", L"TPX", L"TPY", L"TPZ", - L"TQA", L"TQB", L"TQC", L"TQD", L"TQE", L"TQF", L"TQG", L"TQH", L"TQI", L"TQJ", L"TQK", L"TQL", L"TQM", L"TQN", L"TQO", L"TQP", L"TQQ", L"TQR", L"TQS", L"TQT", L"TQU", L"TQV", L"TQW", L"TQX", L"TQY", L"TQZ", L"TRA", L"TRB", L"TRC", L"TRD", L"TRE", L"TRF", L"TRG", L"TRH", L"TRI", L"TRJ", L"TRK", L"TRL", L"TRM", L"TRN", L"TRO", L"TRP", L"TRQ", L"TRR", L"TRS", L"TRT", L"TRU", L"TRV", L"TRW", L"TRX", L"TRY", L"TRZ", L"TSA", L"TSB", L"TSC", L"TSD", L"TSE", L"TSF", L"TSG", L"TSH", L"TSI", L"TSJ", L"TSK", L"TSL", L"TSM", L"TSN", L"TSO", L"TSP", L"TSQ", L"TSR", L"TSS", L"TST", L"TSU", L"TSV", L"TSW", L"TSX", L"TSY", L"TSZ", L"TTA", L"TTB", L"TTC", L"TTD", L"TTE", L"TTF", L"TTG", L"TTH", L"TTI", L"TTJ", L"TTK", L"TTL", L"TTM", L"TTN", L"TTO", L"TTP", L"TTQ", L"TTR", L"TTS", L"TTT", L"TTU", L"TTV", L"TTW", L"TTX", L"TTY", L"TTZ", L"TUA", L"TUB", L"TUC", L"TUD", L"TUE", L"TUF", L"TUG", L"TUH", L"TUI", L"TUJ", L"TUK", L"TUL", L"TUM", L"TUN", L"TUO", L"TUP", L"TUQ", L"TUR", L"TUS", L"TUT", L"TUU", L"TUV", L"TUW", L"TUX", L"TUY", L"TUZ", L"TVA", L"TVB", L"TVC", L"TVD", L"TVE", L"TVF", L"TVG", L"TVH", L"TVI", L"TVJ", L"TVK", L"TVL", L"TVM", L"TVN", L"TVO", L"TVP", L"TVQ", L"TVR", L"TVS", L"TVT", L"TVU", L"TVV", L"TVW", L"TVX", L"TVY", L"TVZ", L"TWA", L"TWB", L"TWC", L"TWD", L"TWE", L"TWF", L"TWG", L"TWH", L"TWI", L"TWJ", L"TWK", L"TWL", L"TWM", L"TWN", L"TWO", L"TWP", L"TWQ", L"TWR", L"TWS", L"TWT", L"TWU", L"TWV", L"TWW", L"TWX", L"TWY", L"TWZ", L"TXA", L"TXB", L"TXC", L"TXD", L"TXE", L"TXF", L"TXG", L"TXH", L"TXI", L"TXJ", L"TXK", L"TXL", L"TXM", L"TXN", L"TXO", L"TXP", L"TXQ", L"TXR", L"TXS", L"TXT", L"TXU", L"TXV", L"TXW", L"TXX", L"TXY", L"TXZ", L"TYA", L"TYB", L"TYC", L"TYD", L"TYE", L"TYF", L"TYG", L"TYH", L"TYI", L"TYJ", L"TYK", L"TYL", L"TYM", L"TYN", L"TYO", L"TYP", L"TYQ", L"TYR", L"TYS", L"TYT", L"TYU", L"TYV", L"TYW", L"TYX", L"TYY", L"TYZ", L"TZA", L"TZB", L"TZC", L"TZD", L"TZE", L"TZF", L"TZG", L"TZH", L"TZI", L"TZJ", L"TZK", L"TZL", L"TZM", L"TZN", L"TZO", L"TZP", L"TZQ", L"TZR", L"TZS", L"TZT", L"TZU", L"TZV", L"TZW", L"TZX", L"TZY", L"TZZ", L"UAA", L"UAB", L"UAC", L"UAD", L"UAE", L"UAF", L"UAG", L"UAH", L"UAI", L"UAJ", L"UAK", L"UAL", L"UAM", - L"UAN", L"UAO", L"UAP", L"UAQ", L"UAR", L"UAS", L"UAT", L"UAU", L"UAV", L"UAW", L"UAX", L"UAY", L"UAZ", L"UBA", L"UBB", L"UBC", L"UBD", L"UBE", L"UBF", L"UBG", L"UBH", L"UBI", L"UBJ", L"UBK", L"UBL", L"UBM", L"UBN", L"UBO", L"UBP", L"UBQ", L"UBR", L"UBS", L"UBT", L"UBU", L"UBV", L"UBW", L"UBX", L"UBY", L"UBZ", L"UCA", L"UCB", L"UCC", L"UCD", L"UCE", L"UCF", L"UCG", L"UCH", L"UCI", L"UCJ", L"UCK", L"UCL", L"UCM", L"UCN", L"UCO", L"UCP", L"UCQ", L"UCR", L"UCS", L"UCT", L"UCU", L"UCV", L"UCW", L"UCX", L"UCY", L"UCZ", L"UDA", L"UDB", L"UDC", L"UDD", L"UDE", L"UDF", L"UDG", L"UDH", L"UDI", L"UDJ", L"UDK", L"UDL", L"UDM", L"UDN", L"UDO", L"UDP", L"UDQ", L"UDR", L"UDS", L"UDT", L"UDU", L"UDV", L"UDW", L"UDX", L"UDY", L"UDZ", L"UEA", L"UEB", L"UEC", L"UED", L"UEE", L"UEF", L"UEG", L"UEH", L"UEI", L"UEJ", L"UEK", L"UEL", L"UEM", L"UEN", L"UEO", L"UEP", L"UEQ", L"UER", L"UES", L"UET", L"UEU", L"UEV", L"UEW", L"UEX", L"UEY", L"UEZ", L"UFA", L"UFB", L"UFC", L"UFD", L"UFE", L"UFF", L"UFG", L"UFH", L"UFI", L"UFJ", L"UFK", L"UFL", L"UFM", L"UFN", L"UFO", L"UFP", L"UFQ", L"UFR", L"UFS", L"UFT", L"UFU", L"UFV", L"UFW", L"UFX", L"UFY", L"UFZ", L"UGA", L"UGB", L"UGC", L"UGD", L"UGE", L"UGF", L"UGG", L"UGH", L"UGI", L"UGJ", L"UGK", L"UGL", L"UGM", L"UGN", L"UGO", L"UGP", L"UGQ", L"UGR", L"UGS", L"UGT", L"UGU", L"UGV", L"UGW", L"UGX", L"UGY", L"UGZ", L"UHA", L"UHB", L"UHC", L"UHD", L"UHE", L"UHF", L"UHG", L"UHH", L"UHI", L"UHJ", L"UHK", L"UHL", L"UHM", L"UHN", L"UHO", L"UHP", L"UHQ", L"UHR", L"UHS", L"UHT", L"UHU", L"UHV", L"UHW", L"UHX", L"UHY", L"UHZ", L"UIA", L"UIB", L"UIC", L"UID", L"UIE", L"UIF", L"UIG", L"UIH", L"UII", L"UIJ", L"UIK", L"UIL", L"UIM", L"UIN", L"UIO", L"UIP", L"UIQ", L"UIR", L"UIS", L"UIT", L"UIU", L"UIV", L"UIW", L"UIX", L"UIY", L"UIZ", L"UJA", L"UJB", L"UJC", L"UJD", L"UJE", L"UJF", L"UJG", L"UJH", L"UJI", L"UJJ", L"UJK", L"UJL", L"UJM", L"UJN", L"UJO", L"UJP", L"UJQ", L"UJR", L"UJS", L"UJT", L"UJU", L"UJV", L"UJW", L"UJX", L"UJY", L"UJZ", L"UKA", L"UKB", L"UKC", L"UKD", L"UKE", L"UKF", L"UKG", L"UKH", L"UKI", L"UKJ", L"UKK", L"UKL", L"UKM", L"UKN", L"UKO", L"UKP", L"UKQ", L"UKR", L"UKS", L"UKT", L"UKU", L"UKV", L"UKW", L"UKX", L"UKY", L"UKZ", - L"ULA", L"ULB", L"ULC", L"ULD", L"ULE", L"ULF", L"ULG", L"ULH", L"ULI", L"ULJ", L"ULK", L"ULL", L"ULM", L"ULN", L"ULO", L"ULP", L"ULQ", L"ULR", L"ULS", L"ULT", L"ULU", L"ULV", L"ULW", L"ULX", L"ULY", L"ULZ", L"UMA", L"UMB", L"UMC", L"UMD", L"UME", L"UMF", L"UMG", L"UMH", L"UMI", L"UMJ", L"UMK", L"UML", L"UMM", L"UMN", L"UMO", L"UMP", L"UMQ", L"UMR", L"UMS", L"UMT", L"UMU", L"UMV", L"UMW", L"UMX", L"UMY", L"UMZ", L"UNA", L"UNB", L"UNC", L"UND", L"UNE", L"UNF", L"UNG", L"UNH", L"UNI", L"UNJ", L"UNK", L"UNL", L"UNM", L"UNN", L"UNO", L"UNP", L"UNQ", L"UNR", L"UNS", L"UNT", L"UNU", L"UNV", L"UNW", L"UNX", L"UNY", L"UNZ", L"UOA", L"UOB", L"UOC", L"UOD", L"UOE", L"UOF", L"UOG", L"UOH", L"UOI", L"UOJ", L"UOK", L"UOL", L"UOM", L"UON", L"UOO", L"UOP", L"UOQ", L"UOR", L"UOS", L"UOT", L"UOU", L"UOV", L"UOW", L"UOX", L"UOY", L"UOZ", L"UPA", L"UPB", L"UPC", L"UPD", L"UPE", L"UPF", L"UPG", L"UPH", L"UPI", L"UPJ", L"UPK", L"UPL", L"UPM", L"UPN", L"UPO", L"UPP", L"UPQ", L"UPR", L"UPS", L"UPT", L"UPU", L"UPV", L"UPW", L"UPX", L"UPY", L"UPZ", L"UQA", L"UQB", L"UQC", L"UQD", L"UQE", L"UQF", L"UQG", L"UQH", L"UQI", L"UQJ", L"UQK", L"UQL", L"UQM", L"UQN", L"UQO", L"UQP", L"UQQ", L"UQR", L"UQS", L"UQT", L"UQU", L"UQV", L"UQW", L"UQX", L"UQY", L"UQZ", L"URA", L"URB", L"URC", L"URD", L"URE", L"URF", L"URG", L"URH", L"URI", L"URJ", L"URK", L"URL", L"URM", L"URN", L"URO", L"URP", L"URQ", L"URR", L"URS", L"URT", L"URU", L"URV", L"URW", L"URX", L"URY", L"URZ", L"USA", L"USB", L"USC", L"USD", L"USE", L"USF", L"USG", L"USH", L"USI", L"USJ", L"USK", L"USL", L"USM", L"USN", L"USO", L"USP", L"USQ", L"USR", L"USS", L"UST", L"USU", L"USV", L"USW", L"USX", L"USY", L"USZ", L"UTA", L"UTB", L"UTC", L"UTD", L"UTE", L"UTF", L"UTG", L"UTH", L"UTI", L"UTJ", L"UTK", L"UTL", L"UTM", L"UTN", L"UTO", L"UTP", L"UTQ", L"UTR", L"UTS", L"UTT", L"UTU", L"UTV", L"UTW", L"UTX", L"UTY", L"UTZ", L"UUA", L"UUB", L"UUC", L"UUD", L"UUE", L"UUF", L"UUG", L"UUH", L"UUI", L"UUJ", L"UUK", L"UUL", L"UUM", L"UUN", L"UUO", L"UUP", L"UUQ", L"UUR", L"UUS", L"UUT", L"UUU", L"UUV", L"UUW", L"UUX", L"UUY", L"UUZ", L"UVA", L"UVB", L"UVC", L"UVD", L"UVE", L"UVF", L"UVG", L"UVH", L"UVI", L"UVJ", L"UVK", L"UVL", L"UVM", - L"UVN", L"UVO", L"UVP", L"UVQ", L"UVR", L"UVS", L"UVT", L"UVU", L"UVV", L"UVW", L"UVX", L"UVY", L"UVZ", L"UWA", L"UWB", L"UWC", L"UWD", L"UWE", L"UWF", L"UWG", L"UWH", L"UWI", L"UWJ", L"UWK", L"UWL", L"UWM", L"UWN", L"UWO", L"UWP", L"UWQ", L"UWR", L"UWS", L"UWT", L"UWU", L"UWV", L"UWW", L"UWX", L"UWY", L"UWZ", L"UXA", L"UXB", L"UXC", L"UXD", L"UXE", L"UXF", L"UXG", L"UXH", L"UXI", L"UXJ", L"UXK", L"UXL", L"UXM", L"UXN", L"UXO", L"UXP", L"UXQ", L"UXR", L"UXS", L"UXT", L"UXU", L"UXV", L"UXW", L"UXX", L"UXY", L"UXZ", L"UYA", L"UYB", L"UYC", L"UYD", L"UYE", L"UYF", L"UYG", L"UYH", L"UYI", L"UYJ", L"UYK", L"UYL", L"UYM", L"UYN", L"UYO", L"UYP", L"UYQ", L"UYR", L"UYS", L"UYT", L"UYU", L"UYV", L"UYW", L"UYX", L"UYY", L"UYZ", L"UZA", L"UZB", L"UZC", L"UZD", L"UZE", L"UZF", L"UZG", L"UZH", L"UZI", L"UZJ", L"UZK", L"UZL", L"UZM", L"UZN", L"UZO", L"UZP", L"UZQ", L"UZR", L"UZS", L"UZT", L"UZU", L"UZV", L"UZW", L"UZX", L"UZY", L"UZZ", L"VAA", L"VAB", L"VAC", L"VAD", L"VAE", L"VAF", L"VAG", L"VAH", L"VAI", L"VAJ", L"VAK", L"VAL", L"VAM", L"VAN", L"VAO", L"VAP", L"VAQ", L"VAR", L"VAS", L"VAT", L"VAU", L"VAV", L"VAW", L"VAX", L"VAY", L"VAZ", L"VBA", L"VBB", L"VBC", L"VBD", L"VBE", L"VBF", L"VBG", L"VBH", L"VBI", L"VBJ", L"VBK", L"VBL", L"VBM", L"VBN", L"VBO", L"VBP", L"VBQ", L"VBR", L"VBS", L"VBT", L"VBU", L"VBV", L"VBW", L"VBX", L"VBY", L"VBZ", L"VCA", L"VCB", L"VCC", L"VCD", L"VCE", L"VCF", L"VCG", L"VCH", L"VCI", L"VCJ", L"VCK", L"VCL", L"VCM", L"VCN", L"VCO", L"VCP", L"VCQ", L"VCR", L"VCS", L"VCT", L"VCU", L"VCV", L"VCW", L"VCX", L"VCY", L"VCZ", L"VDA", L"VDB", L"VDC", L"VDD", L"VDE", L"VDF", L"VDG", L"VDH", L"VDI", L"VDJ", L"VDK", L"VDL", L"VDM", L"VDN", L"VDO", L"VDP", L"VDQ", L"VDR", L"VDS", L"VDT", L"VDU", L"VDV", L"VDW", L"VDX", L"VDY", L"VDZ", L"VEA", L"VEB", L"VEC", L"VED", L"VEE", L"VEF", L"VEG", L"VEH", L"VEI", L"VEJ", L"VEK", L"VEL", L"VEM", L"VEN", L"VEO", L"VEP", L"VEQ", L"VER", L"VES", L"VET", L"VEU", L"VEV", L"VEW", L"VEX", L"VEY", L"VEZ", L"VFA", L"VFB", L"VFC", L"VFD", L"VFE", L"VFF", L"VFG", L"VFH", L"VFI", L"VFJ", L"VFK", L"VFL", L"VFM", L"VFN", L"VFO", L"VFP", L"VFQ", L"VFR", L"VFS", L"VFT", L"VFU", L"VFV", L"VFW", L"VFX", L"VFY", L"VFZ", - L"VGA", L"VGB", L"VGC", L"VGD", L"VGE", L"VGF", L"VGG", L"VGH", L"VGI", L"VGJ", L"VGK", L"VGL", L"VGM", L"VGN", L"VGO", L"VGP", L"VGQ", L"VGR", L"VGS", L"VGT", L"VGU", L"VGV", L"VGW", L"VGX", L"VGY", L"VGZ", L"VHA", L"VHB", L"VHC", L"VHD", L"VHE", L"VHF", L"VHG", L"VHH", L"VHI", L"VHJ", L"VHK", L"VHL", L"VHM", L"VHN", L"VHO", L"VHP", L"VHQ", L"VHR", L"VHS", L"VHT", L"VHU", L"VHV", L"VHW", L"VHX", L"VHY", L"VHZ", L"VIA", L"VIB", L"VIC", L"VID", L"VIE", L"VIF", L"VIG", L"VIH", L"VII", L"VIJ", L"VIK", L"VIL", L"VIM", L"VIN", L"VIO", L"VIP", L"VIQ", L"VIR", L"VIS", L"VIT", L"VIU", L"VIV", L"VIW", L"VIX", L"VIY", L"VIZ", L"VJA", L"VJB", L"VJC", L"VJD", L"VJE", L"VJF", L"VJG", L"VJH", L"VJI", L"VJJ", L"VJK", L"VJL", L"VJM", L"VJN", L"VJO", L"VJP", L"VJQ", L"VJR", L"VJS", L"VJT", L"VJU", L"VJV", L"VJW", L"VJX", L"VJY", L"VJZ", L"VKA", L"VKB", L"VKC", L"VKD", L"VKE", L"VKF", L"VKG", L"VKH", L"VKI", L"VKJ", L"VKK", L"VKL", L"VKM", L"VKN", L"VKO", L"VKP", L"VKQ", L"VKR", L"VKS", L"VKT", L"VKU", L"VKV", L"VKW", L"VKX", L"VKY", L"VKZ", L"VLA", L"VLB", L"VLC", L"VLD", L"VLE", L"VLF", L"VLG", L"VLH", L"VLI", L"VLJ", L"VLK", L"VLL", L"VLM", L"VLN", L"VLO", L"VLP", L"VLQ", L"VLR", L"VLS", L"VLT", L"VLU", L"VLV", L"VLW", L"VLX", L"VLY", L"VLZ", L"VMA", L"VMB", L"VMC", L"VMD", L"VME", L"VMF", L"VMG", L"VMH", L"VMI", L"VMJ", L"VMK", L"VML", L"VMM", L"VMN", L"VMO", L"VMP", L"VMQ", L"VMR", L"VMS", L"VMT", L"VMU", L"VMV", L"VMW", L"VMX", L"VMY", L"VMZ", L"VNA", L"VNB", L"VNC", L"VND", L"VNE", L"VNF", L"VNG", L"VNH", L"VNI", L"VNJ", L"VNK", L"VNL", L"VNM", L"VNN", L"VNO", L"VNP", L"VNQ", L"VNR", L"VNS", L"VNT", L"VNU", L"VNV", L"VNW", L"VNX", L"VNY", L"VNZ", L"VOA", L"VOB", L"VOC", L"VOD", L"VOE", L"VOF", L"VOG", L"VOH", L"VOI", L"VOJ", L"VOK", L"VOL", L"VOM", L"VON", L"VOO", L"VOP", L"VOQ", L"VOR", L"VOS", L"VOT", L"VOU", L"VOV", L"VOW", L"VOX", L"VOY", L"VOZ", L"VPA", L"VPB", L"VPC", L"VPD", L"VPE", L"VPF", L"VPG", L"VPH", L"VPI", L"VPJ", L"VPK", L"VPL", L"VPM", L"VPN", L"VPO", L"VPP", L"VPQ", L"VPR", L"VPS", L"VPT", L"VPU", L"VPV", L"VPW", L"VPX", L"VPY", L"VPZ", L"VQA", L"VQB", L"VQC", L"VQD", L"VQE", L"VQF", L"VQG", L"VQH", L"VQI", L"VQJ", L"VQK", L"VQL", L"VQM", - L"VQN", L"VQO", L"VQP", L"VQQ", L"VQR", L"VQS", L"VQT", L"VQU", L"VQV", L"VQW", L"VQX", L"VQY", L"VQZ", L"VRA", L"VRB", L"VRC", L"VRD", L"VRE", L"VRF", L"VRG", L"VRH", L"VRI", L"VRJ", L"VRK", L"VRL", L"VRM", L"VRN", L"VRO", L"VRP", L"VRQ", L"VRR", L"VRS", L"VRT", L"VRU", L"VRV", L"VRW", L"VRX", L"VRY", L"VRZ", L"VSA", L"VSB", L"VSC", L"VSD", L"VSE", L"VSF", L"VSG", L"VSH", L"VSI", L"VSJ", L"VSK", L"VSL", L"VSM", L"VSN", L"VSO", L"VSP", L"VSQ", L"VSR", L"VSS", L"VST", L"VSU", L"VSV", L"VSW", L"VSX", L"VSY", L"VSZ", L"VTA", L"VTB", L"VTC", L"VTD", L"VTE", L"VTF", L"VTG", L"VTH", L"VTI", L"VTJ", L"VTK", L"VTL", L"VTM", L"VTN", L"VTO", L"VTP", L"VTQ", L"VTR", L"VTS", L"VTT", L"VTU", L"VTV", L"VTW", L"VTX", L"VTY", L"VTZ", L"VUA", L"VUB", L"VUC", L"VUD", L"VUE", L"VUF", L"VUG", L"VUH", L"VUI", L"VUJ", L"VUK", L"VUL", L"VUM", L"VUN", L"VUO", L"VUP", L"VUQ", L"VUR", L"VUS", L"VUT", L"VUU", L"VUV", L"VUW", L"VUX", L"VUY", L"VUZ", L"VVA", L"VVB", L"VVC", L"VVD", L"VVE", L"VVF", L"VVG", L"VVH", L"VVI", L"VVJ", L"VVK", L"VVL", L"VVM", L"VVN", L"VVO", L"VVP", L"VVQ", L"VVR", L"VVS", L"VVT", L"VVU", L"VVV", L"VVW", L"VVX", L"VVY", L"VVZ", L"VWA", L"VWB", L"VWC", L"VWD", L"VWE", L"VWF", L"VWG", L"VWH", L"VWI", L"VWJ", L"VWK", L"VWL", L"VWM", L"VWN", L"VWO", L"VWP", L"VWQ", L"VWR", L"VWS", L"VWT", L"VWU", L"VWV", L"VWW", L"VWX", L"VWY", L"VWZ", L"VXA", L"VXB", L"VXC", L"VXD", L"VXE", L"VXF", L"VXG", L"VXH", L"VXI", L"VXJ", L"VXK", L"VXL", L"VXM", L"VXN", L"VXO", L"VXP", L"VXQ", L"VXR", L"VXS", L"VXT", L"VXU", L"VXV", L"VXW", L"VXX", L"VXY", L"VXZ", L"VYA", L"VYB", L"VYC", L"VYD", L"VYE", L"VYF", L"VYG", L"VYH", L"VYI", L"VYJ", L"VYK", L"VYL", L"VYM", L"VYN", L"VYO", L"VYP", L"VYQ", L"VYR", L"VYS", L"VYT", L"VYU", L"VYV", L"VYW", L"VYX", L"VYY", L"VYZ", L"VZA", L"VZB", L"VZC", L"VZD", L"VZE", L"VZF", L"VZG", L"VZH", L"VZI", L"VZJ", L"VZK", L"VZL", L"VZM", L"VZN", L"VZO", L"VZP", L"VZQ", L"VZR", L"VZS", L"VZT", L"VZU", L"VZV", L"VZW", L"VZX", L"VZY", L"VZZ", L"WAA", L"WAB", L"WAC", L"WAD", L"WAE", L"WAF", L"WAG", L"WAH", L"WAI", L"WAJ", L"WAK", L"WAL", L"WAM", L"WAN", L"WAO", L"WAP", L"WAQ", L"WAR", L"WAS", L"WAT", L"WAU", L"WAV", L"WAW", L"WAX", L"WAY", L"WAZ", - L"WBA", L"WBB", L"WBC", L"WBD", L"WBE", L"WBF", L"WBG", L"WBH", L"WBI", L"WBJ", L"WBK", L"WBL", L"WBM", L"WBN", L"WBO", L"WBP", L"WBQ", L"WBR", L"WBS", L"WBT", L"WBU", L"WBV", L"WBW", L"WBX", L"WBY", L"WBZ", L"WCA", L"WCB", L"WCC", L"WCD", L"WCE", L"WCF", L"WCG", L"WCH", L"WCI", L"WCJ", L"WCK", L"WCL", L"WCM", L"WCN", L"WCO", L"WCP", L"WCQ", L"WCR", L"WCS", L"WCT", L"WCU", L"WCV", L"WCW", L"WCX", L"WCY", L"WCZ", L"WDA", L"WDB", L"WDC", L"WDD", L"WDE", L"WDF", L"WDG", L"WDH", L"WDI", L"WDJ", L"WDK", L"WDL", L"WDM", L"WDN", L"WDO", L"WDP", L"WDQ", L"WDR", L"WDS", L"WDT", L"WDU", L"WDV", L"WDW", L"WDX", L"WDY", L"WDZ", L"WEA", L"WEB", L"WEC", L"WED", L"WEE", L"WEF", L"WEG", L"WEH", L"WEI", L"WEJ", L"WEK", L"WEL", L"WEM", L"WEN", L"WEO", L"WEP", L"WEQ", L"WER", L"WES", L"WET", L"WEU", L"WEV", L"WEW", L"WEX", L"WEY", L"WEZ", L"WFA", L"WFB", L"WFC", L"WFD", L"WFE", L"WFF", L"WFG", L"WFH", L"WFI", L"WFJ", L"WFK", L"WFL", L"WFM", L"WFN", L"WFO", L"WFP", L"WFQ", L"WFR", L"WFS", L"WFT", L"WFU", L"WFV", L"WFW", L"WFX", L"WFY", L"WFZ", L"WGA", L"WGB", L"WGC", L"WGD", L"WGE", L"WGF", L"WGG", L"WGH", L"WGI", L"WGJ", L"WGK", L"WGL", L"WGM", L"WGN", L"WGO", L"WGP", L"WGQ", L"WGR", L"WGS", L"WGT", L"WGU", L"WGV", L"WGW", L"WGX", L"WGY", L"WGZ", L"WHA", L"WHB", L"WHC", L"WHD", L"WHE", L"WHF", L"WHG", L"WHH", L"WHI", L"WHJ", L"WHK", L"WHL", L"WHM", L"WHN", L"WHO", L"WHP", L"WHQ", L"WHR", L"WHS", L"WHT", L"WHU", L"WHV", L"WHW", L"WHX", L"WHY", L"WHZ", L"WIA", L"WIB", L"WIC", L"WID", L"WIE", L"WIF", L"WIG", L"WIH", L"WII", L"WIJ", L"WIK", L"WIL", L"WIM", L"WIN", L"WIO", L"WIP", L"WIQ", L"WIR", L"WIS", L"WIT", L"WIU", L"WIV", L"WIW", L"WIX", L"WIY", L"WIZ", L"WJA", L"WJB", L"WJC", L"WJD", L"WJE", L"WJF", L"WJG", L"WJH", L"WJI", L"WJJ", L"WJK", L"WJL", L"WJM", L"WJN", L"WJO", L"WJP", L"WJQ", L"WJR", L"WJS", L"WJT", L"WJU", L"WJV", L"WJW", L"WJX", L"WJY", L"WJZ", L"WKA", L"WKB", L"WKC", L"WKD", L"WKE", L"WKF", L"WKG", L"WKH", L"WKI", L"WKJ", L"WKK", L"WKL", L"WKM", L"WKN", L"WKO", L"WKP", L"WKQ", L"WKR", L"WKS", L"WKT", L"WKU", L"WKV", L"WKW", L"WKX", L"WKY", L"WKZ", L"WLA", L"WLB", L"WLC", L"WLD", L"WLE", L"WLF", L"WLG", L"WLH", L"WLI", L"WLJ", L"WLK", L"WLL", L"WLM", - L"WLN", L"WLO", L"WLP", L"WLQ", L"WLR", L"WLS", L"WLT", L"WLU", L"WLV", L"WLW", L"WLX", L"WLY", L"WLZ", L"WMA", L"WMB", L"WMC", L"WMD", L"WME", L"WMF", L"WMG", L"WMH", L"WMI", L"WMJ", L"WMK", L"WML", L"WMM", L"WMN", L"WMO", L"WMP", L"WMQ", L"WMR", L"WMS", L"WMT", L"WMU", L"WMV", L"WMW", L"WMX", L"WMY", L"WMZ", L"WNA", L"WNB", L"WNC", L"WND", L"WNE", L"WNF", L"WNG", L"WNH", L"WNI", L"WNJ", L"WNK", L"WNL", L"WNM", L"WNN", L"WNO", L"WNP", L"WNQ", L"WNR", L"WNS", L"WNT", L"WNU", L"WNV", L"WNW", L"WNX", L"WNY", L"WNZ", L"WOA", L"WOB", L"WOC", L"WOD", L"WOE", L"WOF", L"WOG", L"WOH", L"WOI", L"WOJ", L"WOK", L"WOL", L"WOM", L"WON", L"WOO", L"WOP", L"WOQ", L"WOR", L"WOS", L"WOT", L"WOU", L"WOV", L"WOW", L"WOX", L"WOY", L"WOZ", L"WPA", L"WPB", L"WPC", L"WPD", L"WPE", L"WPF", L"WPG", L"WPH", L"WPI", L"WPJ", L"WPK", L"WPL", L"WPM", L"WPN", L"WPO", L"WPP", L"WPQ", L"WPR", L"WPS", L"WPT", L"WPU", L"WPV", L"WPW", L"WPX", L"WPY", L"WPZ", L"WQA", L"WQB", L"WQC", L"WQD", L"WQE", L"WQF", L"WQG", L"WQH", L"WQI", L"WQJ", L"WQK", L"WQL", L"WQM", L"WQN", L"WQO", L"WQP", L"WQQ", L"WQR", L"WQS", L"WQT", L"WQU", L"WQV", L"WQW", L"WQX", L"WQY", L"WQZ", L"WRA", L"WRB", L"WRC", L"WRD", L"WRE", L"WRF", L"WRG", L"WRH", L"WRI", L"WRJ", L"WRK", L"WRL", L"WRM", L"WRN", L"WRO", L"WRP", L"WRQ", L"WRR", L"WRS", L"WRT", L"WRU", L"WRV", L"WRW", L"WRX", L"WRY", L"WRZ", L"WSA", L"WSB", L"WSC", L"WSD", L"WSE", L"WSF", L"WSG", L"WSH", L"WSI", L"WSJ", L"WSK", L"WSL", L"WSM", L"WSN", L"WSO", L"WSP", L"WSQ", L"WSR", L"WSS", L"WST", L"WSU", L"WSV", L"WSW", L"WSX", L"WSY", L"WSZ", L"WTA", L"WTB", L"WTC", L"WTD", L"WTE", L"WTF", L"WTG", L"WTH", L"WTI", L"WTJ", L"WTK", L"WTL", L"WTM", L"WTN", L"WTO", L"WTP", L"WTQ", L"WTR", L"WTS", L"WTT", L"WTU", L"WTV", L"WTW", L"WTX", L"WTY", L"WTZ", L"WUA", L"WUB", L"WUC", L"WUD", L"WUE", L"WUF", L"WUG", L"WUH", L"WUI", L"WUJ", L"WUK", L"WUL", L"WUM", L"WUN", L"WUO", L"WUP", L"WUQ", L"WUR", L"WUS", L"WUT", L"WUU", L"WUV", L"WUW", L"WUX", L"WUY", L"WUZ", L"WVA", L"WVB", L"WVC", L"WVD", L"WVE", L"WVF", L"WVG", L"WVH", L"WVI", L"WVJ", L"WVK", L"WVL", L"WVM", L"WVN", L"WVO", L"WVP", L"WVQ", L"WVR", L"WVS", L"WVT", L"WVU", L"WVV", L"WVW", L"WVX", L"WVY", L"WVZ", + L"TQA", L"TQB", L"TQC", L"TQD", L"TQE", L"TQF", L"TQG", L"TQH", L"TQI", L"TQJ", L"TQK", L"TQL", L"TQM", L"TQN", L"TQO", L"TQP", L"TQQ", L"TQR", L"TQS", L"TQT", L"TQU", L"TQV", L"TQW", L"TQX", L"TQY", L"TQZ", L"TRA", L"TRB", L"TRC", L"TRD", L"TRE", L"TRF", L"TRG", L"TRH", L"TRI", L"TRJ", L"TRK", L"TRL", L"TRM", L"TRN", L"TRO", L"TRP", L"TRQ", L"TRR", L"TRS", L"TRT", L"TRU", L"TRV", L"TRW", L"TRX", L"TRY", L"TRZ", L"TSA", L"TSB", L"TSC", L"TSD", L"TSE", L"TSF", L"TSG", L"TSH", L"TSI", L"TSJ", L"TSK", L"TSL", L"TSM", L"TSN", L"TSO", L"TSP", L"TSQ", L"TSR", L"TSS", L"TST", L"TSU", L"TSV", L"TSW", L"TSX", L"TSY", L"TSZ", L"TTA", L"TTB", L"TTC", L"TTD", L"TTE", L"TTF", L"TTG", L"TTH", L"TTI", L"TTJ", L"TTK", L"TTL", L"TTM", L"TTN", L"TTO", L"TTP", L"TTQ", L"TTR", L"TTS", L"TTT", L"TTU", L"TTV", L"TTW", L"TTX", L"TTY", L"TTZ", L"TUA", L"TUB", L"TUC", L"TUD", L"TUE", L"TUF", L"TUG", L"TUH", L"TUI", L"TUJ", L"TUK", L"TUL", L"TUM", L"TUN", L"TUO", L"TUP", L"TUQ", L"TUR", L"TUS", L"TUT", L"TUU", L"TUV", L"TUW", L"TUX", L"TUY", L"TUZ", L"TVA", L"TVB", L"TVC", L"TVD", L"TVE", L"TVF", L"TVG", L"TVH", L"TVI", L"TVJ", L"TVK", L"TVL", L"TVM", L"TVN", L"TVO", L"TVP", L"TVQ", L"TVR", L"TVS", L"TVT", L"TVU", L"TVV", L"TVW", L"TVX", L"TVY", L"TVZ", L"TWA", L"TWB", L"TWC", L"TWD", L"TWE", L"TWF", L"TWG", L"TWH", L"TWI", L"TWJ", L"TWK", L"TWL", L"TWM", L"TWN", L"TWO", L"TWP", L"TWQ", L"TWR", L"TWS", L"TWT", L"TWU", L"TWV", L"TWW", L"TWX", L"TWY", L"TWZ", L"TXA", L"TXB", L"TXC", L"TXD", L"TXE", L"TXF", L"TXG", L"TXH", L"TXI", L"TXJ", L"TXK", L"TXL", L"TXM", L"TXN", L"TXO", L"TXP", L"TXQ", L"TXR", L"TXS", L"TXT", L"TXU", L"TXV", L"TXW", L"TXX", L"TXY", L"TXZ", L"TYA", L"TYB", L"TYC", L"TYD", L"TYE", L"TYF", L"TYG", L"TYH", L"TYI", L"TYJ", L"TYK", L"TYL", L"TYM", L"TYN", L"TYO", L"TYP", L"TYQ", L"TYR", L"TYS", L"TYT", L"TYU", L"TYV", L"TYW", L"TYX", L"TYY", L"TYZ", L"TZA", L"TZB", L"TZC", L"TZD", L"TZE", L"TZF", L"TZG", L"TZH", L"TZI", L"TZJ", L"TZK", L"TZL", L"TZM", L"TZN", L"TZO", L"TZP", L"TZQ", L"TZR", L"TZS", L"TZT", L"TZU", L"TZV", L"TZW", L"TZX", L"TZY", L"TZZ", L"UAA", L"UAB", L"UAC", L"UAD", L"UAE", L"UAF", L"UAG", L"UAH", L"UAI", L"UAJ", L"UAK", L"UAL", L"UAM", + L"UAN", L"UAO", L"UAP", L"UAQ", L"UAR", L"UAS", L"UAT", L"UAU", L"UAV", L"UAW", L"UAX", L"UAY", L"UAZ", L"UBA", L"UBB", L"UBC", L"UBD", L"UBE", L"UBF", L"UBG", L"UBH", L"UBI", L"UBJ", L"UBK", L"UBL", L"UBM", L"UBN", L"UBO", L"UBP", L"UBQ", L"UBR", L"UBS", L"UBT", L"UBU", L"UBV", L"UBW", L"UBX", L"UBY", L"UBZ", L"UCA", L"UCB", L"UCC", L"UCD", L"UCE", L"UCF", L"UCG", L"UCH", L"UCI", L"UCJ", L"UCK", L"UCL", L"UCM", L"UCN", L"UCO", L"UCP", L"UCQ", L"UCR", L"UCS", L"UCT", L"UCU", L"UCV", L"UCW", L"UCX", L"UCY", L"UCZ", L"UDA", L"UDB", L"UDC", L"UDD", L"UDE", L"UDF", L"UDG", L"UDH", L"UDI", L"UDJ", L"UDK", L"UDL", L"UDM", L"UDN", L"UDO", L"UDP", L"UDQ", L"UDR", L"UDS", L"UDT", L"UDU", L"UDV", L"UDW", L"UDX", L"UDY", L"UDZ", L"UEA", L"UEB", L"UEC", L"UED", L"UEE", L"UEF", L"UEG", L"UEH", L"UEI", L"UEJ", L"UEK", L"UEL", L"UEM", L"UEN", L"UEO", L"UEP", L"UEQ", L"UER", L"UES", L"UET", L"UEU", L"UEV", L"UEW", L"UEX", L"UEY", L"UEZ", L"UFA", L"UFB", L"UFC", L"UFD", L"UFE", L"UFF", L"UFG", L"UFH", L"UFI", L"UFJ", L"UFK", L"UFL", L"UFM", L"UFN", L"UFO", L"UFP", L"UFQ", L"UFR", L"UFS", L"UFT", L"UFU", L"UFV", L"UFW", L"UFX", L"UFY", L"UFZ", L"UGA", L"UGB", L"UGC", L"UGD", L"UGE", L"UGF", L"UGG", L"UGH", L"UGI", L"UGJ", L"UGK", L"UGL", L"UGM", L"UGN", L"UGO", L"UGP", L"UGQ", L"UGR", L"UGS", L"UGT", L"UGU", L"UGV", L"UGW", L"UGX", L"UGY", L"UGZ", L"UHA", L"UHB", L"UHC", L"UHD", L"UHE", L"UHF", L"UHG", L"UHH", L"UHI", L"UHJ", L"UHK", L"UHL", L"UHM", L"UHN", L"UHO", L"UHP", L"UHQ", L"UHR", L"UHS", L"UHT", L"UHU", L"UHV", L"UHW", L"UHX", L"UHY", L"UHZ", L"UIA", L"UIB", L"UIC", L"UID", L"UIE", L"UIF", L"UIG", L"UIH", L"UII", L"UIJ", L"UIK", L"UIL", L"UIM", L"UIN", L"UIO", L"UIP", L"UIQ", L"UIR", L"UIS", L"UIT", L"UIU", L"UIV", L"UIW", L"UIX", L"UIY", L"UIZ", L"UJA", L"UJB", L"UJC", L"UJD", L"UJE", L"UJF", L"UJG", L"UJH", L"UJI", L"UJJ", L"UJK", L"UJL", L"UJM", L"UJN", L"UJO", L"UJP", L"UJQ", L"UJR", L"UJS", L"UJT", L"UJU", L"UJV", L"UJW", L"UJX", L"UJY", L"UJZ", L"UKA", L"UKB", L"UKC", L"UKD", L"UKE", L"UKF", L"UKG", L"UKH", L"UKI", L"UKJ", L"UKK", L"UKL", L"UKM", L"UKN", L"UKO", L"UKP", L"UKQ", L"UKR", L"UKS", L"UKT", L"UKU", L"UKV", L"UKW", L"UKX", L"UKY", L"UKZ", + L"ULA", L"ULB", L"ULC", L"ULD", L"ULE", L"ULF", L"ULG", L"ULH", L"ULI", L"ULJ", L"ULK", L"ULL", L"ULM", L"ULN", L"ULO", L"ULP", L"ULQ", L"ULR", L"ULS", L"ULT", L"ULU", L"ULV", L"ULW", L"ULX", L"ULY", L"ULZ", L"UMA", L"UMB", L"UMC", L"UMD", L"UME", L"UMF", L"UMG", L"UMH", L"UMI", L"UMJ", L"UMK", L"UML", L"UMM", L"UMN", L"UMO", L"UMP", L"UMQ", L"UMR", L"UMS", L"UMT", L"UMU", L"UMV", L"UMW", L"UMX", L"UMY", L"UMZ", L"UNA", L"UNB", L"UNC", L"UND", L"UNE", L"UNF", L"UNG", L"UNH", L"UNI", L"UNJ", L"UNK", L"UNL", L"UNM", L"UNN", L"UNO", L"UNP", L"UNQ", L"UNR", L"UNS", L"UNT", L"UNU", L"UNV", L"UNW", L"UNX", L"UNY", L"UNZ", L"UOA", L"UOB", L"UOC", L"UOD", L"UOE", L"UOF", L"UOG", L"UOH", L"UOI", L"UOJ", L"UOK", L"UOL", L"UOM", L"UON", L"UOO", L"UOP", L"UOQ", L"UOR", L"UOS", L"UOT", L"UOU", L"UOV", L"UOW", L"UOX", L"UOY", L"UOZ", L"UPA", L"UPB", L"UPC", L"UPD", L"UPE", L"UPF", L"UPG", L"UPH", L"UPI", L"UPJ", L"UPK", L"UPL", L"UPM", L"UPN", L"UPO", L"UPP", L"UPQ", L"UPR", L"UPS", L"UPT", L"UPU", L"UPV", L"UPW", L"UPX", L"UPY", L"UPZ", L"UQA", L"UQB", L"UQC", L"UQD", L"UQE", L"UQF", L"UQG", L"UQH", L"UQI", L"UQJ", L"UQK", L"UQL", L"UQM", L"UQN", L"UQO", L"UQP", L"UQQ", L"UQR", L"UQS", L"UQT", L"UQU", L"UQV", L"UQW", L"UQX", L"UQY", L"UQZ", L"URA", L"URB", L"URC", L"URD", L"URE", L"URF", L"URG", L"URH", L"URI", L"URJ", L"URK", L"URL", L"URM", L"URN", L"URO", L"URP", L"URQ", L"URR", L"URS", L"URT", L"URU", L"URV", L"URW", L"URX", L"URY", L"URZ", L"USA", L"USB", L"USC", L"USD", L"USE", L"USF", L"USG", L"USH", L"USI", L"USJ", L"USK", L"USL", L"USM", L"USN", L"USO", L"USP", L"USQ", L"USR", L"USS", L"UST", L"USU", L"USV", L"USW", L"USX", L"USY", L"USZ", L"UTA", L"UTB", L"UTC", L"UTD", L"UTE", L"UTF", L"UTG", L"UTH", L"UTI", L"UTJ", L"UTK", L"UTL", L"UTM", L"UTN", L"UTO", L"UTP", L"UTQ", L"UTR", L"UTS", L"UTT", L"UTU", L"UTV", L"UTW", L"UTX", L"UTY", L"UTZ", L"UUA", L"UUB", L"UUC", L"UUD", L"UUE", L"UUF", L"UUG", L"UUH", L"UUI", L"UUJ", L"UUK", L"UUL", L"UUM", L"UUN", L"UUO", L"UUP", L"UUQ", L"UUR", L"UUS", L"UUT", L"UUU", L"UUV", L"UUW", L"UUX", L"UUY", L"UUZ", L"UVA", L"UVB", L"UVC", L"UVD", L"UVE", L"UVF", L"UVG", L"UVH", L"UVI", L"UVJ", L"UVK", L"UVL", L"UVM", + L"UVN", L"UVO", L"UVP", L"UVQ", L"UVR", L"UVS", L"UVT", L"UVU", L"UVV", L"UVW", L"UVX", L"UVY", L"UVZ", L"UWA", L"UWB", L"UWC", L"UWD", L"UWE", L"UWF", L"UWG", L"UWH", L"UWI", L"UWJ", L"UWK", L"UWL", L"UWM", L"UWN", L"UWO", L"UWP", L"UWQ", L"UWR", L"UWS", L"UWT", L"UWU", L"UWV", L"UWW", L"UWX", L"UWY", L"UWZ", L"UXA", L"UXB", L"UXC", L"UXD", L"UXE", L"UXF", L"UXG", L"UXH", L"UXI", L"UXJ", L"UXK", L"UXL", L"UXM", L"UXN", L"UXO", L"UXP", L"UXQ", L"UXR", L"UXS", L"UXT", L"UXU", L"UXV", L"UXW", L"UXX", L"UXY", L"UXZ", L"UYA", L"UYB", L"UYC", L"UYD", L"UYE", L"UYF", L"UYG", L"UYH", L"UYI", L"UYJ", L"UYK", L"UYL", L"UYM", L"UYN", L"UYO", L"UYP", L"UYQ", L"UYR", L"UYS", L"UYT", L"UYU", L"UYV", L"UYW", L"UYX", L"UYY", L"UYZ", L"UZA", L"UZB", L"UZC", L"UZD", L"UZE", L"UZF", L"UZG", L"UZH", L"UZI", L"UZJ", L"UZK", L"UZL", L"UZM", L"UZN", L"UZO", L"UZP", L"UZQ", L"UZR", L"UZS", L"UZT", L"UZU", L"UZV", L"UZW", L"UZX", L"UZY", L"UZZ", L"VAA", L"VAB", L"VAC", L"VAD", L"VAE", L"VAF", L"VAG", L"VAH", L"VAI", L"VAJ", L"VAK", L"VAL", L"VAM", L"VAN", L"VAO", L"VAP", L"VAQ", L"VAR", L"VAS", L"VAT", L"VAU", L"VAV", L"VAW", L"VAX", L"VAY", L"VAZ", L"VBA", L"VBB", L"VBC", L"VBD", L"VBE", L"VBF", L"VBG", L"VBH", L"VBI", L"VBJ", L"VBK", L"VBL", L"VBM", L"VBN", L"VBO", L"VBP", L"VBQ", L"VBR", L"VBS", L"VBT", L"VBU", L"VBV", L"VBW", L"VBX", L"VBY", L"VBZ", L"VCA", L"VCB", L"VCC", L"VCD", L"VCE", L"VCF", L"VCG", L"VCH", L"VCI", L"VCJ", L"VCK", L"VCL", L"VCM", L"VCN", L"VCO", L"VCP", L"VCQ", L"VCR", L"VCS", L"VCT", L"VCU", L"VCV", L"VCW", L"VCX", L"VCY", L"VCZ", L"VDA", L"VDB", L"VDC", L"VDD", L"VDE", L"VDF", L"VDG", L"VDH", L"VDI", L"VDJ", L"VDK", L"VDL", L"VDM", L"VDN", L"VDO", L"VDP", L"VDQ", L"VDR", L"VDS", L"VDT", L"VDU", L"VDV", L"VDW", L"VDX", L"VDY", L"VDZ", L"VEA", L"VEB", L"VEC", L"VED", L"VEE", L"VEF", L"VEG", L"VEH", L"VEI", L"VEJ", L"VEK", L"VEL", L"VEM", L"VEN", L"VEO", L"VEP", L"VEQ", L"VER", L"VES", L"VET", L"VEU", L"VEV", L"VEW", L"VEX", L"VEY", L"VEZ", L"VFA", L"VFB", L"VFC", L"VFD", L"VFE", L"VFF", L"VFG", L"VFH", L"VFI", L"VFJ", L"VFK", L"VFL", L"VFM", L"VFN", L"VFO", L"VFP", L"VFQ", L"VFR", L"VFS", L"VFT", L"VFU", L"VFV", L"VFW", L"VFX", L"VFY", L"VFZ", + L"VGA", L"VGB", L"VGC", L"VGD", L"VGE", L"VGF", L"VGG", L"VGH", L"VGI", L"VGJ", L"VGK", L"VGL", L"VGM", L"VGN", L"VGO", L"VGP", L"VGQ", L"VGR", L"VGS", L"VGT", L"VGU", L"VGV", L"VGW", L"VGX", L"VGY", L"VGZ", L"VHA", L"VHB", L"VHC", L"VHD", L"VHE", L"VHF", L"VHG", L"VHH", L"VHI", L"VHJ", L"VHK", L"VHL", L"VHM", L"VHN", L"VHO", L"VHP", L"VHQ", L"VHR", L"VHS", L"VHT", L"VHU", L"VHV", L"VHW", L"VHX", L"VHY", L"VHZ", L"VIA", L"VIB", L"VIC", L"VID", L"VIE", L"VIF", L"VIG", L"VIH", L"VII", L"VIJ", L"VIK", L"VIL", L"VIM", L"VIN", L"VIO", L"VIP", L"VIQ", L"VIR", L"VIS", L"VIT", L"VIU", L"VIV", L"VIW", L"VIX", L"VIY", L"VIZ", L"VJA", L"VJB", L"VJC", L"VJD", L"VJE", L"VJF", L"VJG", L"VJH", L"VJI", L"VJJ", L"VJK", L"VJL", L"VJM", L"VJN", L"VJO", L"VJP", L"VJQ", L"VJR", L"VJS", L"VJT", L"VJU", L"VJV", L"VJW", L"VJX", L"VJY", L"VJZ", L"VKA", L"VKB", L"VKC", L"VKD", L"VKE", L"VKF", L"VKG", L"VKH", L"VKI", L"VKJ", L"VKK", L"VKL", L"VKM", L"VKN", L"VKO", L"VKP", L"VKQ", L"VKR", L"VKS", L"VKT", L"VKU", L"VKV", L"VKW", L"VKX", L"VKY", L"VKZ", L"VLA", L"VLB", L"VLC", L"VLD", L"VLE", L"VLF", L"VLG", L"VLH", L"VLI", L"VLJ", L"VLK", L"VLL", L"VLM", L"VLN", L"VLO", L"VLP", L"VLQ", L"VLR", L"VLS", L"VLT", L"VLU", L"VLV", L"VLW", L"VLX", L"VLY", L"VLZ", L"VMA", L"VMB", L"VMC", L"VMD", L"VME", L"VMF", L"VMG", L"VMH", L"VMI", L"VMJ", L"VMK", L"VML", L"VMM", L"VMN", L"VMO", L"VMP", L"VMQ", L"VMR", L"VMS", L"VMT", L"VMU", L"VMV", L"VMW", L"VMX", L"VMY", L"VMZ", L"VNA", L"VNB", L"VNC", L"VND", L"VNE", L"VNF", L"VNG", L"VNH", L"VNI", L"VNJ", L"VNK", L"VNL", L"VNM", L"VNN", L"VNO", L"VNP", L"VNQ", L"VNR", L"VNS", L"VNT", L"VNU", L"VNV", L"VNW", L"VNX", L"VNY", L"VNZ", L"VOA", L"VOB", L"VOC", L"VOD", L"VOE", L"VOF", L"VOG", L"VOH", L"VOI", L"VOJ", L"VOK", L"VOL", L"VOM", L"VON", L"VOO", L"VOP", L"VOQ", L"VOR", L"VOS", L"VOT", L"VOU", L"VOV", L"VOW", L"VOX", L"VOY", L"VOZ", L"VPA", L"VPB", L"VPC", L"VPD", L"VPE", L"VPF", L"VPG", L"VPH", L"VPI", L"VPJ", L"VPK", L"VPL", L"VPM", L"VPN", L"VPO", L"VPP", L"VPQ", L"VPR", L"VPS", L"VPT", L"VPU", L"VPV", L"VPW", L"VPX", L"VPY", L"VPZ", L"VQA", L"VQB", L"VQC", L"VQD", L"VQE", L"VQF", L"VQG", L"VQH", L"VQI", L"VQJ", L"VQK", L"VQL", L"VQM", + L"VQN", L"VQO", L"VQP", L"VQQ", L"VQR", L"VQS", L"VQT", L"VQU", L"VQV", L"VQW", L"VQX", L"VQY", L"VQZ", L"VRA", L"VRB", L"VRC", L"VRD", L"VRE", L"VRF", L"VRG", L"VRH", L"VRI", L"VRJ", L"VRK", L"VRL", L"VRM", L"VRN", L"VRO", L"VRP", L"VRQ", L"VRR", L"VRS", L"VRT", L"VRU", L"VRV", L"VRW", L"VRX", L"VRY", L"VRZ", L"VSA", L"VSB", L"VSC", L"VSD", L"VSE", L"VSF", L"VSG", L"VSH", L"VSI", L"VSJ", L"VSK", L"VSL", L"VSM", L"VSN", L"VSO", L"VSP", L"VSQ", L"VSR", L"VSS", L"VST", L"VSU", L"VSV", L"VSW", L"VSX", L"VSY", L"VSZ", L"VTA", L"VTB", L"VTC", L"VTD", L"VTE", L"VTF", L"VTG", L"VTH", L"VTI", L"VTJ", L"VTK", L"VTL", L"VTM", L"VTN", L"VTO", L"VTP", L"VTQ", L"VTR", L"VTS", L"VTT", L"VTU", L"VTV", L"VTW", L"VTX", L"VTY", L"VTZ", L"VUA", L"VUB", L"VUC", L"VUD", L"VUE", L"VUF", L"VUG", L"VUH", L"VUI", L"VUJ", L"VUK", L"VUL", L"VUM", L"VUN", L"VUO", L"VUP", L"VUQ", L"VUR", L"VUS", L"VUT", L"VUU", L"VUV", L"VUW", L"VUX", L"VUY", L"VUZ", L"VVA", L"VVB", L"VVC", L"VVD", L"VVE", L"VVF", L"VVG", L"VVH", L"VVI", L"VVJ", L"VVK", L"VVL", L"VVM", L"VVN", L"VVO", L"VVP", L"VVQ", L"VVR", L"VVS", L"VVT", L"VVU", L"VVV", L"VVW", L"VVX", L"VVY", L"VVZ", L"VWA", L"VWB", L"VWC", L"VWD", L"VWE", L"VWF", L"VWG", L"VWH", L"VWI", L"VWJ", L"VWK", L"VWL", L"VWM", L"VWN", L"VWO", L"VWP", L"VWQ", L"VWR", L"VWS", L"VWT", L"VWU", L"VWV", L"VWW", L"VWX", L"VWY", L"VWZ", L"VXA", L"VXB", L"VXC", L"VXD", L"VXE", L"VXF", L"VXG", L"VXH", L"VXI", L"VXJ", L"VXK", L"VXL", L"VXM", L"VXN", L"VXO", L"VXP", L"VXQ", L"VXR", L"VXS", L"VXT", L"VXU", L"VXV", L"VXW", L"VXX", L"VXY", L"VXZ", L"VYA", L"VYB", L"VYC", L"VYD", L"VYE", L"VYF", L"VYG", L"VYH", L"VYI", L"VYJ", L"VYK", L"VYL", L"VYM", L"VYN", L"VYO", L"VYP", L"VYQ", L"VYR", L"VYS", L"VYT", L"VYU", L"VYV", L"VYW", L"VYX", L"VYY", L"VYZ", L"VZA", L"VZB", L"VZC", L"VZD", L"VZE", L"VZF", L"VZG", L"VZH", L"VZI", L"VZJ", L"VZK", L"VZL", L"VZM", L"VZN", L"VZO", L"VZP", L"VZQ", L"VZR", L"VZS", L"VZT", L"VZU", L"VZV", L"VZW", L"VZX", L"VZY", L"VZZ", L"WAA", L"WAB", L"WAC", L"WAD", L"WAE", L"WAF", L"WAG", L"WAH", L"WAI", L"WAJ", L"WAK", L"WAL", L"WAM", L"WAN", L"WAO", L"WAP", L"WAQ", L"WAR", L"WAS", L"WAT", L"WAU", L"WAV", L"WAW", L"WAX", L"WAY", L"WAZ", + L"WBA", L"WBB", L"WBC", L"WBD", L"WBE", L"WBF", L"WBG", L"WBH", L"WBI", L"WBJ", L"WBK", L"WBL", L"WBM", L"WBN", L"WBO", L"WBP", L"WBQ", L"WBR", L"WBS", L"WBT", L"WBU", L"WBV", L"WBW", L"WBX", L"WBY", L"WBZ", L"WCA", L"WCB", L"WCC", L"WCD", L"WCE", L"WCF", L"WCG", L"WCH", L"WCI", L"WCJ", L"WCK", L"WCL", L"WCM", L"WCN", L"WCO", L"WCP", L"WCQ", L"WCR", L"WCS", L"WCT", L"WCU", L"WCV", L"WCW", L"WCX", L"WCY", L"WCZ", L"WDA", L"WDB", L"WDC", L"WDD", L"WDE", L"WDF", L"WDG", L"WDH", L"WDI", L"WDJ", L"WDK", L"WDL", L"WDM", L"WDN", L"WDO", L"WDP", L"WDQ", L"WDR", L"WDS", L"WDT", L"WDU", L"WDV", L"WDW", L"WDX", L"WDY", L"WDZ", L"WEA", L"WEB", L"WEC", L"WED", L"WEE", L"WEF", L"WEG", L"WEH", L"WEI", L"WEJ", L"WEK", L"WEL", L"WEM", L"WEN", L"WEO", L"WEP", L"WEQ", L"WER", L"WES", L"WET", L"WEU", L"WEV", L"WEW", L"WEX", L"WEY", L"WEZ", L"WFA", L"WFB", L"WFC", L"WFD", L"WFE", L"WFF", L"WFG", L"WFH", L"WFI", L"WFJ", L"WFK", L"WFL", L"WFM", L"WFN", L"WFO", L"WFP", L"WFQ", L"WFR", L"WFS", L"WFT", L"WFU", L"WFV", L"WFW", L"WFX", L"WFY", L"WFZ", L"WGA", L"WGB", L"WGC", L"WGD", L"WGE", L"WGF", L"WGG", L"WGH", L"WGI", L"WGJ", L"WGK", L"WGL", L"WGM", L"WGN", L"WGO", L"WGP", L"WGQ", L"WGR", L"WGS", L"WGT", L"WGU", L"WGV", L"WGW", L"WGX", L"WGY", L"WGZ", L"WHA", L"WHB", L"WHC", L"WHD", L"WHE", L"WHF", L"WHG", L"WHH", L"WHI", L"WHJ", L"WHK", L"WHL", L"WHM", L"WHN", L"WHO", L"WHP", L"WHQ", L"WHR", L"WHS", L"WHT", L"WHU", L"WHV", L"WHW", L"WHX", L"WHY", L"WHZ", L"WIA", L"WIB", L"WIC", L"WID", L"WIE", L"WIF", L"WIG", L"WIH", L"WII", L"WIJ", L"WIK", L"WIL", L"WIM", L"WIN", L"WIO", L"WIP", L"WIQ", L"WIR", L"WIS", L"WIT", L"WIU", L"WIV", L"WIW", L"WIX", L"WIY", L"WIZ", L"WJA", L"WJB", L"WJC", L"WJD", L"WJE", L"WJF", L"WJG", L"WJH", L"WJI", L"WJJ", L"WJK", L"WJL", L"WJM", L"WJN", L"WJO", L"WJP", L"WJQ", L"WJR", L"WJS", L"WJT", L"WJU", L"WJV", L"WJW", L"WJX", L"WJY", L"WJZ", L"WKA", L"WKB", L"WKC", L"WKD", L"WKE", L"WKF", L"WKG", L"WKH", L"WKI", L"WKJ", L"WKK", L"WKL", L"WKM", L"WKN", L"WKO", L"WKP", L"WKQ", L"WKR", L"WKS", L"WKT", L"WKU", L"WKV", L"WKW", L"WKX", L"WKY", L"WKZ", L"WLA", L"WLB", L"WLC", L"WLD", L"WLE", L"WLF", L"WLG", L"WLH", L"WLI", L"WLJ", L"WLK", L"WLL", L"WLM", + L"WLN", L"WLO", L"WLP", L"WLQ", L"WLR", L"WLS", L"WLT", L"WLU", L"WLV", L"WLW", L"WLX", L"WLY", L"WLZ", L"WMA", L"WMB", L"WMC", L"WMD", L"WME", L"WMF", L"WMG", L"WMH", L"WMI", L"WMJ", L"WMK", L"WML", L"WMM", L"WMN", L"WMO", L"WMP", L"WMQ", L"WMR", L"WMS", L"WMT", L"WMU", L"WMV", L"WMW", L"WMX", L"WMY", L"WMZ", L"WNA", L"WNB", L"WNC", L"WND", L"WNE", L"WNF", L"WNG", L"WNH", L"WNI", L"WNJ", L"WNK", L"WNL", L"WNM", L"WNN", L"WNO", L"WNP", L"WNQ", L"WNR", L"WNS", L"WNT", L"WNU", L"WNV", L"WNW", L"WNX", L"WNY", L"WNZ", L"WOA", L"WOB", L"WOC", L"WOD", L"WOE", L"WOF", L"WOG", L"WOH", L"WOI", L"WOJ", L"WOK", L"WOL", L"WOM", L"WON", L"WOO", L"WOP", L"WOQ", L"WOR", L"WOS", L"WOT", L"WOU", L"WOV", L"WOW", L"WOX", L"WOY", L"WOZ", L"WPA", L"WPB", L"WPC", L"WPD", L"WPE", L"WPF", L"WPG", L"WPH", L"WPI", L"WPJ", L"WPK", L"WPL", L"WPM", L"WPN", L"WPO", L"WPP", L"WPQ", L"WPR", L"WPS", L"WPT", L"WPU", L"WPV", L"WPW", L"WPX", L"WPY", L"WPZ", L"WQA", L"WQB", L"WQC", L"WQD", L"WQE", L"WQF", L"WQG", L"WQH", L"WQI", L"WQJ", L"WQK", L"WQL", L"WQM", L"WQN", L"WQO", L"WQP", L"WQQ", L"WQR", L"WQS", L"WQT", L"WQU", L"WQV", L"WQW", L"WQX", L"WQY", L"WQZ", L"WRA", L"WRB", L"WRC", L"WRD", L"WRE", L"WRF", L"WRG", L"WRH", L"WRI", L"WRJ", L"WRK", L"WRL", L"WRM", L"WRN", L"WRO", L"WRP", L"WRQ", L"WRR", L"WRS", L"WRT", L"WRU", L"WRV", L"WRW", L"WRX", L"WRY", L"WRZ", L"WSA", L"WSB", L"WSC", L"WSD", L"WSE", L"WSF", L"WSG", L"WSH", L"WSI", L"WSJ", L"WSK", L"WSL", L"WSM", L"WSN", L"WSO", L"WSP", L"WSQ", L"WSR", L"WSS", L"WST", L"WSU", L"WSV", L"WSW", L"WSX", L"WSY", L"WSZ", L"WTA", L"WTB", L"WTC", L"WTD", L"WTE", L"WTF", L"WTG", L"WTH", L"WTI", L"WTJ", L"WTK", L"WTL", L"WTM", L"WTN", L"WTO", L"WTP", L"WTQ", L"WTR", L"WTS", L"WTT", L"WTU", L"WTV", L"WTW", L"WTX", L"WTY", L"WTZ", L"WUA", L"WUB", L"WUC", L"WUD", L"WUE", L"WUF", L"WUG", L"WUH", L"WUI", L"WUJ", L"WUK", L"WUL", L"WUM", L"WUN", L"WUO", L"WUP", L"WUQ", L"WUR", L"WUS", L"WUT", L"WUU", L"WUV", L"WUW", L"WUX", L"WUY", L"WUZ", L"WVA", L"WVB", L"WVC", L"WVD", L"WVE", L"WVF", L"WVG", L"WVH", L"WVI", L"WVJ", L"WVK", L"WVL", L"WVM", L"WVN", L"WVO", L"WVP", L"WVQ", L"WVR", L"WVS", L"WVT", L"WVU", L"WVV", L"WVW", L"WVX", L"WVY", L"WVZ", L"WWA", L"WWB", L"WWC", L"WWD", L"WWE", L"WWF", L"WWG", L"WWH", L"WWI", L"WWJ", L"WWK", L"WWL", L"WWM", L"WWN", L"WWO", L"WWP", L"WWQ", L"WWR", L"WWS", L"WWT", L"WWU", L"WWV", L"WWW", L"WWX", L"WWY", L"WWZ", L"WXA", L"WXB", L"WXC", L"WXD", L"WXE", L"WXF", L"WXG", L"WXH", L"WXI", L"WXJ", L"WXK", L"WXL", L"WXM", L"WXN", L"WXO", L"WXP", L"WXQ", L"WXR", L"WXS", L"WXT", L"WXU", L"WXV", L"WXW", L"WXX", L"WXY", L"WXZ", L"WYA", L"WYB", L"WYC", L"WYD", L"WYE", L"WYF", L"WYG", L"WYH", L"WYI", L"WYJ", L"WYK", L"WYL", L"WYM", L"WYN", L"WYO", L"WYP", L"WYQ", L"WYR", L"WYS", L"WYT", L"WYU", L"WYV", L"WYW", L"WYX", L"WYY", L"WYZ", L"WZA", L"WZB", L"WZC", L"WZD", L"WZE", L"WZF", L"WZG", L"WZH", L"WZI", L"WZJ", L"WZK", L"WZL", L"WZM", L"WZN", L"WZO", L"WZP", L"WZQ", L"WZR", L"WZS", L"WZT", L"WZU", L"WZV", L"WZW", L"WZX", L"WZY", L"WZZ", L"XAA", L"XAB", L"XAC", L"XAD", L"XAE", L"XAF", L"XAG", L"XAH", L"XAI", L"XAJ", L"XAK", L"XAL", L"XAM", L"XAN", L"XAO", L"XAP", L"XAQ", L"XAR", L"XAS", L"XAT", L"XAU", L"XAV", L"XAW", L"XAX", L"XAY", L"XAZ", L"XBA", L"XBB", L"XBC", L"XBD", L"XBE", L"XBF", L"XBG", L"XBH", L"XBI", L"XBJ", L"XBK", L"XBL", L"XBM", L"XBN", L"XBO", L"XBP", L"XBQ", L"XBR", L"XBS", L"XBT", L"XBU", L"XBV", L"XBW", L"XBX", L"XBY", L"XBZ", L"XCA", L"XCB", L"XCC", L"XCD", L"XCE", L"XCF", L"XCG", L"XCH", L"XCI", L"XCJ", L"XCK", L"XCL", L"XCM", L"XCN", L"XCO", L"XCP", L"XCQ", L"XCR", L"XCS", L"XCT", L"XCU", L"XCV", L"XCW", L"XCX", L"XCY", L"XCZ", L"XDA", L"XDB", L"XDC", L"XDD", L"XDE", L"XDF", L"XDG", L"XDH", L"XDI", L"XDJ", L"XDK", L"XDL", L"XDM", L"XDN", L"XDO", L"XDP", L"XDQ", L"XDR", L"XDS", L"XDT", L"XDU", L"XDV", L"XDW", L"XDX", L"XDY", L"XDZ", L"XEA", L"XEB", L"XEC", L"XED", L"XEE", L"XEF", L"XEG", L"XEH", L"XEI", L"XEJ", L"XEK", L"XEL", L"XEM", L"XEN", L"XEO", L"XEP", L"XEQ", L"XER", L"XES", L"XET", L"XEU", L"XEV", L"XEW", L"XEX", L"XEY", L"XEZ", L"XFA", L"XFB", L"XFC", L"XFD" }; //------------------------------------------------------------------------------ @@ -191,7 +191,7 @@ namespace OOX { boost::wregex r(L"([\\d]+)-([\\d]+)-([\\d]+)(?:T([\\d]+):([\\d]+):([\\d]+)(?:\\.([\\d]+))?)?"); boost::match_results res; - + if (boost::regex_match(Date, res, r)) { Value = 0; @@ -243,7 +243,7 @@ namespace OOX const boost::uint64_t m1 = t.total_milliseconds(); const boost::uint64_t m2 = day.total_milliseconds(); - Value += 1.0 * m1 / m2; + Value += 1.0 * m1 / m2; } return true; @@ -1021,7 +1021,7 @@ namespace OOX auto formula = dynamic_cast(obj.get()); m_sText = formula->formula.getAssembledFormula(); m_oRef.Init(); - m_oRef = formula->rfx.toString(); + m_oRef = formula->rfx.toString(); } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: @@ -1288,7 +1288,7 @@ namespace OOX { CData data_comment; data_comment.fromXML2(oReader); - + pComment->m_oText = data_comment.m_oRichText.GetPointerEmptyNullable(); } } @@ -1297,9 +1297,9 @@ namespace OOX { CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map>::iterator pFindRow = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); std::map::iterator pFind; @@ -1309,8 +1309,8 @@ namespace OOX } else { - int newCol = *iColIndex; - + int newCol = *iColIndex; + if (pFindRow != sheet->m_oSheetData->m_mapStyleMerges2003.end()) { CCell *pCurrentCell = sheet->m_oSheetData->m_arrItems.back()->m_arrItems.back(); // == this @@ -1438,7 +1438,7 @@ namespace OOX { std::map mapColsStyle; mapColsStyle.insert(std::make_pair(xlsx_flat->m_nLastReadCol, *m_oStyle)); - + sheet->m_oSheetData->m_mapStyleMerges2003.insert(std::make_pair(xlsx_flat->m_nLastReadRow + i + 1, mapColsStyle)); } else @@ -1450,13 +1450,13 @@ namespace OOX for (int i = 0; i < iAcross.get_value_or(0); ++i) { xlsx_flat->m_nLastReadCol++; - + CCell *pCell = new CCell(this->m_pMainDocument); pCell->m_oRef = getCellAddressA(xlsx_flat->m_nLastReadRow, xlsx_flat->m_nLastReadCol); pCell->m_oStyle = pFindContinues->first; pCell->m_oCol = xlsx_flat->m_nLastReadCol - 1; pCell->m_oRow = xlsx_flat->m_nLastReadRow; - + sheet->m_oSheetData->m_arrItems.back()->m_arrItems.push_back(pCell); } } @@ -1482,10 +1482,10 @@ namespace OOX void CCell::AfterRead() { CSharedStrings *pSharedStrings = NULL; - + CXlsx* xlsx = dynamic_cast(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); - + if (xlsx) { if (false == xlsx->m_arWorksheets.back()->m_bPrepareForBinaryWriter) return; @@ -1676,9 +1676,49 @@ namespace OOX oStream.Seek(nEnd); } + XLS::BaseObjectPtr CCell::toBin() + { + /* std::vector shared_formulas_locations_ref; + auto ptr(new XLSB::CELL(m_oRow.get(), shared_formulas_locations_ref)); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCellMetadata.IsInit() || m_oValueMetadata.IsInit()) + { + auto pCellMeta(new XLSB::CELLMETA); + ptr->m_CELLMETA = XLS::BaseObjectPtr{pCellMeta}; + if(m_oCellMetadata.IsInit()) + { + auto metadata(new XLSB::CellMeta); + pCellMeta->m_BrtCellMeta = XLS::BaseObjectPtr{metadata}; + metadata->icmb = m_oCellMetadata->GetValue(); + } + + if(m_oValueMetadata.IsInit()) + { + auto metadata(new XLSB::ValueMeta); + pCellMeta->m_BrtValueMeta = XLS::BaseObjectPtr{metadata}; + metadata->ivmb = m_oValueMetadata->GetValue(); + } + } + if(!m_oFormula.IsInit()) + { + auto sourcePtr(new XLSB::DATACELL); + ptr->m_source = XLS::BaseObjectPtr{sourcePtr}; + sourcePtr->m_Col = m_oCol.get(); + auto cellBase(new XLSB::CellBase); + sourcePtr->m_source = XLS::BaseObjectPtr{cellBase}; + XLSB::Cell oCell; + if(m_oShowPhonetic.IsInit()) + oCell.fPhShow = m_oShowPhonetic->GetValue(); + if(oCell.iStyleRef) + oCell.iStyleRef = m_oStyle.get(); + cellBase->cell = oCell; + }*/ + XLS::BaseObjectPtr objectPtr; + return objectPtr; + } void CCell::fromBin(XLS::BaseObjectPtr& obj) { - ReadAttributes(obj); + ReadAttributes(obj); } void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { @@ -1698,7 +1738,7 @@ namespace OOX WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:Index", iColIndex ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeAcross", iAcross ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:MergeDown", iDown ) - WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:ArrayRange", sArrayRange ) + WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:ArrayRange", sArrayRange ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:StyleID", sStyleId ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:HRef", sHyperlink ) @@ -1757,7 +1797,7 @@ namespace OOX BiffRecord* pSource = nullptr; XLSB::Cell oCell; if(pDATACELL != nullptr) - { + { m_oCol = pDATACELL->m_Col; pSource = static_cast(pDATACELL->m_source.get()); if(pSource != nullptr) @@ -1777,7 +1817,7 @@ namespace OOX } else if(pFMLACELL != nullptr) { - m_oCol = pFMLACELL->m_Col; + m_oCol = pFMLACELL->m_Col; pSource = static_cast(pFMLACELL->m_source.get()); if(pSource != nullptr) oCell = dynamic_cast(pSource)->cell; @@ -1905,7 +1945,7 @@ namespace OOX } } } - } + } } EElementType CCell::getType () const { @@ -2263,7 +2303,7 @@ namespace OOX if (xlsx_flat) { CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map>::iterator pFind = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); if (pFind != sheet->m_oSheetData->m_mapStyleMerges2003.end()) @@ -2296,6 +2336,69 @@ namespace OOX m_arrItems.push_back(pCell); }*/ } + XLS::BaseObjectPtr CRow::toBin() + { + std::vector shared_formulas_locations_ref; + auto ptr(new XLSB::Parenthesis_CELLTABLE(shared_formulas_locations_ref)); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto it = m_arrItems.begin(); it != m_arrItems.end();) + { + ptr->m_arCELL.push_back((*it)->toBin()); + it = m_arrItems.erase(it); + } + + if(m_oCollapsed.IsInit() || m_oCustomFormat.IsInit() || m_oCustomHeight.IsInit() || m_oHidden.IsInit() || m_oHt.IsInit() + || m_oOutlineLevel.IsInit() || m_oPh.IsInit() || m_oR.IsInit() || m_oS.IsInit() || m_oThickBot.IsInit() || m_oThickTop.IsInit()) + { + auto hdrPtr(new XLSB::RowHdr); + ptr->m_BrtRowHdr = XLS::BaseObjectPtr{hdrPtr}; + + if(m_oCollapsed.IsInit()) + hdrPtr->fCollapsed = m_oCollapsed->GetValue(); + + if(m_oCustomFormat.IsInit()) + hdrPtr->fGhostDirty = m_oCustomFormat->GetValue(); + + if(m_oCustomHeight.IsInit()) + hdrPtr->fUnsynced = m_oCustomHeight->GetValue(); + + if(m_oHidden.IsInit()) + hdrPtr->fDyZero = m_oHidden->GetValue(); + + if(m_oHt.IsInit()) + hdrPtr->miyRw = m_oHt->GetValue() * 20.; + + if(m_oOutlineLevel.IsInit()) + hdrPtr->iOutLevel = m_oOutlineLevel->GetValue(); + + if(m_oPh.IsInit()) + hdrPtr->fPhonetic = m_oPh->GetValue(); + + if(m_oR.IsInit()) + hdrPtr->rw = m_oR->GetValue() - 1; + + if(m_oS.IsInit()) + hdrPtr->ixfe_val = m_oS->GetValue(); + + if(m_oThickBot.IsInit()) + hdrPtr->fExDes = m_oThickBot->GetValue(); + + if(m_oThickTop.IsInit()) + hdrPtr->fExAsc = m_oThickTop->GetValue(); + } + + if(m_oDyDescent.IsInit()) + { + auto ptrAccel(new XLSB::ACCELLTABLE); + ptr->m_ACCELLTABLE = XLS::BaseObjectPtr{ptrAccel}; + auto ptrdescent(new XLSB::RwDescent); + ptrAccel->m_BrtRwDescent = XLS::BaseObjectPtr{ptrdescent}; + ptrdescent->dyDescent = m_oDyDescent->GetValue(); + } + + return objectPtr; + } void CRow::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType) { LONG nEnd = oStream.XlsbReadRecordLength() + oStream.GetPos(); @@ -2397,18 +2500,18 @@ namespace OOX { CRow *pCurrentRow = sheet->m_oSheetData->m_arrItems.back(); // == this sheet->m_oSheetData->m_arrItems.pop_back(); - + while (xlsx_flat->m_nLastReadRow < newRow) { xlsx_flat->m_nLastReadRow++; - + CRow *pRow = new CRow(m_pMainDocument); pRow->m_oR = xlsx_flat->m_nLastReadRow; sheet->m_oSheetData->m_arrItems.push_back(pRow); std::map>::iterator pFind = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); - + if (pFind != sheet->m_oSheetData->m_mapStyleMerges2003.end()) { sheet->m_oSheetData->StyleFromMapStyleMerges2003(pFind->second); @@ -2417,7 +2520,7 @@ namespace OOX } sheet->m_oSheetData->m_arrItems.push_back(pCurrentRow); pCurrentRow = NULL; - } + } xlsx_flat->m_nLastReadRow = newRow; } xlsx_flat->m_nLastReadCol = -1; @@ -2450,7 +2553,7 @@ namespace OOX { m_oHt.Init(); m_oHt->SetValue(atof(oReader.GetTextChar())); - + m_oCustomHeight.Init(); m_oCustomHeight->SetValue(SimpleTypes::onoffTrue); } @@ -2602,7 +2705,7 @@ namespace OOX return; CXlsx* xlsx = dynamic_cast(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); - + if(xlsx) { xlsx->m_nLastReadRow = 0; @@ -2671,11 +2774,11 @@ namespace OOX pWorksheet->m_oCols.Init(); } - pWorksheet->m_oCols->m_arrItems.push_back(pColumn); + pWorksheet->m_oCols->m_arrItems.push_back(pColumn); pColumn->m_oMin.Init(); pColumn->m_oMin->SetValue(pWorksheet->m_oCols->m_arrItems.size()); - + pColumn->m_oMax.Init(); pColumn->m_oMax->SetValue(pWorksheet->m_oCols->m_arrItems.size()); } @@ -2687,7 +2790,7 @@ namespace OOX { CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* pWorksheet = xlsx_flat->m_arWorksheets.back(); pWorksheet->m_oSheetFormatPr.Init(); @@ -2848,6 +2951,19 @@ namespace OOX m_arrItems.push_back(pRow); }*/ } + XLS::BaseObjectPtr CSheetData::toBin() + { + auto ptr(new XLSB::CELLTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto it = m_arrItems.begin(); it != m_arrItems.end();) + { + ptr->m_arParenthesis_CELLTABLE.push_back((*it)->toBin()); + it = m_arrItems.erase(it); + } + + return objectPtr; + } EElementType CSheetData::getType () const { return et_x_SheetData; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 5bf61bfa7fd..45f0edb0bc7 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -216,6 +216,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, _UINT32 nRow); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -237,7 +238,7 @@ namespace OOX void ReadComment(XmlUtils::CXmlLiteReader& oReader, CCommentItem* pComment); void AfterRead(); - //----------- 2003 + //----------- 2003 void After2003Read(); nullable pCommentItem; @@ -260,7 +261,7 @@ namespace OOX nullable m_oFormula; nullable m_oRichText; nullable m_oValue; -//----------------------------- +//----------------------------- nullable_string m_oCacheValue; }; @@ -282,8 +283,9 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromXMLToXLSB(XmlUtils::CXmlLiteReader& oReader, NSBinPptxRW::CXlsbBinaryWriter& oStream, CCellXLSB& oCell); void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType); - void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; + void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -325,11 +327,12 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; - + nullable m_oXlsbPos; - + std::map> m_mapStyleMerges2003; // map(row, map(col, style)) void StyleFromMapStyleMerges2003(std::map &mapStyleMerges); void AfterRead(); From 7aa61809a6a6c19d693ccf1f112c839bc52c6d3b Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Mon, 7 Aug 2023 22:33:23 +0600 Subject: [PATCH 101/794] corrected conversion --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 12 ++++++++++++ X2tConverter/src/ASCConverters.cpp | 1 + 2 files changed, 13 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index d45534798ed..5215be725d1 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1924,16 +1924,28 @@ namespace OOX if(m_oOddHeader.IsInit()) castedBegin->stHeader = m_oOddHeader->m_sText; + else + castedBegin->stHeader = false; if(m_oOddFooter.IsInit()) castedBegin->stFooter = m_oOddFooter->m_sText; + else + castedBegin->stFooter = false; if(m_oEvenHeader.IsInit()) castedBegin->stHeaderEven = m_oEvenHeader->m_sText; + else + castedBegin->stHeaderEven = false; if(m_oEvenFooter.IsInit()) castedBegin->stFooterEven = m_oEvenFooter->m_sText; + else + castedBegin->stFooterEven = false; if(m_oFirstHeader.IsInit()) castedBegin->stHeaderFirst = m_oFirstHeader->m_sText; + else + castedBegin->stHeaderFirst = false; if(m_oFirstFooter.IsInit()) castedBegin->stFooterFirst = m_oFirstFooter->m_sText; + else + castedBegin->stFooterFirst = false; return objectPtr; } EElementType CHeaderFooter::getType() const diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index e4996a4d3e7..50964955d76 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1156,6 +1156,7 @@ namespace NExtractTools const OOX::CPath oox_path(sFrom); OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; oXlsb.Read(oox_path); OOX::CContentTypes oContentTypes; From 1f79847c78b1ddd9846d5240989b377c2b5f153d Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Mon, 7 Aug 2023 22:35:15 +0600 Subject: [PATCH 102/794] added xlsb type changing --- OOXML/XlsxFormat/Workbook/Workbook.cpp | 7 +++++++ OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 077845f7fd6..56f93865390 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -487,6 +487,13 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> } const OOX::FileType CWorkbook::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::FileType(L"xl", L"workbook.bin", + L"application/vnd.ms-excel.sheet.binary.macroEnabled.main", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); + } if (m_bMacroEnabled) return OOX::Spreadsheet::FileTypes::WorkbookMacro; else return OOX::Spreadsheet::FileTypes::Workbook; } diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index edffbe2b46f..5db748e55f6 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -823,6 +823,14 @@ mc:Ignorable=\"x14ac\">"); } const OOX::FileType CWorksheet::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::FileType(L"worksheets", L"sheet.bin", + L"application/vnd.ms-excel.worksheet", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", + L"worksheets/sheet", true); + } return m_bIsChartSheet?OOX::Spreadsheet::FileTypes::Chartsheets:OOX::Spreadsheet::FileTypes::Worksheet; } const CPath CWorksheet::DefaultDirectory() const From 6afb01da00d5b30fbbddcff46a49a898517d401b Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 8 Aug 2023 10:06:13 +0300 Subject: [PATCH 103/794] ParagraphStyle Fix --- DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index c4392263aa8..c1aee72166c 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -133,7 +133,7 @@ namespace NSDocxRenderer } //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 6; + lCalculatedSpacing -= 2; if (lCalculatedSpacing != 0) { diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp index 81c1bc8acb7..d5d62a1ae39 100644 --- a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -34,7 +34,7 @@ namespace NSDocxRenderer bool isHeading = true; for(auto& val : oParagraph.m_arLines[0]->m_arConts) - if(val->m_pFontStyle->dFontSize <= m_dAvgFontSize && !val->m_pFontStyle->bBold) + if(val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold) isHeading = false; return isHeading ? L"Heading1" : L"Normal"; From fd81de66bfb8769ff035fda1bb98baa92ff21c33 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Tue, 8 Aug 2023 13:55:00 +0600 Subject: [PATCH 104/794] corrected file types --- OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h | 2 +- OOXML/XlsxFormat/Workbook/Workbook.cpp | 6 +++--- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h index e6e53f35b39..d2a3471bc48 100644 --- a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h +++ b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h @@ -31,7 +31,7 @@ */ #pragma once -#include "../DocxFormat/FileType.h" +#include "../../DocxFormat/FileType.h" namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 56f93865390..d98296dce78 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -49,6 +49,8 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -490,9 +492,7 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"> CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - return OOX::FileType(L"xl", L"workbook.bin", - L"application/vnd.ms-excel.sheet.binary.macroEnabled.main", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); + return OOX::SpreadsheetBin::FileTypes::WorkbookBin; } if (m_bMacroEnabled) return OOX::Spreadsheet::FileTypes::WorkbookMacro; else return OOX::Spreadsheet::FileTypes::Workbook; diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 5db748e55f6..221a81170d1 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -49,6 +49,8 @@ #include "../../XlsbFormat/Biff12_unions/HLINKS.h" #include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -826,10 +828,7 @@ mc:Ignorable=\"x14ac\">"); CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - return OOX::FileType(L"worksheets", L"sheet.bin", - L"application/vnd.ms-excel.worksheet", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", - L"worksheets/sheet", true); + return OOX::SpreadsheetBin::FileTypes::WorksheetBin; } return m_bIsChartSheet?OOX::Spreadsheet::FileTypes::Chartsheets:OOX::Spreadsheet::FileTypes::Worksheet; } From 4ebbfad654a651e354dc4463fcb24bf6fa3c2383 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 8 Aug 2023 12:05:01 +0300 Subject: [PATCH 105/794] Fix spacing in different cconts --- DocxRenderer/src/logic/elements/TextLine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 1c4b118a9a4..0de979d455b 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -111,14 +111,14 @@ namespace NSDocxRenderer if (pFirst->GetNumberOfFeatures() <= pCurrent->GetNumberOfFeatures()) { pFirst->m_oText += L" "; - pFirst->m_dWidth += pFirst->m_dSpaceWidthMM; + pFirst->m_dWidth += (pCurrent->m_dLeft - pFirst->m_dRight); } else { NSStringUtils::CStringUTF32 oNewText = L" "; oNewText += pCurrent->m_oText; pCurrent->m_oText = oNewText; - pCurrent->m_dWidth += pCurrent->m_dSpaceWidthMM; + pCurrent->m_dWidth += (pCurrent->m_dLeft - pFirst->m_dRight); } } From f7ecbf8ddbcf726e8802366304286e80c280c876 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Thu, 10 Aug 2023 15:42:33 +0600 Subject: [PATCH 106/794] added Ccell conversion --- OOXML/XlsbFormat/Xlsb.cpp | 14 +- OOXML/XlsxFormat/Workbook/Workbook.cpp | 3 + OOXML/XlsxFormat/Worksheets/SheetData.cpp | 260 ++++++++++++++++++++-- 3 files changed, 256 insertions(+), 21 deletions(-) diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 442a9dcdef1..4da4dba54d2 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -62,12 +62,12 @@ using namespace XLS; OOX::Spreadsheet::CXlsb::~CXlsb() { -} +} void OOX::Spreadsheet::CXlsb::init() { workbook_code_page = XLS::WorkbookStreamObject::DefaultCodePage; xls_global_info = boost::shared_ptr(new XLS::GlobalWorkbookInfo(workbook_code_page, nullptr)); - xls_global_info->Version = 0x0800; + xls_global_info->Version = 0x0800; m_binaryReader = boost::shared_ptr(new NSBinPptxRW::CBinaryFileReader); m_binaryWriter = boost::shared_ptr(new NSBinPptxRW::CXlsbBinaryWriter); m_bWriteToXlsx = false; @@ -101,6 +101,8 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oDirPath, OOX::CContentTypes return false; m_bWriteToXlsb = true; + PrepareWorkbook(); + IFileContainer::Write(oDirPath / L"", OOX::CPath(_T("")), oContentTypes); oContentTypes.Write(oDirPath); @@ -114,7 +116,7 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* XLS::StreamCacheWriterPtr writer(new XLS::BinaryStreamCacheWriter(m_binaryWriter, xls_global_info)); XLS::BinWriterProcessor proc(writer, objStream); proc.mandatory(*objStream); - + m_binaryWriter->WriteFile(m_binaryWriter->GetBuffer(), (static_cast(m_binaryWriter.get()))->GetPosition()); m_binaryWriter->CloseFile(); @@ -181,7 +183,7 @@ void OOX::Spreadsheet::CXlsb::ReadSheetData() if(dataFindPair != m_mapSheetNameSheetData.end()) dataPosition = dataFindPair->second; - else + else continue; NSFile::CFileBinary oFile; @@ -286,10 +288,10 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() for(size_t i = 0, length = oTableColumns->m_arrItems.size(); i < length; ++i) { - auto& oTableColumn = oTableColumns->m_arrItems[i]; + auto& oTableColumn = oTableColumns->m_arrItems[i]; if(oTableColumn->m_oCalculatedColumnFormula.IsInit()) - { + { lambdaFormula(oTableColumn->m_oCalculatedColumnFormula.get()); } if(oTableColumn->m_oTotalsRowFormula.IsInit()) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index d98296dce78..e5a038513d1 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -317,6 +317,9 @@ namespace OOX { auto ptr(new XLSB::FileVersion); ptr->stAppName = m_oAppName.get(); + ptr->stLastEdited = L""; + ptr->stLowestEdited = L""; + ptr->stRupBuild = L""; workBookStream->m_BrtFileVersion = XLS::BaseObjectPtr{ptr}; } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index e533ec0d150..0db738f9eda 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1678,8 +1678,12 @@ namespace OOX } XLS::BaseObjectPtr CCell::toBin() { - /* std::vector shared_formulas_locations_ref; - auto ptr(new XLSB::CELL(m_oRow.get(), shared_formulas_locations_ref)); + std::vector shared_formulas_locations_ref; + auto ptr(new XLSB::CELL(0, shared_formulas_locations_ref)); + if(m_oRow.IsInit()) + { + ptr->m_Row = m_oRow.get(); + } XLS::BaseObjectPtr objectPtr(ptr); if(m_oCellMetadata.IsInit() || m_oValueMetadata.IsInit()) { @@ -1699,21 +1703,247 @@ namespace OOX metadata->ivmb = m_oValueMetadata->GetValue(); } } + + XLSB::DATACELL* pDATACELL = nullptr; + XLSB::TABLECELL* pTABLECELL = nullptr; + XLSB::FMLACELL* pFMLACELL = nullptr; + XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; + BiffRecord* pSource = nullptr; + + if(!m_oType.IsInit()) + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } + switch (m_oType->GetValue()) + { + case SimpleTypes::Spreadsheet::celltypeNumber: + { + auto pCellRk = new(XLSB::CellRk); + if( m_oValue->m_sText.find('.') == std::string::npos) + { + pCellRk->value.fInt = 1; + pCellRk->value.fX100 = 0; + pCellRk->value.num = std::stoi(m_oValue->m_sText); + } + else + { + pCellRk->value.fInt = 0; + pCellRk->value.fX100 = 1; + pCellRk->value.num = std::stod(m_oValue->m_sText) * 100; + } + pSource = pCellRk; + } + break; + case SimpleTypes::Spreadsheet::celltypeError: + { + if (m_oValue->m_sText == L"#NULL!") + { if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x00; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x00; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#DIV/0!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x07; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x07; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#REF!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x17; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x17; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#NAME?") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x1D; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x1D; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#NUM!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x24; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x24; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#N/A") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x2A; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x2A; + pSource = error; + } + } + else if (m_oValue->m_sText == L"#GETTING_DATA") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x2B; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x2B; + pSource = error; + } + } + } + break; + case SimpleTypes::Spreadsheet::celltypeBool: + { + if(m_oFormula.IsInit()) + { + auto cellBool(new XLSB::FmlaBool); + pSource = cellBool; + cellBool->value = m_oValue->m_sText == L"1" ? true : false; + } + else + { + auto cellBool(new XLSB::CellBool); + pSource = cellBool; + cellBool->value = m_oValue->m_sText == L"1" ? true : false; + } + } + break; + case SimpleTypes::Spreadsheet::celltypeSharedString: + { + auto pCellIsst(new XLSB::CellIsst); + pCellIsst->value = std::stoi(m_oValue->m_sText); + pSource = pCellIsst; + } + break; + case SimpleTypes::Spreadsheet::celltypeInlineStr: + case SimpleTypes::Spreadsheet::celltypeStr: + { + if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + pSource = str; + + } + else + { + auto str(new XLSB::CellSt); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + pSource = str; + } + } + break; + } + if(!m_oFormula.IsInit()) { - auto sourcePtr(new XLSB::DATACELL); - ptr->m_source = XLS::BaseObjectPtr{sourcePtr}; - sourcePtr->m_Col = m_oCol.get(); - auto cellBase(new XLSB::CellBase); - sourcePtr->m_source = XLS::BaseObjectPtr{cellBase}; - XLSB::Cell oCell; - if(m_oShowPhonetic.IsInit()) - oCell.fPhShow = m_oShowPhonetic->GetValue(); - if(oCell.iStyleRef) - oCell.iStyleRef = m_oStyle.get(); - cellBase->cell = oCell; - }*/ - XLS::BaseObjectPtr objectPtr; + pDATACELL = new(XLSB::DATACELL); + ptr->m_source = XLS::BaseObjectPtr{pDATACELL}; + pDATACELL->m_source = XLS::BaseObjectPtr{pSource}; + } + else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeDataTable) + { + pTABLECELL = new(XLSB::TABLECELL); + ptr->m_source = XLS::BaseObjectPtr{pTABLECELL}; + //pFMLACELL->m_source = m_oFormula->toBin(); + pTABLECELL->m_source = XLS::BaseObjectPtr{pSource}; + } + else + { + std::vector ref; + pFMLACELL = new XLSB::FMLACELL(0, ref); + + if(m_oRef.IsInit()) + { + pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, ref); + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; + ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; + } + if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeShared) + { + + if(!m_oRef.IsInit()) + { + //pFMLACELL->m_source = m_oFormula->toBin(); + if(m_oFormula->m_oSi.IsInit()) + pFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); + pFMLACELL->isShared = true; + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + } + else + { + if(m_oFormula->m_oSi.IsInit()) + pSHRFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); + //pSHRFMLACELL->m_source = m_oFormula->toBin(); + } + } + else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeNormal) + { + std::vector ref; + pFMLACELL = new XLSB::FMLACELL(0, ref); + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + //pFMLACELL->m_source = m_oFormula->toBin(); + } + + else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeArray) + { + //pSHRFMLACELL->m_source = m_oFormula->toBin(); + } + } + return objectPtr; } void CCell::fromBin(XLS::BaseObjectPtr& obj) From bc5ab2719c9fb4c82d86825aefef976c7c232863 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 10 Aug 2023 14:37:30 +0300 Subject: [PATCH 107/794] Remove unused files --- DocxRenderer/src/logic/ElementContText.cpp | 534 --------------------- DocxRenderer/src/logic/ElementContText.h | 85 ---- DocxRenderer/src/logic/ElementShape.h | 94 ---- DocxRenderer/src/logic/ImageManager.h | 88 ---- DocxRenderer/src/logic/elements/OldShape.h | 44 -- 5 files changed, 845 deletions(-) delete mode 100644 DocxRenderer/src/logic/ElementContText.cpp delete mode 100644 DocxRenderer/src/logic/ElementContText.h delete mode 100644 DocxRenderer/src/logic/ElementShape.h delete mode 100644 DocxRenderer/src/logic/ImageManager.h delete mode 100644 DocxRenderer/src/logic/elements/OldShape.h diff --git a/DocxRenderer/src/logic/ElementContText.cpp b/DocxRenderer/src/logic/ElementContText.cpp deleted file mode 100644 index 712994ae30e..00000000000 --- a/DocxRenderer/src/logic/ElementContText.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include "ElementContText.h" -#include "../resources/ColorTable.h" -#include "../resources/SingletonTemplate.h" -#include "../resources/utils.h" - -namespace NSDocxRenderer -{ - CContText::CContText(CFontManagerLight& oManagerLight): CBaseItem(ElemType::etContText), - m_pManagerLight(&oManagerLight) - { - } - - void CContText::Clear() - { - } - - CContText::CContText(const CContText& oSrc): CBaseItem(ElemType::etContText) - { - *this = oSrc; - } - - CContText& CContText::operator=(const CContText& oSrc) - { - if (this == &oSrc) - { - return *this; - } - - CBaseItem::operator=(oSrc); - - m_oFont = oSrc.m_oFont; - m_oBrush = oSrc.m_oBrush; - - m_strPickFontName = oSrc.m_strPickFontName; - m_lPickFontStyle = oSrc.m_lPickFontStyle; - - m_oText = oSrc.m_oText; - - m_dBaselineOffset = oSrc.m_dBaselineOffset; - m_dLastX = oSrc.m_dLastX; - m_dSpaceWidthMM = oSrc.m_dSpaceWidthMM; - - m_bIsNeedSpace = oSrc.m_bIsNeedSpace; - m_bIsDoubleStrikeout = oSrc.m_bIsDoubleStrikeout; - m_bIsHighlightPresent = oSrc.m_bIsHighlightPresent; - m_lHighlightColor = oSrc.m_lHighlightColor; - - m_eUnderlineType = oSrc.m_eUnderlineType; - m_lUnderlineColor = oSrc.m_lUnderlineColor; - - m_eVertAlignType = oSrc.m_eVertAlignType; - - m_bIsShadowPresent = oSrc.m_bIsShadowPresent; - m_bIsOutlinePresent = oSrc.m_bIsOutlinePresent; - m_bIsEmbossPresent = oSrc.m_bIsEmbossPresent; - m_bIsEngravePresent = oSrc.m_bIsEngravePresent; - - m_pShape = oSrc.m_pShape; - m_pManagerLight = oSrc.m_pManagerLight; - m_pCont = oSrc.m_pCont; -#if USING_DELETE_DUPLICATING_CONTS == 0 - m_pDuplicateCont = oSrc.m_pDuplicateCont; -#endif - - return *this; - } - - double CContText::GetIntersect(const CContText* oSrc) const - { - double d1 = std::max(m_dLeft, oSrc->m_dLeft); - double d2 = std::min(m_dLeft + m_dWidth, oSrc->m_dLeft + oSrc->m_dWidth); - - if (d2 > d1) - return d2 - d1; - return 0; - } - - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); //отключение проверки орфографии - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - oWriter.WriteString(L""); - if (m_oFont.Italic) - oWriter.WriteString(L""); - - if (m_bIsNeedSpace) - { - m_dWidth += m_dSpaceWidthMM; - m_oText += L" "; - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - oWriter.WriteString(L""); - if (0x02 == (0x02 & m_lPickFontStyle)) - oWriter.WriteString(L""); - - if (m_bIsNeedSpace) - { - m_dWidth += m_pManagerLight->GetSpaceWidth(); - m_oText += L" "; - } - - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - // нужно перемерять... - double ___dSize = (double)(static_cast(m_oFont.Size * 2)) / 2; - m_pManagerLight->LoadFont(m_strPickFontName, m_lPickFontStyle, ___dSize, false); - double dWidth = m_pManagerLight->MeasureStringWidth(m_oText.ToStdWString()); - - double dSpacing = (m_dWidth - dWidth) / (m_oText.length() + 1); - dSpacing *= c_dMMToDx; - - LONG lSpacing = static_cast(dSpacing); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - - if (lSpacing != 0) - { - oWriter.WriteString(L""); - } - } - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L""); - } - } - - int lSize = static_cast(2 * m_oFont.Size); - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L""); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L""); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Strikeout == TRUE) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_oFont.Underline == TRUE) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent) - { - ColorTable& colorTable = SingletonInstance(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold && bIsNeedSaveFormat) - oWriter.WriteString(L""); - if (m_oFont.Italic && bIsNeedSaveFormat) - oWriter.WriteString(L""); - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L""); - if (0x02 == (0x02 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L""); - - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - int lSize = (int)(2 * m_oFont.Size); - oWriter.WriteString(L""); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - - LONG lSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - if (lSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Strikeout == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_oFont.Underline == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - ColorTable& colorTable = SingletonInstance(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L" "); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddSpaceToEnd() - { - m_bIsNeedSpace = true; - m_dWidth += m_dSpaceWidthMM; - } - - bool CContText::IsEqual(const CContText* oSrc) - { - //todo Скорее всего это временное решение - bool bIf1 = true; //m_strPickFontName == oSrc->m_strPickFontName; - bool bIf2 = m_eUnderlineType == oSrc->m_eUnderlineType; - bool bIf3 = m_lUnderlineColor == oSrc->m_lUnderlineColor; - bool bIf4 = m_bIsHighlightPresent == oSrc->m_bIsHighlightPresent; - bool bIf5 = m_lHighlightColor == oSrc->m_lHighlightColor; - bool bIf6 = m_bIsDoubleStrikeout == oSrc->m_bIsDoubleStrikeout; - bool bIf7 = m_bIsShadowPresent == oSrc->m_bIsShadowPresent; - bool bIf8 = m_pShape == oSrc->m_pShape; - bool bIf9 = m_oFont.Name == L"" || oSrc->m_oFont.Name == L"" ? true : m_oFont.IsEqual(&oSrc->m_oFont); - bool bIf10 = m_oBrush.IsEqual(&oSrc->m_oBrush); - - if (bIf1 && bIf2 && bIf3 && bIf4 && bIf5 && bIf6 && bIf7 && bIf8 && bIf9 && bIf10) - /*if( m_strPickFontName == oSrc->m_strPickFontName && - m_eUnderlineType == oSrc->m_eUnderlineType && - m_lUnderlineColor == oSrc->m_lUnderlineColor && - m_bIsHighlightPresent == oSrc->m_bIsHighlightPresent && - m_lHighlightColor == oSrc->m_lHighlightColor && - m_bIsDoubleStrikeout == oSrc->m_bIsDoubleStrikeout && - m_bIsShadowPresent == oSrc->m_bIsShadowPresent && - //m_eVertAlignType == oSrc->m_eVertAlignType && - m_pShape == oSrc->m_pShape && - m_oFont.IsEqual(&oSrc->m_oFont) && - m_oBrush.IsEqual(&oSrc->m_oBrush))*/ - { - return true; - } - return false; - } - - bool CContText::IsDuplicate(CContText* pCont, const eVerticalCrossingType& eVType) - { - if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) - { -#if USING_DELETE_DUPLICATING_CONTS - pCont->m_bIsNotNecessaryToUse = true; -#else - //В итоге собираем список дубликатов - if (!m_pDuplicateCont) - { - m_pDuplicateCont = pCont; - } - return true; -#endif - } - return false; - } - - bool CContText::IsThereAreFontEffects(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; //текущий cont ниже - //Условие пересечения по горизонтали - bool bIf3 = eHType == eHorizontalCrossingType::hctCurrentLeftOfNext; //текущий cont левее - bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее - //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_oFont.Size == pCont->m_oFont.Size; - bool bIf6 = m_oText == pCont->m_oText; - //Цвет тени должен быть серым - bool bIf7 = m_oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_oBrush.Color1 == c_iGreyColor2; - - //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами - //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. - if (bIf5 && bIf6) - { - if (m_bIsEmbossPresent && bIf11) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - if (m_bIsEngravePresent && bIf9) - { - if (bIf2 && bIf4) - { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - } - - //Shadow - if (bIf1 && bIf3 && bIf8) - { - m_bIsShadowPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - else if (bIf2 && bIf4 && bIf7) - { - pCont->m_bIsShadowPresent = true; - m_bIsNotNecessaryToUse = true; - return true; - } - - //Emboss - else if (bIf2 && bIf4 && bIf10) - { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - //Engrave - else if (bIf2 && bIf4 && bIf12) - { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; - return true; - } - } - return false; - } - - bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType) - { - //Условие пересечения по вертикали - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || - eVType == eVerticalCrossingType::vctCurrentInsideNext; - bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; - //Условие пересечения по горизонтали - bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && - fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; - bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || - eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && - fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; - //Размеры шрифта должны бать разными - bool bIf5 = m_oFont.Size * 0.7 > pCont->m_oFont.Size; - bool bIf6 = m_oFont.Size < pCont->m_oFont.Size * 0.7; - - if (bIf3 || bIf4) - { - if (bIf1 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf2 && bIf5) - { - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; - return true; - } - else if (bIf1 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - else if (bIf2 && bIf6) - { - m_eVertAlignType = eVertAlignType::vatSubscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; - return true; - } - } - return false; - } -} diff --git a/DocxRenderer/src/logic/ElementContText.h b/DocxRenderer/src/logic/ElementContText.h deleted file mode 100644 index 9c4f60c2528..00000000000 --- a/DocxRenderer/src/logic/ElementContText.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include "BaseItem.h" -#include "../DesktopEditor/common/StringBuilder.h" -#include "FontManager.h" -#include "../resources/Constants.h" -#include "../resources/LinesTable.h" - - -namespace NSDocxRenderer -{ - class CShape; - - enum class eVertAlignType - { - vatUnknown, - vatBase, - vatSubscript, - vatSuperscript - }; - - class CContText : public CBaseItem - { - public: - NSStructures::CFont m_oFont; - NSStructures::CBrush m_oBrush; - - std::wstring m_strPickFontName {L""}; - LONG m_lPickFontStyle {0}; - - NSStringUtils::CStringUTF32 m_oText; - - double m_dBaselineOffset {0}; - double m_dLastX {0}; - - double m_dSpaceWidthMM {0}; - - bool m_bIsNeedSpace {false}; - bool m_bIsDoubleStrikeout {false}; - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; - - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; - - const CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - CFontManagerLight* m_pManagerLight {nullptr}; - const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - -#if USING_DELETE_DUPLICATING_CONTS == 0 - CContText* m_pDuplicateCont {nullptr}; -#endif - - public: - CContText(CFontManagerLight& oManagerLight); - ~CContText(){} - - void Clear() override final; - - CContText(const CContText& oSrc); - - CContText& operator=(const CContText& oSrc); - - double GetIntersect(const CContText* oSrc) const; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat = false); - - void AddSpaceToEnd(); - bool IsEqual(const CContText* oSrc); - - bool IsDuplicate(CContText* pCont, const eVerticalCrossingType& eVType); - bool IsThereAreFontEffects(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType); - bool IsVertAlignTypeBetweenConts(CContText* pCont, const eVerticalCrossingType& eVType, const eHorizontalCrossingType& eHType); - }; -} diff --git a/DocxRenderer/src/logic/ElementShape.h b/DocxRenderer/src/logic/ElementShape.h deleted file mode 100644 index 4ef67a19c4d..00000000000 --- a/DocxRenderer/src/logic/ElementShape.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include "ElementParagraph.h" -#include "../resources/LinesTable.h" -#include "../resources/VectorGraphics.h" -#include "ImageManager.h" - -namespace NSDocxRenderer -{ - enum class eGraphicsType - { - gtUnknown, - gtRectangle, - gtCurve, - gtComplicatedFigure, - gtNoGraphics, - }; - - class CShape : public CBaseItem - { - public: - enum class eShapeType - { - stUnknown, - stTextBox, - stPicture, - stVectorGraphics, - stVectorTexture, - stGroup, - stCanvas, - }; - - public: - eShapeType m_eType {eShapeType::stUnknown}; - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - double m_dRotate {0.0}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; - - eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; - eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; - eLineType m_eLineType {eLineType::ltUnknown}; - - std::vector m_arParagraphs; - - CImageInfo* m_pImageInfo {nullptr}; - - //Показывает, что есть отношение графики к тексту (подчеркивания/зачеркивания/выделение). - //note Пока сюда записывается указатель на символ с наибольшем размером шрифта. - const CContText* m_pCont {nullptr}; - - private: - UINT m_nShapeId {0}; - - public: - CShape(); - virtual ~CShape(); - virtual void Clear() override final; - - CShape(const CShape& oSrc); - CShape(CImageInfo* pInfo, const std::wstring& strDstMedia); - - CShape& operator=(const CShape& oSrc); - - void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lTypee); - - void WritePath(const CVectorGraphics& oVector); - - void DetermineGraphicsType(const double& dWidth, const double& dHeight, const size_t& nPeacks, const size_t& nCurves); - - bool IsItFitLine(); - bool IsCorrelated(const CShape* pShape); - void ChangeGeometryOfDesiredShape(CShape* pShape); - - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); - - private: - UINT GenerateShapeId(); - UINT GenerateRelativeHeight(); - }; -} diff --git a/DocxRenderer/src/logic/ImageManager.h b/DocxRenderer/src/logic/ImageManager.h deleted file mode 100644 index e85acd06b31..00000000000 --- a/DocxRenderer/src/logic/ImageManager.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once -#include "../DesktopEditor/common/StringBuilder.h" -#include "../DesktopEditor/common/CalculatorCRC32.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include - -namespace NSDocxRenderer -{ - class CImageInfo - { - public: - enum ImageType - { - itPNG = 0, - itJPG = 1 - }; - - public: - ImageType m_eType {itPNG}; - UINT m_nId {0}; - std::wstring m_strFileName {L""}; - - public: - CImageInfo(){} - - CImageInfo(const CImageInfo &oSrc) - { - *this = oSrc; - } - - CImageInfo& operator=(const CImageInfo &oSrc) - { - if (this == &oSrc) - { - return *this; - } - - m_eType = oSrc.m_eType; - m_nId = oSrc.m_nId; - m_strFileName = oSrc.m_strFileName; - - return *this; - } - - }; - - class CImageManager - { - public: - std::map m_mapImagesFile; - std::map m_mapImageData; - - std::wstring m_strDstMedia {L""}; - - int m_lMaxSizeImage {1200}; - int m_lNextIDImage {0}; - - CCalculatorCRC32 m_oCRC; - - public: - - CImageManager(){}; - - void NewDocument(); - - public: - CImageInfo WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); - - CImageInfo WriteImage(const std::wstring& strFile, double& x, double& y, double& width, double& height); - - protected: - void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); - - void SaveImage(const std::wstring& strFileSrc, CImageInfo& oInfo); - - void SaveImage(Aggplus::CImage* pImage, CImageInfo& oInfo); - - CImageInfo GenerateImageID(Aggplus::CImage* pImage); - - CImageInfo GenerateImageID(const std::wstring& strFileName); - - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - - void FlipY(Aggplus::CImage* pImage); - - void FlipX(CBgraFrame* pImage); - }; -} diff --git a/DocxRenderer/src/logic/elements/OldShape.h b/DocxRenderer/src/logic/elements/OldShape.h deleted file mode 100644 index b3d09091097..00000000000 --- a/DocxRenderer/src/logic/elements/OldShape.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include "BaseItem.h" -#include "../../resources/VectorGraphics.h" -#include "Paragraph.h" - -namespace NSDocxRenderer -{ - class COldShape : public CBaseItem - { - public: - //Подобранные константы - static const double POSITION_CORRECTION_FOR_X_MM; - static const double POSITION_CORRECTION_FOR_Y_MM; - static const double SIZE_CORRECTION_FOR_X_MM; - static const double SIZE_CORRECTION_FOR_Y_MM; - - public: - std::wstring m_strPath {L""}; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - - bool m_bIsNoFill {false}; - bool m_bIsNoStroke {false}; - - LONG m_lCoordSizeX {100000}; - LONG m_lCoordSizeY {100000}; - - LONG m_lTxId {-1}; - - std::vector m_arParagraphs; - - public: - COldShape(); - virtual ~COldShape(); - virtual void Clear() override final; - - virtual void AddContent(CBaseItem* pObj) override final{}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - - void GetDataFromVector(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); - - void WritePath(const CVectorGraphics& oVector, const LONG& lType, const LONG& lCoordSize); - }; -} From 2968e8e30335d0cfdaea8fd62fd950514166cefb Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 10 Aug 2023 21:23:33 +0300 Subject: [PATCH 108/794] Add DropCaps support commented for now --- DocxRenderer/DocxRenderer.pro | 2 + DocxRenderer/src/logic/Page.cpp | 77 +++++++++++++++++++- DocxRenderer/src/logic/Page.h | 3 + DocxRenderer/src/logic/elements/BaseItem.h | 1 + DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/logic/elements/DropCap.cpp | 40 ++++++++++ DocxRenderer/src/logic/elements/DropCap.h | 25 +++++++ 7 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 DocxRenderer/src/logic/elements/DropCap.cpp create mode 100644 DocxRenderer/src/logic/elements/DropCap.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 719ccdc04b1..7894edc12f2 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -28,6 +28,7 @@ HEADERS += \ src/logic/elements/Cell.h \ src/logic/elements/ContText.h \ src/logic/elements/Converter.h \ + src/logic/elements/DropCap.h \ src/logic/elements/Image.h \ src/logic/elements/Paragraph.h \ src/logic/elements/Shape.h \ @@ -56,6 +57,7 @@ SOURCES += \ src/logic/elements/Cell.cpp \ src/logic/elements/ContText.cpp \ src/logic/elements/Converter.cpp \ + src/logic/elements/DropCap.cpp \ src/logic/elements/Image.cpp \ src/logic/elements/Paragraph.cpp \ src/logic/elements/Shape.cpp \ diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 56a0c931395..2c68a65646d 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -64,6 +64,10 @@ namespace NSDocxRenderer delete val; m_arOutputObjects.clear(); + for(auto& val : m_arDropCaps) + delete val; + m_arDropCaps.clear(); + ClearTables(); m_pCurrentLine = nullptr; @@ -912,12 +916,12 @@ namespace NSDocxRenderer { //вся логика основана на отсортированных списках объектов //todo для увеличения производительности можно попробовать использовать другие контейнеры + CBaseItem::SortByBaseline(m_arTextLine); for (size_t i = 0; i < m_arTextLine.size(); ++i) - { CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); - } + //AnalyzeDropCaps(); AnalyzeCollectedConts(); DetermineStrikeoutsUnderlinesHighlights(); AddDiacriticalSymbols(); @@ -933,6 +937,70 @@ namespace NSDocxRenderer m_pParagraphStyleManager); } + void CPage::AnalyzeDropCaps() + { + double avg_font_size = m_pParagraphStyleManager->GetAvgFontSize(); + + std::vector possible_caps; + for(size_t i = 0; i < m_arTextLine.size(); i++) + { + auto& line = m_arTextLine[i]; + for(auto& cont : line->m_arConts) + if(!cont->m_bIsNotNecessaryToUse && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) + possible_caps.push_back(cont); + } + + for(auto& cap : possible_caps) + { + size_t num_of_lines = 0; + + for(auto& line : m_arTextLine) + { + // буквица должна быть левее + if(line->m_dLeft < cap->m_dLeft) + continue; + + // если совпадает строка - берем ее и выходим + if(fabs(line->m_dBaselinePos - cap->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + num_of_lines++; + break; + } + + if(line->m_dBaselinePos > cap->m_dBaselinePos) + break; + + if(fabs(line->m_dTop - cap->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < cap->m_dTop) + continue; + + bool skip = false; + for(auto& cont : line->m_arConts) + if(cont == cap) + { + skip = true; + continue; + } + + if(skip) + continue; + + num_of_lines++; + } + if(num_of_lines) + { + cap->m_bIsNotNecessaryToUse = true; + + CDropCap* drop_cap = new CDropCap(); + *static_cast(drop_cap) = *cap; + drop_cap->nLines = num_of_lines; + drop_cap->wsFont = cap->m_pFontStyle->wsFontName; + drop_cap->wsText = cap->m_oText.ToStdWString(); + + drop_cap->nFontSize = static_cast(cap->m_pFontStyle->dFontSize * 2); + m_arDropCaps.push_back(drop_cap); + } + } + } void CPage::AnalyzeCollectedConts() { // определение различных эффектов на основании взаимного расположения символов @@ -1599,6 +1667,11 @@ namespace NSDocxRenderer m_arShapes[i]->ToXml(oWriter); } + for (size_t i = 0; i < m_arDropCaps.size(); ++i) + { + m_arDropCaps[i]->ToXml(oWriter); + } + if (bIsTextShapePresent) { for (size_t i = 0; i < m_arOutputObjects.size(); ++i) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index de261bc19e3..65a86c637e3 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -6,6 +6,7 @@ #include "managers/FontStyleManager.h" #include "managers/ParagraphStyleManager.h" #include "styles/ParagraphStyle.h" +#include "elements/DropCap.h" namespace NSDocxRenderer @@ -37,6 +38,7 @@ namespace NSDocxRenderer std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; std::vector m_arShapes; + std::vector m_arDropCaps; std::vector m_arOutputObjects; @@ -116,6 +118,7 @@ namespace NSDocxRenderer void DetermineDominantGraphics(); void TryMergeShapes(); + void AnalyzeDropCaps(); //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку void ToXml(NSStringUtils::CStringBuilder& oWriter); diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index a1b66220119..9c822fb067f 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -49,6 +49,7 @@ namespace NSDocxRenderer etCell = 5, etRow = 6, etTable = 7, + etDropCap = 8, }; ElemType m_eType; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index c1aee72166c..511459345ee 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -531,6 +531,6 @@ namespace NSDocxRenderer double CContText::CalculateThinSpace() { //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.2; + return m_dSpaceWidthMM * 0.3; } } diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp new file mode 100644 index 00000000000..b216c270dc8 --- /dev/null +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -0,0 +1,40 @@ +#include "DropCap.h" +#include "src/resources/Constants.h" + +namespace NSDocxRenderer +{ + void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"((m_dBaselinePos - m_dTop) * c_dMMToDx * 0.96)); + oWriter.WriteString(L"\" "); + oWriter.WriteString(L"w:lineRule=\"exact\" />"); + oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); + oWriter.WriteString(L"\" w:y=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); + oWriter.WriteString(L"\" />"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + //oWriter.WriteString(L""); + oWriter.WriteString(L"((double)nFontSize * 0.95)); + oWriter.WriteString(L"\" />"); + oWriter.WriteString(L""); + oWriter.WriteString(L"" + wsText + L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } +} diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h new file mode 100644 index 00000000000..fe1c42aafec --- /dev/null +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -0,0 +1,25 @@ +#ifndef DROPCAP_H +#define DROPCAP_H + +#include "BaseItem.h" + +namespace NSDocxRenderer +{ + class CDropCap : public CBaseItem + { + public: + size_t nLines; + + std::wstring wsText; + std::wstring wsFont; + LONG nFontSize; + + CDropCap() : CBaseItem(ElemType::etDropCap) {} + ~CDropCap() = default; + + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override; + virtual void Clear() override {} + }; +} + +#endif // DROPCAP_H From 32c86f6debabb49c63766e03d5a6f2da5efacac8 Mon Sep 17 00:00:00 2001 From: RIMINMIR Date: Fri, 11 Aug 2023 19:11:36 +0600 Subject: [PATCH 109/794] added formula conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 98 +++++++++++++++++++++-- OOXML/XlsxFormat/Worksheets/SheetData.h | 1 + 2 files changed, 94 insertions(+), 5 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 0db738f9eda..8334243c6da 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1085,6 +1085,92 @@ namespace OOX } } + XLS::BaseObjectPtr CFormula::toBin() + { + XLS::BaseObjectPtr objectPtr; + switch(m_oT->GetValue()) + { + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal: + { + auto formula(new XLSB::FmlaBase(false)); + formula->formula = m_sText; + objectPtr = XLS::BaseObjectPtr{dynamic_cast(formula)}; + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared: + { + if(m_oRef.IsInit()) + { + auto formula(new XLSB::ShrFmla(m_oRef.get())); + formula->formula = m_sText; + objectPtr = XLS::BaseObjectPtr{formula}; + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: + { + if(m_oRef.IsInit()) + { + auto formula(new XLSB::ArrFmla(m_oRef.get())); + + formula->formula = m_sText; + if(m_oAca.IsInit()) + { + formula->fAlwaysCalc = m_oAca->GetValue(); + } + objectPtr = XLS::BaseObjectPtr{formula}; + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: + { + + auto dataTable(new XLSB::Table); + + if(m_oCa.IsInit()) + { + + dataTable->fAlwaysCalc = m_oCa->GetValue(); + } + if(m_oRef.IsInit()) + { + dataTable->rfx = m_oRef.get(); + } + + if(m_oDtr.IsInit()) + { + dataTable->fRw = m_oDtr->GetValue(); + } + + if(m_oDt2D.IsInit()) + { + dataTable->fTbl2 = m_oDt2D->GetValue(); + } + + if(m_oDel1.IsInit()) + { + dataTable->fDeleted1 = m_oDel1->GetValue(); + } + + if(m_oDel2.IsInit()) + { + dataTable->fDeleted2 = m_oDel2->GetValue(); + } + + if(m_oR1.IsInit()) + { + dataTable->r1 = m_oR1.get(); + } + + if(m_oR2.IsInit()) + { + dataTable->r2 = m_oR2.get(); + } + } + break; + } + return objectPtr; + } EElementType CFormula::getType () const { return et_x_Formula; @@ -1898,7 +1984,7 @@ namespace OOX { pTABLECELL = new(XLSB::TABLECELL); ptr->m_source = XLS::BaseObjectPtr{pTABLECELL}; - //pFMLACELL->m_source = m_oFormula->toBin(); + pFMLACELL->m_source = m_oFormula->toBin(); pTABLECELL->m_source = XLS::BaseObjectPtr{pSource}; } else @@ -1917,7 +2003,7 @@ namespace OOX if(!m_oRef.IsInit()) { - //pFMLACELL->m_source = m_oFormula->toBin(); + pFMLACELL->m_source = m_oFormula->toBin(); if(m_oFormula->m_oSi.IsInit()) pFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); pFMLACELL->isShared = true; @@ -1926,8 +2012,10 @@ namespace OOX else { if(m_oFormula->m_oSi.IsInit()) + { pSHRFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); - //pSHRFMLACELL->m_source = m_oFormula->toBin(); + pSHRFMLACELL->m_source = m_oFormula->toBin(); + } } } else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeNormal) @@ -1935,12 +2023,12 @@ namespace OOX std::vector ref; pFMLACELL = new XLSB::FMLACELL(0, ref); ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; - //pFMLACELL->m_source = m_oFormula->toBin(); + pFMLACELL->m_source = m_oFormula->toBin(); } else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeArray) { - //pSHRFMLACELL->m_source = m_oFormula->toBin(); + pSHRFMLACELL->m_source = m_oFormula->toBin(); } } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 45f0edb0bc7..26d0476fc03 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -142,6 +142,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream); void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nFlags); void fromBin(XLS::BaseObjectPtr& obj, SimpleTypes::Spreadsheet::ECellFormulaType eType); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; From 719754554125f9426ed3c4217d9567327f4d0ea0 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 11 Aug 2023 17:38:50 +0300 Subject: [PATCH 110/794] Started development of StarMath string parser --- .../StarMath2OOXML/StarMath2OOXML.pro | 16 ++ .../Reader/Converter/StarMath2OOXML/Test.cpp | 8 + .../StarMath2OOXML/cstarmathpars.cpp | 137 ++++++++++++++++++ .../Converter/StarMath2OOXML/cstarmathpars.h | 80 ++++++++++ 4 files changed, 241 insertions(+) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro new file mode 100644 index 00000000000..19b793007bd --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro @@ -0,0 +1,16 @@ +QT -= core gui + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(UnicodeConverter, kernel) + +SOURCES += Test.cpp \ + cstarmathpars.cpp + +HEADERS += \ + cstarmathpars.h + +DESTDIR = $$PWD_ROOT_DIR/build/$$CIRE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp new file mode 100644 index 00000000000..1624792f997 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -0,0 +1,8 @@ +#include "cstarmathpars.h" + +int main() +{ + std::wstring Temp = L"+245 + -376"; + StarMath::CStarMathPars TempO; + TempO.Pars(Temp); +} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp new file mode 100644 index 00000000000..53d1f07891d --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -0,0 +1,137 @@ +#include "cstarmathpars.h" +namespace StarMath +{ +//Class methods CStarMathPars + CStarMathPars::CStarMathPars() + { + } + + CStarMathPars::~CStarMathPars() + { + for(CElement* ReleaseObject: m_arParsLine) + { + delete ReleaseObject; + } + } + + void CStarMathPars::Pars(std::wstring& sStarMathLine) + { + std::wstring m_wsTempValueElement; + std::wstring::iterator itFirst = sStarMathLine.begin(), itEnd = sStarMathLine.end(); + while(itFirst != itEnd) + { + m_wsTempValueElement = sGetElement(itFirst,itEnd); + ParsElement(m_wsTempValueElement); + } + } + std::wstring CStarMathPars::sGetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) + { + std::wstring m_wsElement; + for(itFirst; itFirst != itEnd;itFirst++) + { + if(*itFirst != ' ') m_wsElement.push_back(*itFirst); + else + { + itFirst++; + break; + } + } + return m_wsElement; + } + void CStarMathPars::ParsElement(std::wstring &sOneElement) + { + CNumber m_oDigit; + CUnarySign m_oUnarSign; + bool itDigit = CheckDigit(sOneElement); + if(itDigit) m_arParsLine.push_back(m_oDigit.GetNumber(sOneElement)); + else if(sOneElement.size() > 3 && CheckUnarSign(sOneElement,m_oUnarSign)) ParsElement(sOneElement); + } + + bool CStarMathPars::CheckDigit(std::wstring &wsCheckToken) + { + for(char Check: wsCheckToken) + { + if(!isdigit(Check)) return false; + } + return true; + } + + bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) + { + std::wstring wsTempValueUnarSign; + bool UnarSign = false; + for(int i = 0;i<2;i++) + { + if(wsCheckToken[i] == '+' || wsCheckToken[i] == '-') + { + wsTempValueUnarSign.push_back(wsCheckToken[i]); + UnarSign = true; + } + } + if(!wsTempValueUnarSign.empty() && UnarSign) + { + m_arParsLine.push_back(m_oUnarSign.GetUnarSign(wsTempValueUnarSign)); + wsCheckToken = wsCheckToken.substr(wsTempValueUnarSign.size()); + } + return UnarSign; + } +//Class methods CNumber + CNumber::CNumber() + { + } + + CNumber::~CNumber() + { + } + + std::wstring CNumber::GetValue() + { + return m_sValueNumber; + } + TypeElement CNumber::GetType() + { + return Number; + } + CNumber* CNumber::GetNumber(std::wstring& sNumberElement) + { + + CNumber* oValue = new CNumber; + oValue->m_sValueNumber = sNumberElement; + return oValue; +//Class methods CUnarySign + } + CUnarySign* CUnarySign::GetUnarSign(std::wstring& sUnarToken) + { + CUnarySign* oSign = new CUnarySign; + oSign->m_sUnar = sUnarToken; + return oSign; + } + + std::wstring CUnarySign::GetValue() + { + return m_sUnar; + } + TypeElement CUnarySign::GetType() + { + return m_UnarType; + } + CUnarySign::CUnarySign() + {} + CUnarySign::~CUnarySign() + {} +//Class methods CBinaryOperator + CBinaryOperator::CBinaryOperator() + {} + CBinaryOperator::~CBinaryOperator() + {} + TypeElement CBinaryOperator::GetType() + { + return m_TypeSign; + } + std::wstring CBinaryOperator::GetValue() + { + std::cout << m_TypeSign; + return L"Good"; + } +} + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h new file mode 100644 index 00000000000..f8164011c8d --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -0,0 +1,80 @@ +#ifndef CSTARMATHPARS_H +#define CSTARMATHPARS_H +#include +#include +#include + +namespace StarMath +{ + enum TypeElement{Number,UnarSign,SM_BinOper_cdot,SM_BinOper_times,SM_BinOper_over,SM_BinOper_plus,SM_BinOper_minus,SM_BinOper_frac,SM_BinOper_div}; + class CElement + { + public: + virtual std::wstring GetValue() = 0; + virtual TypeElement GetType() = 0; + }; + + class CNumber: public CElement + { + public: + CNumber(); + ~CNumber(); + CNumber* GetNumber(std::wstring& sNumberElement); + std::wstring GetValue() override; + TypeElement GetType() override ; + private: + std::wstring m_sValueNumber; + TypeElement m_Number = Number; + }; + + class CUnarySign: public CElement + { + public: + CUnarySign(); + ~CUnarySign(); + std::wstring GetValue() override; + TypeElement GetType() override; + CUnarySign* GetUnarSign(std::wstring& sUnarToken); + private: + std::wstring m_sUnar; + TypeElement m_UnarType = UnarSign; + }; + class CBinaryOperator: public CElement + { + public: + CBinaryOperator(); + ~CBinaryOperator(); + std::wstring GetValue() override; + TypeElement GetType() override; + CBinaryOperator* GetSign(std::wstring& wsSignToken); + private: + TypeElement m_TypeSign; + }; + + class CBoxValue: public CElement + { + public: + CBoxValue(); + ~CBoxValue(); + CBoxValue* ReadBox(std::string::iterator& itStartBox,std::string::iterator& itEndBox); + std::wstring GetValue() override; + private: + std::vector arValueBox; + }; + + class CStarMathPars + { + public: + CStarMathPars(); + ~CStarMathPars(); + void Pars(std::wstring& sStarMathLine); + std::wstring sGetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); + void ParsElement(std::wstring& sOneElement); + bool CheckDigit(std::wstring& wsCheckToken); + bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& m_oUnarSign); + private: + std::vector m_arParsLine; + }; +} + +#endif // CSTARMATHPARS_H From a735af265d57efa7c7bb3043f40ff7b8ace93237 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 11 Aug 2023 21:39:12 +0600 Subject: [PATCH 111/794] fix zero height cells --- .../Worksheets/WorksheetChildOther.cpp | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 5215be725d1..f858118df52 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -952,8 +952,13 @@ namespace OOX if(m_oBaseColWidth.IsInit()) ptr->dxGCol = m_oBaseColWidth.get() * 256.; if(m_oDefaultColWidth.IsInit()) + { ptr->cchDefColWidth = m_oDefaultColWidth.get(); - + if(!m_oBaseColWidth.IsInit()) + { + ptr->dxGCol = m_oDefaultColWidth.get(); + } + } if (m_oDefaultRowHeight.IsInit()) ptr->miyDefRwHeight = m_oDefaultRowHeight.get(); else @@ -963,8 +968,11 @@ namespace OOX if (m_oOutlineLevelRow.IsInit()) ptr->iOutLevelRw = m_oOutlineLevelRow.get(); if (m_oThickBottom.IsInit()) ptr->fExDesc = m_oThickBottom.get(); + else ptr->fExDesc = false; if (m_oThickTop.IsInit()) ptr->fExAsc = m_oThickTop.get(); + else ptr->fExAsc = false; if (m_oZeroHeight.IsInit()) ptr->fDyZero = m_oZeroHeight.get(); + else ptr->fDyZero = false; return Castedptr; } EElementType CSheetFormatPr::getType() const @@ -1924,27 +1932,27 @@ namespace OOX if(m_oOddHeader.IsInit()) castedBegin->stHeader = m_oOddHeader->m_sText; - else + else castedBegin->stHeader = false; if(m_oOddFooter.IsInit()) castedBegin->stFooter = m_oOddFooter->m_sText; - else + else castedBegin->stFooter = false; if(m_oEvenHeader.IsInit()) castedBegin->stHeaderEven = m_oEvenHeader->m_sText; - else + else castedBegin->stHeaderEven = false; if(m_oEvenFooter.IsInit()) castedBegin->stFooterEven = m_oEvenFooter->m_sText; - else + else castedBegin->stFooterEven = false; if(m_oFirstHeader.IsInit()) castedBegin->stHeaderFirst = m_oFirstHeader->m_sText; - else + else castedBegin->stHeaderFirst = false; if(m_oFirstFooter.IsInit()) castedBegin->stFooterFirst = m_oFirstFooter->m_sText; - else + else castedBegin->stFooterFirst = false; return objectPtr; } From 38b6a583d2696cbcc5b11f29824ccbb932e1cff8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 16:06:26 +0600 Subject: [PATCH 112/794] Add fonts conversion --- OOXML/XlsxFormat/Styles/Fonts.cpp | 103 ++++++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/Fonts.h | 2 + 2 files changed, 105 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 8a0efa5cabc..8a82cca9d41 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -35,6 +35,8 @@ #include "../ComplexTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../Biff12_unions/FONTS.h" + namespace OOX { namespace Spreadsheet @@ -179,6 +181,95 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CFont::toBin() + { + auto ptr(new XLSB::Font); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oSz.IsInit()) + ptr->dyHeight = m_oSz->m_oVal->GetValue() * 20; + + if(m_oItalic.IsInit()) + ptr->fItalic = m_oItalic->ToBool(); + + if(m_oStrike.IsInit()) + ptr->fStrikeOut = m_oStrike->ToBool(); + + if(m_oOutline.IsInit()) + ptr->fOutline = m_oOutline->ToBool(); + + if(m_oShadow.IsInit()) + ptr->fShadow = m_oShadow->ToBool(); + + if(m_oCondense.IsInit()) + ptr->fCondense = m_oCondense->ToBool(); + + if(m_oExtend.IsInit()) + ptr->fExtend = m_oExtend->ToBool(); + + if(m_oBold.IsInit()) + { + if(m_oBold->ToBool()) + ptr->bls = 0x02BC; + } + + if(m_oUnderline.IsInit()) + { + if(m_oUnderline->m_oUnderline.IsInit()) + { + if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineNone) + ptr->uls = 0; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingle) + ptr->uls = 1; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDouble) + ptr->uls = 2; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingleAccounting) + ptr->uls = 33; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDoubleAccounting) + ptr->uls = 34; + } + } + + if(m_oFamily.IsInit()) + ptr->bFamily = m_oFamily->m_oFontFamily->GetValue(); + + if(m_oCharset.IsInit()) + ptr->bCharSet = m_oCharset->m_oCharset->GetValue(); + + if(m_oColor.IsInit()) + ptr->brtColor = m_oColor->toColor(); + + if(m_oScheme.IsInit()) + { + if(m_oScheme->m_oFontScheme.IsInit()) + { + if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeNone) + ptr->bFontScheme = 0; + else if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeMajor) + ptr->bFontScheme = 1; + else if(m_oScheme->m_oFontScheme == SimpleTypes::Spreadsheet::EFontScheme::fontschemeMinor) + ptr->bFontScheme = 2; + } + } + + + if(m_oRFont.IsInit()) + ptr->fontName = m_oRFont->m_sVal.get(); + if(m_oVertAlign.IsInit()) + { + if(m_oVertAlign->m_oVerticalAlign.IsInit()) + { + if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunBaseline) + ptr->sss = 0; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSuperscript) + ptr->sss = 1; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSubscript) + ptr->sss = 2; + } + } + + return objectPtr; + } EElementType CFont::getType () const { return et_x_Font; @@ -406,6 +497,18 @@ namespace OOX m_mapFonts.insert(std::make_pair(index++, pFont)); } } + XLS::BaseObjectPtr CFonts::toBin() + { + auto ptr(new XLSB::FONTS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_arrItems) + { + ptr->m_arBrtFont.push_back(i->toBin()); + } + + return objectPtr; + } EElementType CFonts::getType () const { return et_x_Fonts; diff --git a/OOXML/XlsxFormat/Styles/Fonts.h b/OOXML/XlsxFormat/Styles/Fonts.h index f629aee2719..1f8050fcb85 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.h +++ b/OOXML/XlsxFormat/Styles/Fonts.h @@ -55,6 +55,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void AddFont (CFont* pFont); From deb206fad2c099739c8737e97758e8ff3baa99dd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 16:06:43 +0600 Subject: [PATCH 113/794] Add nubFmts conversion --- OOXML/XlsxFormat/Styles/NumFmts.cpp | 23 +++++++++++++++++++++++ OOXML/XlsxFormat/Styles/NumFmts.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index 431f9583d69..e6da90431b2 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -36,6 +36,7 @@ #include "../../XlsbFormat/Biff12_unions/ACFMT.h" #include "../../Common/SimpleTypes_Shared.h" +#include "../Biff12_unions/FMTS.h" namespace OOX { @@ -83,6 +84,17 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CNumFmt::toBin() + { + auto ptr(new XLSB::Fmt); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oFormatCode.IsInit()) + ptr->stFmtCode = m_oFormatCode.get(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + + return objectPtr; + } EElementType CNumFmt::getType () const { return et_x_NumFmt; @@ -187,6 +199,17 @@ namespace OOX } } + XLS::BaseObjectPtr CNumFmts::toBin() + { + auto fmts(new XLSB::FMTS); + XLS::BaseObjectPtr objectPtr(fmts); + std::vector objectVector; + for(auto i:m_arrItems) + { + fmts->m_arBrtFmt.push_back(i->toBin()) + } + return objectPtr; + } EElementType CNumFmts::getType () const { return et_x_NumFmts; diff --git a/OOXML/XlsxFormat/Styles/NumFmts.h b/OOXML/XlsxFormat/Styles/NumFmts.h index 70974a26b4f..fa3bc7371b8 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.h +++ b/OOXML/XlsxFormat/Styles/NumFmts.h @@ -61,6 +61,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -90,6 +91,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 44fb83dc3a928b7e519d67b69f63b8536e358328 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 16:07:00 +0600 Subject: [PATCH 114/794] Add Fills conversion --- OOXML/XlsxFormat/Styles/Fills.cpp | 113 ++++++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/Fills.h | 5 ++ 2 files changed, 118 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index 608dba331f8..efbb2b3d5b6 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -38,6 +38,8 @@ #include "../../XlsbFormat/Biff12_records/Fill.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../Biff12_unions/FILLS.h" + namespace OOX { namespace Spreadsheet @@ -110,6 +112,57 @@ namespace OOX { ReadAttributes(obj); } + void CPatternFill::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + if(m_oPatternType.IsInit()) + { + if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeNone) + ptr->fls = 0x00; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeSolid) + ptr->fls = 0x01; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeMediumGray) + ptr->fls = 0x02; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkGray) + ptr->fls = 0x03; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightGray) + ptr->fls = 0x04; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkHorizontal) + ptr->fls = 0x05; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkVertical) + ptr->fls = 0x06; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkDown) + ptr->fls = 0x07; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkUp) + ptr->fls = 0x08; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkGrid) + ptr->fls = 0x09; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkTrellis) + ptr->fls = 0x0A; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightHorizontal) + ptr->fls = 0x0B; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightVertical) + ptr->fls = 0x0C; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightDown) + ptr->fls = 0x0D; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightUp) + ptr->fls = 0x0E; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightGrid) + ptr->fls = 0x0F; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeLightTrellis) + ptr->fls = 0x10; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray125) + ptr->fls = 0x11; + else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray0625) + ptr->fls = 0x12; + } + + if(m_oBgColor.IsInit()) + ptr->brtColorBack = m_oBgColor->toColor(); + + if(m_oFgColor.IsInit()) + ptr->brtColorFore = m_oFgColor->toColor(); + } EElementType CPatternFill::getType () const { return et_x_PatternFill; @@ -230,6 +283,19 @@ namespace OOX m_oColor->fromBin(dynamic_cast(&ptr->brtColor)); } } + void CGradientStop::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + XLSB::GradientStop stop; + if(m_oPosition.IsInit()) + stop.xnumPosition.data.value = m_oPosition->GetValue(); + if(m_oColor.IsInit()) + { + stop.brtColor = m_oColor->toColor(); + } + ptr->xfillGradientStop.push_back(stop); + } + EElementType CGradientStop::getType () const { return et_x_GradientStop; @@ -310,6 +376,28 @@ namespace OOX m_arrItems.push_back(ptrGradStop); } } + } + void CGradientFill::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast(obj.get()); + + if(m_oType.IsInit()) + ptr->iGradientType = m_oType->GetValue(); + if(m_oDegree.IsInit()) + ptr->xnumDegree.data.value = m_oDegree->GetValue(); + if(m_oLeft.IsInit()) + ptr->xnumFillToLeft.data.value = m_oLeft->GetValue(); + if(m_oRight.IsInit()) + ptr->xnumFillToRight.data.value = m_oRight->GetValue(); + if(m_oTop .IsInit()) + ptr->xnumFillToTop.data.value = m_oTop->GetValue(); + if(m_oBottom.IsInit()) + ptr->xnumFillToBottom.data.value = m_oBottom->GetValue(); + + for(auto i:m_arrItems) + { + i->toBin(obj); + } } @@ -397,6 +485,22 @@ namespace OOX if ((m_oGradientFill.IsInit()) && (false == m_oGradientFill->m_oType.IsInit())) m_oGradientFill.reset(); } + XLS::BaseObjectPtr CFill::toBin() + { + auto ptr(new XLSB::Fill); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oPatternFill.IsInit()) + { + m_oPatternFill->toBin(objectPtr); + } + + if(m_oGradientFill.IsInit()) + { + m_oGradientFill->toBin(objectPtr); + } + return objectPtr; + } EElementType CFill::getType () const { return et_x_Fill; @@ -500,6 +604,15 @@ namespace OOX m_mapFills.insert(std::make_pair(index++, pFill)); } } + XLS::BaseObjectPtr CFills::toBin() + { + auto ptr(new XLSB::FILLS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i : m_arrItems) + ptr->m_arBrtFill.push_back(i->toBin()); + return objectPtr; + + } EElementType CFills::getType () const { return et_x_Fills; diff --git a/OOXML/XlsxFormat/Styles/Fills.h b/OOXML/XlsxFormat/Styles/Fills.h index 7294079c861..278d2576811 100644 --- a/OOXML/XlsxFormat/Styles/Fills.h +++ b/OOXML/XlsxFormat/Styles/Fills.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure* obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -122,6 +124,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr obj); virtual EElementType getType () const; @@ -154,6 +157,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -180,6 +184,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 15cf8de9bf585f7fcaf7b8814a96418a9c7d17bf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 17:32:25 +0600 Subject: [PATCH 115/794] Add borders conversion --- OOXML/XlsxFormat/Styles/Borders.cpp | 64 +++++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/Borders.h | 3 ++ 2 files changed, 67 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index c3b94bbdf38..609245afdb7 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -38,6 +38,8 @@ #include "../../XlsbFormat/Biff12_records/Border.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../Biff12_unions/BORDERS.h" + namespace OOX { namespace Spreadsheet @@ -134,6 +136,43 @@ namespace OOX } } + void CBorderProp::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + if(m_oColor.IsInit()) + ptr->brtColor = m_oColor->toColor(); + if(!m_oStyle.IsInit()) + return; + + if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleNone) + ptr->dg = 0x00; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThin) + ptr->dg = 0x01; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMedium) + ptr->dg = 0x02; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashed) + ptr->dg = 0x03; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDotted) + ptr->dg = 0x04; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThick) + ptr->dg = 0x05; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDouble) + ptr->dg = 0x06; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleHair) + ptr->dg = 0x07; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashed) + ptr->dg = 0x08; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDot) + ptr->dg = 0x09; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashDot) + ptr->dg = 0x0A; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDotDot) + ptr->dg = 0x0B; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashDotDot) + ptr->dg = 0x0C; + else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleSlantDashDot) + ptr->dg = 0x0D; + } bool CBorderProp::IsEmpty() { return !(m_oStyle.IsInit() || m_oColor.IsInit()); @@ -302,6 +341,23 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CBorder::toBin() + { + auto ptr(new XLSB::Border); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBottom.IsInit()) + m_oBottom->toBin(&ptr->blxfBottom); + if(m_oDiagonal.IsInit()) + m_oDiagonal->toBin(&ptr->blxfDiag); + if(m_oTop.IsInit()) + m_oTop->toBin(&ptr->blxfTop); + if(m_oStart.IsInit()) + m_oStart->toBin(&ptr->blxfLeft); + if(m_oEnd.IsInit()) + m_oEnd->toBin(&ptr->blxfRight); + + return objectPtr; + } EElementType CBorder::getType () const { return et_x_Border; @@ -401,6 +457,14 @@ namespace OOX m_mapBorders.insert(std::make_pair(index++, pBorder)); } } + XLS::BaseObjectPtr CBorders::toBin() + { + auto ptr(new XLSB::BORDERS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtBorder.push_back(i->toBin()); + return objectPtr; + } EElementType CBorders::getType () const { return et_x_Borders; diff --git a/OOXML/XlsxFormat/Styles/Borders.h b/OOXML/XlsxFormat/Styles/Borders.h index f8b0ddd0173..21f65cc26a3 100644 --- a/OOXML/XlsxFormat/Styles/Borders.h +++ b/OOXML/XlsxFormat/Styles/Borders.h @@ -68,6 +68,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(XLS::BiffStructure* obj); + void toBin(XLS::BiffStructure* obj); bool IsEmpty(); private: @@ -98,6 +99,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -135,6 +137,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 48e3f5541140c08f19a09b7809e84dc84a2a6f10 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 18:58:10 +0600 Subject: [PATCH 116/794] Add cell style xfs conversion --- OOXML/XlsxFormat/Styles/Xfs.cpp | 86 +++++++++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/Xfs.h | 6 ++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 846a31af9fa..c25bcd0ca3e 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -36,6 +36,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../Biff12_unions/CELLSTYLEXFS.h" namespace OOX { @@ -84,6 +85,46 @@ namespace OOX { ReadAttributes(obj); } + void CAligment::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + ptr->cIndent = m_oIndent.get(); + ptr->fJustLast = m_oJustifyLastLine->GetValue(); + ptr->iReadOrder = m_oReadingOrder.get(); + ptr->iReadOrder = m_oRelativeIndent.get(); + ptr->fShrinkToFit = m_oShrinkToFit->GetValue(); + ptr->trot = m_oTextRotation.get(); + ptr->fWrap = m_oWrapText->GetValue(); + + if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentGeneral) + ptr->alc = 0; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentLeft) + ptr->alc = 1; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentCenter) + ptr->alc = 2; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentRight) + ptr->alc = 3; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentFill) + ptr->alc = 4; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentJustify) + ptr->alc = 5; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentCenterContinuous) + ptr->alc = 6; + else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentDistributed) + ptr->alc = 7; + + if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentTop) + ptr->alcV = 0; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentCenter) + ptr->alcV = 1; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentBottom) + ptr->alcV = 2; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentJustify) + ptr->alcV = 3; + else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentDistributed) + ptr->alcV = 4; + + } EElementType CAligment::getType () const { return et_x_Aligment; @@ -220,6 +261,14 @@ namespace OOX { ReadAttributes(obj); } + void CProtection::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oHidden.IsInit()) + ptr->fHidden = m_oHidden->GetValue(); + if(m_oLocked.IsInit()) + ptr->fLocked = m_oLocked->GetValue(); + } EElementType CProtection::getType () const { return et_x_Protection; @@ -310,6 +359,35 @@ namespace OOX m_oAligment = obj; m_oProtection = obj; } + XLS::BaseObjectPtr CXfs::toBin() + { + size_t id = 1; + auto ptr(new XLSB::XF(id, id)); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->ixBorder = m_oBorderId->GetValue(); + m_oBorderId = ptr->ixBorder; + ptr->iFill = m_oFillId->GetValue(); + ptr->font_index = m_oFontId->GetValue(); + ptr->ifmt = m_oNumFmtId->GetValue(); + ptr->fsxButton = m_oPivotButton->GetValue(); + ptr->f123Prefix = m_oQuotePrefix->GetValue(); + + if (m_oXfId.IsInit()) + ptr->ixfParent = m_oXfId->GetValue(); + + ptr->fAtrAlc = m_oApplyAlignment->GetValue(); + ptr->fAtrBdr = m_oApplyBorder->GetValue(); + ptr->fAtrPat = m_oApplyFill->GetValue(); + ptr->fAtrFnt = m_oApplyFont->GetValue(); + ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); + ptr->fAtrProt = m_oApplyProtection->GetValue(); + + m_oAligment->toBin(objectPtr); + m_oProtection->toBin(objectPtr); + + return objectPtr; + } void CXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -491,6 +569,14 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellStyleXfs::toBin() + { + auto ptr(new XLSB::CELLSTYLEXFS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtXF.push_back(i->toBin()); + return objectPtr; + } void CCellStyleXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) diff --git a/OOXML/XlsxFormat/Styles/Xfs.h b/OOXML/XlsxFormat/Styles/Xfs.h index 7ab94d1308a..78d904375fc 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.h +++ b/OOXML/XlsxFormat/Styles/Xfs.h @@ -66,6 +66,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -103,6 +104,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -134,6 +136,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -157,7 +160,7 @@ namespace OOX nullable m_oAligment; nullable m_oProtection; - + }; class CCellXfs : public WritingElementWithChilds @@ -202,6 +205,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From a791775acff663028a316b358eba9974c5f948b3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 19:10:03 +0600 Subject: [PATCH 117/794] Add cell xfs conversion --- OOXML/XlsxFormat/Styles/Xfs.cpp | 16 ++++++++++++++-- OOXML/XlsxFormat/Styles/Xfs.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index c25bcd0ca3e..bd594c116ba 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -36,7 +36,9 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" + #include "../Biff12_unions/CELLSTYLEXFS.h" +#include "../Biff12_unions/CELLXFS.h" namespace OOX { @@ -383,8 +385,10 @@ namespace OOX ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); ptr->fAtrProt = m_oApplyProtection->GetValue(); - m_oAligment->toBin(objectPtr); - m_oProtection->toBin(objectPtr); + if(m_oAligment.IsInit()) + m_oAligment->toBin(objectPtr); + if(m_oProtection.IsInit()) + m_oProtection->toBin(objectPtr); return objectPtr; } @@ -488,6 +492,14 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellXfs::toBin() + { + auto ptr(new XLSB::CELLXFS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtXF.push_back(i->toBin()); + return objectPtr; + } EElementType CCellXfs::getType () const { return et_x_CellXfs; diff --git a/OOXML/XlsxFormat/Styles/Xfs.h b/OOXML/XlsxFormat/Styles/Xfs.h index 78d904375fc..480f460ca73 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.h +++ b/OOXML/XlsxFormat/Styles/Xfs.h @@ -177,6 +177,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; From 83cb27d12335277091b626326c148219993721f0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 19:26:41 +0600 Subject: [PATCH 118/794] Add cell styles conversion --- OOXML/XlsxFormat/Styles/CellStyles.cpp | 29 ++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/CellStyles.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index b8074e2e25b..ea75131393a 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -35,6 +35,8 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/Style.h" +#include "../Biff12_unions/STYLES.h" + namespace OOX { namespace Spreadsheet @@ -71,6 +73,25 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CCellStyle::toBin() + { + auto ptr(new XLSB::Style); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBuiltinId.IsInit()) + ptr->fBuiltIn = m_oBuiltinId->GetValue(); + if (m_oCustomBuiltin.IsInit()) + ptr->fCustom = m_oCustomBuiltin->GetValue(); + if (m_oHidden.IsInit()) + ptr->fHidden = m_oHidden->GetValue(); + if (m_oILevel.IsInit()) + ptr->iLevel = m_oILevel->GetValue(); + if (m_oName.IsInit()) + ptr->stName = m_oName.get(); + if (m_oXfId.IsInit()) + ptr->ixf = m_oXfId->GetValue(); + + return objectPtr; + } EElementType CCellStyle::getType () const { return et_x_CellStyle; @@ -159,6 +180,14 @@ namespace OOX m_arrItems.push_back(pXfs); } } + XLS::BaseObjectPtr CCellStyles::toBin() + { + auto ptr(new XLSB::STYLES); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtStyle.push_back(i->toBin()); + return objectPtr; + } EElementType CCellStyles::getType () const { return et_x_CellStyles; diff --git a/OOXML/XlsxFormat/Styles/CellStyles.h b/OOXML/XlsxFormat/Styles/CellStyles.h index b62b65c3d5b..d69e44c085f 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.h +++ b/OOXML/XlsxFormat/Styles/CellStyles.h @@ -60,6 +60,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -90,6 +91,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(std::vector& obj); virtual EElementType getType () const; From 5b00fc4ad40a94666975b86570919f614139426d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 20:48:13 +0600 Subject: [PATCH 119/794] Add Table styles conversion --- OOXML/XlsxFormat/Styles/TableStyles.cpp | 97 +++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/TableStyles.h | 3 + 2 files changed, 100 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index e65ec236635..9952bfd0172 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -80,6 +80,78 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTableStyleElement::toBin() + { + auto ptr(new XLSB::TableStyleElement); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->index = m_oDxfId->GetValue(); + ptr->size = m_oSize->GetValue(); + + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeWholeTable) + ptr->tseType = 0; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeHeaderRow) + ptr->tseType = 1; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeTotalRow) + ptr->tseType = 2; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumn) + ptr->tseType = 3; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastColumn) + ptr->tseType = 4; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstRowStripe) + ptr->tseType = 5; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondRowStripe) + ptr->tseType = 6; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumnStripe) + ptr->tseType = 7; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondColumnStripe) + ptr->tseType = 8; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstHeaderCell) + ptr->tseType = 9; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastHeaderCell) + ptr->tseType = 10; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstTotalCell) + ptr->tseType = 11; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeLastTotalCell) + ptr->tseType = 12; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstSubtotalColumn) + ptr->tseType = 13; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondSubtotalColumn) + ptr->tseType = 14; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdSubtotalColumn) + ptr->tseType = 15; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstSubtotalRow) + ptr->tseType = 16; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondSubtotalRow) + ptr->tseType = 17; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdSubtotalRow) + ptr->tseType = 18; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeBlankRow) + ptr->tseType = 19; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstColumnSubheading) + ptr->tseType = 20; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondColumnSubheading) + ptr->tseType = 21; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdColumnSubheading) + ptr->tseType = 22; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeFirstRowSubheading) + ptr->tseType = 23; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeSecondRowSubheading) + ptr->tseType = 24; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypeThirdRowSubheading) + ptr->tseType = 25; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypePageFieldLabels) + ptr->tseType = 26; + else if (m_oType == SimpleTypes::Spreadsheet::ETableStyleType::tablestyletypePageFieldValues) + ptr->tseType = 27; + else + ptr->tseType = 19; + } + + return objectPtr; + } EElementType CTableStyleElement::getType () const { return et_x_TableStyleElement; @@ -236,6 +308,23 @@ namespace OOX } } + XLS::BaseObjectPtr CTableStyle::toBin() + { + auto ptr(new XLSB::TABLESTYLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto beginStyle(new XLSB::BeginTableStyle); + ptr->m_BrtBeginTableStyle = XLS::BaseObjectPtr{beginStyle}; + + beginStyle->ctse = m_oCount->GetValue(); + beginStyle->fIsPivot = m_oPivot->GetValue(); + beginStyle->fIsTable = m_oTable->GetValue(); + beginStyle->rgchName = m_oName.get(); + beginStyle->rgchName = m_oDisplayName.get(); + + for(auto i:m_arrItems) + ptr->m_arBrtTableStyleElement.push_back(i->toBin()); + return objectPtr; + } EElementType CTableStyle::getType () const { return et_x_TableStyle; @@ -333,6 +422,14 @@ namespace OOX } } + XLS::BaseObjectPtr CTableStyles::toBin() + { + auto ptr(new XLSB::TABLESTYLES); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arTABLESTYLE.push_back(i->toBin()); + return objectPtr; + } EElementType CTableStyles::getType () const { return et_x_TableStyles; diff --git a/OOXML/XlsxFormat/Styles/TableStyles.h b/OOXML/XlsxFormat/Styles/TableStyles.h index 6c618606c71..e5d8900b5a5 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.h +++ b/OOXML/XlsxFormat/Styles/TableStyles.h @@ -63,6 +63,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -89,6 +90,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -118,6 +120,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From a420375411871751033adef114e1969950f361f5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Aug 2023 21:13:07 +0600 Subject: [PATCH 120/794] Fix include file paths --- OOXML/XlsxFormat/Styles/Borders.cpp | 2 +- OOXML/XlsxFormat/Styles/CellStyles.cpp | 2 +- OOXML/XlsxFormat/Styles/Fills.cpp | 2 +- OOXML/XlsxFormat/Styles/Fonts.cpp | 2 +- OOXML/XlsxFormat/Styles/NumFmts.cpp | 4 ++-- OOXML/XlsxFormat/Styles/Xfs.cpp | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 609245afdb7..383ae94ce7d 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -38,7 +38,7 @@ #include "../../XlsbFormat/Biff12_records/Border.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" -#include "../Biff12_unions/BORDERS.h" +#include "../../../XlsbFormat/Biff12_unions/BORDERS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index ea75131393a..6c9afccd316 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -35,7 +35,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/Style.h" -#include "../Biff12_unions/STYLES.h" +#include "../../XlsbFormat/Biff12_unions/STYLES.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index efbb2b3d5b6..a78fa208ef2 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -38,7 +38,7 @@ #include "../../XlsbFormat/Biff12_records/Fill.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" -#include "../Biff12_unions/FILLS.h" +#include "../../../XlsbFormat/Biff12_unions/FILLS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 8a82cca9d41..f48586e97e6 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -35,7 +35,7 @@ #include "../ComplexTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" -#include "../Biff12_unions/FONTS.h" +#include "../../../XlsbFormat/Biff12_unions/FONTS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index e6da90431b2..267cc2a10eb 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -36,7 +36,7 @@ #include "../../XlsbFormat/Biff12_unions/ACFMT.h" #include "../../Common/SimpleTypes_Shared.h" -#include "../Biff12_unions/FMTS.h" +#include "../../../XlsbFormat/Biff12_unions/FMTS.h" namespace OOX { @@ -206,7 +206,7 @@ namespace OOX std::vector objectVector; for(auto i:m_arrItems) { - fmts->m_arBrtFmt.push_back(i->toBin()) + fmts->m_arBrtFmt.push_back(i->toBin()); } return objectPtr; } diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index bd594c116ba..68715b4da51 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -37,8 +37,8 @@ #include "../../XlsbFormat/Biff12_records/CommonRecords.h" -#include "../Biff12_unions/CELLSTYLEXFS.h" -#include "../Biff12_unions/CELLXFS.h" +#include "../../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" +#include "../../../XlsbFormat/Biff12_unions/CELLXFS.h" namespace OOX { From e180b49191eef1db01a6e83cc72af86c8c57f2e9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 15 Aug 2023 18:51:32 +0600 Subject: [PATCH 121/794] Add style colors conversion --- OOXML/XlsxFormat/Styles/Colors.cpp | 21 +++++++++++++++++++++ OOXML/XlsxFormat/Styles/Colors.h | 1 + OOXML/XlsxFormat/Styles/rPr.cpp | 26 ++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/rPr.h | 3 +++ 4 files changed, 51 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/Colors.cpp b/OOXML/XlsxFormat/Styles/Colors.cpp index 7adcbffdf74..85482906512 100644 --- a/OOXML/XlsxFormat/Styles/Colors.cpp +++ b/OOXML/XlsxFormat/Styles/Colors.cpp @@ -98,6 +98,27 @@ namespace OOX } } } + XLS::BaseObjectPtr CColors::toBin() + { + auto ptr(new XLSB::COLORPALETTE); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oIndexedColors.IsInit()) + { + auto indexСolors(new XLSB::INDEXEDCOLORS); + ptr->m_INDEXEDCOLORS = XLS::BaseObjectPtr{indexСolors}; + indexСolors->m_arIndexedColor = m_oIndexedColors->toBin(); + } + + if(m_oMruColors.IsInit()) + { + auto mruColors(new XLSB::MRUCOLORS); + ptr->m_MRUCOLORS = XLS::BaseObjectPtr{mruColors}; + mruColors->m_arMRUColor = m_oMruColors->toBin() + } + + return objectPtr; + } EElementType CColors::getType () const { return et_x_Colors; diff --git a/OOXML/XlsxFormat/Styles/Colors.h b/OOXML/XlsxFormat/Styles/Colors.h index a8d92c0621b..f593ae4fab6 100644 --- a/OOXML/XlsxFormat/Styles/Colors.h +++ b/OOXML/XlsxFormat/Styles/Colors.h @@ -52,6 +52,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 24c7ce97557..4828ffb14c0 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -68,6 +68,18 @@ namespace OOX m_oRgb = SimpleTypes::Spreadsheet::CHexColor(ptr->bRed, ptr->bGreen, ptr->bBlue); } } + XLS::BaseObjectPtr CRgbColor::toBin() + { + auto ptr(new XLSB::IndexedColor); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRgb.IsInit()) + { + ptr->bRed = m_oRgb->Get_R(); + ptr->bGreen = m_oRgb->Get_G(); + ptr->bBlue = m_oRgb->Get_B(); + } + return objectPtr; + } EElementType CRgbColor::getType () const { return et_x_RgbColor; @@ -136,6 +148,13 @@ namespace OOX m_arrItems.push_back(pRgbColor); } } + std::vector CIndexedColors::toBin() + { + std::vector objectVector; + for(auto i : m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CIndexedColors::getType () const { return et_x_IndexedColors; @@ -635,6 +654,13 @@ namespace OOX m_arrItems.push_back(color); } } + std::vector CMruColors::toBin() + { + std::vector objectVector; + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CMruColors::getType () const { return et_x_MruColors; diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index c88feb4b4fa..e5f60c05b7f 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -88,6 +88,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -115,6 +116,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; static bool GetDefaultRGBAByIndex(int index, unsigned char& unR, unsigned char& unG, unsigned char& unB, unsigned char& unA); @@ -178,6 +180,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); + std::vector toBin(); virtual EElementType getType () const; private: From 6737ac21227e807ccf529ff9ff97cd2d6196ce0e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Aug 2023 15:21:31 +0600 Subject: [PATCH 122/794] Add dxfs converting --- OOXML/XlsxFormat/Styles/dxf.cpp | 27 +++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/dxf.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/dxf.cpp b/OOXML/XlsxFormat/Styles/dxf.cpp index 2cdd59878f6..f64405901f5 100644 --- a/OOXML/XlsxFormat/Styles/dxf.cpp +++ b/OOXML/XlsxFormat/Styles/dxf.cpp @@ -44,6 +44,8 @@ #include "../../Common/SimpleTypes_Shared.h" +#include "../../../XlsbFormat/Biff12_unions/DXFS.h" + namespace OOX { namespace Spreadsheet @@ -188,6 +190,21 @@ namespace OOX } } + XLS::BaseObjectPtr CDxf::toBin() + { + auto ptr(new XLSB::DXF); + XLS::BaseObjectPtr objectPtr(ptr); + NSStringUtils::CStringBuilder writer; + toXML(writer); + XmlUtils::CXmlLiteReader oReader; + auto stringData = writer.GetData(); + + if ( !oReader.FromString(stringData)) + return objectPtr; + ptr->deserialize(oReader); + + return objectPtr; + } EElementType CDxf::getType () const { return et_x_Dxf; @@ -292,6 +309,16 @@ namespace OOX m_arrItems.push_back(new CDxf(dxf)); } } + XLS::BaseObjectPtr CDxfs::toBin() + { + auto ptr(new XLSB::DXFS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + ptr->m_aruDXF.push_back(i->toBin()); + } + return objectPtr; + } void CDxfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { // Читаем атрибуты diff --git a/OOXML/XlsxFormat/Styles/dxf.h b/OOXML/XlsxFormat/Styles/dxf.h index 62a9d518f2e..79b6679a8fd 100644 --- a/OOXML/XlsxFormat/Styles/dxf.h +++ b/OOXML/XlsxFormat/Styles/dxf.h @@ -67,6 +67,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -100,6 +101,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(std::vector& obj); + XLS::BaseObjectPtr toBin(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From a23d7864aa7b1cff5df2da80b3f198e20a0c7df4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Aug 2023 15:23:10 +0600 Subject: [PATCH 123/794] Add drawing ext conversion for styles --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 24 ++++++++ OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 65 ++++++++++++++++++++++ OOXML/XlsxFormat/Slicer/SlicerCacheExt.h | 3 + OOXML/XlsxFormat/Styles/Colors.cpp | 2 +- 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index c2954917a52..6263ecb1497 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -662,6 +662,30 @@ namespace OOX } return objectPtr; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinStyles() + { + auto ptr(new XLSB::FRTSTYLESHEET); + XLS::BaseObjectPtr objectPtr(ptr); + + if (!m_arrExt.empty()) + { + + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{EB79DEF2-80B8-43E5-95BD-54CBDDF9020C}") + { + ptr->m_STYLESHEET14 = i->m_oSlicerStyles->toBin(); + } + else if(i->m_sUri == L"{46F421CA-312F-682F-3DD2-61675219B42D}") + { + ptr->m_DXF14S = i->m_oDxfs->toBin(); + } + } + + } + return objectPtr; + } XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorksheet() { auto ptr(new XLSB::FRTWORKSHEET); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index cdd426cbe95..ca39bab04aa 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -189,6 +189,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBinWorksheet(); XLS::BaseObjectPtr toBinWorkBook(); + XLS::BaseObjectPtr toBinStyles(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 247de917d86..fd569e5852b 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -453,6 +453,35 @@ void CSlicerStyleElement::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) } pReader->Seek(_end_rec); } +XLS::BaseObjectPtr CSlicerStyleElement::toBin() +{ + auto ptr(new XLSB::SlicerStyleElement); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDxfId.IsInit()); + ptr->dxfId = m_oDxfId.get(); + if( m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithData) + ptr->tseType = 0x0000001C; + if(m_oType.IsInit()) + { + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithData) + ptr->tseType = 0x0000001C; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeUnselectedItemWithNoData) + ptr->tseType = 0x0000001D; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeSelectedItemWithData) + ptr->tseType = 0x0000001E; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeSelectedItemWithNoData) + ptr->tseType = 0x0000001F; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredUnselectedItemWithData) + ptr->tseType = 0x00000020; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredSelectedItemWithData) + ptr->tseType = 0x00000021; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredUnselectedItemWithNoData) + ptr->tseType = 0x00000022; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::ESlicerStyleType::cslicerstyletypeHoveredSelectedItemWithNoData) + ptr->tseType = 0x00000023; + } + return objectPtr; +} void CSlicerStyleElement::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -739,6 +768,24 @@ void CSlicerStyle::fromBin(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerStyle::toBin() +{ + auto ptr(new XLSB::SLICERSTYLE); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerStyle); + ptr->m_BrtBeginSlicerStyle = XLS::BaseObjectPtr{ptr1}; + ptr1->stName = m_oName.get(); + } + for(auto i: m_oSlicerStyleElements) + { + ptr->m_arBrtSlicerStyleElement.push_back(i.toBin()); + } + + + return objectPtr; +} void CSlicerStyle::ReadAttributes(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); @@ -992,6 +1039,24 @@ void CSlicerStyles::fromBin(XLS::BaseObjectPtr &obj) } } } +XLS::BaseObjectPtr CSlicerStyles::toBin() +{ + auto ptr(new XLSB::STYLESHEET14); + XLS::BaseObjectPtr objectPtr(ptr); + auto slicerStyle(new XLSB::SLICERSTYLES); + ptr->m_SLICERSTYLES = XLS::BaseObjectPtr {slicerStyle}; + + auto beginStyles(new XLSB::BeginSlicerStyles); + slicerStyle->m_BrtBeginSlicerStyles = XLS::BaseObjectPtr{beginStyles}; + if(m_oDefaultSlicerStyle.IsInit()) + beginStyles->stDefSlicer = m_oDefaultSlicerStyle.get(); + for(auto i:m_oSlicerStyle) + { + slicerStyle->m_arSLICERSTYLE.push_back(i.toBin()); + } + + return objectPtr; +} void CSlicerStyles::ReadAttributes(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index e48b5699444..3fe7869c647 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -159,6 +159,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyleElement; @@ -237,6 +238,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyle; @@ -311,6 +313,7 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const { return et_x_SlicerStyles; diff --git a/OOXML/XlsxFormat/Styles/Colors.cpp b/OOXML/XlsxFormat/Styles/Colors.cpp index 85482906512..9d8aa3a4a7b 100644 --- a/OOXML/XlsxFormat/Styles/Colors.cpp +++ b/OOXML/XlsxFormat/Styles/Colors.cpp @@ -114,7 +114,7 @@ namespace OOX { auto mruColors(new XLSB::MRUCOLORS); ptr->m_MRUCOLORS = XLS::BaseObjectPtr{mruColors}; - mruColors->m_arMRUColor = m_oMruColors->toBin() + mruColors->m_arMRUColor = m_oMruColors->toBin(); } return objectPtr; From 5a52de4b2e3745507392696a2be323289593fdbe Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Aug 2023 16:46:44 +0600 Subject: [PATCH 124/794] Add styles conversion --- OOXML/XlsxFormat/Styles/Styles.h | 1 + OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 70 ++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Styles.h b/OOXML/XlsxFormat/Styles/Styles.h index e9d94ff37ad..83ec20520f1 100644 --- a/OOXML/XlsxFormat/Styles/Styles.h +++ b/OOXML/XlsxFormat/Styles/Styles.h @@ -105,6 +105,7 @@ namespace OOX virtual ~CStyles(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index c4c32202bab..cbc1478bb3d 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -61,6 +61,8 @@ #include "../../XlsbFormat/Biff12_unions/STYLES.h" #include "../../XlsbFormat/Biff12_unions/DXFS.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -210,6 +212,44 @@ namespace OOX } } + XLS::BaseObjectPtr CStyles::WriteBin() const + { + XLSB::StylesStreamPtr stylesStream(new XLSB::StylesStream); + XLS::BaseObjectPtr objectPtr(stylesStream); + if (m_oNumFmts.IsInit()) + stylesStream->m_FMTS = m_oNumFmts->toBin(); + + if (m_oFonts.IsInit()) + stylesStream->m_FONTS = m_oFonts->toBin(); + + if (m_oFills.IsInit()) + stylesStream->m_FILLS = m_oFills->toBin(); + + if (m_oBorders.IsInit()) + stylesStream->m_BORDERS = m_oBorders->toBin(); + + if (m_oCellStyleXfs.IsInit()) + stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin(); + + if (m_oCellXfs.IsInit()) + stylesStream->m_CELLXFS = m_oCellXfs->toBin(); + + if (m_oCellStyles.IsInit()) + stylesStream->m_STYLES = m_oCellStyles->toBin(); + + if (m_oDxfs.IsInit()) + stylesStream->m_DXFS = m_oDxfs->toBin(); + + if (m_oTableStyles.IsInit()) + stylesStream->m_TABLESTYLES = m_oTableStyles->toBin(); + + if (m_oColors.IsInit()) + stylesStream->m_COLORPALETTE = m_oColors->toBin(); + + if (m_oExtLst.IsInit()) + stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); + return objectPtr; + } void CStyles::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -324,6 +364,14 @@ namespace OOX } void CStyles::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"\ @@ -341,7 +389,7 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" std::wstring sPath = oPath.GetPath(); NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); - + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); } void CStyles::AfterRead() @@ -395,7 +443,7 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" cell_style->m_oName = L"Normal"; m_oCellStyles->m_arrItems.push_back(cell_style); - + CXfs *cell_xfs = new CXfs(); cell_xfs->m_oXfId = iXfs; @@ -758,6 +806,11 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" } const OOX::FileType CStyles::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::StylesBin; + } return OOX::Spreadsheet::FileTypes::Styles; } const CPath CStyles::DefaultDirectory() const @@ -766,7 +819,18 @@ xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\">" } const CPath CStyles::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CStyles::GetReadPath() { From d93934a2d4d93825551f0255a565a6ca01be9985 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Aug 2023 19:38:18 +0600 Subject: [PATCH 125/794] Fix xfs conversion --- OOXML/XlsxFormat/Styles/Xfs.cpp | 48 ++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 68715b4da51..98a218804ed 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -90,12 +90,19 @@ namespace OOX void CAligment::toBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); - ptr->cIndent = m_oIndent.get(); + if(m_oIndent.IsInit()) + ptr->cIndent = m_oIndent.get(); + if(m_oJustifyLastLine.IsInit()) ptr->fJustLast = m_oJustifyLastLine->GetValue(); + if(m_oReadingOrder.IsInit()) ptr->iReadOrder = m_oReadingOrder.get(); + if(m_oRelativeIndent.IsInit()) ptr->iReadOrder = m_oRelativeIndent.get(); + if(m_oShrinkToFit.IsInit()) ptr->fShrinkToFit = m_oShrinkToFit->GetValue(); + if(m_oTextRotation.IsInit()) ptr->trot = m_oTextRotation.get(); + if(m_oWrapText.IsInit()) ptr->fWrap = m_oWrapText->GetValue(); if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentGeneral) @@ -366,24 +373,33 @@ namespace OOX size_t id = 1; auto ptr(new XLSB::XF(id, id)); XLS::BaseObjectPtr objectPtr(ptr); - - ptr->ixBorder = m_oBorderId->GetValue(); - m_oBorderId = ptr->ixBorder; - ptr->iFill = m_oFillId->GetValue(); - ptr->font_index = m_oFontId->GetValue(); - ptr->ifmt = m_oNumFmtId->GetValue(); - ptr->fsxButton = m_oPivotButton->GetValue(); - ptr->f123Prefix = m_oQuotePrefix->GetValue(); + if(m_oBorderId.IsInit()) + ptr->ixBorder = m_oBorderId->GetValue(); + if(m_oFillId.IsInit()) + ptr->iFill = m_oFillId->GetValue(); + if(m_oFontId.IsInit()) + ptr->font_index = m_oFontId->GetValue(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + if(m_oPivotButton.IsInit()) + ptr->fsxButton = m_oPivotButton->GetValue(); + if(m_oQuotePrefix.IsInit()) + ptr->f123Prefix = m_oQuotePrefix->GetValue(); if (m_oXfId.IsInit()) ptr->ixfParent = m_oXfId->GetValue(); - - ptr->fAtrAlc = m_oApplyAlignment->GetValue(); - ptr->fAtrBdr = m_oApplyBorder->GetValue(); - ptr->fAtrPat = m_oApplyFill->GetValue(); - ptr->fAtrFnt = m_oApplyFont->GetValue(); - ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); - ptr->fAtrProt = m_oApplyProtection->GetValue(); + if(m_oApplyAlignment.IsInit()) + ptr->fAtrAlc = m_oApplyAlignment->GetValue(); + if(m_oApplyBorder.IsInit()) + ptr->fAtrBdr = m_oApplyBorder->GetValue(); + if(m_oApplyFill.IsInit()) + ptr->fAtrPat = m_oApplyFill->GetValue(); + if(m_oApplyFont.IsInit()) + ptr->fAtrFnt = m_oApplyFont->GetValue(); + if(m_oApplyNumberFormat.IsInit()) + ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); + if(m_oApplyProtection.IsInit()) + ptr->fAtrProt = m_oApplyProtection->GetValue(); if(m_oAligment.IsInit()) m_oAligment->toBin(objectPtr); From cc9c219d62ed4ef0a1c2fd83fd8adad0df5378cd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 17 Aug 2023 13:43:20 +0600 Subject: [PATCH 126/794] Fix fonts conversion defaults --- OOXML/XlsxFormat/Styles/Fonts.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index f48586e97e6..4ef9db4f088 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -191,22 +191,33 @@ namespace OOX if(m_oItalic.IsInit()) ptr->fItalic = m_oItalic->ToBool(); + else + ptr->fItalic = false; if(m_oStrike.IsInit()) ptr->fStrikeOut = m_oStrike->ToBool(); + else + ptr->fStrikeOut = false; if(m_oOutline.IsInit()) - ptr->fOutline = m_oOutline->ToBool(); + ptr->fOutline = m_oOutline->ToBool(); + else + ptr->fOutline = false; if(m_oShadow.IsInit()) ptr->fShadow = m_oShadow->ToBool(); + else + ptr->fShadow = false; if(m_oCondense.IsInit()) ptr->fCondense = m_oCondense->ToBool(); + else + ptr->fCondense = false; if(m_oExtend.IsInit()) ptr->fExtend = m_oExtend->ToBool(); - + else + ptr->fExtend = false; if(m_oBold.IsInit()) { if(m_oBold->ToBool()) From e9dc0d4c2c7e2d113e3dd766d8f2c24503940455 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 18 Aug 2023 16:25:17 +0600 Subject: [PATCH 127/794] Fix worksheet conversion --- OOXML/XlsbFormat/Xlsb.cpp | 1 - .../Worksheets/WorksheetChildOther.cpp | 49 +++++++++++++++---- X2tConverter/src/ASCConverters.cpp | 9 ++-- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 4da4dba54d2..74a9c26ce71 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -101,7 +101,6 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oDirPath, OOX::CContentTypes return false; m_bWriteToXlsb = true; - PrepareWorkbook(); IFileContainer::Write(oDirPath / L"", OOX::CPath(_T("")), oContentTypes); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index f858118df52..4b746b0ff2a 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -964,8 +964,14 @@ namespace OOX else ptr->miyDefRwHeight = 14.4; - if (m_oOutlineLevelCol.IsInit()) ptr->iOutLevelCol = m_oOutlineLevelCol.get(); - if (m_oOutlineLevelRow.IsInit()) ptr->iOutLevelRw = m_oOutlineLevelRow.get(); + if (m_oOutlineLevelCol.IsInit()) + ptr->iOutLevelCol = m_oOutlineLevelCol.get(); + else + ptr->iOutLevelCol = 1; + if (m_oOutlineLevelRow.IsInit()) + ptr->iOutLevelRw = m_oOutlineLevelRow.get(); + else + ptr->iOutLevelRw = 1; if (m_oThickBottom.IsInit()) ptr->fExDesc = m_oThickBottom.get(); else ptr->fExDesc = false; @@ -1258,38 +1264,60 @@ namespace OOX } XLS::BaseObjectPtr CSheetView::toBin() { - if(m_oView.IsInit() || m_oTopLeftCell.IsInit() || m_oTopLeftCell.IsInit()) - { + //if(m_oView.IsInit() || m_oTopLeftCell.IsInit() || m_oTopLeftCell.IsInit()) + //{ auto pWsView(new XLSB::BeginWsView); XLS::BaseObjectPtr castedPtr(pWsView); if (m_oColorId.IsInit()) pWsView->icvHdr = m_oColorId->m_eValue; if (m_oDefaultGridColor.IsInit()) pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; + else + pWsView->fDefaultHdr = false; if (m_oRightToLeft.IsInit()) pWsView->fRightToLeft = m_oRightToLeft->m_eValue; + else + pWsView->fRightToLeft = false; if (m_oShowFormulas.IsInit()) pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; + else + pWsView->fDspFmlaRt = false; if (m_oShowGridLines.IsInit()) pWsView->fDspGridRt = m_oShowGridLines->m_eValue; + else + pWsView->fDspGridRt = false; if (m_oShowOutlineSymbols.IsInit()) pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; + else + pWsView->fDspGuts = false; if (m_oShowRowColHeaders.IsInit()) pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; + else + pWsView->fDspRwColRt = false; if (m_oShowRuler.IsInit()) pWsView->fDspRuler = m_oShowRuler->m_eValue; + else + pWsView->fDspRuler = false; if (m_oShowWhiteSpace.IsInit()) pWsView->fWhitespaceHidden = m_oShowWhiteSpace->m_eValue; + else + pWsView->fWhitespaceHidden = false; if (m_oShowZeros.IsInit()) pWsView->fDspZerosRt = m_oShowZeros->m_eValue; + else + pWsView->fDspZerosRt = false; if (m_oTabSelected.IsInit()) pWsView->fSelected = m_oTabSelected->m_eValue; + else + pWsView->fSelected = false; if(m_oTopLeftCell.IsInit()) pWsView->topLeftCell = m_oTopLeftCell.get(); if (m_oView.IsInit()) pWsView->xlView = m_oView->m_eValue; if (m_oWindowProtection.IsInit()) pWsView->fWnProt = m_oWindowProtection->m_eValue; + else + pWsView->fWnProt = false; if (m_oWorkbookViewId.IsInit()) pWsView->iWbkView = m_oWorkbookViewId->m_eValue; if (m_oZoomScale.IsInit()) @@ -1301,7 +1329,7 @@ namespace OOX if (m_oZoomScaleSheetLayoutView.IsInit()) pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; return castedPtr; - } + /*} else { auto pWsView(new XLSB::BeginCsView); @@ -1313,7 +1341,7 @@ namespace OOX if(m_oZoomScale.IsInit()) pWsView->wScale = m_oZoomScale->m_eValue; return castedPtr; - } + }*/ } EElementType CSheetView::getType() const { @@ -1457,14 +1485,15 @@ namespace OOX XLS::BaseObjectPtr CSheetViews::toBin() { auto view = m_arrItems.back(); - if(view->m_oView.IsInit() || view->m_oTopLeftCell.IsInit() || view->m_oTopLeftCell.IsInit()) - { + //if(view->m_oView.IsInit() || view->m_oTopLeftCell.IsInit() || view->m_oTopLeftCell.IsInit()) + //{ auto castedPtr(new XLSB::WSVIEWS2); XLS::BaseObjectPtr ptr(castedPtr); for(auto i:m_arrItems) castedPtr->m_arWSVIEW2.push_back(i->toBin()); return ptr; - } + //} + /* else { auto castedPtr(new XLSB::CSVIEWS); @@ -1472,7 +1501,7 @@ namespace OOX for(auto i:m_arrItems) castedPtr->m_arCSVIEW.push_back(i->toBin()); return ptr; - } + }*/ } EElementType CSheetViews::getType() const { diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 50964955d76..5ef075971f5 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1158,7 +1158,8 @@ namespace NExtractTools OOX::Spreadsheet::CXlsb oXlsb; oXlsb.m_bWriteToXlsb = true; oXlsb.Read(oox_path); - + //oXlsb.ReadSheetData(); + OOX::CContentTypes oContentTypes; nRes = oXlsb.WriteBin(sTempUnpackedXLSB, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; @@ -3117,7 +3118,7 @@ namespace NExtractTools NSDirectory::CreateDirectory(sTempUnpackedOox); _UINT32 nRes = odf_flat2oox_dir(sFrom, sTempUnpackedOox, sTemp, params); - + if (SUCCEEDED_X2T(nRes)) { nRes = dir2zipMscrypt(sTempUnpackedOox, sTo, sTemp, params); @@ -3231,9 +3232,9 @@ namespace NExtractTools { std::wstring sTempUnpackedODS = sTemp + FILE_SEPARATOR_STR + L"ods_unpacked"; NSDirectory::CreateDirectory(sTempUnpackedODS); - + Oox2Odf::Converter converter(sXlsxDir, L"spreadsheet", params.getFontPath(), bTemplate, sTemp); - + _UINT32 nRes = 0; std::wstring password = params.getSavePassword(); From aa9ff3732064346e33d577bba2c213b460b891a7 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 18 Aug 2023 19:44:42 +0300 Subject: [PATCH 128/794] Development of algorithms --- .../Reader/Converter/StarMath2OOXML/Test.cpp | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 353 ++++++++++++++++-- .../Converter/StarMath2OOXML/cstarmathpars.h | 123 ++++-- 3 files changed, 420 insertions(+), 58 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp index 1624792f997..5d42b1aaef2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -2,7 +2,7 @@ int main() { - std::wstring Temp = L"+245 + -376"; + std::wstring Temp = L"37 over 7 over 7"; StarMath::CStarMathPars TempO; TempO.Pars(Temp); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 53d1f07891d..d077fc78dd6 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -6,7 +6,7 @@ namespace StarMath { } - CStarMathPars::~CStarMathPars() + CStarMathPars::~CStarMathPars() { for(CElement* ReleaseObject: m_arParsLine) { @@ -14,40 +14,74 @@ namespace StarMath } } - void CStarMathPars::Pars(std::wstring& sStarMathLine) + void CStarMathPars::PrintAr() + { + for(int i = 0;iGetType(); + } + } + + void CStarMathPars::Pars(std::wstring& wsStarMathLine) { - std::wstring m_wsTempValueElement; - std::wstring::iterator itFirst = sStarMathLine.begin(), itEnd = sStarMathLine.end(); + std::wstring::iterator itFirst = wsStarMathLine.begin(), itEnd = wsStarMathLine.end(); while(itFirst != itEnd) { - m_wsTempValueElement = sGetElement(itFirst,itEnd); - ParsElement(m_wsTempValueElement); + m_arParsLine.push_back(ParsElement(itFirst,itEnd)); } + PrintAr(); } - std::wstring CStarMathPars::sGetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) + std::wstring CStarMathPars::GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) { std::wstring m_wsElement; for(itFirst; itFirst != itEnd;itFirst++) { - if(*itFirst != ' ') m_wsElement.push_back(*itFirst); - else + if(iswspace(*itFirst)) { itFirst++; break; } + else if(!m_wsElement.empty() && (*itFirst == L'{' || *itFirst == L'}' || (isalpha(*itFirst) && isdigit(m_wsElement.back())) || (isdigit(*itFirst) && isalpha(m_wsElement.back())))) + { + return m_wsElement; + } + else if((*itFirst == L'{' || *itFirst == L'}') && m_wsElement.empty() ) + { + m_wsElement.push_back(*itFirst); + return m_wsElement; + } + else + { + m_wsElement.push_back(*itFirst); + } } - return m_wsElement; + if(!m_wsElement.empty()) return m_wsElement; + else return {}; } - void CStarMathPars::ParsElement(std::wstring &sOneElement) + CElement* CStarMathPars::ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd) { - CNumber m_oDigit; - CUnarySign m_oUnarSign; - bool itDigit = CheckDigit(sOneElement); - if(itDigit) m_arParsLine.push_back(m_oDigit.GetNumber(sOneElement)); - else if(sOneElement.size() > 3 && CheckUnarSign(sOneElement,m_oUnarSign)) ParsElement(sOneElement); + TypeBinOperator enTypeBinOp; + std::wstring wsOneElement = GetElement(itFirst,itEnd); + if(CheckDigit(wsOneElement)) + { + return new CNumber(wsOneElement); + } + else if(CheckBinOperator(wsOneElement,enTypeBinOp) || (wsOneElement.size() == 1 && CheckOneElementBinOperator(wsOneElement[0],enTypeBinOp))) + { + if(!m_arParsLine.empty()) + { + CBinaryOperator* m_pBinOp = new CBinaryOperator; + m_pBinOp->SetLeftArg(m_arParsLine.back()); + m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd)); + m_pBinOp->SetTypeBin(enTypeBinOp); + m_arParsLine.pop_back(); + return m_pBinOp; + } + return NULL; + } } - bool CStarMathPars::CheckDigit(std::wstring &wsCheckToken) + bool CStarMathPars::CheckDigit(const std::wstring &wsCheckToken) { for(char Check: wsCheckToken) { @@ -56,7 +90,17 @@ namespace StarMath return true; } - bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) + /*bool CStarMathPars::CheckScalable_NotScalableBracket(const std::wstring &wsCheckToken, TypeElement &TypeBracket) + { + std::wstring wsSubstring; + if((wsSubstring = wsCheckToken.substr(0,4)) == L"left") + { + wsSubstring = wsCheckToken.substr(5); + return CheckScalable_NotScalableBracket(wsSubstring,TypeBracket); + } + }*/ +////////////////Requires improvement + /*bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) { std::wstring wsTempValueUnarSign; bool UnarSign = false; @@ -74,46 +118,198 @@ namespace StarMath wsCheckToken = wsCheckToken.substr(wsTempValueUnarSign.size()); } return UnarSign; + }*/ + + bool CStarMathPars::CheckBinOperator(const std::wstring &wsCheckToken, TypeBinOperator& enTypeBinOperator) + { + if(wsCheckToken == L"over") + { + enTypeBinOperator = over; + return true; + } + else if(wsCheckToken == L"cdot") + { + enTypeBinOperator = cdot; + return true; + } + else if(wsCheckToken == L"times") + { + enTypeBinOperator = times; + return true; + } + else if(wsCheckToken == L"frac") + { + enTypeBinOperator = frac; + return true; + } + else if(wsCheckToken == L"div") + { + enTypeBinOperator = div; + return true; + } + else if(wsCheckToken == L"oplus") + { + enTypeBinOperator = oplus; + return true; + } + else if(wsCheckToken == L"ominus") + { + enTypeBinOperator = ominus; + return true; + } + else if(wsCheckToken == L"odot") + { + enTypeBinOperator = odot; + return true; + } + else if(wsCheckToken == L"otimes") + { + enTypeBinOperator = otimes; + return true; + } + else if(wsCheckToken == L"odivide") + { + enTypeBinOperator = odivide; + return true; + } + else if(wsCheckToken == L"circ") + { + enTypeBinOperator = circ; + return true; + } + else if(wsCheckToken == L"wideslash") + { + enTypeBinOperator = wideslash; + return true; + } + else if(wsCheckToken == L"widebslash") + { + enTypeBinOperator = widebslash; + return true; + } + else return false; + } + + bool CStarMathPars::CheckOneElementBinOperator(const char &wsCheckToken, TypeBinOperator &enTypeBinOperator) + { + switch (wsCheckToken) + { + case '+': + enTypeBinOperator = plus; + return true; + break; + case '-': + enTypeBinOperator = minus; + return true; + break; + case '*': + enTypeBinOperator = multipl; + return true; + break; + case '/': + enTypeBinOperator = division; + return true; + break; + default: + return false; + break; + } + } + bool CStarMathPars::CheckOperator(const std::wstring &wsCheckToken, TypeOperator & enTypeOperator) + { + if(wsCheckToken == L"lim") + { + enTypeOperator = lim; + return true; + } + else if(wsCheckToken == L"sum") + { + enTypeOperator = sum; + return true; + } + else return false; + } + /*bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken, TypeBinOperator &TypeIndex) + { + if(wsCheckToken == L"from") + { + TypeIndex = SM_Index_from; + return true; + } + else if(wsCheckToken ==L"to") + { + TypeIndex = SM_Index_to; + return true; + } + else return false; + }*/ + bool CStarMathPars::CheckBracket(const char &wsCheckToken, TypeBracket & enTypeBracket) + { + switch (wsCheckToken) { + case '{': + enTypeBracket = brace_opening; + return true; + break; + case '}': + enTypeBracket = brace_closing; + return true; + break; + case '(': + enTypeBracket = round_opening; + return true; + break; + case ')': + enTypeBracket = round_closing; + return true; + break; + case '[': + enTypeBracket = square_opening; + return true; + break; + case ']': + enTypeBracket = square_closing; + return true; + break; + default: + return false; + break; + } } //Class methods CNumber CNumber::CNumber() { } - + CNumber::CNumber(const std::wstring &wsValue) + { + this->m_wsValueNumber = wsValue; + } CNumber::~CNumber() { } std::wstring CNumber::GetValue() { - return m_sValueNumber; + return m_wsValueNumber; } TypeElement CNumber::GetType() { return Number; } - CNumber* CNumber::GetNumber(std::wstring& sNumberElement) - { - - CNumber* oValue = new CNumber; - oValue->m_sValueNumber = sNumberElement; - return oValue; //Class methods CUnarySign - } - CUnarySign* CUnarySign::GetUnarSign(std::wstring& sUnarToken) + CUnarySign* CUnarySign::GetUnarSign(const std::wstring& wsUnarToken) { CUnarySign* oSign = new CUnarySign; - oSign->m_sUnar = sUnarToken; + oSign->m_wsUnar = wsUnarToken; return oSign; } std::wstring CUnarySign::GetValue() { - return m_sUnar; + return m_wsUnar; } TypeElement CUnarySign::GetType() { - return m_UnarType; + return m_enUnarType; } CUnarySign::CUnarySign() {} @@ -123,15 +319,104 @@ namespace StarMath CBinaryOperator::CBinaryOperator() {} CBinaryOperator::~CBinaryOperator() - {} + { + for(CElement* ReleaseObject: arLeftArg) + { + delete ReleaseObject; + } + for(CElement* ReleaseObject: arRightArg) + { + delete ReleaseObject; + } + } TypeElement CBinaryOperator::GetType() { - return m_TypeSign; + for(CElement* enTemp: arLeftArg) + { + std::wcout<< enTemp->GetType() << std::endl; + } + for(CElement* enTemp: arRightArg) + { + std::wcout<< enTemp->GetType() << std::endl; + } + return BinOperator; } std::wstring CBinaryOperator::GetValue() { - std::cout << m_TypeSign; + return {}; + } + TypeBinOperator CBinaryOperator::GetTypeBin() + { + return enTypeBinOp; + } + void CBinaryOperator::SetLeftArg( CElement *oLeftArg) + { + this->arLeftArg.push_back(oLeftArg); + } + void CBinaryOperator::SetRightArg(CElement *oRightArg) + { + this->arRightArg.push_back(oRightArg); + } + void CBinaryOperator::SetTypeBin(const TypeBinOperator &enType) + { + this->enTypeBinOp = enType; + } +//Class methods COperator + COperator::COperator() + {} + COperator::~COperator() + {} + TypeElement COperator::GetType() + { + return enType; + } + std::wstring COperator::GetValue() + { + return L""; + } + COperator* COperator::GetOperator(const TypeElement &enTypeOper) + { + COperator* oOper = new COperator; + oOper->enType = enTypeOper; + return oOper; + } +//Class methods CIndex + CIndex::CIndex() + {} + CIndex::~CIndex() + {} + TypeElement CIndex::GetType() + { + return enType; + } + std::wstring CIndex::GetValue() + { + return L"Good"; + } + CIndex* CIndex::GetIndex(const TypeElement &enTypeIndex) + { + CIndex* oIndex = new CIndex; + oIndex->enType = enTypeIndex; + return oIndex; + } +//Class methods CBracket + CBracket::CBracket() + {} + CBracket::~CBracket() + {} + TypeElement CBracket::GetType() + { + return enTypeEl; + } + std::wstring CBracket::GetValue() + { return L"Good"; } + CBracket* CBracket::GetBracket(const TypeBracket &enTypeBracket) + { + CBracket* oBracket = new CBracket; + oBracket->enTypeBracket = enTypeBracket; + return oBracket; + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f8164011c8d..dc5583a137d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -3,10 +3,54 @@ #include #include #include +#include namespace StarMath { - enum TypeElement{Number,UnarSign,SM_BinOper_cdot,SM_BinOper_times,SM_BinOper_over,SM_BinOper_plus,SM_BinOper_minus,SM_BinOper_frac,SM_BinOper_div}; + enum TypeElement{ + Number, + BinOperator, + Operator, + Bracket, + UnarSign, + Box, + SM_Index_from, + SM_Index_to, + }; + enum TypeBinOperator + { + cdot, + times, + over, + plus, + minus, + frac, + div, + multipl, + division, + oplus, + ominus, + odot, + otimes, + odivide, + circ, + wideslash, + widebslash, + }; + enum TypeOperator + { + lim, + sum, + }; + enum TypeBracket + { + brace_opening, + brace_closing, + round_opening, + round_closing, + square_opening, + square_closing, + }; class CElement { public: @@ -18,13 +62,12 @@ namespace StarMath { public: CNumber(); + CNumber(const std::wstring& wsValue); ~CNumber(); - CNumber* GetNumber(std::wstring& sNumberElement); std::wstring GetValue() override; TypeElement GetType() override ; private: - std::wstring m_sValueNumber; - TypeElement m_Number = Number; + std::wstring m_wsValueNumber; }; class CUnarySign: public CElement @@ -34,44 +77,78 @@ namespace StarMath ~CUnarySign(); std::wstring GetValue() override; TypeElement GetType() override; - CUnarySign* GetUnarSign(std::wstring& sUnarToken); + CUnarySign* GetUnarSign(const std::wstring& wsUnarToken); private: - std::wstring m_sUnar; - TypeElement m_UnarType = UnarSign; + std::wstring m_wsUnar; + TypeElement m_enUnarType = UnarSign; }; class CBinaryOperator: public CElement { public: CBinaryOperator(); - ~CBinaryOperator(); + virtual ~CBinaryOperator(); std::wstring GetValue() override; TypeElement GetType() override; - CBinaryOperator* GetSign(std::wstring& wsSignToken); + TypeBinOperator GetTypeBin(); + void SetTypeBin(const TypeBinOperator& enType); + void SetLeftArg(CElement* oLeftArg); + void SetRightArg(CElement* oRightArg); private: - TypeElement m_TypeSign; + TypeBinOperator enTypeBinOp; + std::vector arLeftArg; + std::vector arRightArg; }; - - class CBoxValue: public CElement + class COperator: public CElement { public: - CBoxValue(); - ~CBoxValue(); - CBoxValue* ReadBox(std::string::iterator& itStartBox,std::string::iterator& itEndBox); + COperator(); + ~COperator(); std::wstring GetValue() override; + TypeElement GetType() override; + COperator* GetOperator(const TypeElement& enTypeOper); private: - std::vector arValueBox; + TypeElement enType; + }; + class CIndex: public CElement + { + public: + CIndex(); + ~CIndex(); + std::wstring GetValue() override; + TypeElement GetType() override; + CIndex* GetIndex(const TypeElement& enTypeIndex); + private: + TypeElement enType; + }; + class CBracket: public CElement + { + public: + CBracket(); + ~CBracket(); + std::wstring GetValue() override; + TypeElement GetType() override; + CBracket* GetBracket(const TypeBracket& enTypeBracket); + private: + TypeBracket enTypeBracket; + TypeElement enTypeEl; }; - class CStarMathPars { public: CStarMathPars(); - ~CStarMathPars(); - void Pars(std::wstring& sStarMathLine); - std::wstring sGetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); - void ParsElement(std::wstring& sOneElement); - bool CheckDigit(std::wstring& wsCheckToken); - bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& m_oUnarSign); + virtual ~CStarMathPars(); + void Pars(std::wstring& wsStarMathLine); + std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); + CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd); + bool CheckDigit(const std::wstring& wsCheckToken); + bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); + bool CheckBinOperator(const std::wstring& wsCheckToken,TypeBinOperator& enTypeBinOperator); + bool CheckOneElementBinOperator(const char& wsCheckToken, TypeBinOperator& enTypeBinOperator); + bool CheckOperator(const std::wstring& wsCheckToken,TypeOperator& enTypeOperator); + bool CheckIndex(const std::wstring& wsCheckToken, TypeElement& TypeIndex); + bool CheckBracket(const char& wsCheckToken,TypeBracket& TypeBracket); + bool CheckScalable_NotScalableBracket(const std::wstring& wsCheckToken, TypeElement& TypeBracket); + void PrintAr(); private: std::vector m_arParsLine; }; From 60797121d2da0d383ecbb68751cafba168cc97b4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 21 Aug 2023 22:01:47 +0600 Subject: [PATCH 129/794] Add shared strings conversion --- OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp | 61 +++++++++++++++++++ OOXML/XlsxFormat/SharedStrings/PhoneticPr.h | 2 + OOXML/XlsxFormat/SharedStrings/Run.h | 1 + .../SharedStrings/SharedStrings.cpp | 17 ++++++ .../XlsxFormat/SharedStrings/SharedStrings.h | 1 + OOXML/XlsxFormat/SharedStrings/Si.cpp | 47 ++++++++++++++ OOXML/XlsxFormat/SharedStrings/Si.h | 1 + OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp | 14 +++++ 8 files changed, 144 insertions(+) diff --git a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp index ec4a8136fd0..1f0b6bae304 100644 --- a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp +++ b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.cpp @@ -67,6 +67,53 @@ namespace OOX { ReadAttributes(obj); } + void CPhonetic::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + if(m_oAlignment.IsInit()) + { + if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentNoControl) + { + ptr->alcH = 0; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentLeft) + { + ptr->alcH = 1; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentCenter) + { + ptr->alcH = 2; + } + else if(m_oAlignment == SimpleTypes::Spreadsheet::phoneticalignmentDistributed) + { + ptr->alcH = 3; + } + } + if(m_oType.IsInit()) + { + if(m_oType == SimpleTypes::Spreadsheet::phonetictypeHalfwidthKatakana) + { + ptr->phType = 0; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeFullwidthKatakana) + { + ptr->phType = 1; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeHiragana) + { + ptr->phType = 2; + } + else if(m_oType == SimpleTypes::Spreadsheet::phonetictypeNoConversion) + { + ptr->phType = 3; + } + } + + if(m_oFontId.IsInit()) + { + ptr->ifnt = m_oFontId->GetValue(); + } + } EElementType CPhonetic::getType () const { return et_x_PhoneticPr; @@ -167,6 +214,20 @@ namespace OOX m_arrItems.push_back(ptr); ReadAttributes(obj); } + std::wstring CRPh::toBin(XLS::BiffStructure* obj) + { + auto ptr = static_cast(obj); + std::wstring result; + if(!m_arrItems.empty()) + { + result = m_arrItems.back()->ToString(); + } + if(m_oEb.IsInit()) + ptr->ichMom = m_oEb->GetValue(); + if(m_oSb.IsInit()) + ptr->ichFirst = m_oSb->GetValue(); + return result; + } EElementType CRPh::getType () const { return et_x_rPh; diff --git a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h index 5185461cc10..2c63de3ae1b 100644 --- a/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h +++ b/OOXML/XlsxFormat/SharedStrings/PhoneticPr.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); virtual EElementType getType () const; private: @@ -88,6 +89,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj, std::wstring& str); + std::wstring toBin(XLS::BiffStructure* obj); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/SharedStrings/Run.h b/OOXML/XlsxFormat/SharedStrings/Run.h index 3f6e9831222..6cd18133c59 100644 --- a/OOXML/XlsxFormat/SharedStrings/Run.h +++ b/OOXML/XlsxFormat/SharedStrings/Run.h @@ -53,6 +53,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::wstring& str, unsigned short fontindex); + std::wstring toBin(unsigned short &fontindex); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index a47ea14445e..c761aa81e28 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -102,6 +102,23 @@ namespace OOX } } + XLS::BaseObjectPtr CSharedStrings::WriteBin() const + { + XLSB::SharedStringsStreamPtr sharedStringsStream(new XLSB::SharedStringsStream); + auto ptr(new XLSB::SHAREDSTRINGS); + XLS::BaseObjectPtr objectPtr(ptr); + + auto atribPtr(new XLSB::BeginSst); + if(m_oCount.IsInit()) + atribPtr->cstTotal = m_oCount->GetValue(); + atribPtr->cstUnique = m_oUniqueCount->GetValue(); + + for(auto i:m_arrItems) + { + ptr->m_BrtBeginSst = i->toBin(); + } + return objectPtr; + } void CSharedStrings::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h index 19e99b05b7a..e8c7b7d513f 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h @@ -54,6 +54,7 @@ namespace OOX virtual ~CSharedStrings(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index 16ee76e6d23..d6e87ac7727 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -130,6 +130,53 @@ namespace OOX m_arrItems.push_back( pItem ); } } + XLS::BaseObjectPtr CSi::toBin() const + { + auto sString(new XLSB::SSTItem); + XLS::BaseObjectPtr objectPtr(sString); + auto ptr = &sString->richStr; + + for(auto i = 0; i < m_arrItems.size(); i++) + { + auto text = static_cast(m_arrItems[i]); + if(text) + { + ptr->str = text->ToString(); + continue; + } + auto crunPtr = static_cast(m_arrItems[i]); + if(crunPtr) + { + USHORT ind = 0; + ptr->str = ptr->str.value() + crunPtr->toBin(ind); + XLSB::StrRun run; + run.ifnt = ind; + run.ich = ptr->str.value().size(); + ptr->rgsStrRun.push_back(run); + } + auto phonPtr = static_cast(m_arrItems[i]); + if(phonPtr) + { + XLSB::PhRun phRun; + phonPtr->toBin(&phRun); + if(i < m_arrItems.size() - 1) + { + auto ph = static_cast(m_arrItems[i+1]); + if(ph) + { + auto phoneticStr = ph->toBin(&phRun); + if(!phoneticStr.empty()) + ptr->phoneticStr = phoneticStr; + } + i++; + } + + ptr->rgsPhRun.push_back(phRun); + } + } + + return objectPtr; + } void CSi::fromBin(XLS::BiffStructure& obj, bool flagIsComment) { auto ptr = static_cast(&obj); diff --git a/OOXML/XlsxFormat/SharedStrings/Si.h b/OOXML/XlsxFormat/SharedStrings/Si.h index d641677d11b..efdc78f6ce7 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.h +++ b/OOXML/XlsxFormat/SharedStrings/Si.h @@ -63,6 +63,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj, bool flagIsComment = false); + XLS::BaseObjectPtr toBin() const; void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream); void toXLSBExt (NSBinPptxRW::CXlsbBinaryWriter& oStream); diff --git a/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp b/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp index 53509a026a6..f9bfb95c114 100644 --- a/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp +++ b/OOXML/XlsxFormat/SharedStrings/XlsxRun.cpp @@ -97,6 +97,20 @@ namespace OOX m_oRPr->m_nFontIndex.Init(); m_oRPr->m_nFontIndex = fontindex; } + std::wstring CRun::toBin(unsigned short &fontindex) + { + if(m_oRPr.IsInit()) + { + if(m_oRPr->m_nFontIndex.IsInit()) + fontindex = m_oRPr->m_nFontIndex->GetValue(); + } + if(!m_arrItems.empty()) + { + auto textPtr = m_arrItems.back(); + return textPtr->ToString(); + } + return L""; + } EElementType CRun::getType () const { return et_x_r; From 14e78b8a93e7e9660c811d10dea281b4f3691577 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 22 Aug 2023 17:37:33 +0600 Subject: [PATCH 130/794] Add shared strings writing --- .../SharedStrings/SharedStrings.cpp | 50 ++++++++++++++----- OOXML/XlsxFormat/SharedStrings/Si.cpp | 5 +- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index c761aa81e28..a8e3890bfd1 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -38,6 +38,8 @@ #include "../../XlsbFormat/Biff12_unions/SHAREDSTRINGS.h" #include "../../XlsbFormat/Biff12_records/SSTItem.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -178,25 +180,38 @@ namespace OOX } void CSharedStrings::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - NSStringUtils::CStringBuilder writer; - writer.WriteString(_T("GetValue()); - WritingStringNullableAttrInt(L"uniqueCount", m_oUniqueCount, m_oUniqueCount->GetValue()); - writer.WriteString(_T(">")); - - for(size_t i = 0; i < m_arrItems.size(); i++) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - m_arrItems[i]->toXML(writer); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); } + else + { + NSStringUtils::CStringBuilder writer; + writer.WriteString(_T("GetValue()); + WritingStringNullableAttrInt(L"uniqueCount", m_oUniqueCount, m_oUniqueCount->GetValue()); + writer.WriteString(_T(">")); - writer.WriteString(_T("")); - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath.c_str(), writer.GetData()); + for(size_t i = 0; i < m_arrItems.size(); i++) + { + m_arrItems[i]->toXML(writer); + } + writer.WriteString(_T("")); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath.c_str(), writer.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); } const OOX::FileType CSharedStrings::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SharedStringsBin; + } return OOX::Spreadsheet::FileTypes::SharedStrings; } const CPath CSharedStrings::DefaultDirectory() const @@ -205,7 +220,18 @@ namespace OOX } const CPath CSharedStrings::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + CPath name = type().DefaultFileName(); + + name.SetExtention(L"bin"); + return name; + } + else + { + return type().DefaultFileName(); + } } const CPath& CSharedStrings::GetReadPath() { diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index d6e87ac7727..b9f6e31e61b 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -135,7 +135,8 @@ namespace OOX auto sString(new XLSB::SSTItem); XLS::BaseObjectPtr objectPtr(sString); auto ptr = &sString->richStr; - + ptr->fExtStr = false; + ptr->fRichStr = false; for(auto i = 0; i < m_arrItems.size(); i++) { auto text = static_cast(m_arrItems[i]); @@ -147,6 +148,7 @@ namespace OOX auto crunPtr = static_cast(m_arrItems[i]); if(crunPtr) { + ptr->fRichStr = true; USHORT ind = 0; ptr->str = ptr->str.value() + crunPtr->toBin(ind); XLSB::StrRun run; @@ -157,6 +159,7 @@ namespace OOX auto phonPtr = static_cast(m_arrItems[i]); if(phonPtr) { + ptr->fExtStr = true; XLSB::PhRun phRun; phonPtr->toBin(&phRun); if(i < m_arrItems.size() - 1) From 60b7fabad96f536e3ef1ef131423f84e2698086c Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 22 Aug 2023 20:24:45 +0600 Subject: [PATCH 131/794] Fix shared strings conversion --- OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index a8e3890bfd1..a9cc1c86ec3 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -111,13 +111,15 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); auto atribPtr(new XLSB::BeginSst); + ptr->m_BrtBeginSst = XLS::BaseObjectPtr{atribPtr}; if(m_oCount.IsInit()) atribPtr->cstTotal = m_oCount->GetValue(); + if(m_oUniqueCount.IsInit()) atribPtr->cstUnique = m_oUniqueCount->GetValue(); for(auto i:m_arrItems) { - ptr->m_BrtBeginSst = i->toBin(); + ptr->m_arBrtSSTItem.push_back(i->toBin()); } return objectPtr; } From 568582f2b5f2ab01d070f8fd37a4909076e02759 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 23 Aug 2023 20:37:30 +0600 Subject: [PATCH 132/794] Add default values for xlsb conversion --- OOXML/XlsxFormat/Styles/Borders.cpp | 7 ++++ OOXML/XlsxFormat/Styles/Fonts.cpp | 6 +++ OOXML/XlsxFormat/Workbook/BookViews.cpp | 10 +++++ OOXML/XlsxFormat/Workbook/CalcPr.cpp | 18 +++++++++ OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 4 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 38 +++++++++++++++++-- .../Worksheets/WorksheetChildOther.cpp | 12 +++--- 7 files changed, 85 insertions(+), 10 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 383ae94ce7d..23a60068942 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -141,6 +141,13 @@ namespace OOX auto ptr = static_cast(obj); if(m_oColor.IsInit()) ptr->brtColor = m_oColor->toColor(); + else + { + XLSB::Color col; + col.xColorType = 0; + ptr->brtColor = col; + } + if(!m_oStyle.IsInit()) return; diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 4ef9db4f088..8028fc89577 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -249,6 +249,12 @@ namespace OOX if(m_oColor.IsInit()) ptr->brtColor = m_oColor->toColor(); + else + { + XLSB::Color col; + col.xColorType = 0; + ptr->brtColor = col; + } if(m_oScheme.IsInit()) { diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index 86bcc02f7a6..40a01cf6490 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -81,6 +81,8 @@ namespace OOX if (m_oActiveTab.IsInit()) ptr->itabCur = m_oActiveTab->GetValue(); + else + ptr->itabCur = 0; if (m_oAutoFilterDateGrouping.IsInit()) ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); @@ -98,12 +100,20 @@ namespace OOX ptr->wTabRatio = m_oTabRatio->GetValue(); if (m_oWindowHeight.IsInit()) ptr->dyWn = m_oWindowHeight->GetValue(); + else + ptr->dyWn = 12750; if (m_oWindowWidth.IsInit()) ptr->dxWn = m_oWindowWidth->GetValue(); + else + ptr->dxWn = 21240; if (m_oXWindow.IsInit()) ptr->xWn = m_oXWindow->GetValue(); + else + ptr->xWn = 2280; if (m_oYWindow.IsInit()) ptr->yWn = m_oYWindow->GetValue(); + else + ptr->yWn = 1650; if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) { diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.cpp b/OOXML/XlsxFormat/Workbook/CalcPr.cpp index 01c6c8cd80a..8e1cdee0c93 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.cpp +++ b/OOXML/XlsxFormat/Workbook/CalcPr.cpp @@ -97,22 +97,40 @@ namespace OOX ptr->fRefA1 = !m_oRefMode->GetValue(); if(m_oIterate.IsInit()) ptr->fIter = m_oIterate->GetValue(); + else + ptr->fIter = 0; if(m_oIterateCount.IsInit()) ptr->cCalcCount = m_oIterateCount->GetValue(); + else + ptr->cCalcCount = 100; if(m_oIterateDelta.IsInit()) ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); + else + ptr->xnumDelta.data.value = 0.001; if(m_oFullPrecision.IsInit()) ptr->fFullPrec = m_oFullPrecision->GetValue(); + else + ptr->fFullPrec = false; if(m_oCalcCompleted.IsInit()) ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); + else + ptr->fSomeUncalced = false; if(m_oCalcOnSave.IsInit()) ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); + else + ptr->fSaveRecalc = false; if(m_oConcurrentCalc.IsInit()) ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); + else + ptr->fMTREnabled = false; if(m_oConcurrentManualCount.IsInit()) ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); + else + ptr->cUserThreadCount = 1; if(m_oForceFullCalc.IsInit()) ptr->fNoDeps = m_oForceFullCalc->GetValue(); + else + ptr->fNoDeps = false; return objectPtr; } diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index b5c8a37e537..896114150c0 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -111,7 +111,9 @@ namespace OOX if(m_oDateCompatibility.IsInit()) ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); if(m_oDefaultThemeVersion.IsInit()) - ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); + ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); + else + ptr->dwThemeVersion = 0; if(m_oFilterPrivacy.IsInit()) ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); if(m_oHidePivotFieldList.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 8334243c6da..1ab1bc6e359 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1795,6 +1795,7 @@ namespace OOX XLSB::FMLACELL* pFMLACELL = nullptr; XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; BiffRecord* pSource = nullptr; + XLSB::Cell* oCell; if(!m_oType.IsInit()) { @@ -1818,6 +1819,7 @@ namespace OOX pCellRk->value.fX100 = 1; pCellRk->value.num = std::stod(m_oValue->m_sText) * 100; } + oCell = &pCellRk->cell; pSource = pCellRk; } break; @@ -1828,12 +1830,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x00; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x00; + oCell = &error->cell; pSource = error; } } @@ -1843,12 +1847,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x07; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x07; + oCell = &error->cell; pSource = error; } } @@ -1858,12 +1864,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x17; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x17; + oCell = &error->cell; pSource = error; } } @@ -1873,12 +1881,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x1D; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x1D; + oCell = &error->cell; pSource = error; } } @@ -1888,12 +1898,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x24; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x24; + oCell = &error->cell; pSource = error; } } @@ -1903,12 +1915,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x2A; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x2A; + oCell = &error->cell; pSource = error; } } @@ -1918,12 +1932,14 @@ namespace OOX { auto error = new XLSB::FmlaError; error->value = 0x2B; + oCell = &error->cell; pSource = error; } else { auto error = new XLSB::CellError; error->value = 0x2B; + oCell = &error->cell; pSource = error; } } @@ -1934,14 +1950,16 @@ namespace OOX if(m_oFormula.IsInit()) { auto cellBool(new XLSB::FmlaBool); - pSource = cellBool; cellBool->value = m_oValue->m_sText == L"1" ? true : false; + oCell = &cellBool->cell; + pSource = cellBool; } else { auto cellBool(new XLSB::CellBool); - pSource = cellBool; cellBool->value = m_oValue->m_sText == L"1" ? true : false; + oCell = &cellBool->cell; + pSource = cellBool; } } break; @@ -1949,6 +1967,7 @@ namespace OOX { auto pCellIsst(new XLSB::CellIsst); pCellIsst->value = std::stoi(m_oValue->m_sText); + oCell = &pCellIsst->cell; pSource = pCellIsst; } break; @@ -1960,6 +1979,8 @@ namespace OOX auto str(new XLSB::FmlaString); if(m_oValue.IsInit()) str->value = m_oValue->m_sText; + oCell = &str->cell; + pSource = str; } @@ -1968,6 +1989,7 @@ namespace OOX auto str(new XLSB::CellSt); if(m_oValue.IsInit()) str->value = m_oValue->m_sText; + oCell = &str->cell; pSource = str; } } @@ -2031,7 +2053,15 @@ namespace OOX pSHRFMLACELL->m_source = m_oFormula->toBin(); } } - + oCell->column = m_oCol.get(); + if(m_oShowPhonetic.IsInit()) + oCell->fPhShow = m_oShowPhonetic->GetValue(); + else + oCell->fPhShow = false; + if(m_oStyle.IsInit()) + oCell->iStyleRef = m_oStyle.get(); + else + oCell->iStyleRef = 0; return objectPtr; } void CCell::fromBin(XLS::BaseObjectPtr& obj) @@ -2686,6 +2716,8 @@ namespace OOX if(m_oHt.IsInit()) hdrPtr->miyRw = m_oHt->GetValue() * 20.; + else + hdrPtr->miyRw = 240; if(m_oOutlineLevel.IsInit()) hdrPtr->iOutLevel = m_oOutlineLevel->GetValue(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 4b746b0ff2a..f8783ea6d5e 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -444,22 +444,22 @@ namespace OOX XLS::BaseObjectPtr objPtr(ptr); if(m_oLeft.IsInit()) - ptr->xnumLeft.data.value = m_oLeft->GetValue(); + ptr->xnumLeft.data.value = std::round(m_oLeft->GetValue() * 100) / 100; if(m_oTop.IsInit()) - ptr->xnumTop.data.value = m_oTop->GetValue(); + ptr->xnumTop.data.value = std::round(m_oTop->GetValue() * 100) / 100; if(m_oRight.IsInit()) - ptr->xnumRight.data.value = m_oRight->GetValue(); + ptr->xnumRight.data.value = std::round(m_oRight->GetValue() * 100) / 100; if(m_oBottom.IsInit()) - ptr->xnumBottom.data.value = m_oBottom->GetValue(); + ptr->xnumBottom.data.value = std::round(m_oBottom->GetValue() * 100) / 100; if(m_oHeader.IsInit()) - ptr->xnumHeader.data.value = m_oHeader->GetValue(); + ptr->xnumHeader.data.value = std::round(m_oHeader->GetValue() * 100) / 100; if(m_oFooter.IsInit()) - ptr->xnumFooter.data.value = m_oFooter->GetValue(); + ptr->xnumFooter.data.value = std::round(m_oFooter->GetValue() * 100) / 100; return objPtr; } From a38a0c302d3e3f248d2a332d847afb7207252858 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 24 Aug 2023 20:06:32 +0600 Subject: [PATCH 133/794] Fix sheet view conversion --- .../Worksheets/WorksheetChildOther.cpp | 89 ++++++++++++++++++- .../Worksheets/WorksheetChildOther.h | 2 + 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index f8783ea6d5e..c9a2dc7e2e1 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1057,6 +1057,43 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CPane::toBin() + { + auto ptr(new XLSB::Pane); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oActivePane.IsInit()) + { + if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + ptr->pnnAcct_xlsb = 0; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + ptr->pnnAcct_xlsb = 1; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + ptr->pnnAcct_xlsb = 2; + else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + ptr->pnnAcct_xlsb = 3; + } + + if(m_oState.IsInit()) + { + if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozenSplit) + ptr->fFrozen = true; + else if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozen) + ptr->fFrozenNoSplit = true; + } + if(m_oTopLeftCell.IsInit()) + ptr->topLeftCell = m_oTopLeftCell.get(); + if(m_oXSplit.IsInit()) + ptr->xnumXSplit.data.value = m_oXSplit->GetValue(); + else + ptr->xnumXSplit.data.value = 0; + if(m_oYSplit.IsInit()) + ptr->xnumYSplit.data.value = m_oYSplit->GetValue(); + else + ptr->xnumYSplit.data.value = 0; + + return objectPtr; + } EElementType CPane::getType() const { return et_x_Pane; @@ -1130,6 +1167,30 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSelection::toBin() + { + auto ptr(new XLSB::Sel); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oActiveCell.IsInit()) + ptr->activeCell = m_oActiveCell.get(); + if(m_oActiveCellId.IsInit()) + ptr->irefAct = m_oActiveCellId->GetValue(); + if(m_oSqref.IsInit()) + ptr->sqref = m_oSqref.get(); + if(m_oPane.IsInit()) + { + if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + ptr->pnn_xlsb = 0; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + ptr->pnn_xlsb = 1; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + ptr->pnn_xlsb = 2; + else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + ptr->pnn_xlsb = 3; + } + + return objectPtr; + } EElementType CSelection::getType() const { return et_x_Selection; @@ -1266,14 +1327,19 @@ namespace OOX { //if(m_oView.IsInit() || m_oTopLeftCell.IsInit() || m_oTopLeftCell.IsInit()) //{ + auto ptr(new XLSB::WSVIEW2); + XLS::BaseObjectPtr castedPtr(ptr); auto pWsView(new XLSB::BeginWsView); - XLS::BaseObjectPtr castedPtr(pWsView); + ptr->m_BrtBeginWsView = XLS::BaseObjectPtr{pWsView}; + if (m_oColorId.IsInit()) pWsView->icvHdr = m_oColorId->m_eValue; + else + pWsView->icvHdr = 64; if (m_oDefaultGridColor.IsInit()) pWsView->fDefaultHdr = m_oDefaultGridColor->m_eValue; else - pWsView->fDefaultHdr = false; + pWsView->fDefaultHdr = true; if (m_oRightToLeft.IsInit()) pWsView->fRightToLeft = m_oRightToLeft->m_eValue; else @@ -1285,11 +1351,11 @@ namespace OOX if (m_oShowGridLines.IsInit()) pWsView->fDspGridRt = m_oShowGridLines->m_eValue; else - pWsView->fDspGridRt = false; + pWsView->fDspGridRt = true; if (m_oShowOutlineSymbols.IsInit()) pWsView->fDspGuts = m_oShowOutlineSymbols->m_eValue; else - pWsView->fDspGuts = false; + pWsView->fDspGuts = true; if (m_oShowRowColHeaders.IsInit()) pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; else @@ -1322,12 +1388,27 @@ namespace OOX pWsView->iWbkView = m_oWorkbookViewId->m_eValue; if (m_oZoomScale.IsInit()) pWsView->wScale = m_oZoomScale->m_eValue; + else + pWsView->wScale = 100; if (m_oZoomScaleNormal.IsInit()) pWsView->wScaleNormal = m_oZoomScaleNormal->m_eValue; + else + pWsView->wScaleNormal = 0; if (m_oZoomScalePageLayoutView.IsInit()) pWsView->wScalePLV = m_oZoomScalePageLayoutView->m_eValue; + else + pWsView->wScalePLV = 0; if (m_oZoomScaleSheetLayoutView.IsInit()) pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; + else + pWsView->wScaleSLV = 0; + if(m_oPane.IsInit()) + ptr->m_BrtPane = m_oPane->toBin(); + + for(auto i:m_arrItems) + { + ptr->m_arBrtSel.push_back(i->toBin()); + } return castedPtr; /*} else diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index c744b9073af..34c2a938064 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -335,6 +335,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -364,6 +365,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: From 8a02c684f426d57d3a861a25480acee38a869a79 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Aug 2023 14:11:18 +0600 Subject: [PATCH 134/794] Fix characters --- OOXML/XlsxFormat/Styles/Colors.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Colors.cpp b/OOXML/XlsxFormat/Styles/Colors.cpp index 9d8aa3a4a7b..5b9d98cfe09 100644 --- a/OOXML/XlsxFormat/Styles/Colors.cpp +++ b/OOXML/XlsxFormat/Styles/Colors.cpp @@ -105,9 +105,9 @@ namespace OOX if(m_oIndexedColors.IsInit()) { - auto indexСolors(new XLSB::INDEXEDCOLORS); - ptr->m_INDEXEDCOLORS = XLS::BaseObjectPtr{indexСolors}; - indexСolors->m_arIndexedColor = m_oIndexedColors->toBin(); + auto indexColors(new XLSB::INDEXEDCOLORS); + ptr->m_INDEXEDCOLORS = XLS::BaseObjectPtr{indexColors}; + indexColors->m_arIndexedColor = m_oIndexedColors->toBin(); } if(m_oMruColors.IsInit()) From e2143e170a03f4130af4b2f46f5c89c828f50ff0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Aug 2023 20:30:42 +0600 Subject: [PATCH 135/794] Fix sheet format pr conversion --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index c9a2dc7e2e1..1c5044c963a 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -956,22 +956,22 @@ namespace OOX ptr->cchDefColWidth = m_oDefaultColWidth.get(); if(!m_oBaseColWidth.IsInit()) { - ptr->dxGCol = m_oDefaultColWidth.get(); + ptr->dxGCol = m_oDefaultColWidth.get() * 256; } } if (m_oDefaultRowHeight.IsInit()) - ptr->miyDefRwHeight = m_oDefaultRowHeight.get(); + ptr->miyDefRwHeight = m_oDefaultRowHeight.get() * 20; else - ptr->miyDefRwHeight = 14.4; + ptr->miyDefRwHeight = 290; if (m_oOutlineLevelCol.IsInit()) ptr->iOutLevelCol = m_oOutlineLevelCol.get(); else - ptr->iOutLevelCol = 1; + ptr->iOutLevelCol = 0; if (m_oOutlineLevelRow.IsInit()) ptr->iOutLevelRw = m_oOutlineLevelRow.get(); else - ptr->iOutLevelRw = 1; + ptr->iOutLevelRw = 0; if (m_oThickBottom.IsInit()) ptr->fExDesc = m_oThickBottom.get(); else ptr->fExDesc = false; @@ -979,6 +979,7 @@ namespace OOX else ptr->fExAsc = false; if (m_oZeroHeight.IsInit()) ptr->fDyZero = m_oZeroHeight.get(); else ptr->fDyZero = false; + ptr->fUnsynced = false; return Castedptr; } EElementType CSheetFormatPr::getType() const @@ -1359,7 +1360,7 @@ namespace OOX if (m_oShowRowColHeaders.IsInit()) pWsView->fDspRwColRt = m_oShowRowColHeaders->m_eValue; else - pWsView->fDspRwColRt = false; + pWsView->fDspRwColRt = true; if (m_oShowRuler.IsInit()) pWsView->fDspRuler = m_oShowRuler->m_eValue; else From 5ac9df5d896dca72939302c363d9e9825a594f7e Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 25 Aug 2023 18:28:53 +0300 Subject: [PATCH 136/794] Improvement of functionality (brackets, scalable brackets, attributes) --- .../Reader/Converter/StarMath2OOXML/Test.cpp | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 509 ++++++++++++++---- .../Converter/StarMath2OOXML/cstarmathpars.h | 123 +++-- 3 files changed, 510 insertions(+), 124 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp index 5d42b1aaef2..7284ecff940 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -2,7 +2,7 @@ int main() { - std::wstring Temp = L"37 over 7 over 7"; + std::wstring Temp = L"lim from color red bold {7 over 5 over 3} to 56 721 "; StarMath::CStarMathPars TempO; TempO.Pars(Temp); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index d077fc78dd6..87576579c8a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -27,27 +27,30 @@ namespace StarMath std::wstring::iterator itFirst = wsStarMathLine.begin(), itEnd = wsStarMathLine.end(); while(itFirst != itEnd) { - m_arParsLine.push_back(ParsElement(itFirst,itEnd)); + m_arParsLine.push_back(ParsElement(itFirst,itEnd,m_arParsLine)); + //std::wcout << GetElement(itFirst,itEnd)<& arParsLine) { TypeBinOperator enTypeBinOp; + TypeBracket enTypeBracket; + TypeOperator enTypeOp; + TypeAttribute enTypeAtt; std::wstring wsOneElement = GetElement(itFirst,itEnd); if(CheckDigit(wsOneElement)) { return new CNumber(wsOneElement); } - else if(CheckBinOperator(wsOneElement,enTypeBinOp) || (wsOneElement.size() == 1 && CheckOneElementBinOperator(wsOneElement[0],enTypeBinOp))) + else if(wsOneElement.size() == 1 && CheckOneElementBinOperator(wsOneElement[0],enTypeBinOp)) + { + return new CBinaryOperator(enTypeBinOp); + } + else if(CheckBinOperator(wsOneElement,enTypeBinOp)) { - if(!m_arParsLine.empty()) + if(!arParsLine.empty()) { CBinaryOperator* m_pBinOp = new CBinaryOperator; - m_pBinOp->SetLeftArg(m_arParsLine.back()); - m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd)); + m_pBinOp->SetLeftArg(arParsLine.back()); + m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd,arParsLine)); m_pBinOp->SetTypeBin(enTypeBinOp); - m_arParsLine.pop_back(); + arParsLine.pop_back(); return m_pBinOp; } return NULL; } + else if(CheckBracket(wsOneElement[0],enTypeBracket)) + { + std::vector arValueBrecket; + std::wstring::iterator itTempIteratorforBacket = itFirst; + wsOneElement = GetElement(itFirst,itEnd); + while(wsOneElement[0] != L'}') + { + arValueBrecket.push_back(ParsElement(itTempIteratorforBacket,itEnd,arValueBrecket)); + itFirst = itTempIteratorforBacket; + wsOneElement = GetElement(itFirst,itEnd); + } + return new CBracket(arValueBrecket,enTypeBracket); + } + else if(CheckOperator(wsOneElement,enTypeOp)) + { + COperator* oTempOp = new COperator; + std::vector arValueBrecket; + std::wstring::iterator itSavePos; + do + { + itSavePos = itFirst; + wsOneElement = GetElement(itFirst,itEnd); + if( wsOneElement == L"from") + oTempOp->SetFrom(ParsElement(itFirst,itEnd,arValueBrecket)); + else if(wsOneElement == L"to") + oTempOp->SetTo(ParsElement(itFirst,itEnd,arValueBrecket)); + else + break; + }while(true); + oTempOp->SetValueOp(ParsElement(itSavePos,itEnd,arValueBrecket)); + oTempOp->SetTypeOp(enTypeOp); + return oTempOp; + } + else if(CheckTopAttribute(wsOneElement,enTypeAtt) || CheckPropertiesAttribute(wsOneElement,enTypeAtt)|| (wsOneElement == L"color" && CheckColorAttribute(GetElement(itFirst,itEnd),enTypeAtt))) + { + return new CAttribute(ParsElement(itFirst,itEnd,arParsLine),enTypeAtt); + } +// else if(wsOneElement == L"left" && CheckScalable_NotScalableBracket(GetElement(itFirst,itEnd),enTypeBracket)) +// { +// std::vector arValueBrecket; +// std::wstring::iterator itTempIteratorforBacket = itFirst; +// wsOneElement = GetElement(itFirst,itEnd); +// while(wsOneElement != L"right") +// { +// arValueBrecket.push_back(ParsElement(itTempIteratorforBacket,itEnd,arValueBrecket)); +// itFirst = itTempIteratorforBacket; +// wsOneElement = GetElement(itFirst,itEnd); +// } +// wsOneElement = GetElement(itFirst,itEnd); +// return new CBracket(arValueBrecket,enTypeBracket); +// } } bool CStarMathPars::CheckDigit(const std::wstring &wsCheckToken) @@ -89,16 +150,44 @@ namespace StarMath } return true; } - - /*bool CStarMathPars::CheckScalable_NotScalableBracket(const std::wstring &wsCheckToken, TypeElement &TypeBracket) + bool CStarMathPars::CheckScalable_NotScalableBracket(const std::wstring &wsCheckToken, TypeBracket &enType) { - std::wstring wsSubstring; - if((wsSubstring = wsCheckToken.substr(0,4)) == L"left") + if(wsCheckToken == L"ldbracket") { - wsSubstring = wsCheckToken.substr(5); - return CheckScalable_NotScalableBracket(wsSubstring,TypeBracket); + enType = ldbracket; + return true; } - }*/ + else if(wsCheckToken == L"lbrace") + { + enType = lbrace; + return true; + } + else if(wsCheckToken == L"langle") + { + enType = langle; + return true; + } + else if(wsCheckToken == L"lceil") + { + enType = lceil; + return true; + } + else if(wsCheckToken == L"lfloor") + { + enType = lfloor; + return true; + } + else if(wsCheckToken == L"lline") + { + enType = lline; + return true; + } + else if(wsCheckToken == L"ldline") + { + enType = ldline; + return true; + } + } ////////////////Requires improvement /*bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) { @@ -197,22 +286,18 @@ namespace StarMath case '+': enTypeBinOperator = plus; return true; - break; case '-': enTypeBinOperator = minus; return true; - break; + case '*': enTypeBinOperator = multipl; return true; - break; case '/': enTypeBinOperator = division; return true; - break; default: return false; - break; } } bool CStarMathPars::CheckOperator(const std::wstring &wsCheckToken, TypeOperator & enTypeOperator) @@ -229,52 +314,256 @@ namespace StarMath } else return false; } - /*bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken, TypeBinOperator &TypeIndex) + bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken) { if(wsCheckToken == L"from") { - TypeIndex = SM_Index_from; return true; } else if(wsCheckToken ==L"to") { - TypeIndex = SM_Index_to; return true; } else return false; - }*/ + } bool CStarMathPars::CheckBracket(const char &wsCheckToken, TypeBracket & enTypeBracket) { switch (wsCheckToken) { case '{': - enTypeBracket = brace_opening; + enTypeBracket = brace; return true; - break; - case '}': - enTypeBracket = brace_closing; - return true; - break; case '(': - enTypeBracket = round_opening; - return true; - break; - case ')': - enTypeBracket = round_closing; + enTypeBracket = round; return true; - break; case '[': - enTypeBracket = square_opening; + enTypeBracket = square; return true; - break; - case ']': - enTypeBracket = square_closing; - return true; - break; default: return false; - break; } } + bool CStarMathPars::CheckTopAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt) + { + if(wsCheckToken == L"acute") + { + enTypeAtt = acute; + return true; + } + else if(wsCheckToken == L"breve") + { + enTypeAtt = breve; + return true; + } + else if(wsCheckToken == L"dot") + { + enTypeAtt = dot; + return true; + } + else if(wsCheckToken == L"dddot") + { + enTypeAtt = dddot; + return true; + } + else if(wsCheckToken == L"vec") + { + enTypeAtt = vec; + return true; + } + else if(wsCheckToken == L"tilde") + { + enTypeAtt = tilde; + return true; + } + else if(wsCheckToken == L"check") + { + enTypeAtt = check; + return true; + } + else if(wsCheckToken == L"grave") + { + enTypeAtt = grave; + return true; + } + else if(wsCheckToken == L"circle") + { + enTypeAtt = circle; + return true; + } + else if(wsCheckToken == L"ddot") + { + enTypeAtt = ddot; + return true; + } + else if(wsCheckToken == L"bar") + { + enTypeAtt = bar; + return true; + } + else if(wsCheckToken == L"harpoon") + { + enTypeAtt = harpoon; + return true; + } + else if(wsCheckToken == L"hat") + { + enTypeAtt = hat; + return true; + } + else if(wsCheckToken == L"widevec") + { + enTypeAtt = widevec; + return true; + } + else if(wsCheckToken == L"widetilde") + { + enTypeAtt = widetilde; + return true; + } + else if(wsCheckToken == L"overline") + { + enTypeAtt = overline; + return true; + } + else if(wsCheckToken == L"overstrike") + { + enTypeAtt = overstrike; + return true; + } + else if(wsCheckToken == L"wideharpoon") + { + enTypeAtt = wideharpoon; + return true; + } + else if(wsCheckToken == L"widehat") + { + enTypeAtt = widehat; + return true; + } + else if(wsCheckToken == L"underline") + { + enTypeAtt = underline; + return true; + } + else return false; + } + bool CStarMathPars::CheckPropertiesAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt) + { + if(wsCheckToken == L"phantom") + { + enTypeAtt = phantom; + return true; + } + else if(wsCheckToken == L"bold") + { + enTypeAtt = bold; + return true; + } + else if(wsCheckToken == L"ital") + { + enTypeAtt = ital; + return true; + } + else return false; + } + bool CStarMathPars::CheckColorAttribute(const std::wstring &wsCheckToken, TypeAttribute &enTypeAtt) + { + if(wsCheckToken == L"black") + { + enTypeAtt = black; + return true; + } + else if(wsCheckToken == L"green") + { + enTypeAtt = green; + return true; + } + else if(wsCheckToken == L"aqua") + { + enTypeAtt = aqua; + return true; + } + else if(wsCheckToken == L"yellow") + { + enTypeAtt = yellow; + return true; + } + else if(wsCheckToken == L"lime") + { + enTypeAtt = lime; + return true; + } + else if(wsCheckToken == L"navy") + { + enTypeAtt = navy; + return true; + } + else if(wsCheckToken == L"purple") + { + enTypeAtt = purple; + return true; + } + else if(wsCheckToken == L"teal") + { + enTypeAtt = teal; + return true; + } + else if(wsCheckToken == L"blue") + { + enTypeAtt = blue; + return true; + } + else if(wsCheckToken == L"red") + { + enTypeAtt = red; + return true; + } + else if(wsCheckToken == L"fuchsia") + { + enTypeAtt = fuchsia; + return true; + } + else if(wsCheckToken == L"gray") + { + enTypeAtt = gray; + return true; + } + else if(wsCheckToken == L"maroon") + { + enTypeAtt = maroon; + return true; + } + else if(wsCheckToken == L"olive") + { + enTypeAtt = olive; + return true; + } + else if(wsCheckToken == L"silver") + { + enTypeAtt = silver; + return true; + } + else if(wsCheckToken == L"coral") + { + enTypeAtt = coral; + return true; + } + else if(wsCheckToken == L"midnightblue") + { + enTypeAtt = midnightblue; + return true; + } + else if(wsCheckToken == L"crimson") + { + enTypeAtt = crimson; + return true; + } + else if(wsCheckToken == L"violet") + { + enTypeAtt = violet; + return true; + } + else return false; + } //Class methods CNumber CNumber::CNumber() { @@ -318,27 +607,19 @@ namespace StarMath //Class methods CBinaryOperator CBinaryOperator::CBinaryOperator() {} + CBinaryOperator::CBinaryOperator(const TypeBinOperator &enType) + { + enTypeBinOp = enType; + arLeftArg = nullptr; + arRightArg = nullptr; + } CBinaryOperator::~CBinaryOperator() { - for(CElement* ReleaseObject: arLeftArg) - { - delete ReleaseObject; - } - for(CElement* ReleaseObject: arRightArg) - { - delete ReleaseObject; - } + delete arLeftArg; + delete arRightArg; } TypeElement CBinaryOperator::GetType() { - for(CElement* enTemp: arLeftArg) - { - std::wcout<< enTemp->GetType() << std::endl; - } - for(CElement* enTemp: arRightArg) - { - std::wcout<< enTemp->GetType() << std::endl; - } return BinOperator; } std::wstring CBinaryOperator::GetValue() @@ -351,72 +632,114 @@ namespace StarMath } void CBinaryOperator::SetLeftArg( CElement *oLeftArg) { - this->arLeftArg.push_back(oLeftArg); + this->arLeftArg = oLeftArg; } void CBinaryOperator::SetRightArg(CElement *oRightArg) { - this->arRightArg.push_back(oRightArg); + this->arRightArg = oRightArg; } void CBinaryOperator::SetTypeBin(const TypeBinOperator &enType) { this->enTypeBinOp = enType; } //Class methods COperator - COperator::COperator() + COperator::COperator(): oFromValue(NULL),oToValue(NULL),oValueOp(NULL) {} COperator::~COperator() - {} + { + delete oFromValue; + delete oToValue; + delete oValueOp; + } TypeElement COperator::GetType() { - return enType; + /*std::wcout << oFromValue->GetType() <GetType() <GetType() <enType = enTypeOper; - return oOper; + return enTypeOp; } -//Class methods CIndex - CIndex::CIndex() - {} - CIndex::~CIndex() - {} - TypeElement CIndex::GetType() + void COperator::SetFrom(CElement *oFrom) { - return enType; + oFromValue = oFrom; } - std::wstring CIndex::GetValue() + void COperator::SetTo(CElement *oTo) { - return L"Good"; + oToValue = oTo; } - CIndex* CIndex::GetIndex(const TypeElement &enTypeIndex) + void COperator::SetValueOp(CElement *oValue) { - CIndex* oIndex = new CIndex; - oIndex->enType = enTypeIndex; - return oIndex; + oValueOp = oValue; + } + void COperator::SetTypeOp(const TypeOperator& enType) + { + enTypeOp = enType; + } + void COperator::AvailabilityMline() + { + bMline = true; } //Class methods CBracket CBracket::CBracket() {} + CBracket::CBracket(const std::vector& arValue,const TypeBracket& enType) + { + arBrecketVal = arValue; + enTypeBracket = enType; + } CBracket::~CBracket() - {} + { + for(CElement* ReleaseObject: arBrecketVal) + { + delete ReleaseObject; + } + } TypeElement CBracket::GetType() { - return enTypeEl; + for(CElement* enTemp: arBrecketVal) + { + std::wcout<< enTemp->GetType() << std::endl; + } + return Bracket; } std::wstring CBracket::GetValue() { - return L"Good"; + return {}; + } +//Class methods CAttribute + CAttribute::CAttribute() + {} + CAttribute::CAttribute(CElement *oValue, const TypeAttribute &enType) + { + enTypeAtt = enType; + oValueAtt = oValue; + } + CAttribute::~CAttribute() + { + delete oValueAtt; + } + std::wstring CAttribute::GetValue() + { + return {}; + } + TypeElement CAttribute::GetType() + { + return Attribute; + } + void CAttribute::SetTypeAtt(const TypeAttribute &enType) + { + enTypeAtt = enType; } - CBracket* CBracket::GetBracket(const TypeBracket &enTypeBracket) + void CAttribute::SetValueAtt(CElement *oValue) { - CBracket* oBracket = new CBracket; - oBracket->enTypeBracket = enTypeBracket; - return oBracket; + oValueAtt = oValue; } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index dc5583a137d..e0c8a4cb149 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -13,9 +13,7 @@ namespace StarMath Operator, Bracket, UnarSign, - Box, - SM_Index_from, - SM_Index_to, + Attribute, }; enum TypeBinOperator { @@ -44,12 +42,61 @@ namespace StarMath }; enum TypeBracket { - brace_opening, - brace_closing, - round_opening, - round_closing, - square_opening, - square_closing, + brace, + round, + square, + ldbracket, + lbrace, + langle, + lceil, + lfloor, + lline, + ldline, + }; + enum TypeAttribute + { + acute, + breve, + dot, + dddot, + vec, + tilde, + check, + grave, + circle, + ddot, + bar, + harpoon, + hat, + widevec, + widetilde, + overline, + overstrike, + wideharpoon, + widehat, + underline,//top elements + phantom, + bold, + ital,//properties (without a pin and headset) + black, + green, + aqua, + yellow, + lime, + navy, + purple, + teal, + blue, + red, + fuchsia, + gray, + maroon, + olive, + silver, + coral, + midnightblue, + crimson, + violet,//color(without rgb and hex) }; class CElement { @@ -63,7 +110,7 @@ namespace StarMath public: CNumber(); CNumber(const std::wstring& wsValue); - ~CNumber(); + virtual ~CNumber(); std::wstring GetValue() override; TypeElement GetType() override ; private: @@ -86,6 +133,7 @@ namespace StarMath { public: CBinaryOperator(); + CBinaryOperator(const TypeBinOperator& enType); virtual ~CBinaryOperator(); std::wstring GetValue() override; TypeElement GetType() override; @@ -95,42 +143,54 @@ namespace StarMath void SetRightArg(CElement* oRightArg); private: TypeBinOperator enTypeBinOp; - std::vector arLeftArg; - std::vector arRightArg; + CElement* arLeftArg; + CElement* arRightArg; }; class COperator: public CElement { public: COperator(); - ~COperator(); + virtual ~COperator(); std::wstring GetValue() override; TypeElement GetType() override; - COperator* GetOperator(const TypeElement& enTypeOper); + TypeOperator GetTypeOp(); + void SetTypeOp(const TypeOperator& enType); + void SetFrom(CElement* oFrom); + void SetTo(CElement* oTo); + void SetValueOp(CElement* oValue); + void AvailabilityMline(); private: - TypeElement enType; + TypeOperator enTypeOp; + CElement* oFromValue{nullptr}; + CElement* oToValue{nullptr}; + CElement* oValueOp{nullptr}; + bool bMline{false}; }; - class CIndex: public CElement + class CBracket: public CElement { public: - CIndex(); - ~CIndex(); + CBracket(); + CBracket(const std::vector& arValue,const TypeBracket& enType); + virtual ~CBracket(); std::wstring GetValue() override; TypeElement GetType() override; - CIndex* GetIndex(const TypeElement& enTypeIndex); private: - TypeElement enType; + TypeBracket enTypeBracket; + std::vector arBrecketVal; }; - class CBracket: public CElement + class CAttribute: public CElement { public: - CBracket(); - ~CBracket(); + CAttribute(); + CAttribute(CElement* oValue,const TypeAttribute& enType); + virtual ~CAttribute(); std::wstring GetValue() override; TypeElement GetType() override; - CBracket* GetBracket(const TypeBracket& enTypeBracket); + void SetTypeAtt(const TypeAttribute& enType); + void SetValueAtt(CElement* oValue); private: - TypeBracket enTypeBracket; - TypeElement enTypeEl; + TypeAttribute enTypeAtt; + CElement* oValueAtt; }; class CStarMathPars { @@ -139,15 +199,18 @@ namespace StarMath virtual ~CStarMathPars(); void Pars(std::wstring& wsStarMathLine); std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); - CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd); + CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, std::vector& arParsLine); bool CheckDigit(const std::wstring& wsCheckToken); bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); bool CheckBinOperator(const std::wstring& wsCheckToken,TypeBinOperator& enTypeBinOperator); bool CheckOneElementBinOperator(const char& wsCheckToken, TypeBinOperator& enTypeBinOperator); bool CheckOperator(const std::wstring& wsCheckToken,TypeOperator& enTypeOperator); - bool CheckIndex(const std::wstring& wsCheckToken, TypeElement& TypeIndex); - bool CheckBracket(const char& wsCheckToken,TypeBracket& TypeBracket); - bool CheckScalable_NotScalableBracket(const std::wstring& wsCheckToken, TypeElement& TypeBracket); + bool CheckIndex(const std::wstring& wsCheckToken); + bool CheckBracket(const char& wsCheckToken,TypeBracket& enTypeBracket); + bool CheckScalable_NotScalableBracket(const std::wstring& wsCheckToken, TypeBracket& enType); + bool CheckTopAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt); + bool CheckPropertiesAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt); + bool CheckColorAttribute(const std::wstring& wsCheckToken, TypeAttribute& enTypeAtt); void PrintAr(); private: std::vector m_arParsLine; From 6a1897d342867b20964954ac02112d0539af67d5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 29 Aug 2023 18:19:30 +0600 Subject: [PATCH 137/794] Fix book views conversion --- OOXML/XlsxFormat/Workbook/BookViews.cpp | 112 +++++++++++++----------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index 40a01cf6490..cc2cc8a740d 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -76,60 +76,72 @@ namespace OOX } XLS::BaseObjectPtr CWorkbookView::toBin() { - auto ptr(new XLSB::BookView); + auto ptr(new XLS::Window1); XLS::BaseObjectPtr objectPtr(ptr); - if (m_oActiveTab.IsInit()) - ptr->itabCur = m_oActiveTab->GetValue(); - else - ptr->itabCur = 0; + if (m_oActiveTab.IsInit()) + { + ptr->itabCur = m_oActiveTab->GetValue(); + ptr->ctabSel = m_oActiveTab->GetValue(); + } + else + { + ptr->itabCur = 0; + ptr->ctabSel = 0; + } - if (m_oAutoFilterDateGrouping.IsInit()) - ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); - if (m_oFirstSheet.IsInit()) - ptr->itabFirst = m_oFirstSheet->GetValue(); - if (m_oMinimized.IsInit()) - ptr->fIconic = m_oMinimized->GetValue(); - if (m_oShowHorizontalScroll.IsInit()) - ptr->fDspHScroll = m_oShowHorizontalScroll->GetValue(); - if (m_oShowSheetTabs.IsInit()) - ptr->fBotAdornment = m_oShowSheetTabs->GetValue(); - if (m_oShowVerticalScroll.IsInit()) - ptr->fDspVScroll = m_oShowVerticalScroll->GetValue(); - if (m_oTabRatio.IsInit()) - ptr->wTabRatio = m_oTabRatio->GetValue(); - if (m_oWindowHeight.IsInit()) - ptr->dyWn = m_oWindowHeight->GetValue(); - else - ptr->dyWn = 12750; - if (m_oWindowWidth.IsInit()) - ptr->dxWn = m_oWindowWidth->GetValue(); - else - ptr->dxWn = 21240; - if (m_oXWindow.IsInit()) - ptr->xWn = m_oXWindow->GetValue(); - else - ptr->xWn = 2280; - if (m_oYWindow.IsInit()) - ptr->yWn = m_oYWindow->GetValue(); - else - ptr->yWn = 1650; + if (m_oAutoFilterDateGrouping.IsInit()) + ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); + if (m_oFirstSheet.IsInit()) + ptr->itabFirst = m_oFirstSheet->GetValue(); + else + ptr->itabFirst = 0; + if (m_oMinimized.IsInit()) + ptr->fIconic = m_oMinimized->GetValue(); + else + ptr->fIconic = false; + if (m_oShowHorizontalScroll.IsInit()) + ptr->fDspHScroll = m_oShowHorizontalScroll->GetValue(); + if (m_oShowSheetTabs.IsInit()) + ptr->fBotAdornment = m_oShowSheetTabs->GetValue(); + if (m_oShowVerticalScroll.IsInit()) + ptr->fDspVScroll = m_oShowVerticalScroll->GetValue(); + if (m_oTabRatio.IsInit()) + ptr->wTabRatio = m_oTabRatio->GetValue(); + else + ptr->wTabRatio = 600; + if (m_oWindowHeight.IsInit()) + ptr->dyWn = m_oWindowHeight->GetValue(); + else + ptr->dyWn = 12750; + if (m_oWindowWidth.IsInit()) + ptr->dxWn = m_oWindowWidth->GetValue(); + else + ptr->dxWn = 21240; + if (m_oXWindow.IsInit()) + ptr->xWn = m_oXWindow->GetValue() * 6; + else + ptr->xWn = 2280; + if (m_oYWindow.IsInit()) + ptr->yWn = m_oYWindow->GetValue() * 110; + else + ptr->yWn = 1650; - if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) - { - ptr->fHidden = true; - ptr->fVeryHidden = false; - } - else if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) - { - ptr->fHidden = false; - ptr->fVeryHidden = true; - } - else - { - ptr->fHidden = false; - ptr->fVeryHidden = false; - } + if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + { + ptr->fHidden = true; + ptr->fVeryHidden = false; + } + else if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + { + ptr->fHidden = false; + ptr->fVeryHidden = true; + } + else + { + ptr->fHidden = false; + ptr->fVeryHidden = false; + } return objectPtr; } From e11e314b22b852969568187060ff6513c83b34e0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 29 Aug 2023 22:51:37 +0300 Subject: [PATCH 138/794] Update drop caps drop caps is shapes now --- DocxRenderer/src/logic/Page.cpp | 94 +++++++++++-------- DocxRenderer/src/logic/Page.h | 1 - DocxRenderer/src/logic/elements/ContText.cpp | 1 + DocxRenderer/src/logic/elements/Converter.cpp | 1 - DocxRenderer/src/logic/elements/DropCap.cpp | 24 ++--- DocxRenderer/src/logic/elements/DropCap.h | 3 +- DocxRenderer/src/logic/elements/Shape.cpp | 13 +-- DocxRenderer/src/logic/elements/TextLine.cpp | 14 +++ DocxRenderer/src/logic/elements/TextLine.h | 1 + .../src/logic/managers/FontManager.cpp | 3 +- 10 files changed, 91 insertions(+), 64 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 2c68a65646d..9fa1bb08a25 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -64,11 +64,6 @@ namespace NSDocxRenderer delete val; m_arOutputObjects.clear(); - for(auto& val : m_arDropCaps) - delete val; - m_arDropCaps.clear(); - - ClearTables(); m_pCurrentLine = nullptr; m_pCurrentRow = nullptr; @@ -367,7 +362,6 @@ namespace NSDocxRenderer dTextH = m_pFontManager->GetFontHeight(); double dBaseLinePos = dTextY + fBaseLineOffset; - auto pCont = new CContText(m_pFontManager); pCont->m_dLeft = dTextX; @@ -921,7 +915,7 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arTextLine.size(); ++i) CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); - //AnalyzeDropCaps(); + AnalyzeDropCaps(); AnalyzeCollectedConts(); DetermineStrikeoutsUnderlinesHighlights(); AddDiacriticalSymbols(); @@ -941,65 +935,96 @@ namespace NSDocxRenderer { double avg_font_size = m_pParagraphStyleManager->GetAvgFontSize(); - std::vector possible_caps; + std::vector> possible_caps; + std::vector drop_caps; + for(size_t i = 0; i < m_arTextLine.size(); i++) { auto& line = m_arTextLine[i]; for(auto& cont : line->m_arConts) if(!cont->m_bIsNotNecessaryToUse && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) - possible_caps.push_back(cont); + possible_caps.push_back({cont, line}); } - for(auto& cap : possible_caps) + for(auto& possible_cap : possible_caps) { + auto& drop_cap_cont = possible_cap.first; + auto& drop_cap_line = possible_cap.second; + size_t num_of_lines = 0; for(auto& line : m_arTextLine) { + if(line == drop_cap_line) + continue; + // буквица должна быть левее - if(line->m_dLeft < cap->m_dLeft) + if(line->m_dLeft < drop_cap_cont->m_dLeft) continue; // если совпадает строка - берем ее и выходим - if(fabs(line->m_dBaselinePos - cap->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + if(fabs(line->m_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { num_of_lines++; break; } - if(line->m_dBaselinePos > cap->m_dBaselinePos) + if(line->m_dBaselinePos > drop_cap_cont->m_dBaselinePos) break; - if(fabs(line->m_dTop - cap->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < cap->m_dTop) - continue; - - bool skip = false; - for(auto& cont : line->m_arConts) - if(cont == cap) - { - skip = true; - continue; - } - - if(skip) + if(fabs(line->m_dTop - drop_cap_cont->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < drop_cap_cont->m_dTop) continue; num_of_lines++; } if(num_of_lines) { - cap->m_bIsNotNecessaryToUse = true; - CDropCap* drop_cap = new CDropCap(); - *static_cast(drop_cap) = *cap; + *static_cast(drop_cap) = *drop_cap_cont; drop_cap->nLines = num_of_lines; - drop_cap->wsFont = cap->m_pFontStyle->wsFontName; - drop_cap->wsText = cap->m_oText.ToStdWString(); + drop_cap->wsFont = drop_cap_cont->m_pFontStyle->wsFontName; + drop_cap->wsText = drop_cap_cont->m_oText.ToStdWString(); - drop_cap->nFontSize = static_cast(cap->m_pFontStyle->dFontSize * 2); - m_arDropCaps.push_back(drop_cap); + drop_cap->nFontSize = static_cast(drop_cap_cont->m_pFontStyle->dFontSize * 2); + drop_caps.push_back(drop_cap); + + drop_cap_cont->m_bIsNotNecessaryToUse = true; + drop_cap_line->RecalcSizes(); } } + + // шейпы из буквиц + for(auto&& drop_cap : drop_caps) + { + auto shape = new CShape(); + shape->m_eType = CShape::eShapeType::stTextBox; + + // перемерим на подобранном шрифте + NSStructures::CFont oFont; + oFont.Name = drop_cap->wsFont; + oFont.Size = static_cast(drop_cap->nFontSize) / 2.0; + m_pFontManager->LoadFontByName(oFont); + + double box_X; + double box_Y; + double box_W; + double box_H; + + m_pFontManager->SetStringGid(0); + m_pFontManager->MeasureString(drop_cap->wsText, 0, 0, box_X, box_Y, box_W, box_H, CFontManager::mtPosition); + + shape->m_dBaselinePos = drop_cap->m_dBaselinePos; + shape->m_dHeight = box_H; + shape->m_dTop = drop_cap->m_dBaselinePos - shape->m_dHeight; + + shape->m_dRight = drop_cap->m_dRight; + shape->m_dLeft = drop_cap->m_dLeft; + shape->m_dWidth = drop_cap->m_dWidth; + + shape->m_arOutputObjects.push_back(drop_cap); + shape->m_bIsBehindDoc = false; + m_arShapes.push_back(shape); + } } void CPage::AnalyzeCollectedConts() { @@ -1667,11 +1692,6 @@ namespace NSDocxRenderer m_arShapes[i]->ToXml(oWriter); } - for (size_t i = 0; i < m_arDropCaps.size(); ++i) - { - m_arDropCaps[i]->ToXml(oWriter); - } - if (bIsTextShapePresent) { for (size_t i = 0; i < m_arOutputObjects.size(); ++i) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 65a86c637e3..6135741dd41 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -38,7 +38,6 @@ namespace NSDocxRenderer std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; std::vector m_arShapes; - std::vector m_arDropCaps; std::vector m_arOutputObjects; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 511459345ee..551b3787fe6 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -112,6 +112,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); + //oWriter.WriteString(L""); oWriter.WriteString(L"wsFontStyleId); diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 6e89ff242fa..f0992c3fbd4 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -460,7 +460,6 @@ namespace NSDocxRenderer pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); pParagraph->RemoveHighlightColor(); - // pParagraph->MergeLines(); } else diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp index b216c270dc8..4c65e3c513e 100644 --- a/DocxRenderer/src/logic/elements/DropCap.cpp +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -9,17 +9,17 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L"((m_dBaselinePos - m_dTop) * c_dMMToDx * 0.96)); + oWriter.AddInt(static_cast((m_dBaselinePos - m_dTop) * c_dMMToDx)); oWriter.WriteString(L"\" "); oWriter.WriteString(L"w:lineRule=\"exact\" />"); - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\" w:y=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\" />"); +// oWriter.WriteString(L""); +// oWriter.WriteString(L" w:x=\""); +// oWriter.AddInt(static_cast(m_dLeft * c_dMMToDx)); +// oWriter.WriteString(L"\" w:y=\""); +// oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); +// oWriter.WriteString(L"\" />"); oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -28,9 +28,11 @@ namespace NSDocxRenderer L"\" w:eastAsia=\"" + wsFont + L"\" w:cs=\"" + wsFont + L"\" />"); - //oWriter.WriteString(L""); +// oWriter.WriteString(L""); oWriter.WriteString(L"((double)nFontSize * 0.95)); + oWriter.AddInt(nFontSize); oWriter.WriteString(L"\" />"); oWriter.WriteString(L""); oWriter.WriteString(L"" + wsText + L""); diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h index fe1c42aafec..99594dfe1cb 100644 --- a/DocxRenderer/src/logic/elements/DropCap.h +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -12,7 +12,8 @@ namespace NSDocxRenderer std::wstring wsText; std::wstring wsFont; - LONG nFontSize; + LONG nFontSize; // Pt * 2 + LONG nOffset; CDropCap() : CBaseItem(ElemType::etDropCap) {} ~CDropCap() = default; diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 2ca2db718f5..6e88a62868b 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -969,18 +969,7 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } + pObj->ToXml(oWriter); } oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 0de979d455b..b916568fae0 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -133,6 +133,20 @@ namespace NSDocxRenderer } } + void CTextLine::RecalcSizes() + { + m_dLeft = 0.0; + m_dTop = 0.0; + m_dWidth = 0.0; + m_dHeight = 0.0; + m_dBaselinePos = 0.0; + m_dRight = 0.0; + + for(auto&& cont : m_arConts) + if(!cont->m_bIsNotNecessaryToUse) + CBaseItem::AddContent(cont); + } + void CTextLine::SetVertAlignType(const eVertAlignType& oType) { m_eVertAlignType = oType; diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index c9ca4c3172b..919f3455759 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -31,6 +31,7 @@ namespace NSDocxRenderer void CheckLineToNecessaryToUse(); void MergeConts(); + void RecalcSizes(); void SetVertAlignType(const eVertAlignType& oType); bool IsShadingPresent(const CTextLine* pLine); }; diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index f72202de4a1..08ad8ae4ede 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -567,7 +567,7 @@ namespace NSDocxRenderer double CFontManager::GetFontHeight() const { - return c_dPtToMM * (m_oFontMetrics.dLineSpacing * m_oFont.Size ) / m_oFontMetrics.dEmHeight; + return c_dPtToMM * (m_oFontMetrics.dLineSpacing * m_oFont.Size) / m_oFontMetrics.dEmHeight; } double CFontManager::GetSpaceWidthMM() const { @@ -770,6 +770,7 @@ namespace NSDocxRenderer void CFontManager::ClearCache() { + m_oFont = {}; if (nullptr == m_pManager) return; m_pManager->GetCache()->Clear(); From dd532eb8236939c28900c930ebe44beccd33e657 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 31 Aug 2023 17:21:58 +0600 Subject: [PATCH 139/794] Add table conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 20 ++++ OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Table/Table.h | 6 ++ OOXML/XlsxFormat/Table/Tables.cpp | 130 ++++++++++++++++++++++++ 4 files changed, 157 insertions(+) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 6263ecb1497..687746ca596 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -683,6 +683,26 @@ namespace OOX } } + } + return objectPtr; + } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinTable() + { + auto ptr(new XLSB::FRTTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + if (!m_arrExt.empty()) + { + + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{504A1905-F514-4f6f-8877-14C23A59335A}") + { + ptr->m_BrtList14 = i->m_oAltTextTable->toBin(); + } + + } + } return objectPtr; } diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index ca39bab04aa..0a0206890c5 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -190,6 +190,7 @@ namespace OOX XLS::BaseObjectPtr toBinWorksheet(); XLS::BaseObjectPtr toBinWorkBook(); XLS::BaseObjectPtr toBinStyles(); + XLS::BaseObjectPtr toBinTable(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Table/Table.h b/OOXML/XlsxFormat/Table/Table.h index c8b9db642b9..8829aa89ffb 100644 --- a/OOXML/XlsxFormat/Table/Table.h +++ b/OOXML/XlsxFormat/Table/Table.h @@ -74,6 +74,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { @@ -111,6 +112,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TableStyleInfo; @@ -149,6 +151,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_TableColumn; @@ -201,6 +204,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { @@ -238,6 +242,7 @@ namespace OOX virtual void toXML2(NSStringUtils::CStringBuilder& writer, int nIndex); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_Table; @@ -368,6 +373,7 @@ namespace OOX { } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 1643f0d8202..cfd4484170d 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -82,6 +82,16 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CAltTextTable::toBin() + { + auto ptr(new XLSB::List14); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oAltText.IsInit()) + ptr->stAltText = m_oAltText.get(); + if(m_oAltTextSummary.IsInit()) + ptr->stAltTextSummary = m_oAltTextSummary.get(); + return objectPtr; + } void CAltTextTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -133,6 +143,22 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CTableStyleInfo::toBin() + { + auto ptr(new XLSB::TableStyleClient); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + ptr->stStyleName = m_oName.get(); + if(m_oShowColumnStripes.IsInit()) + ptr->fColumnStripes = m_oShowColumnStripes->GetValue(); + if(m_oShowFirstColumn.IsInit()) + ptr->fFirstColumn = m_oShowFirstColumn->GetValue(); + if(m_oShowLastColumn.IsInit()) + ptr->fLastColumn = m_oShowLastColumn->GetValue(); + if(m_oShowRowStripes.IsInit()) + ptr->fRowStripes = m_oShowRowStripes->GetValue(); + return objectPtr; + } void CTableStyleInfo::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -239,6 +265,76 @@ namespace Spreadsheet } } } + XLS::BaseObjectPtr CTableColumn::toBin() + { + auto ptr(new XLSB::LISTCOL); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDataCellStyle.IsInit() || m_oTotalsRowDxfId.IsInit() || m_oHeaderRowCellStyle.IsInit() || m_oHeaderRowDxfId.IsInit() + || m_oTotalsRowCellStyle.IsInit()|| m_oDataDxfId.IsInit() || m_oId.IsInit() || m_oName.IsInit() || m_oQueryTableFieldId.IsInit() + || m_oTotalsRowLabel.IsInit() || m_oUniqueName.IsInit() || m_oTotalsRowFunction.IsInit() ) + { + auto ptr1(new XLSB::BeginListCol); + ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleInsertRow = m_oDataCellStyle.get(); + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); + if(m_oHeaderRowDxfId.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + if(m_oDataDxfId.IsInit()) + ptr1->nDxfAgg = m_oDataDxfId->GetValue(); + if(m_oId.IsInit()) + ptr1->idField = m_oId.IsInit(); + + if(m_oName.IsInit()) + ptr1->stCaption = m_oName.get(); + if(m_oQueryTableFieldId.IsInit()) + ptr1->idqsif = m_oQueryTableFieldId->GetValue(); + + if(m_oTotalsRowLabel.IsInit()) + ptr1->stTotal = m_oTotalsRowLabel.get(); + + if(m_oUniqueName.IsInit()) + ptr1->stName = m_oUniqueName.get(); + if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; + } + if(m_oCalculatedColumnFormula.IsInit()) + { + auto fmla(new XLSB::ListCCFmla); + fmla->formula = m_oCalculatedColumnFormula.get(); + ptr->m_BrtListCCFmla = XLS::BaseObjectPtr{fmla}; + } + if(m_oTotalsRowFormula.IsInit()) + { + auto fmla(new XLSB::ListTrFmla); + fmla->formula = m_oTotalsRowFormula.get(); + ptr->m_BrtListTrFmla = XLS::BaseObjectPtr{fmla}; + } + return objectPtr; + } void CTableColumn::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -368,6 +464,14 @@ namespace Spreadsheet m_arrItems.push_back(new CTableColumn(listcol)); } } + XLS::BaseObjectPtr CTableColumns::toBin() + { + auto ptr(new XLSB::LISTCOLS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arLISTCOL.push_back(i->toBin()); + return objectPtr; + } void CTableColumns::ReadAttributes(std::vector& obj) { if(!obj.empty()) @@ -496,6 +600,23 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = ptr->m_FRTTABLE; } } + XLS::BaseObjectPtr CTable::toBin() + { + auto ptr(new XLSB::TABLE); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oAutoFilter.IsInit()) + ptr->m_AUTOFILTER = m_oAutoFilter->toBin(); + if(m_oSortState.IsInit()) + ptr->m_SORTSTATE = m_oSortState->toBin(); + if(m_oTableColumns.IsInit()) + ptr->m_LISTCOLS = m_oTableColumns->toBin(); + if(m_oTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oTableStyleInfo->toBin(); + + if(m_oExtLst.IsInit()) + ptr->m_FRTTABLE = m_oExtLst->toBinTable(); + return objectPtr; + } void CTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -746,6 +867,15 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } + XLS::BaseObjectPtr CTableFile::WriteBin() const + { + XLSB::TableStreamPtr tableStream(new XLSB::TableStream); + XLS::BaseObjectPtr objectPtr(tableStream); + + tableStream->m_TABLE = m_oTable->toBin(); + + return objectPtr; + } void CTableFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; From b6f11208c983379d403ce73cb2a1124dba05fdd6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Sep 2023 21:24:56 +0600 Subject: [PATCH 140/794] Add table writing --- OOXML/XlsxFormat/Table/Autofilter.cpp | 2 +- OOXML/XlsxFormat/Table/Table.h | 5 +- OOXML/XlsxFormat/Table/Tables.cpp | 190 ++++++++++++++++++++++++-- 3 files changed, 181 insertions(+), 16 deletions(-) diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index 6c4733e3159..990559617f2 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -1509,8 +1509,8 @@ namespace OOX if(m_oRef.IsInit()) { auto beginFilter(new XLSB::BeginAFilter); + beginFilter->rfx = m_oRef->GetValue(); ptr->m_BrtBeginAFilter = XLS::BaseObjectPtr{beginFilter}; - beginFilter->rfx = m_oRef->GetValue(); } if(m_oSortState.IsInit()) ptr->m_SORTSTATE = m_oSortState->toBin(); diff --git a/OOXML/XlsxFormat/Table/Table.h b/OOXML/XlsxFormat/Table/Table.h index 8829aa89ffb..585eb7dcad7 100644 --- a/OOXML/XlsxFormat/Table/Table.h +++ b/OOXML/XlsxFormat/Table/Table.h @@ -382,10 +382,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::Table; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index cfd4484170d..62047a2065b 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -42,6 +42,7 @@ #include "../../XlsbFormat/Biff12_unions/LISTCOLS.h" #include "../../XlsbFormat/Biff12_unions/LISTCOL.h" #include "../../XlsbFormat/Biff12_records/BeginListCol.h" +#include "../../XlsbFormat/Biff12_records/BeginListCols.h" #include "../../XlsbFormat/Biff12_records/ListCCFmla.h" #include "../../XlsbFormat/Biff12_records/ListTrFmla.h" #include "../../XlsbFormat/Biff12_records/List14.h" @@ -60,6 +61,8 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -274,32 +277,56 @@ namespace Spreadsheet || m_oTotalsRowLabel.IsInit() || m_oUniqueName.IsInit() || m_oTotalsRowFunction.IsInit() ) { auto ptr1(new XLSB::BeginListCol); - ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; + ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; if(m_oDataCellStyle.IsInit()) ptr1->stStyleInsertRow = m_oDataCellStyle.get(); + else + ptr1->stStyleInsertRow = false; if(m_oTotalsRowDxfId.IsInit()) ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfInsertRow = 0; if(m_oHeaderRowDxfId.IsInit()) ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader = false; if(m_oHeaderRowDxfId.IsInit()) ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHdr = 0; if(m_oTotalsRowCellStyle.IsInit()) ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg = false; if(m_oDataDxfId.IsInit()) ptr1->nDxfAgg = m_oDataDxfId->GetValue(); + else + ptr1->nDxfAgg = 0; if(m_oId.IsInit()) - ptr1->idField = m_oId.IsInit(); + ptr1->idField = m_oId->GetValue(); + else + ptr1->idField = 0; - if(m_oName.IsInit()) + if(m_oName.IsInit()) ptr1->stCaption = m_oName.get(); + else + ptr1->stCaption = false; if(m_oQueryTableFieldId.IsInit()) ptr1->idqsif = m_oQueryTableFieldId->GetValue(); + else + ptr1->idqsif = 0; if(m_oTotalsRowLabel.IsInit()) ptr1->stTotal = m_oTotalsRowLabel.get(); + else + ptr1->stTotal = false; if(m_oUniqueName.IsInit()) ptr1->stName = m_oUniqueName.get(); + else if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else + ptr1->stName = false; if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) @@ -320,6 +347,8 @@ namespace Spreadsheet ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; + else + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; } if(m_oCalculatedColumnFormula.IsInit()) { @@ -468,6 +497,10 @@ namespace Spreadsheet { auto ptr(new XLSB::LISTCOLS); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginListCols); + ptr1->nCols = m_arrItems.size(); + ptr->m_BrtBeginListCols = XLS::BaseObjectPtr{ptr1}; + ptr->indexList = 1; for(auto i:m_arrItems) ptr->m_arLISTCOL.push_back(i->toBin()); return objectPtr; @@ -603,7 +636,125 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") XLS::BaseObjectPtr CTable::toBin() { auto ptr(new XLSB::TABLE); + auto ptr1(new XLSB::BeginList); + ptr->m_BrtBeginList = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oRef.IsInit()) + { + ptr1->rfxList = m_oRef->GetValue(); + ptr1->rfxList.to_string_cache = m_oRef->GetValue(); + } + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else if(m_oDisplayName.IsInit()) + ptr1->stName = m_oDisplayName.get(); + else + ptr1->stName = false; + if(m_oTotalsRowCount.IsInit()) + ptr1->crwTotals = m_oTotalsRowCount->GetValue(); + else + ptr1->crwTotals = 0; + + if(m_oHeaderRowCount.IsInit()) + ptr1->crwHeader = m_oHeaderRowCount->GetValue(); + else + ptr1->crwHeader = 0; + + if(m_oDisplayName.IsInit()) + ptr1->stDisplayName = m_oDisplayName.get(); + else + ptr1->stDisplayName = false; + + if(m_oTableBorderDxfId.IsInit()) + ptr1->nDxfBorder = m_oTableBorderDxfId->GetValue(); + else + ptr1->nDxfBorder = 0; + + if(m_oComment.IsInit()) + ptr1->stComment = m_oComment.get(); + else + ptr1->stComment = false; + + if(m_oConnectionId.IsInit()) + ptr1->dwConnID = m_oConnectionId->GetValue(); + else + ptr1->dwConnID = 0; + + if(m_oDataDxfId.IsInit()) + ptr1->nDxfData = m_oDataDxfId->GetValue(); + else + ptr1->nDxfData = 0; + + + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleData = m_oDataCellStyle.get(); + else + ptr1->stStyleData = false; + + if(m_oHeaderRowBorderDxfId.IsInit()) + ptr1->nDxfHeaderBorder = m_oHeaderRowBorderDxfId->GetValue(); + else + ptr1->nDxfHeaderBorder = 0; + if(m_oHeaderRowCellStyle.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader = false; + + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHeader = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHeader = 0; + + if(m_oInsertRow.IsInit()) + ptr1->fForceInsertToBeVisible = m_oInsertRow.get(); + else + ptr1->fForceInsertToBeVisible = false; + if(m_oInsertRowShift.IsInit()) + ptr1->fInsertRowInsCells = m_oInsertRowShift.get(); + else + ptr1->fInsertRowInsCells = false; + if(m_oPublished.IsInit()) + ptr1->fPublished = m_oPublished.get(); + else + ptr1->fPublished = false; + if(m_oId.IsInit()) + ptr1->idList = m_oId->GetValue(); + else + ptr1->idList = 1; + if(m_oTableType.IsInit()) + { + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeWorksheet) + ptr1->lt = XLSB::ListType::LTRANGE; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeXml) + ptr1->lt = XLSB::ListType::LTXML; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeQueryTable) + ptr1->lt = XLSB::ListType::LTEXTDATA; + } + else + { + ptr1->lt = 0; + } + + if(m_oTotalsRowBorderDxfId.IsInit()) + ptr1->nDxfAggBorder = m_oTotalsRowBorderDxfId->GetValue(); + else + ptr1->nDxfAggBorder = 0; + + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg = false; + + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfAgg = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfAgg = 0; + + if(m_oTotalsRowShown.IsInit()) + ptr1->fShownTotalRow = m_oTotalsRowShown.get(); + else + ptr1->fShownTotalRow = true; if(m_oAutoFilter.IsInit()) ptr->m_AUTOFILTER = m_oAutoFilter->toBin(); if(m_oSortState.IsInit()) @@ -614,7 +765,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") ptr->m_BrtTableStyleClient = m_oTableStyleInfo->toBin(); if(m_oExtLst.IsInit()) - ptr->m_FRTTABLE = m_oExtLst->toBinTable(); + ptr->m_FRTTABLE = m_oExtLst->toBinTable(); return objectPtr; } void CTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) @@ -901,18 +1052,35 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") { if(false == m_oTable.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - int nGlobalNumber = OOX::FileGlobalEnumerated::GetGlobalNumber(); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; + int nGlobalNumber = OOX::FileGlobalEnumerated::GetGlobalNumber(); - sXml.WriteString(L""); - m_oTable->toXML2(sXml, nGlobalNumber); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oTable->toXML2(sXml, nGlobalNumber); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } + const OOX::FileType CTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::TableBin; + } + return OOX::Spreadsheet::FileTypes::Table; + } //--------------------------------------------------------------------------------------------------------------------- From 7dc8a4bb9ba590e65d441e5def6b65143f311b41 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 1 Sep 2023 18:52:29 +0300 Subject: [PATCH 141/794] Fix bug dropcaps fix --- DocxRenderer/src/logic/Page.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 9fa1bb08a25..40278b3459d 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -955,14 +955,14 @@ namespace NSDocxRenderer for(auto& line : m_arTextLine) { - if(line == drop_cap_line) + if(line == drop_cap_line || line->m_bIsNotNecessaryToUse) continue; // буквица должна быть левее if(line->m_dLeft < drop_cap_cont->m_dLeft) continue; - // если совпадает строка - берем ее и выходим + // если совпадает строка по высоте - берем ее и выходим if(fabs(line->m_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { num_of_lines++; From 9e009cc0f8103d01af34f9ddc2f7ad9ed5fea0d7 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Sat, 2 Sep 2023 10:11:57 +0300 Subject: [PATCH 142/794] Revision of reading brackets. Conversion development. --- .../StarMath2OOXML/StarMath2OOXML.pro | 2 + .../Reader/Converter/StarMath2OOXML/Test.cpp | 5 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 78 ++ .../StarMath2OOXML/cconversionsmtoooxml.h | 22 + .../StarMath2OOXML/cstarmathpars.cpp | 890 +++++++++--------- .../Converter/StarMath2OOXML/cstarmathpars.h | 101 +- 6 files changed, 644 insertions(+), 454 deletions(-) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro index 19b793007bd..1353236beec 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro @@ -8,9 +8,11 @@ include($$CORE_ROOT_DIR/Common/base.pri) ADD_DEPENDENCY(UnicodeConverter, kernel) SOURCES += Test.cpp \ + cconversionsmtoooxml.cpp \ cstarmathpars.cpp HEADERS += \ + cconversionsmtoooxml.h \ cstarmathpars.h DESTDIR = $$PWD_ROOT_DIR/build/$$CIRE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp index 7284ecff940..7e664e47147 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -1,8 +1,11 @@ #include "cstarmathpars.h" +#include "cconversionsmtoooxml.h" int main() { - std::wstring Temp = L"lim from color red bold {7 over 5 over 3} to 56 721 "; + std::wstring Temp = L"2+1"; StarMath::CStarMathPars TempO; TempO.Pars(Temp); + ConversionSM2OOXML::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(TempO.GetVector()); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp new file mode 100644 index 00000000000..7c41842c5e3 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -0,0 +1,78 @@ +#include "cconversionsmtoooxml.h" +namespace ConversionSM2OOXML { + CConversionSMtoOOXML::CConversionSMtoOOXML() + { + } + void CConversionSMtoOOXML::StartConversion(std::vector arPars) + { + m_oXmlWrite.WriteNodeBegin(L"m:oMathPara",false); + m_oXmlWrite.WriteNodeBegin(L"m:oMath",false); + m_oXmlWrite.WriteNodeBegin(L"m:r",false); + StandartProperties(); + for(StarMath::CElement* m_oTempElement:arPars) + { + ConversionOneElement(m_oTempElement); + } + EndConversion(); + std::wcout<< m_oXmlWrite.GetXmlString()<GetType() == 0) + { + ConversNumber(dynamic_cast(m_oElement)); + } + else if(m_oElement->GetType() == 1) + { + ConversBinOperator(dynamic_cast (m_oElement)); + } + } + void CConversionSMtoOOXML::ConversBinOperator(StarMath::CBinaryOperator *m_oElement) + { + if(m_oElement->GetTypeBin() == 3 || m_oElement->GetTypeBin() == 4) + { + m_oXmlWrite.WriteNodeBegin(L"m:t",false); + ConversionOneElement(m_oElement->GetLeftArg()); + if(m_oElement->GetTypeRight() == 0) + { + if(m_oElement->GetTypeBin() == 3) m_oXmlWrite.WriteString(L"+"); + else m_oXmlWrite.WriteString(L"-"); + ConversionOneElement(m_oElement->GetRightArg()); + } + m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); + } + } + void CConversionSMtoOOXML::ConversNumber(StarMath::CNumber *m_oElement) + { + m_oXmlWrite.WriteString(m_oElement->GetValue()); + } + void CConversionSMtoOOXML::StandartProperties() + { + m_oXmlWrite.WriteNodeBegin(L"m:rPr",false); + m_oXmlWrite.WriteNodeBegin(L"m:sty",true); + m_oXmlWrite.WriteAttribute(L"m:val",L"p"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeEnd(L"m:rPr",false,false); + m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); + m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); + m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); + m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeBegin(L"w:sz",true); + m_oXmlWrite.WriteAttribute(L"w:val",L"40"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeBegin(L"w:szCs",true); + m_oXmlWrite.WriteAttribute(L"w:val",L"40"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeBegin(L"w:lang",true); + m_oXmlWrite.WriteAttribute(L"w:val",L"en-US"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); + } + void CConversionSMtoOOXML::EndConversion() + { + m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:oMath",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:oMathPara",false,false); + } +} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h new file mode 100644 index 00000000000..f658e68cb14 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -0,0 +1,22 @@ +#ifndef CCONVERSIONSMTOOOXML_H +#define CCONVERSIONSMTOOOXML_H +#include "cstarmathpars.h" +#include "X:/Rabotka/Clone/core/DesktopEditor/xml/include/xmlwriter.h" + +namespace ConversionSM2OOXML { + class CConversionSMtoOOXML + { + public: + CConversionSMtoOOXML(); + //friend class StarMath::CStarMathPars; + void StartConversion(std::vector arPars); + void StandartProperties(); + void ConversionOneElement(StarMath::CElement* m_oElement); + void ConversBinOperator(StarMath::CBinaryOperator* m_oElement); + void ConversNumber(StarMath::CNumber* m_oElement); + void EndConversion(); + private: + XmlUtils::CXmlWriter m_oXmlWrite; + }; +} +#endif // CCONVERSIONSMTOOOXML_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 87576579c8a..89b890d057b 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -30,7 +30,8 @@ namespace StarMath m_arParsLine.push_back(ParsElement(itFirst,itEnd,m_arParsLine)); //std::wcout << GetElement(itFirst,itEnd)<& arParsLine) { - TypeBinOperator enTypeBinOp; - TypeBracket enTypeBracket; - TypeOperator enTypeOp; - TypeAttribute enTypeAtt; + CAttribute* m_oAttribute = new CAttribute; std::wstring wsOneElement = GetElement(itFirst,itEnd); - if(CheckDigit(wsOneElement)) + while((L"color" == wsOneElement && CheckingTheNextElement(itFirst,itEnd,CheckColorAttribute))|| CheckPropertiesAttribute(wsOneElement) || CheckTopAttribute(wsOneElement)) { - return new CNumber(wsOneElement); + if(wsOneElement == L"color") wsOneElement = GetElement(itFirst,itEnd); + m_oAttribute->SetTypeAtt(wsOneElement); + wsOneElement = GetElement(itFirst,itEnd); } - else if(wsOneElement.size() == 1 && CheckOneElementBinOperator(wsOneElement[0],enTypeBinOp)) + + if(CheckDigit(wsOneElement)) { - return new CBinaryOperator(enTypeBinOp); + CNumber* m_oCNumber = new CNumber(wsOneElement); + m_oCNumber->SetAttribute(m_oAttribute); + return m_oCNumber; } - else if(CheckBinOperator(wsOneElement,enTypeBinOp)) + if(CheckSpecialCharacter(wsOneElement)) return new CSpecialCharacters(wsOneElement); + else if(CheckBinOperator(wsOneElement) || CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) { if(!arParsLine.empty()) { - CBinaryOperator* m_pBinOp = new CBinaryOperator; + CBinaryOperator* m_pBinOp = new CBinaryOperator(wsOneElement); + CElement* m_oTempElement{ParsElement(itFirst,itEnd,arParsLine)}; m_pBinOp->SetLeftArg(arParsLine.back()); - m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd,arParsLine)); - m_pBinOp->SetTypeBin(enTypeBinOp); arParsLine.pop_back(); + if(((CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) && (CheckingTheNextElement(itFirst, itEnd,CheckBinOperator)||CheckingTheNextElement(itFirst, itEnd, CheckIndex))) || (CheckBinOperator(wsOneElement) && CheckingTheNextElement(itFirst, itEnd,CheckIndex))) + { + arParsLine.push_back(m_oTempElement); + m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd,arParsLine)); + } + else m_pBinOp->SetRightArg(m_oTempElement); + m_pBinOp->SetAttribute(m_oAttribute); return m_pBinOp; } return NULL; } - else if(CheckBracket(wsOneElement[0],enTypeBracket)) + else if(CheckBracketOpen(wsOneElement) || CheckScalable_NotScalableBracketLeft(wsOneElement) || (L"left" == wsOneElement && CheckingTheNextElement(itFirst,itEnd,CheckScalable_NotScalableBracketLeft))) { + CBracket* m_oBracket = new CBracket; + std::wstring wsTypeBracket; std::vector arValueBrecket; - std::wstring::iterator itTempIteratorforBacket = itFirst; - wsOneElement = GetElement(itFirst,itEnd); - while(wsOneElement[0] != L'}') + if(L"left" == wsOneElement) { - arValueBrecket.push_back(ParsElement(itTempIteratorforBacket,itEnd,arValueBrecket)); - itFirst = itTempIteratorforBacket; + m_oBracket->SetScalable(); wsOneElement = GetElement(itFirst,itEnd); + wsTypeBracket = wsOneElement; + } + else wsTypeBracket = wsOneElement; + while(!CheckingTheNextElement(itFirst,itEnd,CheckBracketClose) && !CheckingTheNextElement(itFirst,itEnd,CheckScalable_NotScalableBracketRight)) + { + arValueBrecket.push_back(ParsElement(itFirst,itEnd,arValueBrecket)); } - return new CBracket(arValueBrecket,enTypeBracket); + wsOneElement = GetElement(itFirst,itEnd); + std::wcout << wsOneElement << std::endl; + if(L"right" == wsOneElement) wsOneElement = GetElement(itFirst,itEnd); + m_oBracket->SetBracketVal(arValueBrecket); + m_oBracket->SetTypeBracket(wsTypeBracket); + m_oBracket ->SetAttribute(m_oAttribute); + return m_oBracket; } - else if(CheckOperator(wsOneElement,enTypeOp)) + else if(CheckOperator(wsOneElement)) { - COperator* oTempOp = new COperator; + COperator* oTempOp = new COperator(wsOneElement); std::vector arValueBrecket; std::wstring::iterator itSavePos; do @@ -119,27 +140,9 @@ namespace StarMath break; }while(true); oTempOp->SetValueOp(ParsElement(itSavePos,itEnd,arValueBrecket)); - oTempOp->SetTypeOp(enTypeOp); + oTempOp->SetAttribute(m_oAttribute); return oTempOp; } - else if(CheckTopAttribute(wsOneElement,enTypeAtt) || CheckPropertiesAttribute(wsOneElement,enTypeAtt)|| (wsOneElement == L"color" && CheckColorAttribute(GetElement(itFirst,itEnd),enTypeAtt))) - { - return new CAttribute(ParsElement(itFirst,itEnd,arParsLine),enTypeAtt); - } -// else if(wsOneElement == L"left" && CheckScalable_NotScalableBracket(GetElement(itFirst,itEnd),enTypeBracket)) -// { -// std::vector arValueBrecket; -// std::wstring::iterator itTempIteratorforBacket = itFirst; -// wsOneElement = GetElement(itFirst,itEnd); -// while(wsOneElement != L"right") -// { -// arValueBrecket.push_back(ParsElement(itTempIteratorforBacket,itEnd,arValueBrecket)); -// itFirst = itTempIteratorforBacket; -// wsOneElement = GetElement(itFirst,itEnd); -// } -// wsOneElement = GetElement(itFirst,itEnd); -// return new CBracket(arValueBrecket,enTypeBracket); -// } } bool CStarMathPars::CheckDigit(const std::wstring &wsCheckToken) @@ -150,43 +153,13 @@ namespace StarMath } return true; } - bool CStarMathPars::CheckScalable_NotScalableBracket(const std::wstring &wsCheckToken, TypeBracket &enType) + bool CStarMathPars::CheckScalable_NotScalableBracketLeft(const std::wstring &wsCheckToken) { - if(wsCheckToken == L"ldbracket") - { - enType = ldbracket; - return true; - } - else if(wsCheckToken == L"lbrace") - { - enType = lbrace; - return true; - } - else if(wsCheckToken == L"langle") - { - enType = langle; - return true; - } - else if(wsCheckToken == L"lceil") - { - enType = lceil; - return true; - } - else if(wsCheckToken == L"lfloor") - { - enType = lfloor; - return true; - } - else if(wsCheckToken == L"lline") - { - enType = lline; - return true; - } - else if(wsCheckToken == L"ldline") - { - enType = ldline; - return true; - } + return(L"ldbracket" == wsCheckToken || L"lbrace" == wsCheckToken || L"langle" == wsCheckToken || L"lceil" == wsCheckToken || L"lfloor" == wsCheckToken || L"lline" == wsCheckToken || L"ldline" == wsCheckToken); + } + bool CStarMathPars::CheckScalable_NotScalableBracketRight(const std::wstring &wsCheckToken) + { + return(L"rdbracket" == wsCheckToken || L"rbrace" == wsCheckToken || L"rangle" == wsCheckToken || L"rceil" == wsCheckToken || L"rfloor" == wsCheckToken || L"rline" == wsCheckToken || L"rdline" == wsCheckToken || L"right" == wsCheckToken); } ////////////////Requires improvement /*bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) @@ -208,361 +181,92 @@ namespace StarMath } return UnarSign; }*/ - - bool CStarMathPars::CheckBinOperator(const std::wstring &wsCheckToken, TypeBinOperator& enTypeBinOperator) + bool CStarMathPars::CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)) { - if(wsCheckToken == L"over") - { - enTypeBinOperator = over; - return true; - } - else if(wsCheckToken == L"cdot") - { - enTypeBinOperator = cdot; - return true; - } - else if(wsCheckToken == L"times") - { - enTypeBinOperator = times; - return true; - } - else if(wsCheckToken == L"frac") - { - enTypeBinOperator = frac; - return true; - } - else if(wsCheckToken == L"div") - { - enTypeBinOperator = div; - return true; - } - else if(wsCheckToken == L"oplus") - { - enTypeBinOperator = oplus; - return true; - } - else if(wsCheckToken == L"ominus") - { - enTypeBinOperator = ominus; - return true; - } - else if(wsCheckToken == L"odot") - { - enTypeBinOperator = odot; - return true; - } - else if(wsCheckToken == L"otimes") - { - enTypeBinOperator = otimes; - return true; - } - else if(wsCheckToken == L"odivide") - { - enTypeBinOperator = odivide; - return true; - } - else if(wsCheckToken == L"circ") - { - enTypeBinOperator = circ; - return true; - } - else if(wsCheckToken == L"wideslash") - { - enTypeBinOperator = wideslash; - return true; - } - else if(wsCheckToken == L"widebslash") - { - enTypeBinOperator = widebslash; - return true; - } - else return false; + std::wstring::iterator itTempVal = itFirst; + bool bResult = func(GetElement(itFirst,itEnd)); + itFirst = itTempVal; + return bResult; } - - bool CStarMathPars::CheckOneElementBinOperator(const char &wsCheckToken, TypeBinOperator &enTypeBinOperator) + bool CStarMathPars::CheckBinOperator(const std::wstring &wsCheckToken) { - switch (wsCheckToken) + return(L"*" ==wsCheckToken || L"/" == wsCheckToken || wsCheckToken == L"over" || wsCheckToken == L"cdot" || wsCheckToken == L"times" || wsCheckToken == L"frac" || wsCheckToken == L"div" || wsCheckToken == L"odot" || wsCheckToken == L"otimes" || wsCheckToken == L"odivide" || wsCheckToken == L"wideslash" || wsCheckToken == L"widebslash"); + } + bool CStarMathPars::CheckBinOperatorLowPriority(const std::wstring &wsCheckToken) + { + return (wsCheckToken == L"oplus" || wsCheckToken == L"ominus"|| wsCheckToken == L"circ"); + } + bool CStarMathPars::CheckPlusOrMinus(const std::wstring &wsCheckToken) + { + switch (wsCheckToken[0]) { - case '+': - enTypeBinOperator = plus; + case L'+': return true; - case '-': - enTypeBinOperator = minus; - return true; - - case '*': - enTypeBinOperator = multipl; - return true; - case '/': - enTypeBinOperator = division; + case L'-': return true; default: - return false; + return false; } } - bool CStarMathPars::CheckOperator(const std::wstring &wsCheckToken, TypeOperator & enTypeOperator) + bool CStarMathPars::CheckOperator(const std::wstring &wsCheckToken) { - if(wsCheckToken == L"lim") - { - enTypeOperator = lim; - return true; - } - else if(wsCheckToken == L"sum") - { - enTypeOperator = sum; - return true; - } - else return false; + return(wsCheckToken == L"lim" || wsCheckToken == L"sum"); } bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken) { - if(wsCheckToken == L"from") - { - return true; - } - else if(wsCheckToken ==L"to") - { - return true; - } - else return false; + return (wsCheckToken == L"from" || wsCheckToken == L"to" || wsCheckToken[0] == L'_' || wsCheckToken[0] == L'^' ); } - bool CStarMathPars::CheckBracket(const char &wsCheckToken, TypeBracket & enTypeBracket) + bool CStarMathPars::CheckBracketOpen(const std::wstring& wsCheckToken) { - switch (wsCheckToken) { + switch (wsCheckToken[0]) { case '{': - enTypeBracket = brace; return true; case '(': - enTypeBracket = round; return true; case '[': - enTypeBracket = square; + return true; + case '}': + return true; + case ')': + return true; + case ']': return true; default: return false; } } - bool CStarMathPars::CheckTopAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt) + bool CStarMathPars::CheckBracketClose(const std::wstring& wsCheckToken) { - if(wsCheckToken == L"acute") - { - enTypeAtt = acute; - return true; - } - else if(wsCheckToken == L"breve") - { - enTypeAtt = breve; - return true; - } - else if(wsCheckToken == L"dot") - { - enTypeAtt = dot; - return true; - } - else if(wsCheckToken == L"dddot") - { - enTypeAtt = dddot; - return true; - } - else if(wsCheckToken == L"vec") - { - enTypeAtt = vec; - return true; - } - else if(wsCheckToken == L"tilde") - { - enTypeAtt = tilde; - return true; - } - else if(wsCheckToken == L"check") - { - enTypeAtt = check; - return true; - } - else if(wsCheckToken == L"grave") - { - enTypeAtt = grave; - return true; - } - else if(wsCheckToken == L"circle") - { - enTypeAtt = circle; - return true; - } - else if(wsCheckToken == L"ddot") - { - enTypeAtt = ddot; - return true; - } - else if(wsCheckToken == L"bar") - { - enTypeAtt = bar; - return true; - } - else if(wsCheckToken == L"harpoon") - { - enTypeAtt = harpoon; - return true; - } - else if(wsCheckToken == L"hat") - { - enTypeAtt = hat; + switch (wsCheckToken[0]) {; + case '}': return true; - } - else if(wsCheckToken == L"widevec") - { - enTypeAtt = widevec; + case ')': return true; - } - else if(wsCheckToken == L"widetilde") - { - enTypeAtt = widetilde; - return true; - } - else if(wsCheckToken == L"overline") - { - enTypeAtt = overline; - return true; - } - else if(wsCheckToken == L"overstrike") - { - enTypeAtt = overstrike; - return true; - } - else if(wsCheckToken == L"wideharpoon") - { - enTypeAtt = wideharpoon; - return true; - } - else if(wsCheckToken == L"widehat") - { - enTypeAtt = widehat; - return true; - } - else if(wsCheckToken == L"underline") - { - enTypeAtt = underline; + case ']': return true; + default: + return false; } - else return false; } - bool CStarMathPars::CheckPropertiesAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt) + bool CStarMathPars::CheckTopAttribute(const std::wstring& wsCheckToken) { - if(wsCheckToken == L"phantom") - { - enTypeAtt = phantom; - return true; - } - else if(wsCheckToken == L"bold") - { - enTypeAtt = bold; - return true; - } - else if(wsCheckToken == L"ital") - { - enTypeAtt = ital; - return true; - } - else return false; + return(L"acute" == wsCheckToken || L"breve" == wsCheckToken || L"dot" == wsCheckToken || L"dddot" == wsCheckToken || L"vec" == wsCheckToken || L"tilde" == wsCheckToken || L"check" == wsCheckToken || L"grave" == wsCheckToken || L"circle" == wsCheckToken || L"ddot" == wsCheckToken || L"bar" == wsCheckToken || L"harpoon" == wsCheckToken || L"hat" == wsCheckToken || L"widevec" == wsCheckToken || L"widetilde" == wsCheckToken || L"overline" == wsCheckToken || L"overstrike" == wsCheckToken || L"wideharpoon" == wsCheckToken || L"widehat" == wsCheckToken || L"underline" == wsCheckToken); } - bool CStarMathPars::CheckColorAttribute(const std::wstring &wsCheckToken, TypeAttribute &enTypeAtt) + bool CStarMathPars::CheckPropertiesAttribute(const std::wstring& wsCheckToken) { - if(wsCheckToken == L"black") - { - enTypeAtt = black; - return true; - } - else if(wsCheckToken == L"green") - { - enTypeAtt = green; - return true; - } - else if(wsCheckToken == L"aqua") - { - enTypeAtt = aqua; - return true; - } - else if(wsCheckToken == L"yellow") - { - enTypeAtt = yellow; - return true; - } - else if(wsCheckToken == L"lime") - { - enTypeAtt = lime; - return true; - } - else if(wsCheckToken == L"navy") - { - enTypeAtt = navy; - return true; - } - else if(wsCheckToken == L"purple") - { - enTypeAtt = purple; - return true; - } - else if(wsCheckToken == L"teal") - { - enTypeAtt = teal; - return true; - } - else if(wsCheckToken == L"blue") - { - enTypeAtt = blue; - return true; - } - else if(wsCheckToken == L"red") - { - enTypeAtt = red; - return true; - } - else if(wsCheckToken == L"fuchsia") - { - enTypeAtt = fuchsia; - return true; - } - else if(wsCheckToken == L"gray") - { - enTypeAtt = gray; - return true; - } - else if(wsCheckToken == L"maroon") - { - enTypeAtt = maroon; - return true; - } - else if(wsCheckToken == L"olive") - { - enTypeAtt = olive; - return true; - } - else if(wsCheckToken == L"silver") - { - enTypeAtt = silver; - return true; - } - else if(wsCheckToken == L"coral") - { - enTypeAtt = coral; - return true; - } - else if(wsCheckToken == L"midnightblue") - { - enTypeAtt = midnightblue; - return true; - } - else if(wsCheckToken == L"crimson") - { - enTypeAtt = crimson; - return true; - } - else if(wsCheckToken == L"violet") - { - enTypeAtt = violet; - return true; - } - else return false; + return(L"ital" == wsCheckToken || L"bold" == wsCheckToken || L"phantom" == wsCheckToken); + } + bool CStarMathPars::CheckColorAttribute(const std::wstring &wsCheckToken) + { + return (L"violet" == wsCheckToken || L"black" == wsCheckToken || L"green" == wsCheckToken || L"aqua" == wsCheckToken || L"yellow" == wsCheckToken || L"lime" == wsCheckToken || L"navy" == wsCheckToken || L"purple" == wsCheckToken || L"teal" == wsCheckToken || L"blue" == wsCheckToken || L"red" == wsCheckToken || L"fuchsia" == wsCheckToken || L"gray" == wsCheckToken || L"maroon" == wsCheckToken || L"olive" == wsCheckToken || L"silver" == wsCheckToken || L"coral" == wsCheckToken || L"midnightblue" == wsCheckToken || L"crimson" == wsCheckToken || L"violet" == wsCheckToken); + } + bool CStarMathPars::CheckSpecialCharacter(const std::wstring &wsCheckToken) + { + return (L"mline" == wsCheckToken || L"grid" == wsCheckToken); + } + std::vector CStarMathPars::GetVector() + { + return m_arParsLine; } //Class methods CNumber CNumber::CNumber() @@ -607,9 +311,76 @@ namespace StarMath //Class methods CBinaryOperator CBinaryOperator::CBinaryOperator() {} - CBinaryOperator::CBinaryOperator(const TypeBinOperator &enType) + CBinaryOperator::CBinaryOperator(const std::wstring& wsToken) { - enTypeBinOp = enType; + if(wsToken == L"+") + { + enTypeBinOp = plus; + } + else if(wsToken == L"-") + { + enTypeBinOp = minus; + } + else if(wsToken == L"*") + { + enTypeBinOp = multipl; + } + else if(wsToken == L"/") + { + enTypeBinOp = division; + } + else if(wsToken == L"over") + { + enTypeBinOp = over; + } + else if(wsToken == L"cdot") + { + enTypeBinOp = cdot; + } + else if(wsToken == L"times") + { + enTypeBinOp = times; + } + else if(wsToken == L"frac") + { + enTypeBinOp = frac; + } + else if(wsToken == L"div") + { + enTypeBinOp = div; + } + else if(wsToken == L"oplus") + { + enTypeBinOp = oplus; + } + else if(wsToken == L"ominus") + { + enTypeBinOp = ominus; + } + else if(wsToken == L"odot") + { + enTypeBinOp = odot; + } + else if(wsToken == L"otimes") + { + enTypeBinOp = otimes; + } + else if(wsToken == L"odivide") + { + enTypeBinOp = odivide; + } + else if(wsToken == L"circ") + { + enTypeBinOp = circ; + } + else if(wsToken == L"wideslash") + { + enTypeBinOp = wideslash; + } + else if(wsToken == L"widebslash") + { + enTypeBinOp = widebslash; + } arLeftArg = nullptr; arRightArg = nullptr; } @@ -642,9 +413,32 @@ namespace StarMath { this->enTypeBinOp = enType; } + CElement* CBinaryOperator::GetLeftArg() + { + return arLeftArg; + } + CElement* CBinaryOperator::GetRightArg() + { + return arRightArg; + } + TypeElement CBinaryOperator::GetTypeRight() + { + return arRightArg->GetType(); + } //Class methods COperator COperator::COperator(): oFromValue(NULL),oToValue(NULL),oValueOp(NULL) {} + COperator::COperator(const std::wstring& wsToken): oFromValue(NULL), oToValue(NULL), oValueOp(NULL) + { + if(wsToken== L"lim") + { + enTypeOp = lim; + } + else if(wsToken == L"sum") + { + enTypeOp = sum; + } + } COperator::~COperator() { delete oFromValue; @@ -682,17 +476,43 @@ namespace StarMath { enTypeOp = enType; } - void COperator::AvailabilityMline() - { - bMline = true; - } //Class methods CBracket CBracket::CBracket() {} - CBracket::CBracket(const std::vector& arValue,const TypeBracket& enType) + CBracket::CBracket(const std::vector& arValue,const std::wstring& wsCheckToken) { arBrecketVal = arValue; - enTypeBracket = enType; + if (L"{" == wsCheckToken) enTypeBracket =brace; + else if (L"(" == wsCheckToken) enTypeBracket = round; + else if (L"[" == wsCheckToken) enTypeBracket = square; + else if(wsCheckToken == L"ldbracket") + { + enTypeBracket = ldbracket; + } + else if(wsCheckToken == L"lbrace") + { + enTypeBracket = lbrace; + } + else if(wsCheckToken == L"langle") + { + enTypeBracket = langle; + } + else if(wsCheckToken == L"lceil") + { + enTypeBracket = lceil; + } + else if(wsCheckToken == L"lfloor") + { + enTypeBracket = lfloor; + } + else if(wsCheckToken == L"lline") + { + enTypeBracket = lline; + } + else if(wsCheckToken == L"ldline") + { + enTypeBracket = ldline; + } } CBracket::~CBracket() { @@ -713,33 +533,261 @@ namespace StarMath { return {}; } + void CBracket::SetScalable() + { + bScalable = true; + } + void CBracket::SetBracketVal(const std::vector &arBrecketValue) + { + arBrecketVal = arBrecketValue; + } + void CBracket::SetTypeBracket(const std::wstring& wsCheckToken) + { + if (L"{" == wsCheckToken) enTypeBracket =brace; + else if (L"(" == wsCheckToken) enTypeBracket = round; + else if (L"[" == wsCheckToken) enTypeBracket = square; + else if(wsCheckToken == L"ldbracket") + { + enTypeBracket = ldbracket; + } + else if(wsCheckToken == L"lbrace") + { + enTypeBracket = lbrace; + } + else if(wsCheckToken == L"langle") + { + enTypeBracket = langle; + } + else if(wsCheckToken == L"lceil") + { + enTypeBracket = lceil; + } + else if(wsCheckToken == L"lfloor") + { + enTypeBracket = lfloor; + } + else if(wsCheckToken == L"lline") + { + enTypeBracket = lline; + } + else if(wsCheckToken == L"ldline") + { + enTypeBracket = ldline; + } + } //Class methods CAttribute CAttribute::CAttribute() - {} - CAttribute::CAttribute(CElement *oValue, const TypeAttribute &enType) { - enTypeAtt = enType; - oValueAtt = oValue; + } + CAttribute::CAttribute(const TypeAttributeTop &enType) + { + enTypeTop = enType; } CAttribute::~CAttribute() { - delete oValueAtt; } - std::wstring CAttribute::GetValue() + void CAttribute::SetTypeAtt(const std::wstring& wsCheckToken) { - return {}; + if(wsCheckToken == L"phantom") + { + bPhantom = true; + } + else if(wsCheckToken == L"bold") + { + bBold = true; + } + else if(wsCheckToken == L"ital") + { + bItal = true; + } + else if(wsCheckToken == L"black") + { + enTypeColor = black; + } + else if(wsCheckToken == L"green") + { + enTypeColor = green; + } + else if(wsCheckToken == L"aqua") + { + enTypeColor = aqua; + } + else if(wsCheckToken == L"yellow") + { + enTypeColor = yellow; + } + else if(wsCheckToken == L"lime") + { + enTypeColor = lime; + } + else if(wsCheckToken == L"navy") + { + enTypeColor = navy; + } + else if(wsCheckToken == L"purple") + { + enTypeColor = purple; + } + else if(wsCheckToken == L"teal") + { + enTypeColor = teal; + } + else if(wsCheckToken == L"blue") + { + enTypeColor = blue; + } + else if(wsCheckToken == L"red") + { + enTypeColor = red; + } + else if(wsCheckToken == L"fuchsia") + { + enTypeColor = fuchsia; + } + else if(wsCheckToken == L"gray") + { + enTypeColor = gray; + } + else if(wsCheckToken == L"maroon") + { + enTypeColor = maroon; + } + else if(wsCheckToken == L"olive") + { + enTypeColor = olive; + } + else if(wsCheckToken == L"silver") + { + enTypeColor = silver; + } + else if(wsCheckToken == L"coral") + { + enTypeColor = coral; + } + else if(wsCheckToken == L"midnightblue") + { + enTypeColor = midnightblue; + } + else if(wsCheckToken == L"crimson") + { + enTypeColor = crimson; + } + else if(wsCheckToken == L"violet") + { + enTypeColor = violet; + } + else if(wsCheckToken == L"acute") + { + enTypeTop = acute; + } + else if(wsCheckToken == L"breve") + { + enTypeTop = breve; + } + else if(wsCheckToken == L"dot") + { + enTypeTop = dot; + } + else if(wsCheckToken == L"dddot") + { + enTypeTop = dddot; + } + else if(wsCheckToken == L"vec") + { + enTypeTop = vec; + } + else if(wsCheckToken == L"tilde") + { + enTypeTop = tilde; + } + else if(wsCheckToken == L"check") + { + enTypeTop = check; + } + else if(wsCheckToken == L"grave") + { + enTypeTop = grave; + } + else if(wsCheckToken == L"circle") + { + enTypeTop = circle; + } + else if(wsCheckToken == L"ddot") + { + enTypeTop = ddot; + } + else if(wsCheckToken == L"bar") + { + enTypeTop = bar; + } + else if(wsCheckToken == L"harpoon") + { + enTypeTop = harpoon; + } + else if(wsCheckToken == L"hat") + { + enTypeTop = hat; + } + else if(wsCheckToken == L"widevec") + { + enTypeTop = widevec; + } + else if(wsCheckToken == L"widetilde") + { + enTypeTop = widetilde; + } + else if(wsCheckToken == L"overline") + { + enTypeTop = overline; + } + else if(wsCheckToken == L"overstrike") + { + enTypeTop = overstrike; + } + else if(wsCheckToken == L"wideharpoon") + { + enTypeTop = wideharpoon; + } + else if(wsCheckToken == L"widehat") + { + enTypeTop = widehat; + } + else if(wsCheckToken == L"underline") + { + enTypeTop = underline; + } + } + TypeAttributeTop CAttribute::GetTypeAtt() + { + return enTypeTop; } - TypeElement CAttribute::GetType() +//Class methods CElement + CElement::~CElement() { - return Attribute; } - void CAttribute::SetTypeAtt(const TypeAttribute &enType) + void CElement::SetAttribute(CAttribute* m_oCAttribute) { - enTypeAtt = enType; + oCAttribute = m_oCAttribute; + } + TypeAttributeTop CElement::GetTypeAttribute() + { + return oCAttribute->GetTypeAtt(); + } +//Class methods CSpecial + CSpecialCharacters::CSpecialCharacters(const std::wstring& wsToken) + { + if(L"mline" == wsToken) enTypeSpecial = mline; + else if(L"grid" == wsToken) enTypeSpecial = grid; + } + CSpecialCharacters::~CSpecialCharacters() + {} + std::wstring CSpecialCharacters::GetValue() + { + return {}; } - void CAttribute::SetValueAtt(CElement *oValue) + TypeElement CSpecialCharacters::GetType() { - oValueAtt = oValue; + return SpecialCharacter; } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index e0c8a4cb149..9541470f6c7 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -14,6 +14,7 @@ namespace StarMath Bracket, UnarSign, Attribute, + SpecialCharacter, }; enum TypeBinOperator { @@ -53,8 +54,9 @@ namespace StarMath lline, ldline, }; - enum TypeAttribute + enum TypeAttributeTop { + noneTop, acute, breve, dot, @@ -75,9 +77,10 @@ namespace StarMath wideharpoon, widehat, underline,//top elements - phantom, - bold, - ital,//properties (without a pin and headset) + }; + enum TypeAttributeColor + { + noneColor, black, green, aqua, @@ -98,13 +101,48 @@ namespace StarMath crimson, violet,//color(without rgb and hex) }; + enum TypeCharacter + { + mline, + grid, + }; + class CAttribute + { + public: + CAttribute(); + CAttribute(const TypeAttributeTop& enType); + virtual ~CAttribute(); + void SetTypeAtt(const std::wstring& wsCheckToken); + TypeAttributeTop GetTypeAtt(); + private: + TypeAttributeTop enTypeTop{noneTop}; + TypeAttributeColor enTypeColor{noneColor}; + bool bBold{false}; + bool bItal{false}; + bool bPhantom{false}; + }; + class CElement { public: + virtual ~CElement(); virtual std::wstring GetValue() = 0; virtual TypeElement GetType() = 0; + void SetAttribute(CAttribute* m_oCAttribute); + TypeAttributeTop GetTypeAttribute(); + private: + CAttribute* oCAttribute; + }; + class CSpecialCharacters: public CElement + { + public: + CSpecialCharacters(const std::wstring& wsToken); + virtual ~CSpecialCharacters(); + std::wstring GetValue() override; + TypeElement GetType() override; + private: + TypeCharacter enTypeSpecial; }; - class CNumber: public CElement { public: @@ -133,7 +171,7 @@ namespace StarMath { public: CBinaryOperator(); - CBinaryOperator(const TypeBinOperator& enType); + CBinaryOperator(const std::wstring& wsToken); virtual ~CBinaryOperator(); std::wstring GetValue() override; TypeElement GetType() override; @@ -141,6 +179,10 @@ namespace StarMath void SetTypeBin(const TypeBinOperator& enType); void SetLeftArg(CElement* oLeftArg); void SetRightArg(CElement* oRightArg); + CElement* GetLeftArg(); + CElement* GetRightArg(); + TypeElement GetTypeRight(); + bool CheckBinOperator(const std::wstring& wsCheckToken); private: TypeBinOperator enTypeBinOp; CElement* arLeftArg; @@ -150,6 +192,7 @@ namespace StarMath { public: COperator(); + COperator(const std::wstring& wsToken); virtual ~COperator(); std::wstring GetValue() override; TypeElement GetType() override; @@ -158,59 +201,53 @@ namespace StarMath void SetFrom(CElement* oFrom); void SetTo(CElement* oTo); void SetValueOp(CElement* oValue); - void AvailabilityMline(); private: TypeOperator enTypeOp; CElement* oFromValue{nullptr}; CElement* oToValue{nullptr}; CElement* oValueOp{nullptr}; - bool bMline{false}; }; class CBracket: public CElement { public: CBracket(); - CBracket(const std::vector& arValue,const TypeBracket& enType); + CBracket(const std::vector& arValue,const std::wstring& wsCheckToken); virtual ~CBracket(); std::wstring GetValue() override; TypeElement GetType() override; + void SetScalable(); + void SetBracketVal(const std::vector& arBrecketValue); + void SetTypeBracket(const std::wstring& wsCheckToken); private: + bool bScalable{false}; TypeBracket enTypeBracket; std::vector arBrecketVal; }; - class CAttribute: public CElement - { - public: - CAttribute(); - CAttribute(CElement* oValue,const TypeAttribute& enType); - virtual ~CAttribute(); - std::wstring GetValue() override; - TypeElement GetType() override; - void SetTypeAtt(const TypeAttribute& enType); - void SetValueAtt(CElement* oValue); - private: - TypeAttribute enTypeAtt; - CElement* oValueAtt; - }; class CStarMathPars { public: CStarMathPars(); virtual ~CStarMathPars(); + std::vector GetVector(); void Pars(std::wstring& wsStarMathLine); std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, std::vector& arParsLine); bool CheckDigit(const std::wstring& wsCheckToken); bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); - bool CheckBinOperator(const std::wstring& wsCheckToken,TypeBinOperator& enTypeBinOperator); - bool CheckOneElementBinOperator(const char& wsCheckToken, TypeBinOperator& enTypeBinOperator); - bool CheckOperator(const std::wstring& wsCheckToken,TypeOperator& enTypeOperator); - bool CheckIndex(const std::wstring& wsCheckToken); - bool CheckBracket(const char& wsCheckToken,TypeBracket& enTypeBracket); - bool CheckScalable_NotScalableBracket(const std::wstring& wsCheckToken, TypeBracket& enType); - bool CheckTopAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt); - bool CheckPropertiesAttribute(const std::wstring& wsCheckToken,TypeAttribute& enTypeAtt); - bool CheckColorAttribute(const std::wstring& wsCheckToken, TypeAttribute& enTypeAtt); + static bool CheckBinOperator(const std::wstring& wsCheckToken); + bool CheckBinOperatorLowPriority(const std::wstring& wsCheckToken); + bool CheckPlusOrMinus(const std::wstring& wsCheckToken); + bool CheckOperator(const std::wstring& wsCheckToken); + static bool CheckIndex(const std::wstring& wsCheckToken); + bool CheckBracketOpen(const std::wstring& wsCheckToken); + static bool CheckBracketClose(const std::wstring& wsCheckToken); + static bool CheckScalable_NotScalableBracketLeft(const std::wstring& wsCheckToken); + static bool CheckScalable_NotScalableBracketRight(const std::wstring& wsCheckToken); + bool CheckTopAttribute(const std::wstring& wsCheckToken); + bool CheckPropertiesAttribute(const std::wstring& wsCheckToken); + static bool CheckColorAttribute(const std::wstring& wsCheckToken); + bool CheckSpecialCharacter(const std::wstring& wsCheckToken); + bool CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,bool (&func)(const std::wstring& wsCheckToken)); void PrintAr(); private: std::vector m_arParsLine; From 4498c5a60f056960e14587cb7ce52905a9c4b533 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 5 Sep 2023 22:19:51 +0600 Subject: [PATCH 143/794] Remove double binary file writing --- OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 62d2cf9c7be..1f05dfa8d4d 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -1288,7 +1288,7 @@ namespace NSBinPptxRW { if (m_lPosition > 0) { - CFileBinary::WriteFile(m_pStreamData, m_lPosition); + //CFileBinary::WriteFile(m_pStreamData, m_lPosition); } m_lPositionFlushed += m_lPosition; m_lPosition = 0; From b4b4596657b113f69ba61994fab1b3602a5c90dd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Sep 2023 16:05:26 +0600 Subject: [PATCH 144/794] Fix table conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 13 +- OOXML/XlsxFormat/Table/Tables.cpp | 354 ++++++++++++------------ 2 files changed, 182 insertions(+), 185 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 687746ca596..5a5a7149868 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -67,6 +67,7 @@ #include "../../XlsbFormat/Biff12_unions/TABLESLICERSEX.h" #include "../../XlsbFormat/Biff12_unions/FRTWORKBOOK.h" #include "../../XlsbFormat/Biff12_unions/FRTPIVOTCACHEDEF.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" namespace OOX { @@ -688,11 +689,12 @@ namespace OOX } XLS::BaseObjectPtr COfficeArtExtensionList::toBinTable() { - auto ptr(new XLSB::FRTTABLE); - XLS::BaseObjectPtr objectPtr(ptr); - if (!m_arrExt.empty()) - { - + auto ptr(new XLSB::FRTTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto frtBegin(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{frtBegin}; + if (!m_arrExt.empty()) + { for(auto i:m_arrExt) { @@ -702,7 +704,6 @@ namespace OOX } } - } return objectPtr; } diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 62047a2065b..a0b49257cad 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -46,6 +46,7 @@ #include "../../XlsbFormat/Biff12_records/ListCCFmla.h" #include "../../XlsbFormat/Biff12_records/ListTrFmla.h" #include "../../XlsbFormat/Biff12_records/List14.h" +#include "../../XlsbFormat/Biff12_records/BeginDeletedName.h" #include "../../XlsbFormat/QueryTableStream.h" #include "../../XlsbFormat/Biff12_unions/QSI.h" @@ -55,7 +56,7 @@ #include "../../XlsbFormat/Biff12_unions/QSIF.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAMES.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAME.h" -#include "../../XlsbFormat/Biff12_records/BeginDeletedName.h" +#include "../../XlsbFormat/Biff12_unions/FRTTABLE.h" #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" @@ -278,92 +279,92 @@ namespace Spreadsheet { auto ptr1(new XLSB::BeginListCol); ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; - if(m_oDataCellStyle.IsInit()) - ptr1->stStyleInsertRow = m_oDataCellStyle.get(); - else - ptr1->stStyleInsertRow = false; - if(m_oTotalsRowDxfId.IsInit()) - ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); - else - ptr1->nDxfInsertRow = 0; - if(m_oHeaderRowDxfId.IsInit()) - ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); - else - ptr1->stStyleHeader = false; - if(m_oHeaderRowDxfId.IsInit()) - ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); - else - ptr1->nDxfHdr = 0; - if(m_oTotalsRowCellStyle.IsInit()) - ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); - else - ptr1->stStyleAgg = false; - if(m_oDataDxfId.IsInit()) - ptr1->nDxfAgg = m_oDataDxfId->GetValue(); - else - ptr1->nDxfAgg = 0; - if(m_oId.IsInit()) - ptr1->idField = m_oId->GetValue(); + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleInsertRow = m_oDataCellStyle.get(); + else + ptr1->stStyleInsertRow = 0xFFFFFFFF; + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfInsertRow = 0xFFFFFFFF; + + if(m_oHeaderRowDxfId.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader = 0xFFFFFFFF; + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHdr = 0xFFFFFFFF; + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); else - ptr1->idField = 0; + ptr1->stStyleAgg = 0xFFFFFFFF; + + if(m_oDataDxfId.IsInit()) + ptr1->nDxfAgg = m_oDataDxfId->GetValue(); + else + ptr1->nDxfAgg = 0xFFFFFFFF; + if(m_oId.IsInit()) + ptr1->idField = m_oId->GetValue(); + else + ptr1->idField = 0; - if(m_oName.IsInit()) + if(m_oName.IsInit()) ptr1->stCaption = m_oName.get(); - else - ptr1->stCaption = false; - if(m_oQueryTableFieldId.IsInit()) - ptr1->idqsif = m_oQueryTableFieldId->GetValue(); - else - ptr1->idqsif = 0; + else + ptr1->stCaption = 0xFFFFFFFF; + if(m_oQueryTableFieldId.IsInit()) + ptr1->idqsif = m_oQueryTableFieldId->GetValue(); + else + ptr1->idqsif = 0xFFFFFFFF; if(m_oTotalsRowLabel.IsInit()) ptr1->stTotal = m_oTotalsRowLabel.get(); - else - ptr1->stTotal = false; + else + ptr1->stTotal = 0xFFFFFFFF; if(m_oUniqueName.IsInit()) ptr1->stName = m_oUniqueName.get(); - else if(m_oName.IsInit()) - ptr1->stName = m_oName.get(); - else - ptr1->stName = false; - if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; - else - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; - } - if(m_oCalculatedColumnFormula.IsInit()) - { - auto fmla(new XLSB::ListCCFmla); - fmla->formula = m_oCalculatedColumnFormula.get(); - ptr->m_BrtListCCFmla = XLS::BaseObjectPtr{fmla}; - } - if(m_oTotalsRowFormula.IsInit()) - { - auto fmla(new XLSB::ListTrFmla); - fmla->formula = m_oTotalsRowFormula.get(); - ptr->m_BrtListTrFmla = XLS::BaseObjectPtr{fmla}; - } - return objectPtr; - } + else + ptr1->stName = 0xFFFFFFFF; + if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; + else + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + } + if(m_oCalculatedColumnFormula.IsInit()) + { + auto fmla(new XLSB::ListCCFmla); + fmla->formula = m_oCalculatedColumnFormula.get(); + ptr->m_BrtListCCFmla = XLS::BaseObjectPtr{fmla}; + } + if(m_oTotalsRowFormula.IsInit()) + { + auto fmla(new XLSB::ListTrFmla); + fmla->formula = m_oTotalsRowFormula.get(); + ptr->m_BrtListTrFmla = XLS::BaseObjectPtr{fmla}; + } + return objectPtr; + } void CTableColumn::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -500,7 +501,6 @@ namespace Spreadsheet auto ptr1(new XLSB::BeginListCols); ptr1->nCols = m_arrItems.size(); ptr->m_BrtBeginListCols = XLS::BaseObjectPtr{ptr1}; - ptr->indexList = 1; for(auto i:m_arrItems) ptr->m_arLISTCOL.push_back(i->toBin()); return objectPtr; @@ -642,129 +642,125 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oRef.IsInit()) { - ptr1->rfxList = m_oRef->GetValue(); - ptr1->rfxList.to_string_cache = m_oRef->GetValue(); + ptr1->rfxList = m_oRef->GetValue(); } - if(m_oName.IsInit()) - ptr1->stName = m_oName.get(); - else if(m_oDisplayName.IsInit()) - ptr1->stName = m_oDisplayName.get(); - else - ptr1->stName = false; - if(m_oTotalsRowCount.IsInit()) - ptr1->crwTotals = m_oTotalsRowCount->GetValue(); - else - ptr1->crwTotals = 0; - - if(m_oHeaderRowCount.IsInit()) - ptr1->crwHeader = m_oHeaderRowCount->GetValue(); - else - ptr1->crwHeader = 0; + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else if(m_oDisplayName.IsInit()) + ptr1->stName = m_oDisplayName.get(); + else + ptr1->stName = 0xFFFFFFFF; + if(m_oTotalsRowCount.IsInit()) + ptr1->crwTotals = m_oTotalsRowCount->GetValue(); + else + ptr1->crwTotals = false; - if(m_oDisplayName.IsInit()) - ptr1->stDisplayName = m_oDisplayName.get(); - else - ptr1->stDisplayName = false; + if(m_oHeaderRowCount.IsInit()) + ptr1->crwHeader = m_oHeaderRowCount->GetValue(); + else + ptr1->crwHeader = true; - if(m_oTableBorderDxfId.IsInit()) - ptr1->nDxfBorder = m_oTableBorderDxfId->GetValue(); - else - ptr1->nDxfBorder = 0; + if(m_oDisplayName.IsInit()) + ptr1->stDisplayName = m_oDisplayName.get(); + else + ptr1->stDisplayName = 0xFFFFFFFF; - if(m_oComment.IsInit()) - ptr1->stComment = m_oComment.get(); - else - ptr1->stComment = false; + if(m_oTableBorderDxfId.IsInit()) + ptr1->nDxfBorder = m_oTableBorderDxfId->GetValue(); + else + ptr1->nDxfBorder = 0xFFFFFFFF; - if(m_oConnectionId.IsInit()) - ptr1->dwConnID = m_oConnectionId->GetValue(); - else - ptr1->dwConnID = 0; + if(m_oComment.IsInit()) + ptr1->stComment = m_oComment.get(); + else + ptr1->stComment = 0xFFFFFFFF; - if(m_oDataDxfId.IsInit()) - ptr1->nDxfData = m_oDataDxfId->GetValue(); - else - ptr1->nDxfData = 0; + if(m_oConnectionId.IsInit()) + ptr1->dwConnID = m_oConnectionId->GetValue(); + else + ptr1->dwConnID = 0; + if(m_oDataDxfId.IsInit()) + ptr1->nDxfData = m_oDataDxfId->GetValue(); + else + ptr1->nDxfData = 0xFFFFFFFF; - if(m_oDataCellStyle.IsInit()) - ptr1->stStyleData = m_oDataCellStyle.get(); - else - ptr1->stStyleData = false; + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleData = m_oDataCellStyle.get(); + else + ptr1->stStyleData = 0xFFFFFFFF; - if(m_oHeaderRowBorderDxfId.IsInit()) - ptr1->nDxfHeaderBorder = m_oHeaderRowBorderDxfId->GetValue(); - else - ptr1->nDxfHeaderBorder = 0; - if(m_oHeaderRowCellStyle.IsInit()) - ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); - else - ptr1->stStyleHeader = false; + if(m_oHeaderRowBorderDxfId.IsInit()) + ptr1->nDxfHeaderBorder = m_oHeaderRowBorderDxfId->GetValue(); + else + ptr1->nDxfHeaderBorder = 0xFFFFFFFF; - if(m_oHeaderRowDxfId.IsInit()) - ptr1->nDxfHeader = m_oHeaderRowDxfId->GetValue(); - else - ptr1->nDxfHeader = 0; + if(m_oHeaderRowCellStyle.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader = 0xFFFFFFFF; - if(m_oInsertRow.IsInit()) - ptr1->fForceInsertToBeVisible = m_oInsertRow.get(); + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHeader = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHeader = 0xFFFFFFFF; + if(m_oInsertRow.IsInit()) + ptr1->fForceInsertToBeVisible = m_oInsertRow.get(); else ptr1->fForceInsertToBeVisible = false; - if(m_oInsertRowShift.IsInit()) - ptr1->fInsertRowInsCells = m_oInsertRowShift.get(); + if(m_oInsertRowShift.IsInit()) + ptr1->fInsertRowInsCells = m_oInsertRowShift.get(); else ptr1->fInsertRowInsCells = false; - if(m_oPublished.IsInit()) - ptr1->fPublished = m_oPublished.get(); + if(m_oPublished.IsInit()) + ptr1->fPublished = m_oPublished.get(); else ptr1->fPublished = false; - if(m_oId.IsInit()) - ptr1->idList = m_oId->GetValue(); - else - ptr1->idList = 1; - if(m_oTableType.IsInit()) - { - if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeWorksheet) - ptr1->lt = XLSB::ListType::LTRANGE; - if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeXml) - ptr1->lt = XLSB::ListType::LTXML; - if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeQueryTable) - ptr1->lt = XLSB::ListType::LTEXTDATA; - } + if(m_oId.IsInit()) + ptr1->idList = m_oId->GetValue(); + + if(m_oTableType.IsInit()) + { + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeWorksheet) + ptr1->lt = XLSB::ListType::LTRANGE; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeXml) + ptr1->lt = XLSB::ListType::LTXML; + if(m_oTableType == SimpleTypes::Spreadsheet::ETableType::typeQueryTable) + ptr1->lt = XLSB::ListType::LTEXTDATA; + } else { - ptr1->lt = 0; + ptr1->lt = XLSB::ListType::LTRANGE; } - if(m_oTotalsRowBorderDxfId.IsInit()) - ptr1->nDxfAggBorder = m_oTotalsRowBorderDxfId->GetValue(); - else - ptr1->nDxfAggBorder = 0; - - if(m_oTotalsRowCellStyle.IsInit()) - ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); - else - ptr1->stStyleAgg = false; - - if(m_oTotalsRowDxfId.IsInit()) - ptr1->nDxfAgg = m_oTotalsRowDxfId->GetValue(); - else - ptr1->nDxfAgg = 0; + if(m_oTotalsRowBorderDxfId.IsInit()) + ptr1->nDxfAggBorder = m_oTotalsRowBorderDxfId->GetValue(); + else + ptr1->nDxfAggBorder = 0xFFFFFFFF; + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg = 0xFFFFFFFF; - if(m_oTotalsRowShown.IsInit()) - ptr1->fShownTotalRow = m_oTotalsRowShown.get(); - else - ptr1->fShownTotalRow = true; - if(m_oAutoFilter.IsInit()) - ptr->m_AUTOFILTER = m_oAutoFilter->toBin(); - if(m_oSortState.IsInit()) - ptr->m_SORTSTATE = m_oSortState->toBin(); - if(m_oTableColumns.IsInit()) - ptr->m_LISTCOLS = m_oTableColumns->toBin(); - if(m_oTableStyleInfo.IsInit()) - ptr->m_BrtTableStyleClient = m_oTableStyleInfo->toBin(); + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfAgg = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfAgg = 0xFFFFFFFF; - if(m_oExtLst.IsInit()) + if(m_oTotalsRowShown.IsInit()) + ptr1->fShownTotalRow = m_oTotalsRowShown.get(); + else + ptr1->fShownTotalRow = false; + ptr1->fSingleCell = false; + if(m_oAutoFilter.IsInit()) + ptr->m_AUTOFILTER = m_oAutoFilter->toBin(); + if(m_oSortState.IsInit()) + ptr->m_SORTSTATE = m_oSortState->toBin(); + if(m_oTableColumns.IsInit()) + ptr->m_LISTCOLS = m_oTableColumns->toBin(); + if(m_oTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oTableStyleInfo->toBin(); + if(m_oExtLst.IsInit()) ptr->m_FRTTABLE = m_oExtLst->toBinTable(); return objectPtr; } From bfaca9d414225e8b0321554334ca54975204d0c8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Sep 2023 19:27:47 +0600 Subject: [PATCH 145/794] Fix wokkbook binary type --- OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h index d2a3471bc48..f52d79a2ec5 100644 --- a/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h +++ b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h @@ -39,10 +39,10 @@ namespace OOX namespace SpreadsheetBin { namespace FileTypes - { + { const FileType WorkbookBin (L"xl", L"workbook.bin", - L"application/vnd.ms-excel.main", + L"application/vnd.ms-excel.sheet.binary.macroEnabled.main", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); const FileType SharedStringsBin (L"", L"sharedStrings.bin", From 9ae35fe594dca21527823847870a0450ab504b5a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Sep 2023 19:30:45 +0600 Subject: [PATCH 146/794] Add default values for workbook records --- OOXML/XlsxFormat/Workbook/CalcPr.cpp | 16 ++++--- OOXML/XlsxFormat/Workbook/Workbook.cpp | 11 +++-- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 56 ++++++++++++++++++------ 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/CalcPr.cpp b/OOXML/XlsxFormat/Workbook/CalcPr.cpp index 8e1cdee0c93..739b5cb9ddc 100644 --- a/OOXML/XlsxFormat/Workbook/CalcPr.cpp +++ b/OOXML/XlsxFormat/Workbook/CalcPr.cpp @@ -89,10 +89,16 @@ namespace OOX if(m_oCalcId.IsInit()) ptr->recalcID = m_oCalcId->GetValue(); + else + ptr->recalcID = 0; if(m_oCalcMode.IsInit()) ptr->fAutoRecalc = m_oCalcMode->GetValue(); + else + ptr->fAutoRecalc = 1; if(m_oFullCalcOnLoad.IsInit()) ptr->fFullCalcOnLoad = m_oFullCalcOnLoad->GetValue(); + else + ptr->fFullCalcOnLoad = false; if(m_oRefMode.IsInit()) ptr->fRefA1 = !m_oRefMode->GetValue(); if(m_oIterate.IsInit()) @@ -102,15 +108,15 @@ namespace OOX if(m_oIterateCount.IsInit()) ptr->cCalcCount = m_oIterateCount->GetValue(); else - ptr->cCalcCount = 100; + ptr->cCalcCount = 0; if(m_oIterateDelta.IsInit()) ptr->xnumDelta.data.value = m_oIterateDelta->GetValue(); else - ptr->xnumDelta.data.value = 0.001; + ptr->xnumDelta.data.value = 0; if(m_oFullPrecision.IsInit()) ptr->fFullPrec = m_oFullPrecision->GetValue(); else - ptr->fFullPrec = false; + ptr->fFullPrec = true; if(m_oCalcCompleted.IsInit()) ptr->fSomeUncalced = m_oCalcCompleted->GetValue(); else @@ -118,11 +124,11 @@ namespace OOX if(m_oCalcOnSave.IsInit()) ptr->fSaveRecalc = m_oCalcOnSave->GetValue(); else - ptr->fSaveRecalc = false; + ptr->fSaveRecalc = true; if(m_oConcurrentCalc.IsInit()) ptr->fMTREnabled = m_oConcurrentCalc->GetValue(); else - ptr->fMTREnabled = false; + ptr->fMTREnabled = true; if(m_oConcurrentManualCount.IsInit()) ptr->cUserThreadCount = m_oConcurrentManualCount->GetValue(); else diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index e5a038513d1..7ff74a97123 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -280,11 +280,11 @@ namespace OOX { XLSB::WorkBookStreamPtr workBookStream(new XLSB::WorkBookStream); - if (m_oBookViews.IsInit()) - { auto viewPtr(new XLSB::BOOKVIEWS); + if (m_oBookViews.IsInit()) + { + auto viewPtr(new XLSB::BOOKVIEWS); + viewPtr->m_arBrtBookView = m_oBookViews->toBin(); workBookStream->m_BOOKVIEWS = XLS::BaseObjectPtr{viewPtr}; - - viewPtr->m_arBrtBookView = m_oBookViews->toBin(); } if (m_oCalcPr.IsInit()) workBookStream->m_BrtCalcProp = m_oCalcPr->toBin(); @@ -295,9 +295,8 @@ namespace OOX if (m_oSheets.IsInit()) { auto ptr(new XLSB::BUNDLESHS); - XLS::BaseObjectPtr objectPtr(ptr); ptr->m_arBrtBundleSh = m_oSheets->toBin(); - workBookStream->m_BUNDLESHS = objectPtr; + workBookStream->m_BUNDLESHS = XLS::BaseObjectPtr{ptr}; } if (m_oWorkbookPr.IsInit()) workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 896114150c0..c80f937e378 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -96,44 +96,72 @@ namespace OOX if(m_oAllowRefreshQuery.IsInit()) ptr->fNoSaveSup = m_oAllowRefreshQuery->GetValue(); + else + ptr->fNoSaveSup = false; if(m_oAutoCompressPictures.IsInit()) - ptr->fAutoCompressPictures = m_oAutoCompressPictures->GetValue(); + ptr->fAutoCompressPictures = m_oAutoCompressPictures->GetValue(); if(m_oBackupFile.IsInit()) - ptr->fBackup = m_oBackupFile->GetValue(); + ptr->fBackup = m_oBackupFile->GetValue(); + else + ptr->fBackup = false; if(m_oCheckCompatibility.IsInit()) - ptr->fCheckCompat = m_oCheckCompatibility->GetValue(); + ptr->fCheckCompat = m_oCheckCompatibility->GetValue(); + else + ptr->fCheckCompat = false; if(m_oCodeName.IsInit()) ptr->strName.value = m_oCodeName->GetValue(); else ptr->strName.value = false; if(m_oDate1904.IsInit()) - ptr->f1904 = m_oDate1904->GetValue(); + ptr->f1904 = m_oDate1904->GetValue(); + else + ptr->f1904 = false; if(m_oDateCompatibility.IsInit()) - ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); + ptr->fNoSaveSup = m_oDateCompatibility->GetValue(); + else + ptr->fNoSaveSup = false; if(m_oDefaultThemeVersion.IsInit()) ptr->dwThemeVersion = m_oDefaultThemeVersion->GetValue(); else ptr->dwThemeVersion = 0; if(m_oFilterPrivacy.IsInit()) - ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); + ptr->fFilterPrivacy = m_oFilterPrivacy->GetValue(); + else + ptr->fFilterPrivacy = false; if(m_oHidePivotFieldList.IsInit()) - ptr->fHidePivotTableFList = m_oHidePivotFieldList->GetValue(); + ptr->fHidePivotTableFList = m_oHidePivotFieldList->GetValue(); + else + ptr->fHidePivotTableFList = false; if(m_oPromptedSolutions.IsInit()) - ptr->fBuggedUserAboutSolution = m_oPromptedSolutions->GetValue(); + ptr->fBuggedUserAboutSolution = m_oPromptedSolutions->GetValue(); + else + ptr->fBuggedUserAboutSolution = false; if(m_oPublishItems.IsInit()) - ptr->fPublishedBookItems = m_oPublishItems->GetValue(); + ptr->fPublishedBookItems = m_oPublishItems->GetValue(); + else + ptr->fPublishedBookItems = false; if(m_oRefreshAllConnections.IsInit()) - ptr->fRefreshAll = m_oRefreshAllConnections->GetValue(); + ptr->fRefreshAll = m_oRefreshAllConnections->GetValue(); + else + ptr->fRefreshAll = false; if(m_oShowBorderUnselectedTables.IsInit()) - ptr->fHideBorderUnselLists = m_oShowBorderUnselectedTables->GetValue(); + ptr->fHideBorderUnselLists = m_oShowBorderUnselectedTables->GetValue(); + else + ptr->fHideBorderUnselLists = false; if(m_oShowInkAnnotation.IsInit()) - ptr->fShowInkAnnotation = m_oShowInkAnnotation->GetValue(); + ptr->fShowInkAnnotation = m_oShowInkAnnotation->GetValue(); if(m_oShowObjects.IsInit()) ptr->mdDspObj = m_oShowObjects->GetValue() ? 1 : 2; + else + ptr->mdDspObj = 0; if(m_oShowPivotChartFilter.IsInit()) - ptr->fShowPivotChartFilter = m_oShowPivotChartFilter->GetValue(); + ptr->fShowPivotChartFilter = m_oShowPivotChartFilter->GetValue(); + else + ptr->fShowPivotChartFilter = false; if(m_oUpdateLinks.IsInit()) - ptr->grbitUpdateLinks = m_oUpdateLinks->GetValue(); + ptr->grbitUpdateLinks = m_oUpdateLinks->GetValue(); + else + ptr->grbitUpdateLinks = 0; return objectPtr; } From daba15e14252b552b4ad8321c7b8fd430eeafd6b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 8 Sep 2023 16:14:24 +0600 Subject: [PATCH 147/794] Fix workbook names conversion --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 47 ++++++++++++++++------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 123b50a4431..90c9eb256a7 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -78,37 +78,58 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); if(m_oComment.IsInit()) - ptr->comment = m_oComment.get(); + ptr->comment = m_oComment.get(); + else + ptr->comment = 0xFFFFFFFF; if(m_oDescription.IsInit()) - ptr->description = m_oDescription.get(); + ptr->description = m_oDescription.get(); + else + ptr->description = 0xFFFFFFFF; if(m_oFunction.IsInit()) - ptr->fFunc = m_oFunction->GetValue(); + ptr->fFunc = m_oFunction->GetValue(); + else + ptr->fFunc = 0xFFFFFFFF; if(m_oFunctionGroupId.IsInit()) - ptr->fGrp = m_oFunctionGroupId->GetValue(); + ptr->fGrp = m_oFunctionGroupId->GetValue(); + if(m_oHelp.IsInit()) - ptr->helpTopic = m_oHelp.get(); + ptr->helpTopic = m_oHelp.get(); + else + ptr->helpTopic = 0xFFFFFFFF; if(m_oHidden.IsInit()) - ptr->fHidden = m_oHidden->GetValue(); + ptr->fHidden = m_oHidden->GetValue(); if (m_oLocalSheetId.IsInit()) ptr->itab = m_oLocalSheetId->GetValue(); if (m_oName.IsInit()) - ptr->name = m_oName.get(); + ptr->name = m_oName.get(); + else + ptr->name = 0xFFFFFFFF; if (m_oPublishToServer.IsInit()) - ptr->fPublished = m_oPublishToServer->GetValue(); + ptr->fPublished = m_oPublishToServer->GetValue(); if (m_oShortcutKey.IsInit()) - ptr->chKey = std::stoi(m_oShortcutKey.get()); + ptr->chKey = std::stoi(m_oShortcutKey.get()); if (m_oVbProcedure.IsInit()) - ptr->fOB = m_oVbProcedure->GetValue(); + ptr->fOB = m_oVbProcedure->GetValue(); + else + ptr->fOB = false; + if(!ptr->fOB) + ptr->fProc = false; + if(!ptr->fProc) + { + ptr->unusedstring1 = 0xFFFFFFFF; + ptr->unusedstring2 = 0xFFFFFFFF; + } + if (m_oWorkbookParameter.IsInit()) - ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); + ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); if (m_oXlm.IsInit()) - ptr->fFutureFunction = m_oXlm->GetValue(); + ptr->fFutureFunction = m_oXlm->GetValue(); if (m_oRef.IsInit()) - ptr->rgce = m_oRef.get(); + ptr->rgce = m_oRef.get(); return objectPtr; } From 6743757a9418853f03b2531547bc92493aedf46b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 8 Sep 2023 16:35:45 +0600 Subject: [PATCH 148/794] Add slicer conversion --- OOXML/XlsxFormat/Slicer/Slicer.cpp | 99 +++++++++++++++++++++++++++--- OOXML/XlsxFormat/Slicer/Slicer.h | 8 +-- 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Slicer/Slicer.cpp b/OOXML/XlsxFormat/Slicer/Slicer.cpp index 4ffeb31420a..a187f302c69 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.cpp +++ b/OOXML/XlsxFormat/Slicer/Slicer.cpp @@ -38,6 +38,8 @@ #include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -72,6 +74,14 @@ void CSlicers::fromBin(XLS::BaseObjectPtr& obj) m_oSlicer.push_back(CSlicer(slicer)); } } +XLS::BaseObjectPtr CSlicers::toBin() +{ + auto ptr(new XLSB::SLICERS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicer) + ptr->m_arSLICER.push_back(i.toBin()); + return objectPtr; +} void CSlicers::toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const { writer.StartNode(sName); @@ -170,6 +180,55 @@ void CSlicer::fromBin(XLS::BaseObjectPtr& obj) ReadAttributes(ptr->m_BrtBeginSlicer); } } +XLS::BaseObjectPtr CSlicer::toBin() +{ + auto ptr1(new XLSB::SLICER); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSlicer); + ptr1->m_BrtBeginSlicer = XLS::BaseObjectPtr{ptr}; + + if(m_oStartItem.IsInit()) + ptr->dwStartSlicerItem = m_oStartItem.get(); + if(m_oColumnCount.IsInit()) + ptr->dwColumnCount = m_oColumnCount.get(); + if(m_oShowCaption.IsInit()) + ptr->fCaptionVisible = m_oShowCaption.get(); + if(m_oLevel.IsInit()) + ptr->dwLevel = m_oLevel.get(); + if(m_oLockedPosition.IsInit()) + ptr->fLockedPosition = m_oLockedPosition.get(); + if(m_oRowHeight.IsInit()) + ptr->dxRowHeight = m_oRowHeight.get(); + + if(m_oName.IsInit()) + ptr->stName = m_oName.get(); + else if(m_oUid.IsInit()) + ptr->stName = m_oUid.get(); + else + ptr->stName = 0xFFFFFFFF; + + if(m_oCache.IsInit()) + ptr->stSlicerCacheName = m_oCache.get(); + else + ptr->stSlicerCacheName = 0xFFFFFFFF; + if(m_oCaption.IsInit()) + ptr->stCaption = m_oCaption.get(); + else + { + ptr->stCaption = 0xFFFFFFFF; + ptr->fCaptionVisible = false; + ptr->fHasCaption = false; + } + + if(m_oStyle.IsInit()) + ptr->stStyle = m_oStyle.get(); + else + { + ptr->stStyle = 0xFFFFFFFF; + ptr->fHasStyle = false; + } + return objectPtr; +} void CSlicer::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -345,6 +404,15 @@ void CSlicerFile::readBin(const CPath& oPath) } } +XLS::BaseObjectPtr CSlicerFile::WriteBin() const +{ + XLSB::SlicersStreamPtr slicersStream(new XLSB::SlicersStream); + XLS::BaseObjectPtr objectPtr(slicersStream); + if(m_oSlicers.IsInit()) + slicersStream->m_SLICERS = m_oSlicers->toBin(); + return objectPtr; +} + void CSlicerFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -370,18 +438,35 @@ void CSlicerFile::write(const CPath& oPath, const CPath& oDirectory, CContentTyp { if(!m_oSlicers.IsInit()) return; + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oSlicers->toXML(sXml, L"slicers"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oSlicers->toXML(sXml, L"slicers"); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } +const OOX::FileType CSlicerFile::type() const +{ + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SlicerBin; + } + return OOX::Spreadsheet::FileTypes::Slicer; +} + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Slicer/Slicer.h b/OOXML/XlsxFormat/Slicer/Slicer.h index ad66ce73e08..b605fd4e60b 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.h +++ b/OOXML/XlsxFormat/Slicer/Slicer.h @@ -59,6 +59,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -96,6 +97,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -121,6 +123,7 @@ namespace OOX read( oRootPath, oPath ); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -129,10 +132,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::Slicer; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); From 0c55adc82a06fb3e2f82bbb21f9eed34a0cbc4fb Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Sun, 10 Sep 2023 15:19:45 +0300 Subject: [PATCH 149/794] Conversion development --- .../StarMath2OOXML/StarMath2OOXML.pro | 3 +- .../Reader/Converter/StarMath2OOXML/Test.cpp | 4 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 203 +++++++++++++++--- .../StarMath2OOXML/cconversionsmtoooxml.h | 19 +- .../StarMath2OOXML/cstarmathpars.cpp | 16 +- .../Converter/StarMath2OOXML/cstarmathpars.h | 105 +-------- .../Converter/StarMath2OOXML/typeselements.h | 105 +++++++++ 7 files changed, 315 insertions(+), 140 deletions(-) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro index 1353236beec..1723166640e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro @@ -13,6 +13,7 @@ SOURCES += Test.cpp \ HEADERS += \ cconversionsmtoooxml.h \ - cstarmathpars.h + cstarmathpars.h \ + typeselements.h DESTDIR = $$PWD_ROOT_DIR/build/$$CIRE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp index 7e664e47147..bfe63d7e432 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -3,9 +3,9 @@ int main() { - std::wstring Temp = L"2+1"; + std::wstring Temp = L"1 + 2 over 3"; StarMath::CStarMathPars TempO; TempO.Pars(Temp); - ConversionSM2OOXML::CConversionSMtoOOXML m_oTest; + StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(TempO.GetVector()); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 7c41842c5e3..e3bb31cf435 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -1,5 +1,7 @@ #include "cconversionsmtoooxml.h" -namespace ConversionSM2OOXML { +#include "../../../../DesktopEditor/common/File.h" +#include +namespace StarMath { CConversionSMtoOOXML::CConversionSMtoOOXML() { } @@ -7,71 +9,218 @@ namespace ConversionSM2OOXML { { m_oXmlWrite.WriteNodeBegin(L"m:oMathPara",false); m_oXmlWrite.WriteNodeBegin(L"m:oMath",false); - m_oXmlWrite.WriteNodeBegin(L"m:r",false); - StandartProperties(); - for(StarMath::CElement* m_oTempElement:arPars) + for(CElement* m_oTempElement:arPars) { ConversionOneElement(m_oTempElement); } EndConversion(); - std::wcout<< m_oXmlWrite.GetXmlString()<GetType() == 0) - { - ConversNumber(dynamic_cast(m_oElement)); - } - else if(m_oElement->GetType() == 1) + switch (m_oElement->GetType()) { - ConversBinOperator(dynamic_cast (m_oElement)); + case Number: + ConversNumber(dynamic_cast(m_oElement)); + break; + case BinOperator: + ConversBinOperator(dynamic_cast (m_oElement)); + break; + case Operator: + ConversOperator(dynamic_cast (m_oElement)); + break; + default: + break; } } - void CConversionSMtoOOXML::ConversBinOperator(StarMath::CBinaryOperator *m_oElement) + void CConversionSMtoOOXML::ConversBinOperator(CBinaryOperator *m_oElement) { - if(m_oElement->GetTypeBin() == 3 || m_oElement->GetTypeBin() == 4) + if(m_oElement->GetTypeBin() == plus || m_oElement->GetTypeBin() == minus || m_oElement->GetTypeBin() == multipl || m_oElement->GetTypeBin() == cdot || m_oElement->GetTypeBin() == times || m_oElement->GetTypeBin() == div || m_oElement->GetTypeBin() == odivide || m_oElement->GetTypeBin() == oplus || m_oElement->GetTypeBin() == ominus || m_oElement->GetTypeBin() == odot || m_oElement->GetTypeBin() == otimes) { - m_oXmlWrite.WriteNodeBegin(L"m:t",false); ConversionOneElement(m_oElement->GetLeftArg()); - if(m_oElement->GetTypeRight() == 0) + m_oXmlWrite.WriteNodeBegin(L"m:r",false); + StandartProperties(); + m_oXmlWrite.WriteNodeBegin(L"m:t",false); + switch (m_oElement->GetTypeBin()) + { + case plus: m_oXmlWrite.WriteString(L"+");break; + case minus: + m_oXmlWrite.WriteString(L"-"); + break; + case multipl: + m_oXmlWrite.WriteString(L"*"); + break; + case cdot: + m_oXmlWrite.WriteString(L"\u00B7"); + break; + case times: + m_oXmlWrite.WriteString(L"\u00D7"); + break; + case div: + m_oXmlWrite.WriteString(L"\u00F7"); + break; + case odivide: + m_oXmlWrite.WriteString(L"\u2298"); + break; + case oplus: + m_oXmlWrite.WriteString(L"\u2295"); + break; + case ominus: + m_oXmlWrite.WriteString(L"\u2296"); + break; + case odot: + m_oXmlWrite.WriteString(L"\u2299"); + break; + case otimes: + m_oXmlWrite.WriteString(L"\u2297"); + break; + default: + break; + } + if(m_oElement->GetTypeRight() == Number) + { + CNumber* m_oNumber = dynamic_cast (m_oElement->GetRightArg()); + m_oXmlWrite.WriteString(m_oNumber->GetValue()); + m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); + } + else { - if(m_oElement->GetTypeBin() == 3) m_oXmlWrite.WriteString(L"+"); - else m_oXmlWrite.WriteString(L"-"); + m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); ConversionOneElement(m_oElement->GetRightArg()); } - m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); + + } + else if(m_oElement->GetTypeBin() == over || m_oElement->GetTypeBin() == division) + { + m_oXmlWrite.WriteNodeBegin(L"m:f",false); + if(m_oElement->GetTypeBin() == division) PropertiesMFPR(true,L"skw"); + else PropertiesMFPR(false,L""); + BlockRecording(L"m:num",m_oElement->GetLeftArg()); + BlockRecording(L"m:den",m_oElement->GetRightArg()); + m_oXmlWrite.WriteNodeEnd(L"m:f",false,false); } } - void CConversionSMtoOOXML::ConversNumber(StarMath::CNumber *m_oElement) + void CConversionSMtoOOXML::ConversNumber(CNumber *m_oElement) { + m_oXmlWrite.WriteNodeBegin(L"m:r",false); + StandartProperties(); + m_oXmlWrite.WriteNodeBegin(L"m:t",false); m_oXmlWrite.WriteString(m_oElement->GetValue()); + m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); + } + void CConversionSMtoOOXML::ConversOperator(COperator *m_oElement) + { + if(m_oElement->GetTypeOp() == sum) + { + m_oXmlWrite.WriteNodeBegin(L"m:nary",false); + PropertiesNaryPr(L"\u2211",nullptr == m_oElement->GetFrom(),m_oElement->GetTo()); + if(m_oElement->GetFrom() == nullptr) m_oXmlWrite.WriteNode(L"m:sub",L""); + else + { + BlockRecording(L"m:sub",m_oElement->GetFrom()); + } + if(m_oElement->GetTo() == nullptr) m_oXmlWrite.WriteNode(L"m:sup",L""); + else + { + BlockRecording(L"m:sup",m_oElement->GetTo()); + } + BlockRecording(L"m:e",m_oElement->GetValueOp()); + m_oXmlWrite.WriteNodeEnd(L"m:nary",false,false); + } } void CConversionSMtoOOXML::StandartProperties() { - m_oXmlWrite.WriteNodeBegin(L"m:rPr",false); - m_oXmlWrite.WriteNodeBegin(L"m:sty",true); - m_oXmlWrite.WriteAttribute(L"m:val",L"p"); + m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); + m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); + m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); + m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeBegin(L"w:sz",true); + m_oXmlWrite.WriteAttribute(L"w:val",L"40"); m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeEnd(L"m:rPr",false,false); + m_oXmlWrite.WriteNodeBegin(L"w:szCs",true); + m_oXmlWrite.WriteAttribute(L"w:val",L"40"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); + } + void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType) + { + m_oXmlWrite.WriteNodeBegin(L"m:fPr",false); + if(bType) + { + m_oXmlWrite.WriteNodeBegin(L"m:type",true); + m_oXmlWrite.WriteAttribute(L"m:val",wsType); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + } + m_oXmlWrite.WriteNodeBegin(L"m:ctrlPr",false); m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNode(L"w:i",L""); + //m_oXmlWrite.WriteNode(L"w:iCs",L""); m_oXmlWrite.WriteNodeBegin(L"w:sz",true); m_oXmlWrite.WriteAttribute(L"w:val",L"40"); m_oXmlWrite.WriteNodeEnd(L"w",true,true); m_oXmlWrite.WriteNodeBegin(L"w:szCs",true); m_oXmlWrite.WriteAttribute(L"w:val",L"40"); m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeBegin(L"w:lang",true); - m_oXmlWrite.WriteAttribute(L"w:val",L"en-US"); + m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:ctrlPr",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:fPr",false,false); + } + void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup) + { + m_oXmlWrite.WriteNodeBegin(L"m:naryPr",false); + m_oXmlWrite.WriteNodeBegin(L"m:chr",true); + m_oXmlWrite.WriteAttribute(L"m:val",wsTypeOperator); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNodeBegin(L"m:limLoc",true); + m_oXmlWrite.WriteAttribute(L"m:val",L"undOvr"); m_oXmlWrite.WriteNodeEnd(L"w",true,true); + if(bEmptySub) + { + m_oXmlWrite.WriteNodeBegin(L"m:subHide",true); + m_oXmlWrite.WriteAttribute(L"m:val",L"1"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + } + if(bEmptySup) + { + m_oXmlWrite.WriteNodeBegin(L"m:supHide",true); + m_oXmlWrite.WriteAttribute(L"m:val",L"1"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + } + m_oXmlWrite.WriteNodeBegin(L"m:ctrlPr",false); + m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); + m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); + m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); + m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); + m_oXmlWrite.WriteNodeEnd(L"w",true,true); + m_oXmlWrite.WriteNode(L"w:i",L""); m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:ctrlPr",false,false); + m_oXmlWrite.WriteNodeEnd(L"m:naryPr",false,false); + } + void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock) + { + m_oXmlWrite.WriteNodeBegin(wsNameBlock,false); + ConversionOneElement(CValueBlock); + m_oXmlWrite.WriteNodeEnd(wsNameBlock,false,false); + } + std::wstring CConversionSMtoOOXML::GetOOXML() + { + return m_oXmlWrite.GetXmlString(); } void CConversionSMtoOOXML::EndConversion() { - m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); + //m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); m_oXmlWrite.WriteNodeEnd(L"m:oMath",false,false); m_oXmlWrite.WriteNodeEnd(L"m:oMathPara",false,false); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index f658e68cb14..6c47b84ddff 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -1,20 +1,27 @@ #ifndef CCONVERSIONSMTOOOXML_H #define CCONVERSIONSMTOOOXML_H #include "cstarmathpars.h" -#include "X:/Rabotka/Clone/core/DesktopEditor/xml/include/xmlwriter.h" +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" -namespace ConversionSM2OOXML { + + +namespace StarMath { class CConversionSMtoOOXML { public: CConversionSMtoOOXML(); //friend class StarMath::CStarMathPars; - void StartConversion(std::vector arPars); + void StartConversion(std::vector arPars); void StandartProperties(); - void ConversionOneElement(StarMath::CElement* m_oElement); - void ConversBinOperator(StarMath::CBinaryOperator* m_oElement); - void ConversNumber(StarMath::CNumber* m_oElement); + void PropertiesMFPR(bool bType,const std::wstring& wsType); + void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup); + void ConversionOneElement(CElement* m_oElement); + void ConversBinOperator(CBinaryOperator* m_oElement); + void ConversNumber(CNumber* m_oElement); + void ConversOperator(COperator* m_oElement); + void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock); void EndConversion(); + std::wstring GetOOXML() ; private: XmlUtils::CXmlWriter m_oXmlWrite; }; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 89b890d057b..e4d6c1662cd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -116,7 +116,6 @@ namespace StarMath arValueBrecket.push_back(ParsElement(itFirst,itEnd,arValueBrecket)); } wsOneElement = GetElement(itFirst,itEnd); - std::wcout << wsOneElement << std::endl; if(L"right" == wsOneElement) wsOneElement = GetElement(itFirst,itEnd); m_oBracket->SetBracketVal(arValueBrecket); m_oBracket->SetTypeBracket(wsTypeBracket); @@ -447,9 +446,6 @@ namespace StarMath } TypeElement COperator::GetType() { - /*std::wcout << oFromValue->GetType() <GetType() <GetType() < #include #include @@ -7,105 +8,6 @@ namespace StarMath { - enum TypeElement{ - Number, - BinOperator, - Operator, - Bracket, - UnarSign, - Attribute, - SpecialCharacter, - }; - enum TypeBinOperator - { - cdot, - times, - over, - plus, - minus, - frac, - div, - multipl, - division, - oplus, - ominus, - odot, - otimes, - odivide, - circ, - wideslash, - widebslash, - }; - enum TypeOperator - { - lim, - sum, - }; - enum TypeBracket - { - brace, - round, - square, - ldbracket, - lbrace, - langle, - lceil, - lfloor, - lline, - ldline, - }; - enum TypeAttributeTop - { - noneTop, - acute, - breve, - dot, - dddot, - vec, - tilde, - check, - grave, - circle, - ddot, - bar, - harpoon, - hat, - widevec, - widetilde, - overline, - overstrike, - wideharpoon, - widehat, - underline,//top elements - }; - enum TypeAttributeColor - { - noneColor, - black, - green, - aqua, - yellow, - lime, - navy, - purple, - teal, - blue, - red, - fuchsia, - gray, - maroon, - olive, - silver, - coral, - midnightblue, - crimson, - violet,//color(without rgb and hex) - }; - enum TypeCharacter - { - mline, - grid, - }; class CAttribute { public: @@ -201,6 +103,9 @@ namespace StarMath void SetFrom(CElement* oFrom); void SetTo(CElement* oTo); void SetValueOp(CElement* oValue); + CElement* GetValueOp(); + CElement* GetFrom(); + CElement* GetTo(); private: TypeOperator enTypeOp; CElement* oFromValue{nullptr}; @@ -233,7 +138,7 @@ namespace StarMath std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, std::vector& arParsLine); bool CheckDigit(const std::wstring& wsCheckToken); - bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); + //bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); static bool CheckBinOperator(const std::wstring& wsCheckToken); bool CheckBinOperatorLowPriority(const std::wstring& wsCheckToken); bool CheckPlusOrMinus(const std::wstring& wsCheckToken); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h new file mode 100644 index 00000000000..cd3023ee4ad --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -0,0 +1,105 @@ +#ifndef TYPESELEMENTS_H +#define TYPESELEMENTS_H +namespace StarMath +{ +enum TypeElement{ + Number, + BinOperator, + Operator, + Bracket, + UnarSign, + Attribute, + SpecialCharacter, +}; +enum TypeBinOperator +{ + cdot, + times, + over, + plus, + minus, + frac, + div, + multipl, + division, + oplus, + ominus, + odot, + otimes, + odivide, + circ, + wideslash, + widebslash, +}; +enum TypeOperator +{ + lim, + sum, +}; +enum TypeBracket +{ + brace, + round, + square, + ldbracket, + lbrace, + langle, + lceil, + lfloor, + lline, + ldline, +}; +enum TypeAttributeTop +{ + noneTop, + acute, + breve, + dot, + dddot, + vec, + tilde, + check, + grave, + circle, + ddot, + bar, + harpoon, + hat, + widevec, + widetilde, + overline, + overstrike, + wideharpoon, + widehat, + underline,//top elements +}; +enum TypeAttributeColor +{ + noneColor, + black, + green, + aqua, + yellow, + lime, + navy, + purple, + teal, + blue, + red, + fuchsia, + gray, + maroon, + olive, + silver, + coral, + midnightblue, + crimson, + violet,//color(without rgb and hex) +}; +enum TypeCharacter +{ + mline, + grid, +}; +} +#endif // TYPESELEMENTS_H From e70589f943a43857e281331a0d2004a1d8dfca23 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 11 Sep 2023 18:24:48 +0600 Subject: [PATCH 150/794] Fix default values for workbook definde names --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 90c9eb256a7..688cf789db4 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -102,6 +102,8 @@ namespace OOX if (m_oLocalSheetId.IsInit()) ptr->itab = m_oLocalSheetId->GetValue(); + else + ptr->itab = 0xFFFFFFFF; if (m_oName.IsInit()) ptr->name = m_oName.get(); From e72afe11d355c16a609d6b8579b6009a59d71ebb Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 11 Sep 2023 18:14:38 +0300 Subject: [PATCH 151/794] Adding tests --- .../StarMath2OOXML/StarMath2OOXML.pri | 16 ++ .../StarMath2OOXML/StarMath2OOXML.pro | 19 --- .../Reader/Converter/StarMath2OOXML/Test.cpp | 16 +- .../TestSMConverter/TestSMConverter.pro | 18 ++ .../StarMath2OOXML/TestSMConverter/main.cpp | 159 ++++++++++++++++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 12 +- 6 files changed, 207 insertions(+), 33 deletions(-) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri delete mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri new file mode 100644 index 00000000000..fe88c40eb88 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri @@ -0,0 +1,16 @@ + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(UnicodeConverter, kernel) + +SOURCES += $$PWD/cconversionsmtoooxml.cpp \ + $$PWD/cstarmathpars.cpp + +HEADERS += \ + $$PWD/cconversionsmtoooxml.h \ + $$PWD/cstarmathpars.h \ + $$PWD/typeselements.h + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro deleted file mode 100644 index 1723166640e..00000000000 --- a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pro +++ /dev/null @@ -1,19 +0,0 @@ -QT -= core gui - -CORE_ROOT_DIR = $$PWD/../../../.. -PWD_ROOT_DIR = $$PWD - -include($$CORE_ROOT_DIR/Common/base.pri) - -ADD_DEPENDENCY(UnicodeConverter, kernel) - -SOURCES += Test.cpp \ - cconversionsmtoooxml.cpp \ - cstarmathpars.cpp - -HEADERS += \ - cconversionsmtoooxml.h \ - cstarmathpars.h \ - typeselements.h - -DESTDIR = $$PWD_ROOT_DIR/build/$$CIRE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp index bfe63d7e432..4f9a843b9c2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/Test.cpp @@ -1,11 +1,11 @@ #include "cstarmathpars.h" #include "cconversionsmtoooxml.h" -int main() -{ - std::wstring Temp = L"1 + 2 over 3"; - StarMath::CStarMathPars TempO; - TempO.Pars(Temp); - StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(TempO.GetVector()); -} +//int main() +//{ +// std::wstring Temp = L"1 + 2 over 3"; +// StarMath::CStarMathPars TempO; +// TempO.Pars(Temp); +// StarMath::CConversionSMtoOOXML m_oTest; +// m_oTest.StartConversion(TempO.GetVector()); +//} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro new file mode 100644 index 00000000000..788618500be --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/TestSMConverter.pro @@ -0,0 +1,18 @@ +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri) +include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) + + + +SOURCES += main.cpp + +DESTDIR = $$PWD/build diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp new file mode 100644 index 00000000000..ff0774672ee --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -0,0 +1,159 @@ +#include "../cstarmathpars.h" +#include "../cconversionsmtoooxml.h" +#include "gtest/gtest.h" + + + +TEST(SMConvectorTest, BinOperatorPlus) +{ + std::wstring wsBinOperatorPlus = L"2 + 3"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"2+3"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOver) +{ + std::wstring wsBinOperatorPlus = L"2 over 3"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"23"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorCdot) +{ + std::wstring wsBinOperatorPlus = L"5 cdot 8"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"5\u00B78"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorTimes) +{ + std::wstring wsBinOperatorPlus = L"5 times 8"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"5\u00D78"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorMultipl) +{ + std::wstring wsBinOperatorPlus = L"4 * 2"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"4*2"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorDiv) +{ + std::wstring wsBinOperatorPlus = L"4div2"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"4\u00F72"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorDivision) +{ + std::wstring wsBinOperatorPlus = L"4/2"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"42"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOplus) +{ + std::wstring wsBinOperatorPlus = L"226oplus179"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"226\u2295179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOdot) +{ + std::wstring wsBinOperatorPlus = L"226 odot 179"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"226\u2299179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,BinOperatorOtimes) +{ + std::wstring wsBinOperatorPlus = L"226 otimes 179"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"226\u2297179"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSum) +{ + std::wstring wsBinOperatorPlus = L"sum 5"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"5"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumFrom) +{ + std::wstring wsBinOperatorPlus = L"sum from 10 5"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"105"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumTo) +{ + std::wstring wsBinOperatorPlus = L"sum to 10 5"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"105"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} + +TEST(SMConvectorTest,OperatorSumFromTo) +{ + std::wstring wsBinOperatorPlus = L"sum from 666 to 777 567"; + StarMath::CStarMathPars m_oTempO; + m_oTempO.Pars(wsBinOperatorPlus); + StarMath::CConversionSMtoOOXML m_oTest; + m_oTest.StartConversion(m_oTempO.GetVector()); + std::wstring XmlString = L"666777567"; + EXPECT_EQ(m_oTest.GetOOXML(),XmlString); +} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index e3bb31cf435..f0988e010bc 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -14,10 +14,10 @@ namespace StarMath { ConversionOneElement(m_oTempElement); } EndConversion(); - NSFile::CFileBinary oFile; - oFile.CreateFileW(L"Test.txt"); - oFile.WriteStringUTF8(m_oXmlWrite.GetXmlString()); - oFile.CloseFile(); +// NSFile::CFileBinary oFile; +// oFile.CreateFileW(L"Test.txt"); +// oFile.WriteStringUTF8(m_oXmlWrite.GetXmlString()); +// oFile.CloseFile(); } void CConversionSMtoOOXML::ConversionOneElement(CElement *m_oElement) { @@ -98,7 +98,7 @@ namespace StarMath { else if(m_oElement->GetTypeBin() == over || m_oElement->GetTypeBin() == division) { m_oXmlWrite.WriteNodeBegin(L"m:f",false); - if(m_oElement->GetTypeBin() == division) PropertiesMFPR(true,L"skw"); + if(m_oElement->GetTypeBin() == division) PropertiesMFPR(true,L"lin"); else PropertiesMFPR(false,L""); BlockRecording(L"m:num",m_oElement->GetLeftArg()); BlockRecording(L"m:den",m_oElement->GetRightArg()); @@ -119,7 +119,7 @@ namespace StarMath { if(m_oElement->GetTypeOp() == sum) { m_oXmlWrite.WriteNodeBegin(L"m:nary",false); - PropertiesNaryPr(L"\u2211",nullptr == m_oElement->GetFrom(),m_oElement->GetTo()); + PropertiesNaryPr(L"\u2211",nullptr == m_oElement->GetFrom(),nullptr == m_oElement->GetTo()); if(m_oElement->GetFrom() == nullptr) m_oXmlWrite.WriteNode(L"m:sub",L""); else { From 8a203f4851cac18babf1fa1c783ebaf23ca9dc30 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 11 Sep 2023 21:30:12 +0600 Subject: [PATCH 152/794] Add slicer Cache conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 37 ++++ OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Slicer/SlicerCache.cpp | 243 ++++++++++++++++++++- OOXML/XlsxFormat/Slicer/SlicerCache.h | 19 +- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 40 ++++ OOXML/XlsxFormat/Slicer/SlicerCacheExt.h | 3 + 6 files changed, 329 insertions(+), 14 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 5a5a7149868..8da2a022165 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -687,6 +687,43 @@ namespace OOX } return objectPtr; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinSlicerCache() + { + auto ptr(new XLSB::FRTSLICERCACHE); + XLS::BaseObjectPtr objectPtr(ptr); + if (!m_arrExt.empty()) + { + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{03082B11-2C62-411c-B77F-237D8FCFBE4C}") + { + auto ptr1(new XLSB::SLICERCACHEBOOKPIVOTTABLES); + ptr->m_SLICERCACHEBOOKPIVOTTABLES = XLS::BaseObjectPtr{ptr1}; + auto ptr2(new XLSB::SlicerCacheBookPivotTables); + ptr1->m_BrtSlicerCacheBookPivotTables = XLS::BaseObjectPtr{ptr2}; + for(auto j:i->m_oSlicerCachePivotTables) + { + XLSB::SlicerCachePivotTable table; + j->toBin(&table); + ptr2->pivotTables.push_back(table); + } + } + if(i->m_sUri == L"{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}") + { + auto ptr1(new XLSB::TABLESLICERCACHE); + ptr->m_TABLESLICERCACHE = XLS::BaseObjectPtr{ptr1}; + ptr1->m_BrtBeginTableSlicerCache = i->m_oTableSlicerCache->toBin(); + } + if(i->m_sUri == L"{470722E0-AACD-4C17-9CDC-17EF765DBC7E}") + { + auto ptr1(new XLSB::SLICERCACHECROSSFILTEREXT); + ptr->m_SLICERCACHECROSSFILTEREXT = XLS::BaseObjectPtr{ptr1}; + ptr1->m_BrtSlicerCacheHideItemsWithNoData = i->m_oSlicerCacheHideItemsWithNoData->toBin(); + } + } + } + return objectPtr; + } XLS::BaseObjectPtr COfficeArtExtensionList::toBinTable() { auto ptr(new XLSB::FRTTABLE); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 0a0206890c5..2ca7f126c2c 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -191,6 +191,7 @@ namespace OOX XLS::BaseObjectPtr toBinWorkBook(); XLS::BaseObjectPtr toBinStyles(); XLS::BaseObjectPtr toBinTable(); + XLS::BaseObjectPtr toBinSlicerCache(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp index 092ffb02e92..2f437cfa67f 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp @@ -59,6 +59,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { namespace Spreadsheet @@ -77,6 +78,23 @@ void COlapSlicerCacheItem::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheItem::toBin() +{ + auto ptr(new XLSB::SlicerCacheOlapItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oNd.IsInit()) + ptr->fNoData = m_oNd.get(); + if(m_oN.IsInit()) + ptr->stName = m_oN.get(); + else + ptr->stName = 0xFFFFFFFF; + if(m_oC.IsInit()) + ptr->stTitle = m_oC.get(); + for(auto i:m_oP) + if(i.m_oN.IsInit()) + ptr->parents.push_back(i.m_oN.get()); + return objectPtr; +} void COlapSlicerCacheItem::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -256,6 +274,19 @@ void COlapSlicerCacheItemParent::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReade } pReader->Seek(_end_rec); } +XLS::BaseObjectPtr COlapSlicerCacheRange::toBin() +{ + auto ptr(new XLSB::SLICERCACHESIRANGE); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oStartItem.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheSiRange); + ptr1->iitemstart = m_oStartItem.get(); + } + for(auto i:m_oI) + ptr->m_arBrtSlicerCacheOlapItem.push_back(i.toBin()); + return objectPtr; +} void COlapSlicerCacheRange::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -372,6 +403,17 @@ void CTabularSlicerCacheItem::fromBin(XLS::BiffStructure& obj) { ReadAttributes(obj); } +void CTabularSlicerCacheItem::toBin(XLS::BiffStructure *obj) +{ + auto ptr = static_cast(obj); + + if(m_oX.IsInit()) + ptr->iCache = m_oX.get(); + if(m_oS.IsInit()) + ptr->fSelected = m_oS.get(); + if(m_oNd.IsInit()) + ptr->fNoData = m_oNd.get(); +} void CTabularSlicerCacheItem::ReadAttributes(XLS::BiffStructure& obj) { auto ptr = static_cast(&obj); @@ -473,6 +515,13 @@ void COlapSlicerCacheSelection::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheSelection::toBin() +{ + auto ptr(new XLSB::SlicerCacheSelection); + XLS::BaseObjectPtr objectPtr(ptr); + + return objectPtr; +} void COlapSlicerCacheSelection::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -590,6 +639,38 @@ void COlapSlicerCacheLevelData::fromBin(XLS::BaseObjectPtr& obj) } } } +XLS::BaseObjectPtr COlapSlicerCacheLevelData::toBin() +{ + auto ptr(new XLSB::SLICERCACHELEVELDATA); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerCacheLevelData); + ptr->m_BrtBeginSlicerCacheLevelData = XLS::BaseObjectPtr{ptr1}; + + if(m_oCount.IsInit()) + ptr1->citem = m_oCount.get(); + if(m_oSortOrder.IsInit()) + ptr1->fSortOrder = m_oSortOrder->GetValue(); + if(m_oUniqueName.IsInit()) + ptr1->stUniqueName = m_oUniqueName.get(); + else + ptr1->stUniqueName = 0xFFFFFFFF; + if(m_oSourceCaption.IsInit()) + ptr1->stSourceCaption = m_oSourceCaption.get(); + else + ptr1->stSourceCaption = 0xFFFFFFFF; + if(m_oCrossFilter.IsInit()) + ptr1->fCrossFilter = m_oCrossFilter->GetValue(); + if(!m_oRanges.empty()) + { + auto ptr2(new XLSB::SLICERCACHESIRANGES); + ptr->m_SLICERCACHESIRANGES = XLS::BaseObjectPtr{ptr2}; + for(auto i:m_oRanges) + { + ptr2->m_arSLICERCACHESIRANGE.push_back(i.toBin()); + } + } + return objectPtr; +} void COlapSlicerCacheLevelData::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -763,7 +844,20 @@ void CTabularSlicerCacheItems::fromBin(XLS::BaseObjectPtr& obj) } } } - +XLS::BaseObjectPtr CTabularSlicerCacheItems::toBin() +{ + auto ptr(new XLSB::SlicerCacheNativeItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCount.IsInit()) + ptr->cItems = m_oCount.get(); + for(auto i:m_oI) + { + XLSB::SlicerCacheNativeItemStruct object; + i.toBin(&object); + ptr->rgItems.push_back(object); + } + return objectPtr; +} void CTabularSlicerCacheItems::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -853,7 +947,14 @@ void CTabularSlicerCacheItems::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) } pReader->Seek(_end_rec); } - +XLS::BaseObjectPtr COlapSlicerCacheSelections::toBin() +{ + auto ptr(new XLSB::SLICERCACHESELECTIONS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSelection) + ptr->m_arBrtSlicerCacheSelection.push_back(i.toBin()); + return objectPtr; +} void COlapSlicerCacheSelections::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -975,6 +1076,17 @@ void COlapSlicerCacheLevelsData::fromBin(XLS::BaseObjectPtr& obj) } } +XLS::BaseObjectPtr COlapSlicerCacheLevelsData::toBin() +{ + auto ptr(new XLSB::SLICERCACHELEVELSDATA); + XLS::BaseObjectPtr objectPtr(ptr); + if(!m_oLevel.empty()) + { + for(auto i:m_oLevel) + ptr->m_arSLICERCACHELEVELDATA.push_back(i.toBin()); + } + return objectPtr; +} void COlapSlicerCacheLevelsData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1075,6 +1187,26 @@ void CTabularSlicerCache::fromBin(XLS::BaseObjectPtr& obj) m_oItems = ptr->m_BrtSlicerCacheNativeItem; } } +XLS::BaseObjectPtr CTabularSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHENATIVEITEMS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerCacheNative); + ptr->m_BrtSlicerCacheNativeItem = XLS::BaseObjectPtr{ptr1}; + if(m_oPivotCacheId.IsInit()) + ptr1->dwcacheId = m_oPivotCacheId.get(); + if(m_oSortOrder.IsInit()) + ptr1->fSortOrder = m_oSortOrder->GetValue() + 1; + if(m_oCustomListSort.IsInit()) + ptr1->fSortUsingCustomLists = m_oCustomListSort.get(); + if(m_oShowMissing.IsInit()) + ptr1->fShowAllItems = m_oShowMissing.get(); + if(m_oCrossFilter.IsInit()) + ptr1->fCrossFilter = m_oCrossFilter->GetValue(); + + ptr->m_BrtSlicerCacheNativeItem = m_oItems->toBin(); + return objectPtr; +} void CTabularSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1227,6 +1359,22 @@ void COlapSlicerCache::fromBin(XLS::BaseObjectPtr& obj) m_oSelections = ptr->m_SLICERCACHESELECTIONS; } } +XLS::BaseObjectPtr COlapSlicerCache::toBin() +{ + auto ptr(new XLSB::SLICERCACHEOLAPIMPL); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oPivotCacheId.IsInit()) + { + auto ptr1(new XLSB::BeginSlicerCacheOlapImpl); + ptr->m_BrtBeginSlicerCacheOlapImpl = XLS::BaseObjectPtr{ptr1}; + ptr1->ipivotcacheid = m_oPivotCacheId.get(); + } + if(m_oLevels.IsInit()) + ptr->m_SLICERCACHELEVELSDATA = m_oLevels->toBin(); + if(m_oSelections.IsInit()) + ptr->m_SLICERCACHESELECTIONS = m_oSelections->toBin(); + return objectPtr; +} void COlapSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1343,6 +1491,15 @@ void CSlicerCacheData::fromBin(XLS::BaseObjectPtr& obj) m_oTabular = obj; } } +XLS::BaseObjectPtr CSlicerCacheData::toBin() +{ + XLS::BaseObjectPtr objectPtr; + if(m_oOlap.IsInit()) + objectPtr = m_oOlap->toBin(); + else if(m_oTabular.IsInit()) + objectPtr = m_oTabular->toBin(); + return objectPtr; +} void CSlicerCacheData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1435,7 +1592,16 @@ void CSlicerCachePivotTable::ReadAttributes(XLS::BiffStructure& obj) m_oName = ptr->stPivotTable.value(); } } - +void CSlicerCachePivotTable::toBin(XLS::BiffStructure* obj) +{ + auto ptr = static_cast(obj); + if(m_oTabId.IsInit()) + ptr->iTabId = m_oTabId.get(); + if(m_oName.IsInit()) + ptr->stPivotTable = m_oName.get(); + else + ptr->stPivotTable = 0xFFFFFFFF; +} void CSlicerCachePivotTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -1529,6 +1695,38 @@ void CSlicerCacheDefinition::fromBin(XLS::BaseObjectPtr& obj) m_oExtLst = ptr->m_FRTSLICERCACHE; } } +XLS::BaseObjectPtr CSlicerCacheDefinition::toBin() +{ + auto ptr(new XLSB::SLICERCACHE); + auto ptr1(new XLSB::BeginSlicerCacheDef); + ptr->m_BrtBeginSlicerCacheDef = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + else + ptr1->stName = 0xFFFFFFFF; + if(m_oSourceName.IsInit()) + ptr1->stHierarchy = m_oSourceName.get(); + else + ptr1->stHierarchy = 0xFFFFFFFF; + if(!m_oPivotTables.empty()) + { + auto ptr2(new XLSB::SlicerCachePivotTables); + ptr->m_BrtSlicerCachePivotTables = XLS::BaseObjectPtr{ptr2}; + for(auto i:m_oPivotTables) + { + XLSB::SlicerCachePivotTable table; + i.toBin(&table); + ptr2->pivotTables.push_back(table); + } + } + if(m_oData.IsInit()) + ptr->m_slicerCacheData = m_oData->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTSLICERCACHE = m_oExtLst->toBinSlicerCache(); + + return objectPtr; +} void CSlicerCacheDefinition::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1769,7 +1967,15 @@ void CSlicerCacheFile::readBin(const CPath& oPath) //slicerCachesStream.reset(); } } +XLS::BaseObjectPtr CSlicerCacheFile::WriteBin() const +{ + XLSB::SlicerCachesStreamPtr slicerCachesStream(new XLSB::SlicerCachesStream); + XLS::BaseObjectPtr objectPtr(slicerCachesStream); + if(m_oSlicerCacheDefinition.IsInit()) + slicerCachesStream->m_SLICERCACHE = m_oSlicerCacheDefinition->toBin(); + return objectPtr; +} void CSlicerCacheFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -1796,18 +2002,35 @@ void CSlicerCacheFile::write(const CPath& oPath, const CPath& oDirectory, CConte { if(!m_oSlicerCacheDefinition.IsInit()) return; + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + NSStringUtils::CStringBuilder sXml; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oSlicerCacheDefinition->toXML(sXml, L"slicerCacheDefinition"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oSlicerCacheDefinition->toXML(sXml, L"slicerCacheDefinition"); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } +const OOX::FileType CSlicerCacheFile::type() const +{ + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::SlicerCacheBin; + } + return OOX::Spreadsheet::FileTypes::SlicerCache; +} + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.h b/OOXML/XlsxFormat/Slicer/SlicerCache.h index b44b6ceb298..595e0e39ccb 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.h @@ -97,6 +97,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -125,6 +126,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -151,6 +153,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -177,6 +180,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -203,6 +207,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -234,6 +239,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -260,6 +266,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -285,6 +292,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const{} virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -312,6 +320,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -344,6 +353,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -373,6 +383,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -397,6 +408,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -423,6 +435,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -455,6 +468,7 @@ namespace OOX read( oRootPath, oPath ); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -463,10 +477,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::SlicerCache; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index fd569e5852b..0318146d80f 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -66,6 +66,16 @@ void CSlicerCacheOlapLevelName::fromBin(XLS::BiffStructure& obj) { ReadAttributes(obj); } +void CSlicerCacheOlapLevelName::toBin(XLS::BiffStructure* obj) +{ + auto ptr = static_cast(obj); + if(m_oCount.IsInit()) + ptr->cHiddenItems = m_oCount.get(); + if(m_oUniqueName.IsInit()) + ptr->stUniqueName = m_oUniqueName.get(); + else + ptr->stUniqueName = 0xFFFFFFFF; +} void CSlicerCacheOlapLevelName::ReadAttributes(XLS::BiffStructure& obj) { auto ptr = static_cast(&obj); @@ -161,6 +171,20 @@ void CSlicerCacheHideNoData::fromBin(XLS::BaseObjectPtr &obj) } } +XLS::BaseObjectPtr CSlicerCacheHideNoData::toBin() +{ + auto ptr(new XLSB::SlicerCacheHideItemsWithNoData); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCount.IsInit()) + ptr->cHideItemLevelsCount = m_oCount.get(); + for(auto i:m_oSlicerCacheOlapLevelName) + { + XLSB::SlicerCacheLevelData levelData; + i.toBin(&levelData); + ptr->rgLevels.push_back(levelData); + } + return objectPtr; +} void CSlicerCacheHideNoData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) @@ -254,6 +278,22 @@ void CTableSlicerCache::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); } +XLS::BaseObjectPtr CTableSlicerCache::toBin() +{ + auto ptr(new XLSB::BeginTableSlicerCache); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oTableId.IsInit()) + ptr->dwLstd = m_oTableId.get(); + if(m_oColumn.IsInit()) + ptr->dwColumn = m_oColumn.get(); + if(m_oSortOrder.IsInit()) + ptr->fSortOrder = m_oSortOrder->GetValue() + 1; + if(m_oCustomListSort.IsInit()) + ptr->fSortUsingCustomLists = m_oCustomListSort.get(); + if(m_oCrossFilter.IsInit()) + ptr->iCrossFilter = m_oCrossFilter->GetValue(); + return objectPtr; +} void CTableSlicerCache::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index 3fe7869c647..a56af42276d 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -72,6 +72,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BiffStructure& obj); + void toBin(XLS::BiffStructure* obj); void ReadAttributes(XLS::BiffStructure& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -98,6 +99,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); @@ -124,6 +126,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; From 7cee2951e8e22996df5874e471c5b182ab8c91a9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 12 Sep 2023 19:23:31 +0600 Subject: [PATCH 153/794] Fix slicers conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 5 +++++ OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 8da2a022165..986cae641da 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -773,6 +773,11 @@ namespace OOX { ptr->m_SLICERSEX = i->m_oSlicerList->toBin(); } + else if(i->m_sUri == L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}") + { + if(i->m_oSlicerListExt.IsInit()) + ptr->m_SLICERSEX = i->m_oSlicerListExt->toBin(); + } } return objectPtr; } diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 0318146d80f..46faf77b862 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -627,7 +627,7 @@ XLS::BaseObjectPtr CSlicerRef::toBin() XLS::BaseObjectPtr objectPtr(ptr); auto ptr1(new XLSB::BeginSlicerEx); ptr1->FRTheader.relID.relId = m_oRId->GetValue(); - + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; return objectPtr; } From 35fbf846836787054acae2ba248123f7643765f7 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 14 Sep 2023 15:17:15 +0300 Subject: [PATCH 154/794] Change logic --- DocxRenderer/src/logic/Page.cpp | 4 +- DocxRenderer/src/logic/elements/BaseItem.h | 4 +- DocxRenderer/src/logic/elements/ContText.cpp | 27 +++ DocxRenderer/src/logic/elements/ContText.h | 3 + DocxRenderer/src/logic/elements/Converter.cpp | 183 ++++++++++-------- DocxRenderer/src/logic/elements/Paragraph.cpp | 2 +- DocxRenderer/src/logic/elements/TextLine.cpp | 1 + DocxRenderer/src/logic/elements/TextLine.h | 1 + 8 files changed, 138 insertions(+), 87 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 40278b3459d..ac458e52858 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -364,6 +364,7 @@ namespace NSDocxRenderer auto pCont = new CContText(m_pFontManager); + pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; @@ -376,6 +377,7 @@ namespace NSDocxRenderer pCont->m_dWidth = dTextW; pCont->m_dHeight = dTextH; pCont->m_dRight = dTextX + dTextW; + pCont->m_dTrueHeight = _h - oMetrics.dBaselineOffset; pCont->m_oText = oText; @@ -1150,8 +1152,6 @@ namespace NSDocxRenderer { pCurrCont->m_bIsUnderlinePresent = true; pCurrCont->m_eUnderlineType = pShape->m_eLineType; - - // почему 0.3? pCurrCont->m_lUnderlineColor = pShape->m_dHeight > 0.3 ? pShape->m_oBrush.Color1 : pShape->m_oPen.Color; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 9c822fb067f..118b8548c96 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -76,8 +76,8 @@ namespace NSDocxRenderer virtual void AddContent(CBaseItem* pObj); virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); + virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj); bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 551b3787fe6..e7fbc57d9a8 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -103,6 +103,33 @@ namespace NSDocxRenderer } } + [[nodiscard]] eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + { + if(oSrc->m_eType != ElemType::etContText) + return CBaseItem::GetVerticalCrossingType(oSrc); + + auto m_dTop_copy = m_dTop; + auto m_dTop_copy_src = oSrc->m_dTop; + + m_dTop = m_dBaselinePos - m_dTrueHeight; + const_cast(oSrc)->m_dTop = oSrc->m_dBaselinePos - static_cast(oSrc)->m_dTrueHeight; + + auto vert_cross = CBaseItem::GetVerticalCrossingType(oSrc); + + if(vert_cross == eVerticalCrossingType::vctCurrentAboveNext && + (m_dBaselinePos - oSrc->m_dTop < m_dTrueHeight * 0.3)) + vert_cross = eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + + if(vert_cross == eVerticalCrossingType::vctCurrentBelowNext && + (oSrc->m_dBaselinePos - m_dTop < static_cast(oSrc)->m_dTrueHeight * 0.3)) + vert_cross = eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + + m_dTop = m_dTop_copy; + const_cast(oSrc)->m_dTop = m_dTop_copy_src; + + return vert_cross; + } + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) { if (m_bIsNotNecessaryToUse) diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 8fc0c2e380e..0f1346f3c31 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -54,6 +54,7 @@ namespace NSDocxRenderer const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; UINT m_iNumDuplicates {0}; + double m_dTrueHeight{0}; public: CContText(CFontManager* pManager); @@ -63,6 +64,8 @@ namespace NSDocxRenderer virtual void AddContent(CBaseItem* pObj) override final {}; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + [[nodiscard]] virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; + CContText& operator= (const CContText& rCont); void AddWideSpaceToXml(double dSpacingMM, diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index f0992c3fbd4..a72b276d28e 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -97,39 +97,44 @@ namespace NSDocxRenderer bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; bool bIsNeedParagraphToShape = eType == TextAssociationType::tatParagraphToShape && eBaseType == CBaseItem::ElemType::etParagraph; - CTable* pCurrTable = nullptr; - size_t nTableIndex = 0; +// CTable* pCurrTable = nullptr; +// size_t nTableIndex = 0; size_t nIndexForCheking = c_nAntiZero; - if (!rTables.empty()) - { - CBaseItem::SortByBaseline(rTables); - pCurrTable = rTables.front(); - nTableIndex = 0; - - //Если линий нет, то добавлем сразу - if (rTextLines.empty()) - { - for (size_t i = 0; i < rTables.size(); ++i) - { - if (bIsNeedParagraphToShape) - { - CreateShapeFormTable(pCurrTable, rOutputObjects); - } - else - { - rOutputObjects.push_back(rTables[i]); - } - } - } - } +// if (!rTables.empty()) +// { +// CBaseItem::SortByBaseline(rTables); +// pCurrTable = rTables.front(); +// nTableIndex = 0; + +// //Если линий нет, то добавлем сразу +// if (rTextLines.empty()) +// { +// for (size_t i = 0; i < rTables.size(); ++i) +// { +// if (bIsNeedParagraphToShape) +// { +// CreateShapeFormTable(pCurrTable, rOutputObjects); +// } +// else +// { +// rOutputObjects.push_back(rTables[i]); +// } +// } +// } +// } CBaseItem::SortByBaseline(rTextLines); + double avg_height = 0; + size_t n = 0; + for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) { pCurrLine = rTextLines[nIndex]; + avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dTrueHeight / (n + 1)); + if (pCurrLine->m_bIsNotNecessaryToUse) { continue; @@ -142,40 +147,40 @@ namespace NSDocxRenderer } - while (pCurrTable) - { - eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); - - //добавляем таблицу в общий массив, если она идет после текущей строки - if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - if (bIsNeedParagraphToShape) - { - CreateShapeFormTable(pCurrTable, rOutputObjects); - } - else - { - rOutputObjects.push_back(pCurrTable); - } - dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); - pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - if (eType != TextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) - { - pCurrTable->m_bIsNeedSpacing = true; - } - dPreviousStringBaseline = pCurrTable->m_dBaselinePos; - pCurrTable = nullptr; - //таблицы отсортированы, можно сразу взять следующую для проверки - for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) - { - pCurrTable = rTables[i]; - } - } - else - { - break; - } - } +// while (pCurrTable) +// { +// eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); + +// //добавляем таблицу в общий массив, если она идет после текущей строки +// if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) +// { +// if (bIsNeedParagraphToShape) +// { +// CreateShapeFormTable(pCurrTable, rOutputObjects); +// } +// else +// { +// rOutputObjects.push_back(pCurrTable); +// } +// dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); +// pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); +// if (eType != TextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) +// { +// pCurrTable->m_bIsNeedSpacing = true; +// } +// dPreviousStringBaseline = pCurrTable->m_dBaselinePos; +// pCurrTable = nullptr; +// //таблицы отсортированы, можно сразу взять следующую для проверки +// for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) +// { +// pCurrTable = rTables[i]; +// } +// } +// else +// { +// break; +// } +// } dPrevBeforeSpacing = dCurrBeforeSpacing; if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) @@ -184,14 +189,14 @@ namespace NSDocxRenderer } else { - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight - dPreviousStringBaseline; } dPreviousStringBaseline = pCurrLine->m_dBaselinePos; //Если у текущей линии есть дубликаты, то создаем из них шейпы if (pCurrLine->m_iNumDuplicates > 0) { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; + dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dTrueHeight; auto iNumDuplicates = pCurrLine->m_iNumDuplicates; CreateSingleLineShape(pCurrLine, rOutputObjects); @@ -226,14 +231,14 @@ namespace NSDocxRenderer { case eVerticalCrossingType::vctCurrentInsideNext: case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dTrueHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; dPreviousStringBaseline = pNextLine->m_dBaselinePos; bIsPassed = true; break; case eVerticalCrossingType::vctCurrentOutsideNext: case eVerticalCrossingType::vctCurrentAboveNext: case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dTrueHeight; bIsPassed = true; break; default: @@ -260,10 +265,11 @@ namespace NSDocxRenderer //Логика определения параметров для DetermineTextAlignmentType if (pNextLine) { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dTrueHeight - dPreviousStringBaseline; + //dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + bIf1 = fabs(pCurrLine->m_dTrueHeight - pNextLine->m_dTrueHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //расстрояние между строк тоже одинаково bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //или @@ -283,22 +289,22 @@ namespace NSDocxRenderer if (pNextNextLine) { - double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - + //double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dTrueHeight - dPreviousStringBaseline; if (bIf1 && (bIf2 || bIf3)) { if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(pNextLine->m_dTrueHeight - pNextNextLine->m_dTrueHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) { pNextNextLine = nullptr; } } else { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(pNextLine->m_dTrueHeight - pNextNextLine->m_dTrueHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { - if (dNextBeforeSpacing < dNextNextBeforeSpacing) + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { pNextNextLine = nullptr; } @@ -321,6 +327,11 @@ namespace NSDocxRenderer pCurrLine, pNextLine, pNextNextLine, dPageWidth, bIsUseNextNextLine, bIsSingleLineParagraph); auto pParagraph = new CParagraph(); + + pParagraph->m_dLineHeight = avg_height; + avg_height = 0; + n = 0; + pParagraph->m_eTextAlignmentType = eTextAlignmentType; if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) @@ -348,12 +359,12 @@ namespace NSDocxRenderer pParagraph->m_dFirstLine = 0; } - pParagraph->m_dTop = pCurrLine->m_dTop; + pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight; pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - pParagraph->m_dHeight = pCurrLine->m_dHeight; + pParagraph->m_dHeight = pCurrLine->m_dTrueHeight; //размер строк во всем параграфе - pParagraph->m_dLineHeight= pCurrLine->m_dHeight; + // pParagraph->m_dLineHeight = avg_height; //pCurrLine->m_dHeight; pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); pParagraph->m_arLines.push_back(pCurrLine); @@ -376,7 +387,7 @@ namespace NSDocxRenderer pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; dPreviousStringBaseline = pCurrLine->m_dBaselinePos; double dCorrectionBeforeSpacing = dCurrBeforeSpacing; @@ -384,7 +395,7 @@ namespace NSDocxRenderer { if (pNextLine) { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой @@ -424,13 +435,13 @@ namespace NSDocxRenderer pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале if (pNextLine) { - dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой @@ -507,12 +518,12 @@ namespace NSDocxRenderer pParagraph->m_arLines.push_back(pLine); pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dTop; + pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; pParagraph->m_dFirstLine = 0; pParagraph->m_dRight = pLine->m_dRight; pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dHeight; + pParagraph->m_dHeight = pLine->m_dTrueHeight; if (*pBeforeSpacing < 0) { pParagraph->m_dHeight += *pBeforeSpacing; @@ -533,6 +544,7 @@ namespace NSDocxRenderer void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector &rOutputObjects) { auto pParagraph = new CParagraph(); + pParagraph->m_arLines.push_back(pLine); pParagraph->m_dRightBorder = 0; @@ -547,9 +559,9 @@ namespace NSDocxRenderer pShape->m_arOutputObjects.push_back(pParagraph); pShape->m_eType = CShape::eShapeType::stTextBox; pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dTop; + pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; + pShape->m_dHeight = pLine->m_dTrueHeight; pShape->m_bIsBehindDoc = false; rOutputObjects.push_back(pShape); @@ -581,15 +593,22 @@ namespace NSDocxRenderer if (bIsSameTypeText && bIsShapesPresent) { pShape = pBackShape; - pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; } else { pShape = new CShape(); pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight += pParagraph->m_dLineHeight * pParagraph->m_nNumLines; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines; } +// pShape->m_dLeft = pParagraph->m_dLeft; +// pShape->m_dTop = pParagraph->m_dTop; +// pShape->m_dRight = pParagraph->m_dRight; +// pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; +// pShape->m_dWidth = fabs(pParagraph->m_dRight - pParagraph->m_dLeft); +// pShape->m_dHeight = pParagraph->m_dTop - pParagraph->m_dBaselinePos; + pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 3b414b80d3d..47c22a725c5 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -154,7 +154,7 @@ namespace NSDocxRenderer //Добавляем пробел в конец каждой строки pLastCont->m_oText += L" "; pLastCont->m_bSpaceIsNotNeeded = true; - pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthMM; + pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthSelected; auto pNext = m_arLines[i]; auto pCont = pNext->m_arConts.front(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index b916568fae0..5c647026331 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -24,6 +24,7 @@ namespace NSDocxRenderer void CTextLine::AddContent(CBaseItem *pObj) { CBaseItem::AddContent(pObj); + m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(pObj)->m_dTrueHeight); if (dynamic_cast(pObj)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) { diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 919f3455759..416e0a1d3d4 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -21,6 +21,7 @@ namespace NSDocxRenderer CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; CShape* m_pDominantShape {nullptr}; UINT m_iNumDuplicates {0}; + double m_dTrueHeight{0}; public: CTextLine(); From adcfe318323933a99f7afcf07dc3f28a6cd7c3fe Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 15 Sep 2023 19:26:02 +0600 Subject: [PATCH 155/794] Add pivot tables conversion --- OOXML/XlsxFormat/Pivot/PivotTable.h | 107 +-- OOXML/XlsxFormat/Pivot/Pivots.cpp | 965 ++++++++++++++++++++++++++-- 2 files changed, 960 insertions(+), 112 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotTable.h b/OOXML/XlsxFormat/Pivot/PivotTable.h index 8c0c7328778..52b26642f9e 100644 --- a/OOXML/XlsxFormat/Pivot/PivotTable.h +++ b/OOXML/XlsxFormat/Pivot/PivotTable.h @@ -101,6 +101,7 @@ namespace OOX WritingStringNullableAttrInt(L"v", m_oV, m_oV->GetValue()); writer.WriteString(L"/>"); } + XLS::BaseObjectPtr toBinPrfItem(); void fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -176,7 +177,7 @@ namespace OOX CField(){} virtual ~CField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -204,7 +205,7 @@ namespace OOX WritingElement_ReadAttributes_ReadSingle ( oReader, L"x", m_oX ) WritingElement_ReadAttributes_End( oReader ) } - + nullable_int m_oX; }; class CColumnRowFields : public WritingElementWithChilds @@ -214,7 +215,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowFields) CColumnRowFields(){} virtual ~CColumnRowFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -226,6 +227,8 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinRows(); + XLS::BaseObjectPtr toBinCols(); virtual EElementType getType () const { return et_x_ColumnRowFields; @@ -241,7 +244,7 @@ namespace OOX WritingElement_XlsbConstructors(CDataField) CDataField(){} virtual ~CDataField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -252,13 +255,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_DataField; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_int m_oBaseField; nullable m_oBaseItem; nullable m_oFld; @@ -276,7 +280,7 @@ namespace OOX WritingElement_XlsbConstructors(CDataFields) CDataFields(){} virtual ~CDataFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -287,6 +291,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_DataFields; @@ -302,7 +307,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageField) CPageField(){} virtual ~CPageField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -313,13 +318,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PageField; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_int m_oFld; nullable_int m_oHier; nullable m_oItem; @@ -335,7 +341,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageFields) CPageFields(){} virtual ~CPageFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -346,6 +352,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PageFields; @@ -361,7 +368,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldItem) CFieldItem(){} virtual ~CFieldItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -372,13 +379,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_FieldItem; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oChild; nullable_bool m_oExpanded; nullable_bool m_oDrillAcross; @@ -399,7 +407,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldItems) CFieldItems(){} virtual ~CFieldItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -410,12 +418,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_FieldItems; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable m_oCount; }; class CReference : public WritingElement @@ -425,7 +434,7 @@ namespace OOX WritingElement_XlsbConstructors(CReference) CReference(){} virtual ~CReference() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -436,13 +445,15 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_Reference; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oAvgSubtotal; nullable_bool m_oByPosition; nullable_bool m_oCountASubtotal; @@ -471,7 +482,7 @@ namespace OOX WritingElement_XlsbConstructors(CReferences) CReferences(){} virtual ~CReferences() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -482,12 +493,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_References; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable m_oCount; }; class CPivotArea : public WritingElement @@ -497,7 +509,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotArea) CPivotArea(){} virtual ~CPivotArea() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -508,10 +520,12 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotArea; } + XLS::BaseObjectPtr writeAttribures(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -538,7 +552,7 @@ namespace OOX WritingElement_XlsbConstructors(CAutoSortScope) CAutoSortScope(){} virtual ~CAutoSortScope() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -549,12 +563,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_AutoSortScope; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader){} - + nullable m_oPivotArea; }; class CPivotField : public WritingElement @@ -564,7 +579,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotField) CPivotField(){} virtual ~CPivotField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -575,13 +590,15 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotField; } void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oAllDrilled; nullable_bool m_oAutoShow; nullable_bool m_oAvgSubtotal; @@ -630,7 +647,7 @@ namespace OOX nullable_string m_oUniqueMemberProperty; nullable_bool m_oVarPSubtotal; nullable_bool m_oVarSubtotal; - + nullable m_oAutoSortScope; nullable m_oItems; nullable m_oExtLst; @@ -642,7 +659,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotFields) CPivotFields(){} virtual ~CPivotFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -653,6 +670,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotFields; @@ -668,7 +686,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowItem) CColumnRowItem(){} virtual ~CColumnRowItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -679,17 +697,18 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_ColumnRowItem; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable m_oI; nullable m_oR; nullable m_oT; - }; + }; class CColumnRowItems : public WritingElementWithChilds { public: @@ -697,7 +716,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowItems) CColumnRowItems(){} virtual ~CColumnRowItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -709,6 +728,8 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinRows(); + XLS::BaseObjectPtr toBinCols(); virtual EElementType getType () const { return et_x_ColumnRowItems; @@ -724,7 +745,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableFormat) CPivotTableFormat(){} virtual ~CPivotTableFormat() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -735,6 +756,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotTableFormat; @@ -744,7 +766,7 @@ namespace OOX nullable m_oAction; nullable m_oDxfId; - + nullable m_oPivotArea; nullable m_oExtLst; }; @@ -755,7 +777,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableFormats) CPivotTableFormats(){} virtual ~CPivotTableFormats() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -766,6 +788,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotTableFormats; @@ -781,7 +804,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableStyleInfo) CPivotTableStyleInfo(){} virtual ~CPivotTableStyleInfo() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -797,6 +820,7 @@ namespace OOX if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -823,7 +847,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableLocation) CPivotTableLocation(){} virtual ~CPivotTableLocation() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -840,6 +864,7 @@ namespace OOX return; } void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotTableLocation; @@ -876,12 +901,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotTableDefinition; } - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr writeAttributes(); //---------- nullable m_oColFields; nullable m_oColItems; @@ -961,11 +988,11 @@ namespace OOX nullable_bool m_oUseAutoFormatting; nullable_string m_oVacatedStyle; nullable_bool m_oVisualTotals; - + nullable m_oCreatedVersion; nullable m_oMinRefreshableVersion; nullable m_oUpdatedVersion; - + nullable m_oDataPosition; nullable m_oAutoFormatId; nullable m_oCacheId; @@ -980,7 +1007,7 @@ namespace OOX CPivotTableFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; } @@ -1011,12 +1038,10 @@ namespace OOX memcpy(m_pData, pData, length); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotTable; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 892ed777ee6..309b086bbe6 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -131,6 +131,8 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../ComplexTypes_Spreadsheet.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -148,7 +150,7 @@ namespace Spreadsheet xlsb->ReadBin(oPath, pivotTableStream.get()); if (pivotTableStream != nullptr) - { + { //XLS::BaseObjectPtr ptr(static_cast(pivotTableStream.get()), NullDeleter()); //XLS::BaseObjectPtr ptr = boost::make_shared(static_cast(pivotTableStream.get())); m_oPivotTableDefinition = pivotTableStream; @@ -157,6 +159,10 @@ namespace Spreadsheet //pivotTableStream.reset(); } } + XLS::BaseObjectPtr CPivotTableFile::WriteBin() const + { + return m_oPivotTableDefinition->toBin(); + } void CPivotTableFile::read(const CPath& oRootPath, const CPath& oPath) { @@ -181,30 +187,44 @@ namespace Spreadsheet } void CPivotTableFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if(m_oPivotTableDefinition.IsInit()) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oPivotTableDefinition->toXML(sXml); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); - - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); } - else if(m_nDataLength > 0 && m_pData) + else { - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(m_pData, m_nDataLength); - oFile.CloseFile(); + if(m_oPivotTableDefinition.IsInit()) + { + NSStringUtils::CStringBuilder sXml; - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + sXml.WriteString(L""); + m_oPivotTableDefinition->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + else if(m_nDataLength > 0 && m_pData) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); + oFile.WriteFile(m_pData, m_nDataLength); + oFile.CloseFile(); + } } + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); } + const OOX::FileType CPivotTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::PivotTableBin; + } + return OOX::Spreadsheet::FileTypes::PivotTable; + } //------------------------------------ void CPivotTableDefinition::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -284,7 +304,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"updatedVersion", m_oUpdatedVersion, m_oUpdatedVersion->GetValue()); WritingStringNullableAttrBool2(L"useAutoFormatting", m_oUseAutoFormatting); WritingStringNullableAttrBool2(L"visualTotals", m_oVisualTotals); - + writer.WriteString(L">"); if(m_oLocation.IsInit()) @@ -293,7 +313,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oPivotFields.IsInit()) m_oPivotFields->toXML(writer); if(m_oRowFields.IsInit()) - m_oRowFields->toXML2(writer, L"rowFields"); + m_oRowFields->toXML2(writer, L"rowFields"); if(m_oRowItems.IsInit()) m_oRowItems->toXML2(writer, L"rowItems"); if(m_oColFields.IsInit()) @@ -304,7 +324,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oPageFields->toXML(writer); if(m_oDataFields.IsInit()) m_oDataFields->toXML(writer); - + if(m_oFormats.IsInit()) m_oFormats->toXML(writer); //if(m_oConditionalFormats.IsInit()) @@ -322,7 +342,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" // m_oRowHierarchiesUsage->toXML(writer); //if(m_oColHierarchiesUsage.IsInit()) // m_oColHierarchiesUsage->toXML(writer); - + if(m_oExtLst.IsInit()) { writer.WriteString(m_oExtLst->toXMLWithNS(_T(""))); @@ -361,6 +381,149 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (L"extLst" == sName) m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotTableDefinition::toBin() + { + auto ptr(new XLSB::PivotTableStream); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginSXView = writeAttributes(); + if(m_oLocation.IsInit()) + ptr->m_SXLOCATION = m_oLocation->toBin(); + if(m_oPivotFields.IsInit()) + ptr->m_SXVDS = m_oPivotFields->toBin(); + if(m_oRowFields.IsInit()) + ptr->m_ISXVDRWS = m_oRowFields->toBinRows(); + if(m_oColFields.IsInit()) + ptr->m_ISXVDCOLS = m_oColFields->toBinCols(); + if(m_oRowItems.IsInit()) + ptr->m_SXLIRWS = m_oRowItems->toBinRows(); + if(m_oColItems.IsInit()) + ptr->m_SXLICOLS = m_oColItems->toBinCols(); + + if(m_oDataFields.IsInit()) + ptr->m_SXDIS = m_oDataFields->toBin(); + if(m_oFormats.IsInit()) + ptr->m_SXFORMATS = m_oFormats->toBin(); + if(m_oPivotTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oPivotTableStyleInfo->toBin(); + if(m_oPageFields.IsInit()) + ptr->m_SXPIS = m_oPageFields->toBin(); + + return objectPtr; + } + XLS::BaseObjectPtr CPivotTableDefinition::writeAttributes() + { + auto ptr(new XLSB::BeginSXView); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oApplyAlignmentFormats.IsInit()) + ptr->ibitAtrAlc = m_oApplyAlignmentFormats.get(); + if (m_oApplyBorderFormats.IsInit()) + ptr->ibitAtrBdr = m_oApplyBorderFormats.get(); + if (m_oApplyFontFormats.IsInit()) + ptr->ibitAtrFnt = m_oApplyFontFormats.get(); + if (m_oApplyNumberFormats.IsInit()) + ptr->ibitAtrNum = m_oApplyNumberFormats.get(); + if (m_oApplyPatternFormats.IsInit()) + ptr->ibitAtrPat = m_oApplyPatternFormats.get(); + if (m_oApplyWidthHeightFormats.IsInit()) + ptr->ibitAtrProt = m_oApplyWidthHeightFormats.get(); + if (m_oApplyAlignmentFormats.IsInit()) + ptr->ibitAtrAlc = m_oApplyAlignmentFormats.get(); + + if (m_oAsteriskTotals.IsInit()) + ptr->fHideTotAnnotation = m_oAsteriskTotals.get(); + if (m_oVisualTotals.IsInit()) + ptr->fNotVisualTotals = m_oVisualTotals.get(); + if (m_oAutoFormatId.IsInit()) + ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + if (m_oCacheId.IsInit()) + ptr->idCache = m_oCacheId->GetValue(); + if (m_oChartFormat.IsInit()) + ptr->dwCrtFmtId = m_oChartFormat->GetValue(); + if (m_oColGrandTotals.IsInit()) + ptr->fColGrand = m_oColGrandTotals.get(); + + if (m_oColHeaderCaption.IsInit()) ptr->irstColHdrName = m_oColHeaderCaption.get(); + else + ptr->fUseColHdrName = false; + if (m_oCompact.IsInit()) ptr->fDefaultCompact = m_oCompact.get(); + if (m_oCompactData.IsInit()) ptr->fCompactData = m_oCompactData.get(); + if (m_oCreatedVersion.IsInit()) ptr->bVerSxMacro = m_oCreatedVersion->GetValue(); + if (m_oCustomListSort.IsInit()) ptr->fDontUseCustomLists = !m_oCustomListSort.get(); + if (m_oDataCaption.IsInit()) ptr->irstData = m_oDataCaption.get(); + else + ptr->irstData = 0xFFFFFFFF; + if (m_oDataOnRows.IsInit()) ptr->fDefaultCompact = m_oDataOnRows.get(); + if (m_oDataPosition.IsInit()) ptr->ipos4Data = m_oDataPosition->GetValue(); + if (m_oDisableFieldList.IsInit()) ptr->fDisableFList = m_oDisableFieldList.get(); + if (m_oEditData.IsInit()) ptr->fEnableDataEd = m_oEditData.get(); + if (m_oEnableDrill.IsInit()) ptr->fEnableDrilldown = m_oEnableDrill.get(); + if (m_oEnableFieldProperties.IsInit()) ptr->fEnableFieldDialog = m_oEnableFieldProperties.get(); + if (m_oEnableWizard.IsInit()) ptr->fEnableWizard = m_oEnableWizard.get(); + if (m_oErrorCaption.IsInit()) ptr->irstErrorString = m_oErrorCaption.get(); + else + ptr->fEmptyDisplayErrorString = true; + if (m_oFieldListSortAscending.IsInit()) ptr->fNonDefaultSortInFlist = m_oFieldListSortAscending.get(); + if (m_oFieldPrintTitles.IsInit()) ptr->fPrintTitles = m_oFieldPrintTitles.get(); + if (m_oGrandTotalCaption.IsInit()) ptr->irstGrand = m_oGrandTotalCaption.get(); + else + ptr->fDisplayGrand = false; + if (m_oGridDropZones.IsInit()) ptr->fNewDropZones = !m_oGridDropZones.get(); + if (m_oImmersive.IsInit()) ptr->fTurnOffImmersive = m_oImmersive.get(); + if (m_oIndent.IsInit()) ptr->cIndentInc = m_oIndent->GetValue(); + if (m_oItemPrintTitles.IsInit()) ptr->fRepeatItemsOnEachPrintedPage = m_oItemPrintTitles.get(); + if (m_oMdxSubqueries.IsInit()) ptr->fDefaultCompact = m_oMdxSubqueries.get(); + if (m_oMergeItem.IsInit()) ptr->fMergeLabels = m_oMergeItem.get(); + if (m_oMinRefreshableVersion.IsInit()) ptr->bVerSxUpdateableMin = m_oMinRefreshableVersion->GetValue(); + if (m_oMissingCaption.IsInit()) ptr->irstNullString = m_oMissingCaption.get(); + else + ptr->fEmptyDisplayNullString = true; + if (m_oMultipleFieldFilters.IsInit()) ptr->fSingleFilterPerField = !m_oMultipleFieldFilters.get(); + if (m_oName.IsInit()) ptr->irstName = m_oName.get(); + else + ptr->irstName = 0xFFFFFFFF; + if (m_oOutline.IsInit()) ptr->fDefaultOutline = m_oOutline.get(); + if (m_oOutlineData.IsInit()) ptr->fOutlineData = m_oOutlineData.get(); + if (m_oPageOverThenDown.IsInit()) ptr->fAcrossPageLay = m_oPageOverThenDown.get(); + if (m_oPageStyle.IsInit()) ptr->irstPageFieldStyle = m_oPageStyle.get(); + else + ptr->fDisplayPageFieldStyle = false; + if (m_oPageWrap.IsInit()) ptr->cWrapPage = m_oPageWrap->GetValue(); + if (m_oPivotTableStyle.IsInit()) ptr->irstTableStyle = m_oPivotTableStyle.get(); + else + ptr->fDisplayTableStyle = false; + if (m_oPreserveFormatting.IsInit()) ptr->fPreserveFormatting = m_oPreserveFormatting.get(); + if (m_oPrintDrill.IsInit()) ptr->fPrintDrillIndicators = m_oPrintDrill.get(); + if (m_oPublished.IsInit()) ptr->fPublished = m_oPublished.get(); + if (m_oRowGrandTotals.IsInit()) ptr->fRwGrand = m_oRowGrandTotals.get(); + if (m_oRowHeaderCaption.IsInit()) ptr->irstRwHdrName = m_oRowHeaderCaption.get(); + else + ptr->fUseRwHdrName = false; + if (m_oShowCalcMbrs.IsInit()) ptr->fNotViewCalculatedMembers = !m_oShowCalcMbrs.get(); + if (m_oShowDataDropDown.IsInit()) ptr->fHideDDData = !m_oShowDataDropDown.get(); + if (m_oShowDataTips.IsInit()) ptr->fNoPivotTips = !m_oShowDataTips.get(); + if (m_oShowDrill.IsInit()) ptr->fHideDrillIndicators = !m_oShowDrill.get(); + if (m_oShowDropZones.IsInit()) ptr->fNoStencil = !m_oShowDropZones.get(); + if (m_oShowEmptyCol.IsInit()) ptr->fIncludeEmptyCol = m_oShowEmptyCol.get(); + if (m_oShowEmptyRow.IsInit()) ptr->fIncludeEmptyRw = m_oShowEmptyRow.get(); + if (m_oShowError.IsInit()) ptr->fDisplayErrorString = m_oShowError.get(); + if (m_oShowHeaders.IsInit()) ptr->fNoHeaders = !m_oShowHeaders.get(); + if (m_oShowItems.IsInit()) ptr->fDisplayImmediateItems = m_oShowItems.get(); + if (m_oShowMemberPropertyTips.IsInit()) ptr->fMemPropsInTips = m_oShowMemberPropertyTips.get(); + if (m_oShowMissing.IsInit()) ptr->fDisplayNullString = m_oShowMissing.get(); + if (m_oShowMultipleLabel.IsInit()) ptr->fPageMultipleItemLabel = m_oShowMultipleLabel.get(); + if (m_oSubtotalHiddenItems.IsInit()) ptr->fSubtotalHiddenPageItems = m_oSubtotalHiddenItems.get(); + if (m_oTag.IsInit()) ptr->irstTag = m_oTag.get(); + else + ptr->fDisplayTag = false; + if (m_oUpdatedVersion.IsInit()) ptr->bVerSxLastUpdated = m_oUpdatedVersion->GetValue(); + if (m_oUseAutoFormatting.IsInit()) ptr->fAutoFormat = m_oUseAutoFormatting.get(); + if (m_oVacatedStyle.IsInit()) ptr->irstVacateStyle = m_oVacatedStyle.get(); + else + ptr->fDisplayVacateStyle = false; + + return objectPtr; + } void CPivotTableDefinition::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -398,6 +561,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->m_SXPIS != nullptr) m_oPageFields = ptr->m_SXPIS; + + } } void CPivotTableDefinition::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -677,7 +842,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L"<" + sName); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -685,7 +850,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CColumnRowFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -751,6 +916,30 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CColumnRowFields::toBinRows() + { + auto ptr(new XLSB::ISXVDRWS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginISXVDRws); + ptr->m_BrtBeginISXVDRws = XLS::BaseObjectPtr{ptr1}; + if(m_oCount.IsInit()) + ptr1->cisxvd = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr1->rgisxvdrws.push_back(i->m_oX.get()); + return objectPtr; + } + XLS::BaseObjectPtr CColumnRowFields::toBinCols() + { + auto ptr(new XLSB::ISXVDCOLS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginISXVDCols); + ptr->m_BrtBeginISXVDCols = XLS::BaseObjectPtr{ptr1}; + if(m_oCount.IsInit()) + ptr1->cisxvd = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr1->rgisxvdcols.push_back(i->m_oX.get()); + return objectPtr; + } void CColumnRowFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -765,7 +954,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L"<" + sName); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -773,7 +962,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CColumnRowItems::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -796,6 +985,22 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CColumnRowItems::toBinRows() + { + auto ptr(new XLSB::SXLIRWS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXLI.push_back(i->toBin()); + return objectPtr; + } + XLS::BaseObjectPtr CColumnRowItems::toBinCols() + { + auto ptr(new XLSB::SXLICOLS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXLI.push_back(i->toBin()); + return objectPtr; + } void CColumnRowItems::fromBin(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeSXLIRWS) @@ -831,7 +1036,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"r", m_oR, m_oR->GetValue()); WritingStringNullableAttrString(L"t", m_oT, m_oT->ToString()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -857,6 +1062,62 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CColumnRowItem::toBin() + { + auto ptr(new XLSB::SXLI); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSXLI); + ptr->m_BrtBeginSXLI = XLS::BaseObjectPtr{ptr1}; + if(m_oI.IsInit()) + ptr1->iData = m_oI->GetValue(); + if(m_oR.IsInit()) + ptr1->cSic = m_oR->GetValue(); + if(m_oT.IsInit()) + { + if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeData) + ptr1->itmtype = XLSB::PivotItemType::PITDATA; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeDefault) + ptr1->itmtype = XLSB::PivotItemType::PITDEFAULT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeSum) + ptr1->itmtype = XLSB::PivotItemType::PITSUM; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeCountA) + ptr1->itmtype = XLSB::PivotItemType::PITCOUNTA; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeAverage) + ptr1->itmtype = XLSB::PivotItemType::PITAVG; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeMax) + ptr1->itmtype = XLSB::PivotItemType::PITMAX; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeMin) + ptr1->itmtype = XLSB::PivotItemType::PITMIN; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeProduct) + ptr1->itmtype = XLSB::PivotItemType::PITPRODUCT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeCount) + ptr1->itmtype = XLSB::PivotItemType::PITCOUNT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDev) + ptr1->itmtype = XLSB::PivotItemType::PITSTDDEV; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDevP) + ptr1->itmtype = XLSB::PivotItemType::PITSTDDEVP; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeVar) + ptr1->itmtype = XLSB::PivotItemType::PITVAR; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeVarP) + ptr1->itmtype = XLSB::PivotItemType::PITVARP; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeGrandTotalt) + ptr1->itmtype = XLSB::PivotItemType::PITGRAND; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) + ptr1->itmtype = XLSB::PivotItemType::PITBLANK; + } + if(m_arrItems.empty()) + return objectPtr; + + auto ptr2(new XLSB::ISXVIS(m_arrItems.size())); + ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; + auto ptr3(new XLSB::BeginISXVIs(m_arrItems.size())); + ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; + + for(auto i:m_arrItems) + if(i->m_oV.IsInit()) + ptr3->rgisxvis.push_back(i->m_oV->GetValue()); + return objectPtr; + } void CColumnRowItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -959,7 +1220,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -967,7 +1228,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CDataFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1004,6 +1265,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CDataFields::toBin() + { + auto ptr(new XLSB::SXDIS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXDI.push_back(i->toBin()); + return objectPtr; + } void CDataFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1039,6 +1308,76 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CDataField::toBin() + { + auto ptr1(new XLSB::SXDI); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXDI); + ptr1->m_BrtBeginSXDI = XLS::BaseObjectPtr{ptr}; + + if(m_oBaseField.IsInit()) + ptr->isxvd = m_oBaseField.get(); + if(m_oBaseItem.IsInit()) + ptr->isxvi = m_oBaseItem->GetValue(); + if(m_oFld.IsInit()) + ptr->isxvdData = m_oFld->GetValue(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt.ifmt = m_oNumFmtId->GetValue(); + if(m_oName.IsInit()) + { + ptr->stDisplayName = m_oName.get(); + ptr->fLoadDisplayName = true; + } + else + ptr->fLoadDisplayName = false; + if(m_oShowDataAs.IsInit()) + { + if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsNormal) + ptr->df = XLSB::ShowDataAs::NORMAL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsDifference) + ptr->df = XLSB::ShowDataAs::DIFFERENCE_; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOff) + ptr->df = XLSB::ShowDataAs::PERCENT; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentDiff) + ptr->df = XLSB::ShowDataAs::PERCENTDIFF; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsIndex) + ptr->df = XLSB::ShowDataAs::INDEX; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfTotal) + ptr->df = XLSB::ShowDataAs::PERCENTOFTOTAL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfCol) + ptr->df = XLSB::ShowDataAs::PERCENTOFCOL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfRow) + ptr->df = XLSB::ShowDataAs::PERCENTOFROW; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsRunTotal) + ptr->df = XLSB::ShowDataAs::PERCENTOFRUNTOTAL; + } + if(m_oSubtotal.IsInit()) + { + if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionSum) + ptr->iiftab = XLSB::DataConsolidationFunction::SUM; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionCount) + ptr->iiftab = XLSB::DataConsolidationFunction::COUNT; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionAverage) + ptr->iiftab = XLSB::DataConsolidationFunction::AVERAGE; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionMaximum) + ptr->iiftab = XLSB::DataConsolidationFunction::MAX; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionMinimum) + ptr->iiftab = XLSB::DataConsolidationFunction::MIN; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionProduct) + ptr->iiftab = XLSB::DataConsolidationFunction::PRODUCT; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionCountNums) + ptr->iiftab = XLSB::DataConsolidationFunction::COUNTNUM; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionStdDev) + ptr->iiftab = XLSB::DataConsolidationFunction::STDDEV; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionStdDevP) + ptr->iiftab = XLSB::DataConsolidationFunction::STDDEVP; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionVariance) + ptr->iiftab = XLSB::DataConsolidationFunction::STDVAR; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionVarP) + ptr->iiftab = XLSB::DataConsolidationFunction::STDVARP; + } + return objectPtr; + } void CDataField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1155,7 +1494,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -1163,7 +1502,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CPageFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1200,6 +1539,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageFields::toBin() + { + auto ptr(new XLSB::SXPIS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXPI.push_back(i->toBin()); + return objectPtr; + } void CPageFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1233,6 +1580,29 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPageField::toBin() + { + auto ptr1(new XLSB::SXPI); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXPI); + ptr1->m_BrtBeginSXPI = XLS::BaseObjectPtr{ptr}; + + if(m_oFld.IsInit()) + ptr->isxvd = m_oFld.get(); + if(m_oItem.IsInit()) + ptr->isxvi = m_oItem->GetValue(); + if(m_oHier.IsInit()) + ptr->isxth = m_oHier.get(); + if(m_oName.IsInit()) + ptr->irstUnique = m_oName.get(); + else + ptr->irstUnique = 0xFFFFFFFF; + if(m_oCap.IsInit()) + ptr->irstDisplay = m_oCap.get(); + else + ptr->irstDisplay = 0xFFFFFFFF; + return objectPtr; + } void CPageField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1280,7 +1650,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -1288,7 +1658,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CFieldItems::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1325,6 +1695,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CFieldItems::toBin() + { + auto ptr(new XLSB::SXVIS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXVI.push_back(i->toBin()); + return objectPtr; + } void CFieldItems::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1355,6 +1733,69 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CFieldItem::toBin() + { + auto ptr1(new XLSB::SXVI); + XLS::BaseObjectPtr objectPtr(ptr1); + + auto ptr(new XLSB::BeginSXVI); + ptr1->m_BrtBeginSXVI = XLS::BaseObjectPtr{ptr}; + + if(m_oChild.IsInit()) + ptr->fHasChildrenEst = m_oChild.get(); + if(m_oExpanded.IsInit()) + ptr->fDrilledMember = m_oExpanded.get(); + if(m_oDrillAcross.IsInit()) + ptr->fCollapsedMember = m_oDrillAcross.get(); + if(m_oCalculated.IsInit()) + ptr->fFormula = m_oCalculated.get(); + if(m_oHidden.IsInit()) + ptr->fHidden = m_oHidden.get(); + if(m_oMissing.IsInit()) + ptr->fMissing = m_oMissing.get(); + if(m_oUserCaption.IsInit()) + ptr->displayName = m_oUserCaption.get(); + if(m_oCharacter.IsInit()) + ptr->fOlapFilterSelected = m_oCharacter.get(); + if(m_oHideDetails.IsInit()) + ptr->fHideDetail = m_oHideDetails.get(); + if(m_oItemIndex.IsInit()) + ptr->iCache = m_oItemIndex->GetValue(); + if(m_oItemType.IsInit()) + { + if(m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeData) + ptr->itmtype = XLSB::PivotItemType::PITDATA; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeDefault) + ptr->itmtype = XLSB::PivotItemType::PITDEFAULT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeSum) + ptr->itmtype = XLSB::PivotItemType::PITSUM; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeCountA) + ptr->itmtype = XLSB::PivotItemType::PITCOUNTA; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeAverage) + ptr->itmtype = XLSB::PivotItemType::PITAVG; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeMax) + ptr->itmtype = XLSB::PivotItemType::PITMAX; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeMin) + ptr->itmtype = XLSB::PivotItemType::PITMIN; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeProduct) + ptr->itmtype = XLSB::PivotItemType::PITPRODUCT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeCount) + ptr->itmtype = XLSB::PivotItemType::PITCOUNT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDev) + ptr->itmtype = XLSB::PivotItemType::PITSTDDEV; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDevP) + ptr->itmtype = XLSB::PivotItemType::PITSTDDEVP; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeVar) + ptr->itmtype = XLSB::PivotItemType::PITVAR; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeVarP) + ptr->itmtype = XLSB::PivotItemType::PITVARP; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeGrandTotalt) + ptr->itmtype = XLSB::PivotItemType::PITGRAND; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) + ptr->itmtype = XLSB::PivotItemType::PITBLANK; + } + return objectPtr; + } void CFieldItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1474,7 +1915,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -1482,7 +1923,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CPivotFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1517,7 +1958,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(new CPivotField(item)); } } - + XLS::BaseObjectPtr CPivotFields::toBin() + { + auto ptr(new XLSB::SXVDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXVD.push_back(i->toBin()); + return objectPtr; + } void CPivotFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1577,7 +2025,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrString(L"itemPageCount",m_oItemPageCount, m_oItemPageCount->ToString()); WritingStringNullableAttrString(L"numFmtId", m_oNumFmtId, m_oNumFmtId->ToString()); writer.WriteString(L">"); - + if(m_oAutoSortScope.IsInit()) m_oAutoSortScope->toXML(writer); @@ -1623,6 +2071,167 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //m_oExtLst = ptr->m_FRTSXVD; } } + XLS::BaseObjectPtr CPivotField::toBin() + { + auto ptr(new XLSB::SXVD); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginSXVD = writeAttributes(); + if(m_oItems.IsInit()) + ptr->m_SXVIS = m_oItems->toBin(); + if(m_oAutoSortScope.IsInit()) + ptr->m_AUTOSORTSCOPE = m_oAutoSortScope->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotField::writeAttributes() + { + auto ptr(new XLSB::BeginSXVD); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oAllDrilled.IsInit()) + ptr->fDrilledLevel = m_oAllDrilled.get(); + + if(m_oAutoShow.IsInit()) + ptr->fAutoShow = m_oAutoShow.get(); + + if(m_oAvgSubtotal.IsInit()) + ptr->fAverage = m_oAvgSubtotal.get(); + + if(m_oAxis.IsInit()) + { + if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) + ptr->sxaxis.bCol = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisPage) + ptr->sxaxis.bPage = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + ptr->sxaxis.bRw = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + ptr->sxaxis.bData = true; + } + if(m_oCompact.IsInit()) + ptr->fCompact = m_oCompact.get(); + + if(m_oCountASubtotal.IsInit()) + ptr->fCounta = m_oCountASubtotal.get(); + + if(m_oCountSubtotal.IsInit()) + ptr->fCount = m_oCountSubtotal.get(); + if(m_oDataField.IsInit()) + ptr->fDrilledLevel = m_oDataField.get(); + if(m_oDataSourceSort.IsInit()) + ptr->fTensorSort = m_oDataSourceSort.get(); + if(m_oDefaultAttributeDrillState.IsInit()) + ptr->fItemsDrilledByDefault = m_oDefaultAttributeDrillState.get(); + if(m_oDefaultSubtotal.IsInit()) + ptr->fDefault = m_oDefaultSubtotal.get(); + if(m_oDragOff.IsInit()) + ptr->fDragToHide = m_oDragOff.get(); + + if (m_oDragToCol.IsInit()) ptr->fDragToColumn = m_oDragToCol.get(); + if (m_oDragToData.IsInit()) ptr->fDragToData = m_oDragToData.get(); + if (m_oDragToPage.IsInit()) ptr->fDragToPage = m_oDragToPage.get(); + if (m_oDragToRow.IsInit()) ptr->fDragToRow = m_oDragToRow.get(); + if (m_oHiddenLevel.IsInit()) ptr->fHiddenLvl = m_oHiddenLevel.get(); + if (m_oHideNewItems.IsInit()) ptr->fHideNewItems = m_oHideNewItems.get(); + if (m_oIncludeNewItemsInFilter.IsInit()) ptr->fFilterInclusive = m_oIncludeNewItemsInFilter.get(); + if (m_oInsertBlankRow.IsInit()) ptr->fInsertBlankRow = m_oInsertBlankRow.get(); + if (m_oInsertPageBreak.IsInit()) ptr->fPageBreaksBetweenItems = m_oInsertPageBreak.get(); + + if(m_oItemPageCount.IsInit()) + ptr->citmAutoShow = m_oItemPageCount->GetValue(); + + if(m_oMaxSubtotal.IsInit()) + ptr->fMax = m_oMaxSubtotal.get(); + + if(m_oMeasureFilter.IsInit()) + ptr->fHasAdvFilter = m_oMeasureFilter.get(); + + if(m_oMinSubtotal.IsInit()) + ptr->fMin = m_oMinSubtotal.get(); + + if(m_oMultipleItemSelectionAllowed.IsInit()) + ptr->fEnableMultiplePageItems = m_oMultipleItemSelectionAllowed.get(); + + if(m_oName.IsInit()) + ptr->irstName = m_oName.get(); + else + ptr->fDisplayName = false; + + + if (m_oNonAutoSortDefault.IsInit()) + ptr->fNotAutoSortDft = m_oNonAutoSortDefault.get(); + + if (m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + + if (m_oOutline.IsInit()) + ptr->fOutline = m_oOutline.get(); + + if (m_oProductSubtotal.IsInit()) + ptr->fProduct = m_oProductSubtotal.get(); + + if (m_oRankBy.IsInit()) + ptr->isxdiAutoShow = m_oRankBy->GetValue(); + + if (m_oServerField.IsInit()) + ptr->fServerBased = m_oServerField.get(); + + if (m_oShowAll.IsInit()) + ptr->fShowAllItems = m_oShowAll.get(); + + if (m_oShowDropDowns.IsInit()) + ptr->fHideDD = !m_oShowDropDowns.get(); + + if (m_oShowPropAsCaption.IsInit()) + ptr->fMemPropDisplayInCaption = m_oShowPropAsCaption.get(); + + if (m_oShowPropCell.IsInit()) + ptr->fMemPropDisplayInReport = m_oShowPropCell.get(); + + if (m_oShowPropTip.IsInit()) + ptr->fMemPropDisplayInTip = m_oShowPropTip.get(); + if(m_oSortType.IsInit()) + { + if(m_oSortType->GetValue() != SimpleTypes::Spreadsheet::EFieldSortType::sortManual) + ptr->fAutoSort = true; + if(m_oSortType->GetValue() == SimpleTypes::Spreadsheet::EFieldSortType::sortAscending) + ptr->fAscendSort = true; + else + ptr->fAscendSort = false; + } + + if (m_oStdDevPSubtotal.IsInit()) + ptr->fStdevp = m_oStdDevPSubtotal.get(); + + if (m_oStdDevSubtotal.IsInit()) + ptr->fStdev = m_oStdDevSubtotal.get(); + + if (m_oSubtotalCaption.IsInit()) + ptr->irstSub.value() = m_oSubtotalCaption.get(); + else + ptr->fDisplaySub = false; + + if (m_oSubtotalTop.IsInit()) + ptr->fSubtotalAtTop = !m_oSubtotalTop.get(); + + if (m_oSumSubtotal.IsInit()) + ptr->fSum = m_oSumSubtotal.get(); + + if (m_oTopAutoShow.IsInit()) + ptr->fTopAutoShow = !m_oTopAutoShow.get(); + + if (m_oUniqueMemberProperty.IsInit()) + ptr->irstMemberPropertyCaption = m_oUniqueMemberProperty.get(); + else + ptr->fUseMemPropCaption = false; + + if (m_oVarPSubtotal.IsInit()) + ptr->fVarp = m_oVarPSubtotal.get(); + + if (m_oVarSubtotal.IsInit()) + ptr->fVar = m_oVarSubtotal.get(); + + return objectPtr; + } void CPivotField::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1751,7 +2360,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else m_oSortType = SimpleTypes::Spreadsheet::EFieldSortType::sortAscending; - if(ptr->fStdevp) m_oStdDevPSubtotal = ptr->fStdevp; @@ -1830,7 +2438,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_else_if ( oReader, L"varPSubtotal", m_oVarPSubtotal ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"varSubtotal", m_oVarSubtotal ) WritingElement_ReadAttributes_End( oReader ) - } + } //------------------------------------ void CReferences::toXML(NSStringUtils::CStringBuilder& writer) const @@ -1840,7 +2448,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -1848,7 +2456,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CReferences::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1871,6 +2479,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CReferences::toBin() + { + auto ptr(new XLSB::PRFILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPRFILTER.push_back(i->toBin()); + return objectPtr; + } void CReferences::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1912,7 +2528,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrBool2(L"varPSubtotal", m_oVarPSubtotal); WritingStringNullableAttrBool2(L"varSubtotal", m_oVarSubtotal); writer.WriteString(L">"); - + if(m_oX.IsInit()) { m_oX->toXML(writer); @@ -1956,7 +2572,71 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CReference::toBin() + { + auto ptr(new XLSB::PRFILTER); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPRFilter = writeAttributes(); + ///@todo дописать конветрацию + ptr->m_arPRFITEM.push_back(m_oX->toBinPrfItem()); + return objectPtr; + } + XLS::BaseObjectPtr CReference::writeAttributes() + { + auto ptr(new XLSB::BeginPRFilter); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oAvgSubtotal.IsInit()) + ptr->prFilter.itmtypeAVERAGE = m_oAvgSubtotal.get(); + + if (m_oByPosition.IsInit()) + ptr->prFilter.itmtypeAVERAGE = m_oByPosition.get(); + + if (m_oCountASubtotal.IsInit()) + ptr->prFilter.itmtypeCOUNTA = m_oCountASubtotal.get(); + + if (m_oCountSubtotal.IsInit()) + ptr->prFilter.itmtypeCOUNT = m_oCountSubtotal.get(); + + if (m_oDefaultSubtotal.IsInit()) + ptr->prFilter.itmtypeDEFAULT = m_oDefaultSubtotal.get(); + + if (m_oMaxSubtotal.IsInit()) + ptr->prFilter.itmtypeMAX = m_oMaxSubtotal.get(); + + if (m_oMinSubtotal.IsInit()) + ptr->prFilter.itmtypeMIN = m_oMinSubtotal.get(); + + if (m_oProductSubtotal.IsInit()) + ptr->prFilter.itmtypePRODUCT = m_oProductSubtotal.get(); + + if (m_oRelative.IsInit()) + ptr->prFilter.itmtypeAVERAGE = m_oRelative.get(); + + if (m_oSelected.IsInit()) + ptr->prFilter.fSelected = m_oSelected.get(); + + if (m_oStdDevPSubtotal.IsInit()) + ptr->prFilter.itmtypeSTDEVP = m_oStdDevPSubtotal.get(); + + if (m_oStdDevSubtotal.IsInit()) + ptr->prFilter.itmtypeSTDEV = m_oStdDevSubtotal.get(); + if (m_oSumSubtotal.IsInit()) + ptr->prFilter.itmtypeSUM = m_oSumSubtotal.get(); + + if (m_oVarPSubtotal.IsInit()) + ptr->prFilter.itmtypeVARP = m_oVarPSubtotal.get(); + + if (m_oVarSubtotal.IsInit()) + ptr->prFilter.itmtypeVAR = m_oVarSubtotal.get(); + + if (m_oField.IsInit()) + ptr->prFilter.isxvd = m_oField->GetValue(); + + if (m_oCount.IsInit()) + ptr->prFilter.cItems = m_oCount->GetValue(); + return objectPtr; + } void CReference::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -2012,7 +2692,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -2020,7 +2700,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CPivotTableFormats::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -2057,6 +2737,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPivotTableFormats::toBin() + { + auto ptr(new XLSB::SXFORMATS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXFORMAT.push_back(i->toBin()); + return objectPtr; + } void CPivotTableFormats::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -2070,7 +2758,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrString(L"action", m_oAction, m_oAction->ToString()); WritingStringNullableAttrString(L"dxfId", m_oDxfId, m_oDxfId->ToString()); writer.WriteString(L">"); - + if(m_oPivotArea.IsInit()) { m_oPivotArea->toXML(writer); @@ -2095,6 +2783,22 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotTableFormat::toBin() + { + auto ptr(new XLSB::SXFORMAT); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDxfId.IsInit()) + { + auto ptr1(new XLSB::BeginSXFormat); + ptr->m_BrtBeginSXFormat = XLS::BaseObjectPtr{ptr1}; + ptr1->dxfid = m_oDxfId->GetValue(); + if(m_oAction.IsInit()) + ptr1->rlType = m_oAction->GetValue(); + } + if(m_oPivotArea.IsInit()) + ptr->m_PIVOTRULE = m_oPivotArea->toBin(); + return objectPtr; + } void CPivotTableFormat::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -2123,12 +2827,12 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_if ( oReader, L"action", m_oAction ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"dxfId", m_oDxfId ) WritingElement_ReadAttributes_End( oReader ) - } + } //------------------------------------ void CAutoSortScope::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L""); - + if(m_oPivotArea.IsInit()) { m_oPivotArea->toXML(writer); @@ -2161,6 +2865,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oPivotArea = ptr->m_PIVOTRULE; } } + XLS::BaseObjectPtr CAutoSortScope::toBin() + { + auto ptr(new XLSB::AUTOSORTSCOPE); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_PIVOTRULE = m_oPivotArea->toBin(); + return objectPtr; + } //------------------------------------ void CPivotArea::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -2178,7 +2889,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrBool2(L"outline", m_oOutline); WritingStringNullableAttrString(L"offsetRef", m_oOffsetRef, *m_oOffsetRef); writer.WriteString(L">"); - + if(m_oReferences.IsInit()) { m_oReferences->toXML(writer); @@ -2202,6 +2913,69 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotArea::toBin() + { + auto ptr(new XLSB::PIVOTRULE); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPRule = writeAttribures(); + if(m_oReferences.IsInit()) + ptr->m_PRFILTERS = m_oReferences->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotArea::writeAttribures() + { + auto ptr(new XLSB::BeginPRule); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oAxis.IsInit()) + { + if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) + ptr->pruleheaderdata.sxaxis.bCol = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisPage) + ptr->pruleheaderdata.sxaxis.bPage = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + ptr->pruleheaderdata.sxaxis.bRw = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) + ptr->pruleheaderdata.sxaxis.bData = true; + } + if(m_oCacheIndex.IsInit()) + ptr->pruleheaderdata.fCacheBased = m_oCacheIndex.get(); + if(m_oCollapsedLevelsAreSubtotals.IsInit()) + ptr->pruleheaderdata.fFuzzy = m_oCollapsedLevelsAreSubtotals.get(); + if(m_oDataOnly.IsInit()) + ptr->pruleheaderdata.fDataOnly = m_oDataOnly.get(); + if(m_oField.IsInit()) + ptr->pruleheaderdata.isxvd = m_oField.get(); + if(m_oFieldPosition.IsInit()) + ptr->pruleheaderdata.iDim = m_oFieldPosition->GetValue(); + if(m_oGrandCol.IsInit()) + ptr->pruleheaderdata.fGrandCol = m_oGrandCol.get(); + if(m_oGrandRow.IsInit()) + ptr->pruleheaderdata.fGrandRw = m_oGrandRow.get(); + if(m_oLabelOnly.IsInit()) + ptr->pruleheaderdata.fLabelOnly = m_oLabelOnly.get(); + if(m_oOffsetRef.IsInit()) + ptr->pruleheaderdata.rfxLoc = m_oOffsetRef.get(); + if(m_oOutline.IsInit()) + ptr->pruleheaderdata.fLineMode = m_oOutline.get(); + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaNone) + ptr->pruleheaderdata.isxrtype = 0x00; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaNormal) + ptr->pruleheaderdata.isxrtype = 0x01; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaData) + ptr->pruleheaderdata.isxrtype = 0x02; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaAll) + ptr->pruleheaderdata.isxrtype = 0x03; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaOrigin) + ptr->pruleheaderdata.isxrtype = 0x04; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaFieldButton) + ptr->pruleheaderdata.isxrtype = 0x05; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaTopEnd) + ptr->pruleheaderdata.isxrtype = 0x06; + } + return objectPtr; + } void CPivotArea::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -2310,7 +3084,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"rowPageCount", m_oRowPageCount, m_oRowPageCount->GetValue()); writer.WriteString(L"/>"); } - + void CPivotTableLocation::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -2333,6 +3107,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } + XLS::BaseObjectPtr CPivotTableLocation::toBin() + { + auto ptr1(new XLSB::SXLOCATION); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXLocation); + ptr1->m_BrtBeginSXLocation = XLS::BaseObjectPtr{ptr}; + + if(m_oColPageCount.IsInit()) + ptr->ccolPage = m_oColPageCount->GetValue(); + if(m_oFirstDataCol.IsInit()) + ptr->colFirstData = m_oFirstDataCol->GetValue(); + if(m_oFirstDataRow.IsInit()) + ptr->rwFirstData = m_oFirstDataRow->GetValue(); + if(m_oFirstHeaderRow.IsInit()) + ptr->rwFirstHead = m_oFirstHeaderRow->GetValue(); + if(m_oRowPageCount.IsInit()) + ptr->crwPage = m_oRowPageCount->GetValue(); + if(m_oRef.IsInit()) + ptr->rfxGeom = m_oRef.get(); + return objectPtr; + } + void CPivotTableLocation::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -2377,6 +3173,24 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oName = ptr->stStyleName.value(); } } + XLS::BaseObjectPtr CPivotTableStyleInfo::toBin() + { + auto ptr(new XLSB::TableStyleClient); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oShowColHeaders.IsInit()) + ptr->fColumnHeaders = m_oShowColHeaders.get(); + if(m_oShowRowHeaders.IsInit()) + ptr->fRowHeaders = m_oShowRowHeaders.get(); + if(m_oShowColStripes.IsInit()) + ptr->fRowStripes = m_oShowColStripes.get(); + if(m_oShowLastColumn.IsInit()) + ptr->fLastColumn = m_oShowLastColumn.get(); + if(m_oName.IsInit()) + ptr->stStyleName = m_oName.get(); + else + ptr->stStyleName = 0xFFFFFFFF; + return objectPtr; + } void CPivotTableStyleInfo::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -2493,8 +3307,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCacheSource.IsInit()) m_oCacheSource->toXML(writer); if(m_oCacheFields.IsInit()) - m_oCacheFields->toXML(writer); - + m_oCacheFields->toXML(writer); + if(m_oExtLst.IsInit()) { writer.WriteString(m_oExtLst->toXMLWithNS(_T(""))); @@ -2625,7 +3439,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -2633,7 +3447,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CPivotCacheFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -2694,7 +3508,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"mappingCount", m_oMappingCount, m_oMappingCount->GetValue()); WritingStringNullableAttrInt(L"numFmtId", m_oNumFmtId, m_oNumFmtId->GetValue()); writer.WriteString(L">"); - + if(m_oSharedItems.IsInit()) { m_oSharedItems->toXML(writer); @@ -2805,7 +3619,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_else_if ( oReader, L"mappingCount", m_oMappingCount ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"uniqueList", m_oNumFmtId ) WritingElement_ReadAttributes_End( oReader ) - } + } //------------------------------------ void CSharedItems::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -2833,7 +3647,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CSharedItems::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -3070,7 +3884,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -3122,7 +3936,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -3379,7 +4193,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingElement_ReadAttributes_Read_else_if ( oReader, L"m_oEndNum", m_oEndNum ) WritingElement_ReadAttributes_Read_else_if ( oReader, L"m_oGroupInterval", m_oGroupInterval ) WritingElement_ReadAttributes_End( oReader ) - } + } //------------------------------------ void CPivotCharacterValue::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -3546,7 +4360,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( L"x" == sName ) m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } - } + } void CPivotErrorValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -4060,7 +4874,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"connectionId", m_oConnectionId, m_oConnectionId->GetValue()); WritingStringNullableAttrString(L"type", m_oType, m_oType->ToString()); writer.WriteString(L">"); - + if(m_oWorksheetSource.IsInit()) { m_oWorksheetSource->toXML(writer); @@ -4198,7 +5012,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -4254,7 +5068,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -4349,7 +5163,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -4472,7 +5286,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L""); - + if(m_oPages.IsInit()) { m_oPages->toXML(writer); @@ -4538,7 +5352,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" WritingStringNullableAttrInt(L"base", m_oBase, m_oBase->GetValue()); WritingStringNullableAttrInt(L"par", m_oPar, m_oPar->GetValue()); writer.WriteString(L">"); - + if(m_oDiscretePr.IsInit()) { m_oDiscretePr->toXML(writer); @@ -4637,7 +5451,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" return; } NSFile::CFileBinary::ReadAllBytes(oPath.GetPath(), &m_pData, m_nDataLength); - + return; //XmlUtils::CXmlLiteReader oReader; @@ -4729,7 +5543,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr = static_cast(obj.get()); if(ptr != nullptr) - { + { NSStringUtils::CStringBuilder writer; writer.WriteString(L""); writer.WriteString(L"m_arPIVOTCACHERECORD.empty()) { //m_arrItems.push_back(new CPivotCacheRecord(item)); - + CPivotCacheRecord xmlItem(ptr->m_arPIVOTCACHERECORD.front()); xmlItem.toXML(writer); ptr->m_arPIVOTCACHERECORD.erase(ptr->m_arPIVOTCACHERECORD.begin()); @@ -4777,7 +5591,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L""); } void CPivotCacheRecord::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -4943,5 +5757,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + + XLS::BaseObjectPtr CSharedItemsIndex::toBinPrfItem() + { + auto ptr(new XLSB::BeginPRFItem); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oV.IsInit()) + ptr->iitem = m_oV->GetValue(); + return objectPtr; + } } //Spreadsheet } // namespace OOX From 4ab4f7416639da22197a90ceaeec67387572bd19 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 19 Sep 2023 20:37:28 +0600 Subject: [PATCH 156/794] Add pivot cache definition conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 19 + OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 129 +-- .../Pivot/PivotCacheDefinitionExt.cpp | 10 + .../Pivot/PivotCacheDefinitionExt.h | 1 + OOXML/XlsxFormat/Pivot/PivotTable.h | 1 + OOXML/XlsxFormat/Pivot/Pivots.cpp | 795 +++++++++++++++++- 7 files changed, 886 insertions(+), 70 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 986cae641da..1b6855a8344 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -687,6 +687,25 @@ namespace OOX } return objectPtr; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinPivotCache() + { + auto ptr(new XLSB::FRTPIVOTCACHEDEF); + XLS::BaseObjectPtr objectPtr(ptr); + + if (!m_arrExt.empty()) + { + for(auto i:m_arrExt) + { + + if(i->m_sUri == L"{725AE2AE-9491-48be-B2B4-4EB974FC3084}") + { + ptr->m_PCD14 = i->m_oPivotCacheDefinitionExt->toBin(); + } + + } + } + return objectPtr; + } XLS::BaseObjectPtr COfficeArtExtensionList::toBinSlicerCache() { auto ptr(new XLSB::FRTSLICERCACHE); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 2ca7f126c2c..48cfb8d7bad 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -192,6 +192,7 @@ namespace OOX XLS::BaseObjectPtr toBinStyles(); XLS::BaseObjectPtr toBinTable(); XLS::BaseObjectPtr toBinSlicerCache(); + XLS::BaseObjectPtr toBinPivotCache(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 4bd71ff7171..9111c189735 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -57,7 +57,7 @@ namespace OOX WritingElement_XlsbConstructors(CSharedItems) CSharedItems(){} virtual ~CSharedItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -68,12 +68,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_SharedItems; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr writeAttributes(); nullable_bool m_oContainsBlank; nullable_bool m_oContainsDate; @@ -83,13 +85,15 @@ namespace OOX nullable_bool m_oContainsNumber; nullable_bool m_oContainsSemiMixedTypes; nullable_bool m_oContainsString; - + nullable_bool m_oLongText; nullable_double m_oMinValue; nullable_double m_oMaxValue; nullable m_oMinDate; nullable m_oMaxDate; nullable m_oCount; + private: + XLS::BaseObjectPtr parsePCDI(XLS::BaseObjectPtr object); }; class COLAPGroupItems : public WritingElementWithChilds { @@ -98,7 +102,7 @@ namespace OOX WritingElement_XlsbConstructors(COLAPGroupItems) COLAPGroupItems(){} virtual ~COLAPGroupItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -109,6 +113,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_OLAPGroupItems; @@ -124,7 +129,7 @@ namespace OOX WritingElement_XlsbConstructors(CDiscreteGroupingProperties) CDiscreteGroupingProperties(){} virtual ~CDiscreteGroupingProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -135,6 +140,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_DiscreteGroupingProperties; @@ -150,7 +156,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeGroupingProperties) CRangeGroupingProperties(){} virtual ~CRangeGroupingProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -161,6 +167,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_RangeGroupingProperties; @@ -177,9 +184,9 @@ namespace OOX nullable m_oEndDate; nullable_double m_oStartNum; - nullable_double m_oEndNum; + nullable_double m_oEndNum; nullable_double m_oGroupInterval; - + }; class CFieldGroupProperties : public WritingElement { @@ -188,7 +195,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldGroupProperties) CFieldGroupProperties(){} virtual ~CFieldGroupProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -199,6 +206,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_FieldGroupProperties; @@ -208,7 +216,7 @@ namespace OOX nullable m_oBase; nullable m_oPar; - + nullable m_oDiscretePr; nullable m_oRangePr; nullable m_oGroupItems; @@ -220,7 +228,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheField) CPivotCacheField(){} virtual ~CPivotCacheField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -230,11 +238,13 @@ namespace OOX } virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const { return et_x_PivotCacheField; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -252,7 +262,7 @@ namespace OOX nullable m_oLevel; nullable m_oMappingCount; nullable m_oNumFmtId; - + nullable m_oSharedItems; //nullable m_oMpMap; nullable m_oFieldGroup; @@ -265,7 +275,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheFields) CPivotCacheFields(){} virtual ~CPivotCacheFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -276,6 +286,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheFields; @@ -291,7 +302,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeSet) CRangeSet(){} virtual ~CRangeSet() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -302,6 +313,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_RangeSet; @@ -325,7 +337,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeSets) CRangeSets(){} virtual ~CRangeSets() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -336,6 +348,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_RangeSets; @@ -351,7 +364,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItem) CPageItem(){} virtual ~CPageItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -362,6 +375,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PageItem; @@ -378,7 +392,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItems) CPageItems(){} virtual ~CPageItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -389,6 +403,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PageItems; @@ -404,7 +419,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItemValues) CPageItemValues(){} virtual ~CPageItemValues() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -415,6 +430,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PageItemValues; @@ -447,12 +463,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_ConsolidationSource; } void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable_bool m_oAutoPage; @@ -466,7 +483,7 @@ namespace OOX WritingElement_XlsbConstructors(CWorksheetSource) CWorksheetSource(){} virtual ~CWorksheetSource() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -477,6 +494,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_WorksheetSource; @@ -511,12 +529,13 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheSource; } void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable m_oConnectionId; nullable m_oType; @@ -524,7 +543,7 @@ namespace OOX nullable m_oConsolidation; nullable m_oWorksheetSource; nullable m_oExtLst; - }; + }; class CPivotCacheDefinition : public WritingElement { public: @@ -547,12 +566,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheDefinition; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable_bool m_oBackgroundQuery; nullable_bool m_oEnableRefresh; @@ -591,10 +612,10 @@ namespace OOX CPivotCacheDefinitionFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; - + bIsWritten = false; } CPivotCacheDefinitionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) @@ -626,9 +647,9 @@ namespace OOX const std::string srIdRecordsA( srIdRecords.begin(), srIdRecords.end() ); std::string rIdAttr = " r:id=\""+ srIdRecordsA +"\""; m_nDataLength = length + (long)rIdAttr.length(); - + m_pData = new BYTE[m_nDataLength]; - + long nTreshold = 220; memcpy(m_pData, pData, nTreshold); memcpy(m_pData + nTreshold, rIdAttr.c_str(), rIdAttr.length()); @@ -642,12 +663,10 @@ namespace OOX } } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotCacheDefinition; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); @@ -664,7 +683,7 @@ namespace OOX nullable m_oPivotCashDefinition; private: CPath m_oReadPath; - + BYTE *m_pData; long m_nDataLength; @@ -678,7 +697,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCharacterValue) CPivotCharacterValue(){} virtual ~CPivotCharacterValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -689,19 +708,20 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCharacterValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -711,7 +731,7 @@ namespace OOX nullable m_oFormatIndex; //tpls - }; + }; class CPivotBooleanValue : public WritingElementWithChilds { public: @@ -719,7 +739,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotBooleanValue) CPivotBooleanValue(){} virtual ~CPivotBooleanValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -730,6 +750,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotBooleanValue; @@ -742,7 +763,7 @@ namespace OOX nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable m_oCount; - }; + }; class CPivotNumericValue : public WritingElementWithChilds { public: @@ -750,7 +771,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotNumericValue) CPivotNumericValue(){} virtual ~CPivotNumericValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -761,19 +782,20 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotNumericValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_double m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -783,7 +805,7 @@ namespace OOX nullable m_oFormatIndex; //tpls - }; + }; class CPivotDateTimeValue : public WritingElementWithChilds { public: @@ -791,7 +813,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotDateTimeValue) CPivotDateTimeValue(){} virtual ~CPivotDateTimeValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -802,13 +824,14 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotBooleanValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; @@ -822,7 +845,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotErrorValue) CPivotErrorValue(){} virtual ~CPivotErrorValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -833,19 +856,20 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotErrorValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -855,7 +879,7 @@ namespace OOX nullable m_oFormatIndex; //tpls - }; + }; class CPivotNoValue : public WritingElementWithChilds { public: @@ -863,7 +887,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotNoValue) CPivotNoValue(){} virtual ~CPivotNoValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -874,18 +898,19 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotNoValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -895,7 +920,7 @@ namespace OOX nullable m_oFormatIndex; //tpls - }; - + }; + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp index 6312d219d54..22d57d25a45 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp @@ -54,6 +54,16 @@ void CPivotCacheDefinitionExt::fromXML(XmlUtils::CXmlLiteReader& oReader) return; oReader.ReadTillEnd(); } +XLS::BaseObjectPtr CPivotCacheDefinitionExt::toBin() +{ + auto ptr(new XLSB::PCD14); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCD14); + ptr->m_BrtBeginPCD14 = XLS::BaseObjectPtr{ptr1}; + if(m_oPivotCacheId.IsInit()) + ptr1->icacheId = m_oPivotCacheId.get(); + return objectPtr; +} void CPivotCacheDefinitionExt::fromBin(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typePCD14) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h index 2f1c35cdb9b..8a3cefbcea3 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h @@ -61,6 +61,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheDefinitionExt; diff --git a/OOXML/XlsxFormat/Pivot/PivotTable.h b/OOXML/XlsxFormat/Pivot/PivotTable.h index 52b26642f9e..f3b94ce4b02 100644 --- a/OOXML/XlsxFormat/Pivot/PivotTable.h +++ b/OOXML/XlsxFormat/Pivot/PivotTable.h @@ -102,6 +102,7 @@ namespace OOX writer.WriteString(L"/>"); } XLS::BaseObjectPtr toBinPrfItem(); + XLS::BaseObjectPtr toBinItemIndex(); void fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 309b086bbe6..54e60a15dcf 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -3222,7 +3222,12 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //pivotCacheDefStream.reset(); } } + XLS::BaseObjectPtr CPivotCacheDefinitionFile::WriteBin() const + { + auto pivotCacheDefStream = m_oPivotCashDefinition->toBin(); + return pivotCacheDefStream; + } void CPivotCacheDefinitionFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -3251,29 +3256,43 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (bIsWritten) return; bIsWritten = true; - if(m_oPivotCashDefinition.IsInit()) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oPivotCashDefinition->toXML(sXml); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + if(m_oPivotCashDefinition.IsInit()) + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oPivotCashDefinition->toXML(sXml); - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + else if(m_nDataLength > 0 && m_pData) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); + oFile.WriteFile(m_pData, m_nDataLength); + oFile.CloseFile(); + } } - else if(m_nDataLength > 0 && m_pData) + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } + const OOX::FileType CPivotCacheDefinitionFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(m_pData, m_nDataLength); - oFile.CloseFile(); - - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + return OOX::SpreadsheetBin::FileTypes::PivotCacheDefinitionBin; } + return OOX::Spreadsheet::FileTypes::PivotCacheDefinition; } //------------------------------------ void CPivotCacheDefinition::toXML(NSStringUtils::CStringBuilder& writer) const @@ -3333,6 +3352,83 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (L"extLst" == sName) m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotCacheDefinition::toBin() + { + auto ptr(new XLSB::PivotCacheDefStream); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPivotCacheDef = writeAttributes(); + if(m_oCacheFields.IsInit()) + ptr->m_PCDFIELDS = m_oCacheFields->toBin(); + if(m_oCacheSource.IsInit()) + ptr->m_PCDSOURCE = m_oCacheSource->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTPIVOTCACHEDEF = m_oExtLst->toBinPivotCache(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotCacheDefinition::writeAttributes() + { + auto ptr(new XLSB::BeginPivotCacheDef); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oBackgroundQuery.IsInit()) + ptr->fBackgroundQuery = m_oBackgroundQuery.get(); + + if (m_oEnableRefresh.IsInit()) + ptr->fEnableRefresh = !m_oEnableRefresh.get(); + + if (m_oRid.IsInit()) + ptr->stRelIDRecords.value = m_oRid->GetValue(); + else + ptr->fLoadRelIDRecords = false; + + if (m_oInvalid.IsInit()) + ptr->fInvalid = m_oInvalid.get(); + + if (m_oCreatedVersion.IsInit()) + ptr->bVerCacheCreated = m_oCreatedVersion->GetValue(); + + if (m_oMinRefreshableVersion.IsInit()) + ptr->bVerCacheRefreshableMin = m_oMinRefreshableVersion->GetValue(); + + if (m_oMissingItemsLimit.IsInit()) + ptr->citmGhostMax = m_oMissingItemsLimit->GetValue(); + + if (m_oOptimizeMemory.IsInit()) + ptr->fOptimizeCache = m_oOptimizeMemory.get(); + + if (m_oRecordCount.IsInit()) + ptr->cRecords = m_oRecordCount->GetValue(); + + if (m_oRefreshedBy.IsInit()) + ptr->stRefreshedWho = m_oRefreshedBy.get(); + else + ptr->fLoadRefreshedWho = false; + + if (m_oRefreshedDateIso.IsInit()) + ptr->xnumRefreshedDate.data.value = std::stod(m_oRefreshedDateIso->GetValue()); + + if (m_oRefreshedVersion.IsInit()) + ptr->bVerCacheLastRefresh = m_oRefreshedVersion->GetValue(); + + if (m_oRefreshOnLoad.IsInit()) + ptr->fRefreshOnLoad = m_oRefreshOnLoad.get(); + + if (m_oSaveData.IsInit()) + ptr->fSaveData = m_oSaveData.get(); + + if (m_oSupportAdvancedDrill.IsInit()) + ptr->fSupportAttribDrill = m_oSupportAdvancedDrill.get(); + + if (m_oSupportSubquery.IsInit()) + ptr->fSupportSubquery = m_oSupportSubquery.get(); + + if (m_oTupleCache.IsInit()) + ptr->fSheetData = m_oTupleCache.get(); + + if (m_oUpgradeOnRefresh.IsInit()) + ptr->fUpgradeOnRefresh = m_oUpgradeOnRefresh.get(); + + return objectPtr; + } void CPivotCacheDefinition::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -3470,6 +3566,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPivotCacheFields::toBin() + { + auto ptr(new XLSB::PCDFIELDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDFIELD.push_back(i->toBin()); + return objectPtr; + } void CPivotCacheFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -3544,6 +3648,62 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotCacheField::toBin() + { + auto ptr(new XLSB::PCDFIELD); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->m_BrtBeginPCDField = writeAttributes(); + if(m_oSharedItems.IsInit()) + ptr->m_PCDFATBL = m_oSharedItems->toBin(); + if(m_oFieldGroup.IsInit()) + ptr->m_PCDFGROUP = m_oFieldGroup->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotCacheField::writeAttributes() + { + auto ptr(new XLSB::BeginPCDField); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oName.IsInit()) + ptr->stFldName.value() = m_oName.get(); + + if (m_oCaption.IsInit()) + ptr->stFldCaption.value() = m_oCaption.get(); + + if (m_oDatabaseField.IsInit()) + ptr->fSrcField = m_oDatabaseField.get(); + + if (m_oServerField.IsInit()) + ptr->fServerBased = m_oServerField.get(); + + if (m_oFormula.IsInit()) + ptr->fldFmla = m_oFormula.get(); + + if (m_oHierarchy.IsInit()) + ptr->ihdb = m_oHierarchy.get(); + + if (m_oMemberPropertyField.IsInit()) + ptr->fOlapMemPropField = m_oMemberPropertyField.get(); + + if (m_oPropertyName.IsInit()) + ptr->stMemPropName.value() = m_oPropertyName.get(); + + if (m_oSqlType.IsInit()) + ptr->wTypeSql = m_oSqlType.get(); + + if (m_oUniqueList.IsInit()) + ptr->fCantGetUniqueItems = !m_oUniqueList.get(); + + if (m_oLevel.IsInit()) + ptr->isxtl = m_oLevel->GetValue(); + if(m_oMappingCount.IsInit()) + ptr->cIsxtmps = m_oMappingCount->GetValue(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + + return objectPtr; + } void CPivotCacheField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -3700,6 +3860,114 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CSharedItems::toBin() + { + auto ptr(new XLSB::PCDFATBL); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPCDFAtbl = writeAttributes(); + for(auto i:m_arrItems) + { + auto valueBool = static_cast(i); + if(valueBool) + { + XLS::BaseObjectPtr element= valueBool->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + auto noVal = static_cast(i); + if(noVal) + { + XLS::BaseObjectPtr element = noVal->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + auto numVal = static_cast(i); + if(numVal) + { + XLS::BaseObjectPtr element = numVal->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + auto charVal = static_cast(i); + if(charVal) + { + XLS::BaseObjectPtr element = charVal->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + auto dateValue = static_cast(i); + if(dateValue) + { + XLS::BaseObjectPtr element = dateValue->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + auto errorVal = static_cast(i); + if(errorVal) + { + XLS::BaseObjectPtr element = errorVal->toBin(); + ptr->m_arSource.push_back(parsePCDI(element)); + continue; + } + } + return objectPtr; + } + XLS::BaseObjectPtr CSharedItems::parsePCDI(XLS::BaseObjectPtr object) + { + if(object->get_type() == XLS::typePCDI) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = object; + return XLS::BaseObjectPtr{ptr1}; + } + else if(object->get_type() == XLS::typePCDIA) + { + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = object; + return XLS::BaseObjectPtr{ptr1}; + } + } + XLS::BaseObjectPtr CSharedItems::writeAttributes() + { + auto ptr(new XLSB::BeginPCDFAtbl); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oContainsBlank.IsInit()) + ptr->fHasBlankItem = m_oContainsBlank.get(); + if(m_oContainsDate.IsInit()) + ptr->fDateInField = m_oContainsDate.get(); + if(m_oContainsInteger.IsInit()) + ptr->fIntField = m_oContainsInteger.get(); + if(m_oContainsMixedTypes.IsInit()) + ptr->fMixedTypesIgnoringBlanks = m_oContainsMixedTypes.get(); + if(m_oContainsNonDate.IsInit()) + ptr->fNonDates = m_oContainsNonDate.get(); + if(m_oContainsNumber.IsInit()) + ptr->fNumField = m_oContainsNumber.get(); + if(m_oContainsSemiMixedTypes.IsInit()) + ptr->fTextEtcField = m_oContainsSemiMixedTypes.get(); + + if(m_oContainsString.IsInit()) + ptr->fHasTextItem = m_oContainsString.get(); + if(m_oLongText.IsInit()) + ptr->fHasLongTextItem = m_oLongText.get(); + if(m_oCount.IsInit()) + ptr->citems = m_oCount->GetValue(); + if(m_oMinDate.IsInit() && m_oMaxDate.IsInit()) + { + ptr->xnumMin.data.value = std::stod(m_oMinDate->GetValue()); + ptr->xnumMax.data.value =std::stod(m_oMaxDate->GetValue()); + } + else + { + if(m_oMinValue.IsInit()) + ptr->xnumMin.data.value = m_oMinValue.get(); + if(m_oMaxValue.IsInit()) + ptr->xnumMax.data.value = m_oMaxValue.get(); + } + + return objectPtr; + } void CSharedItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -3910,6 +4178,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CDiscreteGroupingProperties::toBin() + { + auto ptr(new XLSB::PCDFGDISCRETE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtPCDIIndex.push_back(i->toBinItemIndex()); + return objectPtr; + } void CDiscreteGroupingProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -3996,6 +4272,63 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr COLAPGroupItems::toBin() + { + auto ptr(new XLSB::PCDFGITEMS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + auto boolVal = static_cast(i); + if(boolVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = boolVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto dataValue = static_cast(i); + if(dataValue) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = dataValue->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto errorValue = static_cast(i); + if(errorValue) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = errorValue->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto noVal = static_cast(i); + if(noVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = noVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto numericVal = static_cast(i); + if(numericVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = numericVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto charVal = static_cast(i); + if(charVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = charVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + } + return objectPtr; + } void COLAPGroupItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4123,6 +4456,44 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CRangeGroupingProperties::toBin() + { + auto ptr1(new XLSB::PCDFGRANGE); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginPCDFGRange); + ptr1->m_BrtBeginPCDFGRange = XLS::BaseObjectPtr{ptr}; + + if(m_oAutoStart.IsInit()) + ptr->fAutoStart = m_oAutoStart.get(); + if(m_oAutoEnd.IsInit()) + ptr->fAutoEnd = m_oAutoEnd.get(); + if(m_oGroupInterval.IsInit()) + ptr->xnumBy.data.value = m_oGroupInterval.get(); + if(m_oStartDate.IsInit() && m_oEndDate.IsInit()) + { + ptr->xnumStart.data.value = std::stod(m_oStartDate->GetValue()); + ptr->xnumEnd.data.value = std::stod(m_oEndDate->GetValue()); + } + else + { + if(m_oStartNum.IsInit()) + ptr->xnumStart.data.value = m_oStartNum.get(); + if(m_oEndNum.IsInit()) + ptr->xnumEnd.data.value = m_oEndNum.get(); + } + if(m_oGroupBy.IsInit()) + { + if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByNumericRanges) ptr->iByType = 0x00; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupBySeconds) ptr->iByType = 0x01; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByMinutes) ptr->iByType = 0x02; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByHours) ptr->iByType = 0x03; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByDays) ptr->iByType = 0x04; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByMonths) ptr->iByType = 0x05; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByQuarters) ptr->iByType = 0x06; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByYears) ptr->iByType = 0x07; + } + return objectPtr; + } void CRangeGroupingProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4241,6 +4612,47 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotCharacterValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIAString); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIString); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + if(m_oBold.IsInit()) + ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); + if(m_oItalic.IsInit()) + ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); + if(m_oStrike.IsInit()) + ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); + if(m_oUnderline.IsInit()) + ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); + if(m_oFormatIndex.IsInit()) + ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); + if(m_oBackColor.IsInit()) + ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); + if(m_oForeColor.IsInit()) + ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); + return objectPtr; + } + } void CPivotCharacterValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -4361,6 +4773,67 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotErrorValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIAError); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + { + if (m_oValue == L"#NULL!") ptr->err = 0x00; + else if (m_oValue == L"#DIV/0!") ptr->err = 0x07; + else if (m_oValue == L"#VALUE!") ptr->err = 0x0F; + else if (m_oValue == L"#REF!") ptr->err = 0x17; + else if (m_oValue == L"#NAME?") ptr->err = 0x1D; + else if (m_oValue == L"#NUM!") ptr->err = 0x24; + else if (m_oValue == L"#N/A") ptr->err = 0x2A; + else if (m_oValue == L"#GETTING_DATA") ptr->err = 0x2B; + } + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIError); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + { + if (m_oValue == L"#NULL!") ptr->err = 0x00; + else if (m_oValue == L"#DIV/0!") ptr->err = 0x07; + else if (m_oValue == L"#VALUE!") ptr->err = 0x0F; + else if (m_oValue == L"#REF!") ptr->err = 0x17; + else if (m_oValue == L"#NAME?") ptr->err = 0x1D; + else if (m_oValue == L"#NUM!") ptr->err = 0x24; + else if (m_oValue == L"#N/A") ptr->err = 0x2A; + else if (m_oValue == L"#GETTING_DATA") ptr->err = 0x2B; + } + if(m_oBold.IsInit()) + ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); + if(m_oItalic.IsInit()) + ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); + if(m_oStrike.IsInit()) + ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); + if(m_oUnderline.IsInit()) + ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); + if(m_oFormatIndex.IsInit()) + ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); + if(m_oBackColor.IsInit()) + ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); + if(m_oForeColor.IsInit()) + ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); + return objectPtr; + } + } void CPivotErrorValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -4505,6 +4978,47 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { ReadAttributes(obj); } + XLS::BaseObjectPtr CPivotNumericValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIANumber); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDINumber); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->xnum.data.value = m_oValue.get(); + if(m_oBold.IsInit()) + ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); + if(m_oItalic.IsInit()) + ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); + if(m_oStrike.IsInit()) + ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); + if(m_oUnderline.IsInit()) + ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); + if(m_oFormatIndex.IsInit()) + ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); + if(m_oBackColor.IsInit()) + ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); + if(m_oForeColor.IsInit()) + ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); + return objectPtr; + } + } void CPivotNumericValue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -4614,6 +5128,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotDateTimeValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIADatetime); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIDatetime); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->datetime.fromString(m_oValue->GetValue()); + + return objectPtr; + } + } void CPivotDateTimeValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -4702,6 +5244,35 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotBooleanValue::toBin() + { + if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) + { + auto ptr(new XLSB::PCDIABoolean); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->f = m_oValue.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIBoolean); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->f = m_oValue.get(); + return objectPtr; + } + } void CPivotBooleanValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -4801,7 +5372,46 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { ReadAttributes(obj); } - + XLS::BaseObjectPtr CPivotNoValue::toBin() + { + if(m_arrItems.empty() || m_oBold.IsInit() || m_oItalic.IsInit() || m_oStrike.IsInit() || m_oUnderline.IsInit() || m_oFormatIndex.IsInit() + || m_oBackColor.IsInit() || m_oForeColor.IsInit()) + { + auto ptr(new XLSB::PCDIMissing); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBold.IsInit()) + ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); + if(m_oItalic.IsInit()) + ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); + if(m_oStrike.IsInit()) + ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); + if(m_oUnderline.IsInit()) + ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); + if(m_oFormatIndex.IsInit()) + ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); + if(m_oBackColor.IsInit()) + ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); + if(m_oForeColor.IsInit()) + ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); + return objectPtr; + } + else + { + auto ptr(new XLSB::PCDIAMissing); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCaption.IsInit()) + ptr->info.stCaption = m_oCaption.get(); + if(m_oCalculated.IsInit()) + ptr->info.fFmla = m_oCalculated.get(); + if(m_oUnused.IsInit()) + ptr->info.fGhost = m_oUnused.get(); + if(m_oCount.IsInit()) + ptr->info.cIMemProps = m_oCount->GetValue(); + for(auto i:m_arrItems) + ptr->info.rgIMemProps.push_back(i->m_oV.get()); + return objectPtr; + } + } void CPivotNoValue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -4919,6 +5529,32 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oConsolidation = ptr->m_PCDSCONSOL; } } + XLS::BaseObjectPtr CPivotCacheSource::toBin() + { + auto ptr(new XLSB::PCDSOURCE); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSource); + ptr->m_BrtBeginPCDSource = XLS::BaseObjectPtr{ptr1}; + if(m_oType.IsInit()) + { + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceWorksheet) + ptr1->iSrcType = 0x00000000; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceExternal) + ptr1->iSrcType = 0x00000001; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceConsolidation) + ptr1->iSrcType = 0x00000002; + if(m_oType == SimpleTypes::Spreadsheet::ESourceCacheType::typeSourceScenario) + ptr1->iSrcType = 0x00000003; + } + if(m_oConnectionId.IsInit()) + ptr1->dwConnID = m_oConnectionId->GetValue(); + + if(m_oWorksheetSource.IsInit()) + ptr->m_PCDSRANGE = m_oWorksheetSource->toBin(); + if(m_oConsolidation.IsInit()) + ptr->m_PCDSCONSOL = m_oConsolidation->toBin(); + return objectPtr; + } void CPivotCacheSource::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -4969,6 +5605,29 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CWorksheetSource::toBin() + { + auto ptr1(new XLSB::PCDSRANGE); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginPCDSRange); + ptr1->m_BrtBeginPCDSRange = XLS::BaseObjectPtr{ptr}; + + if(m_oSheet.IsInit()) + ptr->sheetName = m_oSheet.get(); + else + ptr->fLoadSheet = false; + if(m_oRef.IsInit()) + ptr->range.fromString(m_oRef.get()); + if(m_oName.IsInit()) + ptr->namedRange = m_oName.get(); + else + ptr->fName = false; + if(m_oRid.IsInit()) + ptr->relId.value = m_oRid->GetValue(); + else + ptr->fLoadRelId = false; + return objectPtr; + } void CWorksheetSource::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5042,6 +5701,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageItemValues::toBin() + { + auto ptr(new XLSB::PCDSCPAGES); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCPAGE.push_back(i->toBin()); + return objectPtr; + } void CPageItemValues::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5098,6 +5765,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageItems::toBin() + { + auto ptr(new XLSB::PCDSCPAGE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCPITEM.push_back(i->toBin()); + return objectPtr; + } void CPageItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5132,6 +5807,17 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CPageItem::toBin() + { + auto ptr(new XLSB::PCDSCPITEM); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSCPItem); + ptr->m_BrtBeginPCDSCPItem = XLS::BaseObjectPtr{ptr1}; + if(m_oName.IsInit()) + ptr1->stName = m_oName.get(); + + return objectPtr; + } void CPageItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5193,6 +5879,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CRangeSets::toBin() + { + auto ptr(new XLSB::PCDSCSETS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDSCSET.push_back(i->toBin()); + return objectPtr; + } void CRangeSets::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5234,6 +5928,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CRangeSet::toBin() + { + auto ptr(new XLSB::BeginPCDSCSet); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oSheet.IsInit()) + ptr->irstSheet = m_oSheet.get(); + if(m_oRef.IsInit()) + ptr->rfx = m_oRef.get(); + if(m_oName.IsInit()) + ptr->irstName = m_oName.get(); + if(m_oRid.IsInit()) + ptr->irstRelId.value = m_oRid->GetValue(); + if(m_oI1.IsInit()) + ptr->rgiItem[0] = m_oI1->GetValue(); + if(m_oI2.IsInit()) + ptr->rgiItem[1] = m_oI2->GetValue(); + if(m_oI3.IsInit()) + ptr->rgiItem[2] = m_oI3->GetValue(); + if(m_oI4.IsInit()) + ptr->rgiItem[3] = m_oI4->GetValue(); + return objectPtr; + } void CRangeSet::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5314,6 +6030,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oRangeSets = oReader; } } + XLS::BaseObjectPtr CConsolidationSource::toBin() + { + auto ptr(new XLSB::PCDSCONSOL); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDSConsol); + ptr->m_BrtBeginPCDSConsol = XLS::BaseObjectPtr{ptr1}; + if(m_oAutoPage.IsInit()) + ptr1->fAutoPage = m_oAutoPage.get(); + if(m_oPages.IsInit()) + ptr->m_PCDSCPAGES = m_oPages->toBin(); + if(m_oRangeSets.IsInit()) + ptr->m_PCDSCSETS = m_oRangeSets->toBin(); + return objectPtr; + } void CConsolidationSource::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5386,6 +6116,26 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oGroupItems = oReader; } } + XLS::BaseObjectPtr CFieldGroupProperties::toBin() + { + auto ptr(new XLSB::PCDFGROUP); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oPar.IsInit() || m_oBase.IsInit()) + { + auto ptr1(new XLSB::BeginPCDFGroup); + if(m_oPar.IsInit()) + ptr1->ifdbParent = m_oPar->GetValue(); + if(m_oBase.IsInit()) + ptr1->ifdbBase = m_oBase->GetValue(); + } + if(m_oDiscretePr.IsInit()) + ptr->m_PCDFGDISCRETE = m_oDiscretePr->toBin(); + if(m_oRangePr.IsInit()) + ptr->m_PCDFGRANGE = m_oRangePr->toBin(); + if(m_oGroupItems.IsInit()) + ptr->m_PCDFGITEMS = m_oGroupItems->toBin(); + return objectPtr; + } void CFieldGroupProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -5758,6 +6508,15 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } + XLS::BaseObjectPtr CSharedItemsIndex::toBinItemIndex() + { + auto ptr(new XLSB::PCDIIndex); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oV.IsInit()) + ptr->iitem = m_oV->GetValue(); + return objectPtr; + } + XLS::BaseObjectPtr CSharedItemsIndex::toBinPrfItem() { auto ptr(new XLSB::BeginPRFItem); From 85c420d501f0abc5f69f20b4d0832156285c7211 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 21 Sep 2023 22:05:22 +0600 Subject: [PATCH 157/794] Add pivot cache records conversion --- OOXML/XlsxFormat/Pivot/PivotCacheRecords.h | 19 +-- OOXML/XlsxFormat/Pivot/Pivots.cpp | 169 ++++++++++++++++++--- 2 files changed, 159 insertions(+), 29 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h b/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h index 8f00b1f924f..354d07ff750 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h @@ -57,7 +57,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheRecord) CPivotCacheRecord(){} virtual ~CPivotCacheRecord() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -68,6 +68,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheRecord; @@ -96,11 +97,12 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotCacheRecords; } - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); nullable m_oCount; nullable m_oExtLst; @@ -114,7 +116,7 @@ namespace OOX CPivotCacheRecordsFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; } @@ -145,12 +147,10 @@ namespace OOX memcpy(m_pData, pData, length); } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotCacheRecords; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); @@ -165,11 +165,12 @@ namespace OOX } //--------------------------------------------------------------------- nullable m_oPivotCacheRecords; - //--------- + //--------- BYTE *m_pData = NULL; DWORD m_nDataLength = 0; private: - CPath m_oReadPath; + CPath m_oReadPath; + std::wstring prepareData() const; }; } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 54e60a15dcf..4e207bb88f4 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -38,6 +38,7 @@ #include "../../XlsbFormat/PivotTableStream.h" #include "../../XlsbFormat/PivotCacheDefStream.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORDS.h" +#include "../../XlsbFormat/Biff12_records/BeginPivotCacheRecords.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORD.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORDDT.h" #include "../../XlsbFormat/Biff12_unions/PCDIDT.h" @@ -133,6 +134,7 @@ #include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include namespace OOX { namespace Spreadsheet @@ -6190,6 +6192,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //pivotCacheRecordsStream.reset(); } } + XLS::BaseObjectPtr CPivotCacheRecordsFile::WriteBin() const + { + auto pivotCacheRecordsStream(new XLSB::PivotCacheRecordsStream); + if(m_oPivotCacheRecords.IsInit()) + pivotCacheRecordsStream->m_PIVOTCACHERECORDS = m_oPivotCacheRecords->toBin(); + else if(m_nDataLength > 0 && m_pData) + { + CPivotCacheRecords records; + XmlUtils::CXmlLiteReader reader; + auto wstringData = prepareData(); + reader.FromString(wstringData); + reader.ReadNextNode(); + records.fromXML(reader); + pivotCacheRecordsStream->m_PIVOTCACHERECORDS = records.toBin(); + } + return XLS::BaseObjectPtr{pivotCacheRecordsStream}; + } void CPivotCacheRecordsFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -6216,34 +6235,70 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } void CPivotCacheRecordsFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if(m_oPivotCacheRecords.IsInit()) + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else { - std::wstring sPath = oPath.GetPath(); - - if (false == m_oPivotCacheRecords->m_strOutputXml.empty()) + if(m_oPivotCacheRecords.IsInit()) { - NSFile::CFileBinary::SaveToFile(sPath, m_oPivotCacheRecords->m_strOutputXml); + std::wstring sPath = oPath.GetPath(); + + if (false == m_oPivotCacheRecords->m_strOutputXml.empty()) + { + NSFile::CFileBinary::SaveToFile(sPath, m_oPivotCacheRecords->m_strOutputXml); + } + else + { + NSStringUtils::CStringBuilder sXml; + sXml.WriteString(L""); + m_oPivotCacheRecords->toXML(sXml); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + } - else + else if(m_nDataLength > 0 && m_pData) { - NSStringUtils::CStringBuilder sXml; - sXml.WriteString(L""); - m_oPivotCacheRecords->toXML(sXml); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); + oFile.WriteFile(m_pData, m_nDataLength); + oFile.CloseFile(); + } - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); } - else if(m_nDataLength > 0 && m_pData) + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } + const OOX::FileType CPivotCacheRecordsFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(m_pData, m_nDataLength); - oFile.CloseFile(); - - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + return OOX::SpreadsheetBin::FileTypes::PivotCacheRecordsBin; + } + return OOX::Spreadsheet::FileTypes::PivotCacheRecords; + } + std::wstring CPivotCacheRecordsFile::prepareData() const + { + std::vector dataChars; + std::string rawStringData{reinterpret_cast(m_pData)}; + //std::string stringData(reinterpret_cast(m_pData)); + std::wstring_convert> converter; + std::wstring result; + for (char i : rawStringData) + { + try { + // Попытка конвертировать каждый символ + result += converter.from_bytes(std::string(1, i)); + } catch (const std::range_error&) { + // Пропускаем невалидные символы + } } + + return result; } //------------------------------------ void CPivotCacheRecords::toXML(NSStringUtils::CStringBuilder& writer) const @@ -6323,6 +6378,18 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.Clear(); } } + XLS::BaseObjectPtr CPivotCacheRecords::toBin() + { + auto ptr(new XLSB::PIVOTCACHERECORDS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPivotCacheRecords); + ptr1->crecords = m_arrItems.size(); + ptr->m_BrtBeginPivotCacheRecords = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + ptr->m_arPIVOTCACHERECORD.push_back(i->toBin()); + + return objectPtr; + } void CPivotCacheRecords::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -6396,6 +6463,68 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent(oReader)); } } + XLS::BaseObjectPtr CPivotCacheRecord::toBin() + { + auto ptr(new XLSB::PIVOTCACHERECORD); + auto ptr1(new XLSB::PIVOTCACHERECORDDT); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_source = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + { + auto ptrPCDIDT(new XLSB::PCDIDT); + + auto boolValue = static_cast(i); + if(boolValue) + { + ptrPCDIDT->m_source = boolValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto dataValue = static_cast(i); + if(dataValue) + { + ptrPCDIDT->m_source = dataValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto errorValue = static_cast(i); + if(errorValue) + { + ptrPCDIDT->m_source = errorValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto noValue = static_cast(i); + if(noValue) + { + ptrPCDIDT->m_source = noValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto numValue = static_cast(i); + if(numValue) + { + ptrPCDIDT->m_source = numValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto charValue = static_cast(i); + if(charValue) + { + ptrPCDIDT->m_source = charValue->toBin(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + auto itemIndex = static_cast(i); + if(charValue) + { + ptrPCDIDT->m_source = itemIndex->toBinItemIndex(); + ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); + continue; + } + } + return objectPtr; + } void CPivotCacheRecord::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); From 7a198ac6db10309b47fcbeb1046f06a229ea9daa Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 25 Sep 2023 14:29:33 +0300 Subject: [PATCH 158/794] Fix paragpraph logic finally --- DocxRenderer/src/logic/Page.cpp | 55 +------------------ DocxRenderer/src/logic/elements/ContText.cpp | 50 +++++++---------- DocxRenderer/src/logic/elements/Converter.cpp | 1 + DocxRenderer/src/logic/elements/TextLine.cpp | 27 +++++++-- DocxRenderer/src/logic/elements/TextLine.h | 3 + 5 files changed, 51 insertions(+), 85 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index ac458e52858..61cd055e9de 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -991,7 +991,9 @@ namespace NSDocxRenderer drop_caps.push_back(drop_cap); drop_cap_cont->m_bIsNotNecessaryToUse = true; - drop_cap_line->RecalcSizes(); + drop_cap_line->CheckLineToNecessaryToUse(); + if(!drop_cap_line->m_bIsNotNecessaryToUse) + drop_cap_line->RecalcSizes(); } } @@ -1353,49 +1355,22 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arTextLine.size(); ++i) { auto pCurrLine = m_arTextLine[i]; - if (pCurrLine->m_bIsNotNecessaryToUse) - { continue; - } if (pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript) { auto pBaseLine = pCurrLine->m_pLine; if (pBaseLine) { - double dFontSize = 0; - - for (size_t j = 0; j < pBaseLine->m_arConts.size(); ++j) - { - auto pCont = pBaseLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) - { - continue; - } - dFontSize = pCont->m_pFontStyle->dFontSize; - break; - } - for (auto& pCont : pCurrLine->m_arConts) { - pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, - pCont->m_pFontStyle->wsFontName, - dFontSize, - pCont->m_pFontStyle->bItalic, - pCont->m_pFontStyle->bBold); - if (pBaseLine->m_dLeft > pCont->m_dLeft) - { pBaseLine->m_dLeft = pCont->m_dLeft; - } if (pBaseLine->m_dRight < pCont->m_dRight) - { pBaseLine->m_dRight = pCont->m_dRight; - } pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; - pBaseLine->m_arConts.push_back(pCont); pCont = nullptr; } @@ -1408,41 +1383,17 @@ namespace NSDocxRenderer auto pSubLine = pCurrLine->m_pLine; if (pSubLine) { - double dFontSize = 0; - - for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) - { - auto pCont = pCurrLine->m_arConts[j]; - if (pCont == nullptr || pCont->m_bIsNotNecessaryToUse || !pCont->m_pCont) - { - continue; - } - dFontSize = pCont->m_pFontStyle->dFontSize; - break; - } - for (auto& pCont : pSubLine->m_arConts) { if (pCont == nullptr) continue; - pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(pCont->m_pFontStyle->oBrush, - pCont->m_pFontStyle->wsFontName, - dFontSize, - pCont->m_pFontStyle->bItalic, - pCont->m_pFontStyle->bBold); - if (pCurrLine->m_dLeft > pCont->m_dLeft) - { pCurrLine->m_dLeft = pCont->m_dLeft; - } if (pCurrLine->m_dRight < pCont->m_dRight) - { pCurrLine->m_dRight = pCont->m_dRight; - } pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; - pCurrLine->m_arConts.push_back(pCont); pCont = nullptr; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index e7fbc57d9a8..7a29547f7df 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -79,27 +79,23 @@ namespace NSDocxRenderer if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - // нужно перемерять... - NSStructures::CFont oFont; - oFont.Name = m_pFontStyle->wsFontName; - oFont.Bold = m_pFontStyle->bBold; - oFont.Italic = m_pFontStyle->bItalic; - oFont.Size = m_pFontStyle->dFontSize; - m_pManager->LoadFontByName(oFont); - - double dBoxX; - double dBoxY; - double dBoxWidth; - double dBoxHeight; - - m_pManager->SetStringGid(0); - m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); - m_dWidthSelected = dBoxWidth; - m_dSpaceWidthSelected = m_pManager->GetSpaceWidthMM(); - } + // нужно перемерять... + NSStructures::CFont oFont; + oFont.Name = m_pFontStyle->wsFontName; + oFont.Bold = m_pFontStyle->bBold; + oFont.Italic = m_pFontStyle->bItalic; + oFont.Size = m_pFontStyle->dFontSize; + m_pManager->LoadFontByName(oFont); + + double dBoxX; + double dBoxY; + double dBoxWidth; + double dBoxHeight; + + m_pManager->SetStringGid(0); + m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); + m_dWidthSelected = dBoxWidth; + m_dSpaceWidthSelected = m_pManager->GetSpaceWidthMM(); } } @@ -149,15 +145,11 @@ namespace NSDocxRenderer if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { - if (m_eVertAlignType != eVertAlignType::vatSubscript && - m_eVertAlignType != eVertAlignType::vatSuperscript) - { - double dSpacing = (m_dWidth - m_dWidthSelected) / (m_oText.length()); - dSpacing *= c_dMMToDx; + double dSpacing = (m_dWidth - m_dWidthSelected) / (m_oText.length()); + dSpacing *= c_dMMToDx; - //mm to points * 20 - lCalculatedSpacing = static_cast(dSpacing); - } + //mm to points * 20 + lCalculatedSpacing = static_cast(dSpacing); } //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index a72b276d28e..d3caa1b7005 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -127,6 +127,7 @@ namespace NSDocxRenderer CBaseItem::SortByBaseline(rTextLines); + double avg_height = 0; size_t n = 0; diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 5c647026331..a67a072ce41 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -37,12 +37,9 @@ namespace NSDocxRenderer void CTextLine::CheckLineToNecessaryToUse() { for (size_t i = 0; i < m_arConts.size(); ++i) - { if (!m_arConts[i]->m_bIsNotNecessaryToUse) - { return; - } - } + m_bIsNotNecessaryToUse = true; } @@ -142,10 +139,14 @@ namespace NSDocxRenderer m_dHeight = 0.0; m_dBaselinePos = 0.0; m_dRight = 0.0; + m_dTrueHeight = 0.0; for(auto&& cont : m_arConts) if(!cont->m_bIsNotNecessaryToUse) + { + m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(cont)->m_dTrueHeight); CBaseItem::AddContent(cont); + } } void CTextLine::SetVertAlignType(const eVertAlignType& oType) @@ -203,4 +204,22 @@ namespace NSDocxRenderer pPrev->ToXml(oWriter); } + [[nodiscard]] eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + { + if(oSrc->m_eType != ElemType::etContText) + return CBaseItem::GetVerticalCrossingType(oSrc); + + auto m_dTop_copy = m_dTop; + auto m_dTop_copy_src = oSrc->m_dTop; + + m_dTop = m_dBaselinePos - m_dTrueHeight; + const_cast(oSrc)->m_dTop = oSrc->m_dBaselinePos - static_cast(oSrc)->m_dTrueHeight; + + auto vert_cross = CBaseItem::GetVerticalCrossingType(oSrc); + + m_dTop = m_dTop_copy; + const_cast(oSrc)->m_dTop = m_dTop_copy_src; + + return vert_cross; + } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 416e0a1d3d4..d3d247d6c90 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -1,5 +1,7 @@ #pragma once #include "ContText.h" +#include "BaseItem.h" + namespace NSDocxRenderer { @@ -29,6 +31,7 @@ namespace NSDocxRenderer virtual void Clear() override final; virtual void AddContent(CBaseItem* pObj) override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + [[nodiscard]] virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; void CheckLineToNecessaryToUse(); void MergeConts(); From 417267a96375dc64d312e0ca1ba8024b4d3a745e Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 25 Sep 2023 16:12:50 +0300 Subject: [PATCH 159/794] adding parsing of structures such as matrices, indexes --- .../StarMath2OOXML/cstarmathpars.cpp | 295 +++++++++++++++--- .../Converter/StarMath2OOXML/cstarmathpars.h | 78 ++++- .../Converter/StarMath2OOXML/typeselements.h | 100 +++++- 3 files changed, 420 insertions(+), 53 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index e4d6c1662cd..fd5de25f4ea 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -21,6 +21,29 @@ namespace StarMath m_arParsLine[i]->GetType(); } } +//Test version (works correctly only with operators, does not work correctly with attributes) + CElement* CStarMathPars::ReadWithoutBrackets(std::wstring::iterator &itFirst, std::wstring::iterator &itEnd,std::vector& arParsLine) + { + CElement* m_oOneElement = ParsElement(itFirst,itEnd,arParsLine); + if(m_oOneElement->GetType() != Bracket) + { + std::vector arTempValue; + arTempValue.push_back(m_oOneElement); + while(CheckingTheNextElement(itFirst,itEnd,CheckBinOperator)|| CheckingTheNextElement(itFirst,itEnd,CheckPlusOrMinus)||CheckingTheNextElement(itFirst,itEnd,CheckBinOperatorLowPriority)) + { + arTempValue.push_back(ParsElement(itFirst,itEnd,arTempValue)); + } + if(arTempValue.size()== 1) return m_oOneElement = arTempValue.back(); + else + { + CBracket* m_oBracket = new CBracket; + m_oBracket->SetBracketVal(arTempValue); + m_oBracket->SetTypeBracket(L"brace"); + return m_oBracket; + } + } + else return m_oOneElement; + } void CStarMathPars::Pars(std::wstring& wsStarMathLine) { @@ -44,11 +67,11 @@ namespace StarMath itFirst++; break; } - else if(!m_wsElement.empty() && (*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || (iswalpha(*itFirst) && iswdigit(m_wsElement.back())) || (iswdigit(*itFirst) && iswalpha(m_wsElement.back())))) + else if(!m_wsElement.empty() && (*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || (iswdigit(*itFirst) && !iswdigit(m_wsElement.back())) || (iswalpha(*itFirst) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *itFirst || L'>' == *itFirst || L'=' == *itFirst)))) { return m_wsElement; } - else if((*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst ) && m_wsElement.empty() ) + else if(((*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || L'=' == *itFirst ) && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *itFirst || L'<' == *itFirst || L'>' == *itFirst)) || (m_wsElement.back() == L'>' && (L'>' == *itFirst || L'=' == *itFirst)) ) ) ) { m_wsElement.push_back(*itFirst); itFirst++; @@ -79,14 +102,37 @@ namespace StarMath m_oCNumber->SetAttribute(m_oAttribute); return m_oCNumber; } - if(CheckSpecialCharacter(wsOneElement)) return new CSpecialCharacters(wsOneElement); + else if(CheckSpecialCharacter(wsOneElement) || CheckSpecialOperation(wsOneElement) || CheckSpecialConnection(wsOneElement)) return new CSpecialSymbol(wsOneElement); + else if(CheckFunction(wsOneElement)) + { + CFunction* m_oFunction = new CFunction; + m_oFunction->SetTypeFunction(wsOneElement); + if(L"ln" == wsOneElement) m_oFunction->SetArgument(ReadWithoutBrackets(itFirst,itEnd,arParsLine)); + else m_oFunction->SetArgument(ParsElement(itFirst,itEnd,arParsLine)); + m_oFunction->SetAttribute(m_oAttribute); + return m_oFunction; + } + else if(CheckIndex(wsOneElement)) + { + CIndex* m_oIndex = new CIndex(wsOneElement); + m_oIndex->SetArgument(arParsLine.back()); + m_oIndex->SetIndex(ParsElement(itFirst,itEnd,arParsLine)); + return m_oIndex; + } + else if(CheckMatrix(wsOneElement)) + { + CMatrix* m_oMatrix = new CMatrix(wsOneElement); + m_oMatrix->SetArgument(ParsElement(itFirst,itEnd,arParsLine)); + m_oMatrix->SetAttribute(m_oAttribute); + return m_oMatrix; + } else if(CheckBinOperator(wsOneElement) || CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) { if(!arParsLine.empty()) { CBinaryOperator* m_pBinOp = new CBinaryOperator(wsOneElement); CElement* m_oTempElement{ParsElement(itFirst,itEnd,arParsLine)}; - m_pBinOp->SetLeftArg(arParsLine.back()); + m_pBinOp->SetArgument(arParsLine.back()); arParsLine.pop_back(); if(((CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) && (CheckingTheNextElement(itFirst, itEnd,CheckBinOperator)||CheckingTheNextElement(itFirst, itEnd, CheckIndex))) || (CheckBinOperator(wsOneElement) && CheckingTheNextElement(itFirst, itEnd,CheckIndex))) { @@ -189,7 +235,7 @@ namespace StarMath } bool CStarMathPars::CheckBinOperator(const std::wstring &wsCheckToken) { - return(L"*" ==wsCheckToken || L"/" == wsCheckToken || wsCheckToken == L"over" || wsCheckToken == L"cdot" || wsCheckToken == L"times" || wsCheckToken == L"frac" || wsCheckToken == L"div" || wsCheckToken == L"odot" || wsCheckToken == L"otimes" || wsCheckToken == L"odivide" || wsCheckToken == L"wideslash" || wsCheckToken == L"widebslash"); + return(L"*" ==wsCheckToken || L"/" == wsCheckToken || wsCheckToken == L"over" || wsCheckToken == L"cdot" || wsCheckToken == L"times" || wsCheckToken == L"div" || wsCheckToken == L"odot" || wsCheckToken == L"otimes" || wsCheckToken == L"odivide" || wsCheckToken == L"wideslash" || wsCheckToken == L"widebslash"); } bool CStarMathPars::CheckBinOperatorLowPriority(const std::wstring &wsCheckToken) { @@ -213,7 +259,11 @@ namespace StarMath } bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken) { - return (wsCheckToken == L"from" || wsCheckToken == L"to" || wsCheckToken[0] == L'_' || wsCheckToken[0] == L'^' ); + return (wsCheckToken == L"_" || wsCheckToken == L"^" || L"lsup" == wsCheckToken || L"lsub" == wsCheckToken || L"csup" == wsCheckToken || L"csub" == wsCheckToken); + } + bool CStarMathPars::CheckIndexOp(const std::wstring &wsCheckToken) + { + return(L"from" == wsCheckToken || L"to" == wsCheckToken); } bool CStarMathPars::CheckBracketOpen(const std::wstring& wsCheckToken) { @@ -224,12 +274,6 @@ namespace StarMath return true; case '[': return true; - case '}': - return true; - case ')': - return true; - case ']': - return true; default: return false; } @@ -261,12 +305,32 @@ namespace StarMath } bool CStarMathPars::CheckSpecialCharacter(const std::wstring &wsCheckToken) { - return (L"mline" == wsCheckToken || L"grid" == wsCheckToken); + return (L"mline" == wsCheckToken || L"#" == wsCheckToken || L"##" == wsCheckToken); + } + bool CStarMathPars::CheckSpecialOperation(const std::wstring &wsCheckToken) + { + return(L"intersection" == wsCheckToken || L"union" == wsCheckToken || L"setminus" == wsCheckToken || L"setquoyient" == wsCheckToken || L"subseteq" == wsCheckToken || L"subset" == wsCheckToken || L"supset" == wsCheckToken || L"supseteq" == wsCheckToken || L"nsubset" == wsCheckToken || L"nsupseteq" == wsCheckToken || L"nsupset" == wsCheckToken || L"nsubseteq" == wsCheckToken || L"in" == wsCheckToken || L"notin" == wsCheckToken || L"owns" == wsCheckToken); + } + bool CStarMathPars::CheckSpecialConnection(const std::wstring &wsCheckToken) + { + return(L"approx" == wsCheckToken || L"sim" == wsCheckToken || L"simeq" == wsCheckToken || L"equiv" == wsCheckToken || L"prop" == wsCheckToken || L"parallel" == wsCheckToken || L"ortho" == wsCheckToken || L"divides" == wsCheckToken || L"ndivides" == wsCheckToken || L"toward" == wsCheckToken || L"transl" == wsCheckToken || L"transr" == wsCheckToken || L"def" == wsCheckToken || L"=" == wsCheckToken || L"<>" == wsCheckToken || L"<" == wsCheckToken || L"<=" == wsCheckToken || L"leslant" == wsCheckToken || L">" == wsCheckToken || L">=" == wsCheckToken || L"geslant" == wsCheckToken || L"<<" == wsCheckToken || L">>" == wsCheckToken || L"prec" == wsCheckToken || L"succ" == wsCheckToken || L"preccurlyeq" == wsCheckToken || L"succcurlyeq" == wsCheckToken || L"precsim" == wsCheckToken || L"succsim" == wsCheckToken || L"nprec" == wsCheckToken || L"nsucc" == wsCheckToken || L"dlarrow" == wsCheckToken || L"dlrarrow" == wsCheckToken || L"drarrow" == wsCheckToken); } std::vector CStarMathPars::GetVector() { return m_arParsLine; } + bool CStarMathPars::CheckFunction(const std::wstring &wsCheckToken) + { + return(L"sin" == wsCheckToken || L"cos" == wsCheckToken || L"ln" == wsCheckToken || L"tan" == wsCheckToken || L"cot" == wsCheckToken || L"sinh" == wsCheckToken || L"cosh" == wsCheckToken || L"tanh" == wsCheckToken || L"coth" == wsCheckToken || L"arcsin" == wsCheckToken || L"arccos" == wsCheckToken || L"arctan" == wsCheckToken || L"arccot" == wsCheckToken || L"arsinh" == wsCheckToken || L"arcosh" == wsCheckToken || L"artanh" == wsCheckToken || L"arcoth" == wsCheckToken || L"abs" == wsCheckToken || L"fact" == wsCheckToken || L"sqrt" == wsCheckToken || L"nroot" == wsCheckToken); + } + bool CStarMathPars::CheckOperation(const std::wstring &wsCheckToken) + { + return(L"intersection" == wsCheckToken || L"union" == wsCheckToken || L"setminus" == wsCheckToken || L"setquoytient" == wsCheckToken || L"subseteq" == wsCheckToken || L"subset" == wsCheckToken); + } + bool CStarMathPars::CheckMatrix(const std::wstring &wsCheckToken) + { + return (L"stack" == wsCheckToken || L"matrix" == wsCheckToken || L"binom" == wsCheckToken); + } //Class methods CNumber CNumber::CNumber() { @@ -309,7 +373,9 @@ namespace StarMath {} //Class methods CBinaryOperator CBinaryOperator::CBinaryOperator() - {} + { + oRightArg = nullptr; + } CBinaryOperator::CBinaryOperator(const std::wstring& wsToken) { if(wsToken == L"+") @@ -380,13 +446,11 @@ namespace StarMath { enTypeBinOp = widebslash; } - arLeftArg = nullptr; - arRightArg = nullptr; + oRightArg = nullptr; } CBinaryOperator::~CBinaryOperator() { - delete arLeftArg; - delete arRightArg; + delete oRightArg; } TypeElement CBinaryOperator::GetType() { @@ -400,29 +464,21 @@ namespace StarMath { return enTypeBinOp; } - void CBinaryOperator::SetLeftArg( CElement *oLeftArg) - { - this->arLeftArg = oLeftArg; - } - void CBinaryOperator::SetRightArg(CElement *oRightArg) + void CBinaryOperator::SetRightArg(CElement *oArgument) { - this->arRightArg = oRightArg; + oRightArg = oArgument; } void CBinaryOperator::SetTypeBin(const TypeBinOperator &enType) { this->enTypeBinOp = enType; } - CElement* CBinaryOperator::GetLeftArg() - { - return arLeftArg; - } CElement* CBinaryOperator::GetRightArg() { - return arRightArg; + return oRightArg; } TypeElement CBinaryOperator::GetTypeRight() { - return arRightArg->GetType(); + return oRightArg->GetType(); } //Class methods COperator COperator::COperator(): oFromValue(NULL),oToValue(NULL),oValueOp(NULL) @@ -551,7 +607,7 @@ namespace StarMath } void CBracket::SetTypeBracket(const std::wstring& wsCheckToken) { - if (L"{" == wsCheckToken) enTypeBracket =brace; + if (L"{" == wsCheckToken) enTypeBracket = brace; else if (L"(" == wsCheckToken) enTypeBracket = round; else if (L"[" == wsCheckToken) enTypeBracket = square; else if(wsCheckToken == L"ldbracket") @@ -782,20 +838,183 @@ namespace StarMath return oCAttribute->GetTypeAtt(); } //Class methods CSpecial - CSpecialCharacters::CSpecialCharacters(const std::wstring& wsToken) + CSpecialSymbol::CSpecialSymbol(const std::wstring& wsToken) { if(L"mline" == wsToken) enTypeSpecial = mline; - else if(L"grid" == wsToken) enTypeSpecial = grid; - } - CSpecialCharacters::~CSpecialCharacters() + else if(L"#" == wsToken) enTypeSpecial = grid; + else if(L"##" == wsToken) enTypeSpecial = dlgrid; + else if(L"intersection" == wsToken) enTypeSpecial = intersection; + else if(L"union" == wsToken) enTypeSpecial = Union; + else if(L"setminus" == wsToken) enTypeSpecial = setminus; + else if(L"setquoyient" == wsToken) enTypeSpecial = setquoyient; + else if(L"subseteg" == wsToken) enTypeSpecial = subseteq; + else if(L"subset" == wsToken) enTypeSpecial = subset; + else if(L"supset" == wsToken) enTypeSpecial = supset; + else if(L"supseteq" == wsToken) enTypeSpecial = supseteq; + else if(L"nsubset" == wsToken) enTypeSpecial = nsubset; + else if(L"nsubseteq" == wsToken) enTypeSpecial = nsubseteq; + else if(L"nsupseteq" == wsToken) enTypeSpecial = nsupseteq; + else if(L"nsupset" == wsToken) enTypeSpecial = nsupset; + else if(L"in" == wsToken) enTypeSpecial = in; + else if(L"notin" == wsToken) enTypeSpecial = notin; + else if(L"owns" == wsToken) enTypeSpecial = owns; + else if(L"approx" == wsToken) enTypeSpecial = approx; + else if(L"sim" == wsToken) enTypeSpecial = sim; + else if(L"simeq" == wsToken) enTypeSpecial = simeq; + else if(L"equiv" == wsToken) enTypeSpecial = equiv; + else if(L"prop" == wsToken) enTypeSpecial = prop; + else if(L"parallel" == wsToken) enTypeSpecial = parallel; + else if(L"ortho" == wsToken) enTypeSpecial = ortho; + else if(L"divides" == wsToken) enTypeSpecial = divides; + else if(L"ndivides" == wsToken) enTypeSpecial = ndivides; + else if(L"toward" == wsToken) enTypeSpecial = toward; + else if(L"transl" == wsToken) enTypeSpecial = transl; + else if(L"transr" == wsToken) enTypeSpecial = transr; + else if(L"def" == wsToken) enTypeSpecial = def; + else if(L"=" == wsToken) enTypeSpecial = equals; + else if(L"<>" == wsToken) enTypeSpecial = notequals; + else if(L"<" == wsToken) enTypeSpecial = learrow; + else if(L"<=" == wsToken) enTypeSpecial = learrowequals; + else if(L"leslant" == wsToken) enTypeSpecial = leslant; + else if(L">" == wsToken) enTypeSpecial = riarrow; + else if(L">=" == wsToken) enTypeSpecial = riarrowequals; + else if(L"geslant" == wsToken) enTypeSpecial = geslant; + else if(L"<<" == wsToken) enTypeSpecial = dllearrow; + else if(L">>" == wsToken) enTypeSpecial = dlriarrow; + else if(L"prec" == wsToken) enTypeSpecial = prec; + else if(L"succ" == wsToken) enTypeSpecial = succ; + else if(L"preccurlyeq" == wsToken) enTypeSpecial = preccurlyeq; + else if(L"succcurlyeq" == wsToken) enTypeSpecial = succcurlyeq; + else if(L"precsim" == wsToken) enTypeSpecial = precsim; + else if(L"succsim" == wsToken) enTypeSpecial = succsim; + else if(L"nprec" == wsToken) enTypeSpecial = nprec; + else if(L"nsucc" == wsToken) enTypeSpecial = nsucc; + else if(L"dlarrow" == wsToken) enTypeSpecial = dlarrow; + else if(L"dlrarrow" == wsToken) enTypeSpecial = dlrarrow; + else if(L"drarrow" == wsToken) enTypeSpecial = drarrow; + SetAttribute(nullptr); + } + CSpecialSymbol::~CSpecialSymbol() {} - std::wstring CSpecialCharacters::GetValue() + std::wstring CSpecialSymbol::GetValue() { return {}; } - TypeElement CSpecialCharacters::GetType() + TypeElement CSpecialSymbol::GetType() + { + return SpecialSymbol; + } +//class methods CFunction + CFunction::CFunction() + {} + CFunction::~CFunction() + { + } + std::wstring CFunction::GetValue() { - return SpecialCharacter; + return L""; } + TypeElement CFunction::GetType() + { + return Function; + } + TypeFunction CFunction::GetTypeFun() + { + return enTypeFun; + } + void CFunction::SetTypeFunction(const std::wstring &wsCheckToken) + { + if(L"sin" == wsCheckToken) enTypeFun = sin; + else if(L"abs" == wsCheckToken) enTypeFun = abs; + else if(L"fact" == wsCheckToken) enTypeFun = fact; + else if(L"sqrt" == wsCheckToken) enTypeFun = sqrt; + else if(L"cos" == wsCheckToken) enTypeFun = cos; + else if(L"tan" == wsCheckToken) enTypeFun = tan; + else if(L"cot" == wsCheckToken) enTypeFun = cot; + else if(L"sinh" == wsCheckToken) enTypeFun = sinh; + else if(L"cosh" == wsCheckToken) enTypeFun = cosh; + else if(L"tanh" == wsCheckToken) enTypeFun = tanh; + else if(L"coth" == wsCheckToken) enTypeFun = coth; + else if(L"arcsin" == wsCheckToken) enTypeFun = arcsin; + else if(L"arccos" == wsCheckToken) enTypeFun = arccos; + else if(L"arctan" == wsCheckToken) enTypeFun = arctan; + else if(L"arccot" == wsCheckToken) enTypeFun = arccot; + else if(L"arsinh" == wsCheckToken) enTypeFun = arsinh; + else if(L"arcosh" == wsCheckToken) enTypeFun = arcosh; + else if(L"artanh" == wsCheckToken) enTypeFun = artanh; + else if(L"arcoth" == wsCheckToken) enTypeFun = arcoth; + else if(L"ln" == wsCheckToken) enTypeFun = ln; + } +//class methods CArgumentContainer + CArgumentContainer::CArgumentContainer() + { + oArgument = nullptr; + } + CArgumentContainer::~CArgumentContainer() + { + delete oArgument; + } + std::wstring CArgumentContainer::GetValue() + { + return L""; + } + TypeElement CArgumentContainer::GetType() + { + return TwoArgumentContainer; + } + void CArgumentContainer::SetArgument(CElement *oValue) + { + oArgument = oValue; + } + CElement* CArgumentContainer::GetArgument() + { + return oArgument; + } +//class methods CIndex + CIndex::CIndex(const std::wstring& wsToken) + { + if(L"^" == wsToken) enTypeIn = upper; + else if(L"_" == wsToken) enTypeIn = lower; + else if(L"lsup" == wsToken) enTypeIn = lsup; + else if(L"lsub" == wsToken) enTypeIn = lsub; + else if(L"csup" == wsToken) enTypeIn = csup; + else if(L"csub" == wsToken) enTypeIn = csub; + SetAttribute(nullptr); + } + CIndex::~CIndex() + { + delete oIndex; + } + std::wstring CIndex::GetValue() + { + return {}; + } + TypeElement CIndex::GetType() + { + return Index; + } + void CIndex::SetIndex(CElement *oValueIndex) + { + oIndex = oValueIndex; + } +//class methods CMatrix + CMatrix::CMatrix(const std::wstring& wsToken) + { + if (L"binom" == wsToken) enTypeMatrix = binom; + else if(L"stack" == wsToken) enTypeMatrix = stack; + else if(L"matrix" == wsToken) enTypeMatrix = matrix; + } + CMatrix::~CMatrix() + {} + std::wstring CMatrix::GetValue() + { + return {}; + } + TypeElement CMatrix::GetType() + { + return Matrix; + } } + + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f7bf9b31f1d..1d594a53566 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -35,15 +35,15 @@ namespace StarMath private: CAttribute* oCAttribute; }; - class CSpecialCharacters: public CElement + class CSpecialSymbol: public CElement { public: - CSpecialCharacters(const std::wstring& wsToken); - virtual ~CSpecialCharacters(); + CSpecialSymbol(const std::wstring& wsToken); + virtual ~CSpecialSymbol(); std::wstring GetValue() override; TypeElement GetType() override; private: - TypeCharacter enTypeSpecial; + TypeSymbol enTypeSpecial; }; class CNumber: public CElement { @@ -69,7 +69,21 @@ namespace StarMath std::wstring m_wsUnar; TypeElement m_enUnarType = UnarSign; }; - class CBinaryOperator: public CElement + + class CArgumentContainer: public CElement + { + public: + CArgumentContainer(); + virtual ~CArgumentContainer(); + std::wstring GetValue() override; + TypeElement GetType() override; + void SetArgument(CElement* oValue); + CElement* GetArgument(); + private: + CElement* oArgument; + }; + + class CBinaryOperator: public CArgumentContainer { public: CBinaryOperator(); @@ -78,17 +92,13 @@ namespace StarMath std::wstring GetValue() override; TypeElement GetType() override; TypeBinOperator GetTypeBin(); + void SetRightArg(CElement* oArgument); void SetTypeBin(const TypeBinOperator& enType); - void SetLeftArg(CElement* oLeftArg); - void SetRightArg(CElement* oRightArg); - CElement* GetLeftArg(); CElement* GetRightArg(); TypeElement GetTypeRight(); - bool CheckBinOperator(const std::wstring& wsCheckToken); private: + CElement* oRightArg; TypeBinOperator enTypeBinOp; - CElement* arLeftArg; - CElement* arRightArg; }; class COperator: public CElement { @@ -128,6 +138,41 @@ namespace StarMath TypeBracket enTypeBracket; std::vector arBrecketVal; }; + class CFunction: public CArgumentContainer + { + public: + CFunction(); + virtual ~CFunction(); + std::wstring GetValue() override; + TypeElement GetType() override; + TypeFunction GetTypeFun(); + void SetTypeFunction(const std::wstring& wsCheckToken); + private: + TypeFunction enTypeFun; + }; + class CIndex: public CArgumentContainer + { + public: + CIndex(const std::wstring& wsToken); + virtual ~CIndex(); + std::wstring GetValue() override; + TypeElement GetType() override; + void SetIndex(CElement* oValueIndex); + CElement* GetIndex(); + private: + TypeIndex enTypeIn; + CElement* oIndex; + }; + class CMatrix: public CArgumentContainer + { + public: + CMatrix(const std::wstring& wsToken); + virtual ~CMatrix(); + std::wstring GetValue() override; + TypeElement GetType() override; + private: + TypeMatrix enTypeMatrix; + }; class CStarMathPars { public: @@ -137,13 +182,15 @@ namespace StarMath void Pars(std::wstring& wsStarMathLine); std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, std::vector& arParsLine); + CElement* ReadWithoutBrackets(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,std::vector& arParsLine); bool CheckDigit(const std::wstring& wsCheckToken); //bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); static bool CheckBinOperator(const std::wstring& wsCheckToken); - bool CheckBinOperatorLowPriority(const std::wstring& wsCheckToken); - bool CheckPlusOrMinus(const std::wstring& wsCheckToken); + static bool CheckBinOperatorLowPriority(const std::wstring& wsCheckToken); + static bool CheckPlusOrMinus(const std::wstring& wsCheckToken); bool CheckOperator(const std::wstring& wsCheckToken); static bool CheckIndex(const std::wstring& wsCheckToken); + bool CheckIndexOp(const std::wstring& wsCheckToken); bool CheckBracketOpen(const std::wstring& wsCheckToken); static bool CheckBracketClose(const std::wstring& wsCheckToken); static bool CheckScalable_NotScalableBracketLeft(const std::wstring& wsCheckToken); @@ -152,7 +199,12 @@ namespace StarMath bool CheckPropertiesAttribute(const std::wstring& wsCheckToken); static bool CheckColorAttribute(const std::wstring& wsCheckToken); bool CheckSpecialCharacter(const std::wstring& wsCheckToken); + bool CheckSpecialOperation(const std::wstring& wsCheckToken);//doing first + bool CheckSpecialConnection(const std::wstring& wsCheckToken);// doint first bool CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,bool (&func)(const std::wstring& wsCheckToken)); + bool CheckFunction(const std::wstring& wsCheckToken); + bool CheckOperation(const std::wstring& wsCheckToken); + bool CheckMatrix(const std::wstring& wsCheckToken); void PrintAr(); private: std::vector m_arParsLine; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index cd3023ee4ad..80e0cf70565 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -9,7 +9,12 @@ enum TypeElement{ Bracket, UnarSign, Attribute, - SpecialCharacter, + SpecialSymbol, + Function, + TwoArgumentContainer, + Operation, + Index, + Matrix, }; enum TypeBinOperator { @@ -96,10 +101,101 @@ enum TypeAttributeColor crimson, violet,//color(without rgb and hex) }; -enum TypeCharacter +enum TypeSymbol { mline, grid, + dlgrid, + intersection, + Union, + setminus, + setquoyient, + subseteq, + subset, + supset, + supseteq, + nsubset, + nsupseteq, + nsupset, + nsubseteq, + in, + notin, + owns, + approx, + sim, + simeq, + equiv, + prop, + parallel, + ortho, + divides, + ndivides, + toward, + transl, + transr, + def, + equals, + notequals, + learrow, + learrowequals, + leslant, + riarrow, + riarrowequals, + geslant, + dllearrow, + dlriarrow, + prec, + succ, + preccurlyeq, + succcurlyeq, + precsim, + succsim, + nprec, + nsucc, + dlarrow, + dlrarrow, + drarrow, +}; +enum TypeFunction +{ + abs, + fact, + sqrt, + nroot,//nroot? + sin, + cos, + tan, + cot, + sinh, + cosh, + tanh, + coth, + arcsin, + arccos, + arctan, + arccot, + arsinh, + arcosh, + artanh, + arcoth, + ln, + exp, + log, +}; +enum TypeIndex +{ + upper, + lower, + lsup, + lsub, + csup, + csub, +}; +enum TypeMatrix +{ + binom, + stack, + matrix, }; } #endif // TYPESELEMENTS_H From 23c93145b17a15ebb69c71a35703b8a519c7a581 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 28 Sep 2023 13:32:10 +0600 Subject: [PATCH 160/794] Fix pivot table stream writing --- OOXML/XlsbFormat/PivotTableStream.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsbFormat/PivotTableStream.cpp b/OOXML/XlsbFormat/PivotTableStream.cpp index 59a7b082e6c..98b716a6cee 100644 --- a/OOXML/XlsbFormat/PivotTableStream.cpp +++ b/OOXML/XlsbFormat/PivotTableStream.cpp @@ -74,7 +74,7 @@ BaseObjectPtr PivotTableStream::clone() } const bool PivotTableStream::loadContent(BinProcessor& proc) -{ +{ while (true) { CFRecordType::TypeId type = proc.getNextRecordType(); @@ -331,6 +331,7 @@ const bool PivotTableStream::saveContent(XLS::BinProcessor & proc) if (m_FRTSXVIEW != nullptr) proc.mandatory(*m_FRTSXVIEW); + proc.mandatory(); return true; } From 2193366443dda65f6fd67af9180cbb75ad01d153 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Sep 2023 20:12:31 +0600 Subject: [PATCH 161/794] Fix pivot tables conversion --- OOXML/XlsxFormat/Pivot/Pivots.cpp | 209 +++++++++++++++++++++---- OOXML/XlsxFormat/Workbook/Workbook.cpp | 3 +- 2 files changed, 177 insertions(+), 35 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 4e207bb88f4..0a54fce59b2 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -60,6 +60,7 @@ #include "../../XlsbFormat/Biff12_records/BeginSXLocation.h" #include "../../XlsbFormat/Biff12_unions/SXVDS.h" #include "../../XlsbFormat/Biff12_unions/SXVD.h" +#include "../../XlsbFormat/Biff12_records/BeginSXVDs.h" #include "../../XlsbFormat/Biff12_records/BeginSXVD.h" #include "../../XlsbFormat/Biff12_unions/SXVIS.h" #include "../../XlsbFormat/Biff12_unions/SXVI.h" @@ -77,7 +78,9 @@ #include "../../XlsbFormat/Biff12_records/BeginISXVDRws.h" #include "../../XlsbFormat/Biff12_records/BeginISXVDCols.h" #include "../../XlsbFormat/Biff12_unions/SXLIRWS.h" +#include "../../XlsbFormat/Biff12_records/BeginSXLIRws.h" #include "../../XlsbFormat/Biff12_unions/SXLICOLS.h" +#include "../../XlsbFormat/Biff12_records/BeginSXLICols.h" #include "../../XlsbFormat/Biff12_unions/SXLI.h" #include "../../XlsbFormat/Biff12_unions/ISXVIS.h" #include "../../XlsbFormat/Biff12_records/BeginSXLI.h" @@ -85,6 +88,7 @@ #include "../../XlsbFormat/Biff12_unions/SXDIS.h" #include "../../XlsbFormat/Biff12_unions/SXDI.h" #include "../../XlsbFormat/Biff12_records/BeginSXDI.h" +#include "../../XlsbFormat/Biff12_records/BeginSXDIs.h" #include "../../XlsbFormat/Biff12_unions/SXFORMATS.h" #include "../../XlsbFormat/Biff12_unions/SXFORMAT.h" #include "../../XlsbFormat/Biff12_records/BeginSXFormat.h" @@ -94,6 +98,7 @@ #include "../../XlsbFormat/Biff12_records/BeginSXPI.h" #include "../../XlsbFormat/Biff12_records/BeginPivotCacheDef.h" #include "../../XlsbFormat/Biff12_unions/PCDFIELDS.h" +#include "../../XlsbFormat/Biff12_records/BeginPCDFields.h" #include "../../XlsbFormat/Biff12_unions/PCDFIELD.h" #include "../../XlsbFormat/Biff12_records/BeginPCDField.h" #include "../../XlsbFormat/Biff12_unions/PCDFATBL.h" @@ -122,6 +127,9 @@ #include "../../XlsbFormat/Biff12_unions/PCDSCSET.h" #include "../../XlsbFormat/Biff12_records/BeginPCDSCSet.h" #include "../../XlsbFormat/Biff12_records/PCRRecord.h" +#include "../../XlsbFormat/Biff12_unions/FRTSXVIEW.h" +#include "../../XlsbFormat/Biff12_unions/SXVIEW14.h" +#include "../../XlsbFormat/Biff12_records/BeginSXView14.h" #include @@ -396,10 +404,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_ISXVDRWS = m_oRowFields->toBinRows(); if(m_oColFields.IsInit()) ptr->m_ISXVDCOLS = m_oColFields->toBinCols(); - if(m_oRowItems.IsInit()) - ptr->m_SXLIRWS = m_oRowItems->toBinRows(); - if(m_oColItems.IsInit()) - ptr->m_SXLICOLS = m_oColItems->toBinCols(); + if(m_oRowItems.IsInit()) + ptr->m_SXLIRWS = m_oRowItems->toBinRows(); + if(m_oColItems.IsInit()) + ptr->m_SXLICOLS = m_oColItems->toBinCols(); if(m_oDataFields.IsInit()) ptr->m_SXDIS = m_oDataFields->toBin(); @@ -410,6 +418,22 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oPageFields.IsInit()) ptr->m_SXPIS = m_oPageFields->toBin(); + /*auto frt(new XLSB::FRTSXVIEW); + auto sxview14(new XLSB::SXVIEW14); + auto beginsxview(new XLSB::BeginSXView14); + ptr->m_FRTSXVIEW = XLS::BaseObjectPtr{frt}; + frt->m_SXVIEW14 = XLS::BaseObjectPtr{sxview14}; + sxview14->m_BrtBeginSXView14 = XLS::BaseObjectPtr{beginsxview}; + beginsxview->fAutoApply = false; + beginsxview->fCalcMembersInAdvFilters = false; + beginsxview->fEnableWB = false; + beginsxview->fFillDownLabelsDefault = false; + beginsxview->fShowValuesRow = false; + beginsxview->sxma.value() = 0; + beginsxview->irstAltText = 0xFFFFFFFF; + beginsxview->irstAltTextSummary = 0xFFFFFFFF; + beginsxview->irstWeight = 0xFFFFFFFF;*/ + return objectPtr; } XLS::BaseObjectPtr CPivotTableDefinition::writeAttributes() @@ -417,8 +441,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr(new XLSB::BeginSXView); XLS::BaseObjectPtr objectPtr(ptr); - if (m_oApplyAlignmentFormats.IsInit()) - ptr->ibitAtrAlc = m_oApplyAlignmentFormats.get(); if (m_oApplyBorderFormats.IsInit()) ptr->ibitAtrBdr = m_oApplyBorderFormats.get(); if (m_oApplyFontFormats.IsInit()) @@ -434,14 +456,22 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oAsteriskTotals.IsInit()) ptr->fHideTotAnnotation = m_oAsteriskTotals.get(); + else + ptr->fHideTotAnnotation = false; if (m_oVisualTotals.IsInit()) ptr->fNotVisualTotals = m_oVisualTotals.get(); + else + ptr->fNotVisualTotals = false; if (m_oAutoFormatId.IsInit()) ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + else + ptr->itblAutoFmt = 0; if (m_oCacheId.IsInit()) ptr->idCache = m_oCacheId->GetValue(); if (m_oChartFormat.IsInit()) ptr->dwCrtFmtId = m_oChartFormat->GetValue(); + else + ptr->dwCrtFmtId = 0; if (m_oColGrandTotals.IsInit()) ptr->fColGrand = m_oColGrandTotals.get(); @@ -452,30 +482,42 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oCompactData.IsInit()) ptr->fCompactData = m_oCompactData.get(); if (m_oCreatedVersion.IsInit()) ptr->bVerSxMacro = m_oCreatedVersion->GetValue(); if (m_oCustomListSort.IsInit()) ptr->fDontUseCustomLists = !m_oCustomListSort.get(); + else ptr->fDontUseCustomLists = false; if (m_oDataCaption.IsInit()) ptr->irstData = m_oDataCaption.get(); else ptr->irstData = 0xFFFFFFFF; if (m_oDataOnRows.IsInit()) ptr->fDefaultCompact = m_oDataOnRows.get(); if (m_oDataPosition.IsInit()) ptr->ipos4Data = m_oDataPosition->GetValue(); + else ptr->ipos4Data = -1; if (m_oDisableFieldList.IsInit()) ptr->fDisableFList = m_oDisableFieldList.get(); + else ptr->fDisableFList = false; if (m_oEditData.IsInit()) ptr->fEnableDataEd = m_oEditData.get(); + else + ptr->fEnableDataEd = false; if (m_oEnableDrill.IsInit()) ptr->fEnableDrilldown = m_oEnableDrill.get(); if (m_oEnableFieldProperties.IsInit()) ptr->fEnableFieldDialog = m_oEnableFieldProperties.get(); if (m_oEnableWizard.IsInit()) ptr->fEnableWizard = m_oEnableWizard.get(); if (m_oErrorCaption.IsInit()) ptr->irstErrorString = m_oErrorCaption.get(); else + { ptr->fEmptyDisplayErrorString = true; + ptr->fDisplayErrorString = false; + } if (m_oFieldListSortAscending.IsInit()) ptr->fNonDefaultSortInFlist = m_oFieldListSortAscending.get(); + else ptr->fNonDefaultSortInFlist = false; if (m_oFieldPrintTitles.IsInit()) ptr->fPrintTitles = m_oFieldPrintTitles.get(); + else ptr->fPrintTitles = false; if (m_oGrandTotalCaption.IsInit()) ptr->irstGrand = m_oGrandTotalCaption.get(); else ptr->fDisplayGrand = false; if (m_oGridDropZones.IsInit()) ptr->fNewDropZones = !m_oGridDropZones.get(); if (m_oImmersive.IsInit()) ptr->fTurnOffImmersive = m_oImmersive.get(); + else ptr->fTurnOffImmersive = false; if (m_oIndent.IsInit()) ptr->cIndentInc = m_oIndent->GetValue(); if (m_oItemPrintTitles.IsInit()) ptr->fRepeatItemsOnEachPrintedPage = m_oItemPrintTitles.get(); if (m_oMdxSubqueries.IsInit()) ptr->fDefaultCompact = m_oMdxSubqueries.get(); if (m_oMergeItem.IsInit()) ptr->fMergeLabels = m_oMergeItem.get(); + else ptr->fMergeLabels = false; if (m_oMinRefreshableVersion.IsInit()) ptr->bVerSxUpdateableMin = m_oMinRefreshableVersion->GetValue(); if (m_oMissingCaption.IsInit()) ptr->irstNullString = m_oMissingCaption.get(); else @@ -487,6 +529,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oOutline.IsInit()) ptr->fDefaultOutline = m_oOutline.get(); if (m_oOutlineData.IsInit()) ptr->fOutlineData = m_oOutlineData.get(); if (m_oPageOverThenDown.IsInit()) ptr->fAcrossPageLay = m_oPageOverThenDown.get(); + else ptr->fAcrossPageLay = false; if (m_oPageStyle.IsInit()) ptr->irstPageFieldStyle = m_oPageStyle.get(); else ptr->fDisplayPageFieldStyle = false; @@ -496,25 +539,36 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->fDisplayTableStyle = false; if (m_oPreserveFormatting.IsInit()) ptr->fPreserveFormatting = m_oPreserveFormatting.get(); if (m_oPrintDrill.IsInit()) ptr->fPrintDrillIndicators = m_oPrintDrill.get(); + else ptr->fPrintDrillIndicators = false; if (m_oPublished.IsInit()) ptr->fPublished = m_oPublished.get(); + else ptr->fPublished = false; if (m_oRowGrandTotals.IsInit()) ptr->fRwGrand = m_oRowGrandTotals.get(); if (m_oRowHeaderCaption.IsInit()) ptr->irstRwHdrName = m_oRowHeaderCaption.get(); else ptr->fUseRwHdrName = false; if (m_oShowCalcMbrs.IsInit()) ptr->fNotViewCalculatedMembers = !m_oShowCalcMbrs.get(); + else ptr->fNotViewCalculatedMembers = false; if (m_oShowDataDropDown.IsInit()) ptr->fHideDDData = !m_oShowDataDropDown.get(); + else ptr->fHideDDData = false; if (m_oShowDataTips.IsInit()) ptr->fNoPivotTips = !m_oShowDataTips.get(); + else ptr->fNoPivotTips = false; if (m_oShowDrill.IsInit()) ptr->fHideDrillIndicators = !m_oShowDrill.get(); + else ptr->fHideDrillIndicators = false; if (m_oShowDropZones.IsInit()) ptr->fNoStencil = !m_oShowDropZones.get(); + else ptr->fNoStencil = false; if (m_oShowEmptyCol.IsInit()) ptr->fIncludeEmptyCol = m_oShowEmptyCol.get(); + else ptr->fIncludeEmptyCol = false; if (m_oShowEmptyRow.IsInit()) ptr->fIncludeEmptyRw = m_oShowEmptyRow.get(); + else ptr->fIncludeEmptyRw = false; if (m_oShowError.IsInit()) ptr->fDisplayErrorString = m_oShowError.get(); if (m_oShowHeaders.IsInit()) ptr->fNoHeaders = !m_oShowHeaders.get(); + else ptr->fNoHeaders = false; if (m_oShowItems.IsInit()) ptr->fDisplayImmediateItems = m_oShowItems.get(); if (m_oShowMemberPropertyTips.IsInit()) ptr->fMemPropsInTips = m_oShowMemberPropertyTips.get(); if (m_oShowMissing.IsInit()) ptr->fDisplayNullString = m_oShowMissing.get(); if (m_oShowMultipleLabel.IsInit()) ptr->fPageMultipleItemLabel = m_oShowMultipleLabel.get(); if (m_oSubtotalHiddenItems.IsInit()) ptr->fSubtotalHiddenPageItems = m_oSubtotalHiddenItems.get(); + else ptr->fSubtotalHiddenPageItems = false; if (m_oTag.IsInit()) ptr->irstTag = m_oTag.get(); else ptr->fDisplayTag = false; @@ -563,8 +617,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->m_SXPIS != nullptr) m_oPageFields = ptr->m_SXPIS; - - + if(ptr->m_FRTSXVIEW) + { + auto result = static_cast(ptr->m_FRTSXVIEW.get()); + auto result2 = static_cast(result->m_SXVIEW14.get()); + auto result3 = static_cast(result2->m_BrtBeginSXView14.get()); + auto result4 = result3; + } } } void CPivotTableDefinition::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -926,6 +985,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_BrtBeginISXVDRws = XLS::BaseObjectPtr{ptr1}; if(m_oCount.IsInit()) ptr1->cisxvd = m_oCount->GetValue(); + else + ptr1->cisxvd = m_arrItems.size(); for(auto i:m_arrItems) ptr1->rgisxvdrws.push_back(i->m_oX.get()); return objectPtr; @@ -938,6 +999,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_BrtBeginISXVDCols = XLS::BaseObjectPtr{ptr1}; if(m_oCount.IsInit()) ptr1->cisxvd = m_oCount->GetValue(); + else + ptr1->cisxvd = m_arrItems.size(); for(auto i:m_arrItems) ptr1->rgisxvdcols.push_back(i->m_oX.get()); return objectPtr; @@ -990,6 +1053,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CColumnRowItems::toBinRows() { auto ptr(new XLSB::SXLIRWS); + auto ptr1(new XLSB::BeginSXLIRws); + ptr1->csxlis = m_arrItems.size(); + ptr->m_BrtBeginSXLIRws = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arSXLI.push_back(i->toBin()); @@ -998,6 +1064,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CColumnRowItems::toBinCols() { auto ptr(new XLSB::SXLICOLS); + auto ptr1(new XLSB::BeginSXLICols); + ptr1->csxlis = m_arrItems.size(); + ptr->m_BrtBeginSXLICols = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arSXLI.push_back(i->toBin()); @@ -1067,13 +1136,27 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CColumnRowItem::toBin() { auto ptr(new XLSB::SXLI); + auto size = 0; + + for(auto i:m_arrItems) + { + if(i->m_oV.IsInit()) + size++; + + } + XLS::BaseObjectPtr objectPtr(ptr); auto ptr1(new XLSB::BeginSXLI); + ptr1->cisxvis = size; ptr->m_BrtBeginSXLI = XLS::BaseObjectPtr{ptr1}; if(m_oI.IsInit()) ptr1->iData = m_oI->GetValue(); + else + ptr1->iData = 0; if(m_oR.IsInit()) ptr1->cSic = m_oR->GetValue(); + else + ptr1->cSic = 0; if(m_oT.IsInit()) { if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeData) @@ -1107,17 +1190,24 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) ptr1->itmtype = XLSB::PivotItemType::PITBLANK; } - if(m_arrItems.empty()) - return objectPtr; + else + { + ptr1->itmtype = XLSB::PivotItemType::PITDATA; + } + + auto ptr2(new XLSB::ISXVIS(size)); + ptr2->_cisxvis = size; - auto ptr2(new XLSB::ISXVIS(m_arrItems.size())); ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; - auto ptr3(new XLSB::BeginISXVIs(m_arrItems.size())); + auto ptr3(new XLSB::BeginISXVIs(size)); + ptr3->_cisxvis = size; ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; for(auto i:m_arrItems) if(i->m_oV.IsInit()) ptr3->rgisxvis.push_back(i->m_oV->GetValue()); + else + ptr3->rgisxvis.push_back(0); return objectPtr; } void CColumnRowItem::fromBin(XLS::BaseObjectPtr& obj) @@ -1270,6 +1360,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CDataFields::toBin() { auto ptr(new XLSB::SXDIS); + auto ptr1(new XLSB::BeginSXDIs); + ptr->m_BrtBeginSXDIs = XLS::BaseObjectPtr{ptr1}; + ptr1->csxdis = m_arrItems.size(); XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arSXDI.push_back(i->toBin()); @@ -1325,6 +1418,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->isxvdData = m_oFld->GetValue(); if(m_oNumFmtId.IsInit()) ptr->ifmt.ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt.ifmt = 0; if(m_oName.IsInit()) { ptr->stDisplayName = m_oName.get(); @@ -1353,6 +1448,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsRunTotal) ptr->df = XLSB::ShowDataAs::PERCENTOFRUNTOTAL; } + else + { + ptr->df = XLSB::ShowDataAs::NORMAL; + } if(m_oSubtotal.IsInit()) { if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionSum) @@ -1378,6 +1477,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionVarP) ptr->iiftab = XLSB::DataConsolidationFunction::STDVARP; } + else + { + ptr->iiftab = XLSB::DataConsolidationFunction::SUM; + } return objectPtr; } void CDataField::fromBin(XLS::BaseObjectPtr& obj) @@ -1963,6 +2066,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CPivotFields::toBin() { auto ptr(new XLSB::SXVDS); + auto ptr1(new XLSB::BeginSXVDs); + ptr1->csxvds = m_arrItems.size(); + ptr->m_BrtBeginSXVDs = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arSXVD.push_back(i->toBin()); @@ -2140,6 +2246,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oItemPageCount.IsInit()) ptr->citmAutoShow = m_oItemPageCount->GetValue(); + else + ptr->citmAutoShow = 0; if(m_oMaxSubtotal.IsInit()) ptr->fMax = m_oMaxSubtotal.get(); @@ -2164,6 +2272,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oNumFmtId.IsInit()) ptr->ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt = 0; if (m_oOutline.IsInit()) ptr->fOutline = m_oOutline.get(); @@ -2173,6 +2283,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oRankBy.IsInit()) ptr->isxdiAutoShow = m_oRankBy->GetValue(); + else + ptr->isxdiAutoShow = 0; if (m_oServerField.IsInit()) ptr->fServerBased = m_oServerField.get(); @@ -3118,6 +3230,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oColPageCount.IsInit()) ptr->ccolPage = m_oColPageCount->GetValue(); + else + ptr->ccolPage = 0; if(m_oFirstDataCol.IsInit()) ptr->colFirstData = m_oFirstDataCol->GetValue(); if(m_oFirstDataRow.IsInit()) @@ -3126,6 +3240,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->rwFirstHead = m_oFirstHeaderRow->GetValue(); if(m_oRowPageCount.IsInit()) ptr->crwPage = m_oRowPageCount->GetValue(); + else + ptr->crwPage = 0; if(m_oRef.IsInit()) ptr->rfxGeom = m_oRef.get(); return objectPtr; @@ -3184,13 +3300,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oShowRowHeaders.IsInit()) ptr->fRowHeaders = m_oShowRowHeaders.get(); if(m_oShowColStripes.IsInit()) - ptr->fRowStripes = m_oShowColStripes.get(); + ptr->fColumnStripes = m_oShowColStripes.get(); + else + ptr->fColumnStripes = false; + if(m_oShowRowStripes.IsInit()) + ptr->fRowStripes = m_oShowRowStripes.get(); + else + ptr->fRowStripes = false; if(m_oShowLastColumn.IsInit()) ptr->fLastColumn = m_oShowLastColumn.get(); if(m_oName.IsInit()) ptr->stStyleName = m_oName.get(); else ptr->stStyleName = 0xFFFFFFFF; + return objectPtr; } void CPivotTableStyleInfo::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) @@ -3373,6 +3496,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr); if (m_oBackgroundQuery.IsInit()) ptr->fBackgroundQuery = m_oBackgroundQuery.get(); + else + ptr->fBackgroundQuery = false; if (m_oEnableRefresh.IsInit()) ptr->fEnableRefresh = !m_oEnableRefresh.get(); @@ -3384,6 +3509,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oInvalid.IsInit()) ptr->fInvalid = m_oInvalid.get(); + else + ptr->fInvalid = false; if (m_oCreatedVersion.IsInit()) ptr->bVerCacheCreated = m_oCreatedVersion->GetValue(); @@ -3393,9 +3520,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oMissingItemsLimit.IsInit()) ptr->citmGhostMax = m_oMissingItemsLimit->GetValue(); + else + ptr->citmGhostMax = -1; if (m_oOptimizeMemory.IsInit()) ptr->fOptimizeCache = m_oOptimizeMemory.get(); + else + ptr->fOptimizeCache = false; if (m_oRecordCount.IsInit()) ptr->cRecords = m_oRecordCount->GetValue(); @@ -3403,7 +3534,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oRefreshedBy.IsInit()) ptr->stRefreshedWho = m_oRefreshedBy.get(); else - ptr->fLoadRefreshedWho = false; + ptr->stRefreshedWho = L"Aspose"; if (m_oRefreshedDateIso.IsInit()) ptr->xnumRefreshedDate.data.value = std::stod(m_oRefreshedDateIso->GetValue()); @@ -3413,21 +3544,31 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oRefreshOnLoad.IsInit()) ptr->fRefreshOnLoad = m_oRefreshOnLoad.get(); + else + ptr->fRefreshOnLoad = false; if (m_oSaveData.IsInit()) ptr->fSaveData = m_oSaveData.get(); if (m_oSupportAdvancedDrill.IsInit()) ptr->fSupportAttribDrill = m_oSupportAdvancedDrill.get(); + else + ptr->fSupportAttribDrill = false; if (m_oSupportSubquery.IsInit()) ptr->fSupportSubquery = m_oSupportSubquery.get(); + else + ptr->fSupportSubquery = false; if (m_oTupleCache.IsInit()) ptr->fSheetData = m_oTupleCache.get(); + else + ptr->fSheetData = false; if (m_oUpgradeOnRefresh.IsInit()) ptr->fUpgradeOnRefresh = m_oUpgradeOnRefresh.get(); + else + ptr->fUpgradeOnRefresh = false; return objectPtr; } @@ -3560,7 +3701,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( L"cacheFields" == sName ) + if ( L"cacheField" == sName ) { CPivotCacheField* pPivotCacheField = new CPivotCacheField(); *pPivotCacheField = oReader; @@ -3572,6 +3713,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptr(new XLSB::PCDFIELDS); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCDFields); + ptr1->cFields = m_arrItems.size(); + ptr->m_BrtBeginPCDFields = XLS::BaseObjectPtr{ptr1}; for(auto i:m_arrItems) ptr->m_arPCDFIELD.push_back(i->toBin()); return objectPtr; @@ -3667,29 +3811,39 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr(new XLSB::BeginPCDField); XLS::BaseObjectPtr objectPtr(ptr); - if (m_oName.IsInit()) - ptr->stFldName.value() = m_oName.get(); + if (m_oName.IsInit()) + ptr->stFldName = m_oName.get(); if (m_oCaption.IsInit()) - ptr->stFldCaption.value() = m_oCaption.get(); + ptr->stFldCaption = m_oCaption.get(); + else + ptr->fCaption = false; if (m_oDatabaseField.IsInit()) ptr->fSrcField = m_oDatabaseField.get(); + else + ptr->fSrcField = false; if (m_oServerField.IsInit()) ptr->fServerBased = m_oServerField.get(); if (m_oFormula.IsInit()) ptr->fldFmla = m_oFormula.get(); + else + ptr->fLoadFmla = false; if (m_oHierarchy.IsInit()) ptr->ihdb = m_oHierarchy.get(); if (m_oMemberPropertyField.IsInit()) ptr->fOlapMemPropField = m_oMemberPropertyField.get(); + else + ptr->fOlapMemPropField = false; if (m_oPropertyName.IsInit()) ptr->stMemPropName.value() = m_oPropertyName.get(); + else + ptr->fLoadPropName = false; if (m_oSqlType.IsInit()) ptr->wTypeSql = m_oSqlType.get(); @@ -6283,22 +6437,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } std::wstring CPivotCacheRecordsFile::prepareData() const { - std::vector dataChars; - std::string rawStringData{reinterpret_cast(m_pData)}; - //std::string stringData(reinterpret_cast(m_pData)); - std::wstring_convert> converter; - std::wstring result; - for (char i : rawStringData) - { - try { - // Попытка конвертировать каждый символ - result += converter.from_bytes(std::string(1, i)); - } catch (const std::range_error&) { - // Пропускаем невалидные символы - } - } - return result; + std::string stringData(reinterpret_cast(m_pData), m_nDataLength); + std::wstring_convert> converter; + + return converter.from_bytes(stringData); } //------------------------------------ void CPivotCacheRecords::toXML(NSStringUtils::CStringBuilder& writer) const diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 7ff74a97123..5354977701e 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -157,13 +157,12 @@ namespace OOX { if (oReader.IsEmptyNode()) return; - int nCurDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth)) { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if (L"pivotCaches" == sName) + if (L"pivotCache" == sName) { CWorkbookPivotCache *pPivotCache = new CWorkbookPivotCache(); m_arrItems.push_back(pPivotCache); From 004af5b9cc9893c2818fc1dffadc64d964d8516b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Sep 2023 21:04:18 +0600 Subject: [PATCH 162/794] add default column width --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 1c5044c963a..c0af3506880 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -951,6 +951,8 @@ namespace OOX XLS::BaseObjectPtr Castedptr(ptr); if(m_oBaseColWidth.IsInit()) ptr->dxGCol = m_oBaseColWidth.get() * 256.; + else + ptr->dxGCol = 2304; if(m_oDefaultColWidth.IsInit()) { ptr->cchDefColWidth = m_oDefaultColWidth.get(); @@ -959,6 +961,10 @@ namespace OOX ptr->dxGCol = m_oDefaultColWidth.get() * 256; } } + else + { + ptr->cchDefColWidth = 9; + } if (m_oDefaultRowHeight.IsInit()) ptr->miyDefRwHeight = m_oDefaultRowHeight.get() * 20; else From 7ed274c3e9e23addf74d755d51ceaab97be3f51c Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 2 Oct 2023 16:16:35 +0300 Subject: [PATCH 163/794] Fix lines below text & size of super/sub script --- DocxRenderer/src/logic/Page.cpp | 2 +- DocxRenderer/src/logic/elements/ContText.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 61cd055e9de..cfc9fce688b 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1234,7 +1234,7 @@ namespace NSDocxRenderer pShape->m_eLineType != eLineType::ltUnknown; //Условие по вертикали - bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.15; + bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.3; //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 7a29547f7df..80e0ba48315 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -225,14 +225,19 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); } - if (m_eVertAlignType == eVertAlignType::vatSubscript) + if(m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) { - oWriter.WriteString(L""); + int lSize = static_cast(3.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); } + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L""); else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { oWriter.WriteString(L""); - } oWriter.WriteString(L""); From 416ef9c03c2994ec0b792dae5bbafe028836fbfa Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 2 Oct 2023 20:57:53 +0600 Subject: [PATCH 164/794] Add table slicer conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 5 +- OOXML/XlsxFormat/Slicer/Slicer.cpp | 5 +- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 59 +++++++++++++++++++--- OOXML/XlsxFormat/Slicer/SlicerCacheExt.h | 4 ++ 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 1b6855a8344..7f4194e949e 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -654,7 +654,7 @@ namespace OOX if(i->m_sUri == L"{46BE6895-7355-4a93-B00E-2C351335B9C9}") { - ptr->m_TABLESLICERCACHEIDS = i->m_oSlicerCachesExt->toBin(); + ptr->m_TABLESLICERCACHEIDS = i->m_oSlicerCachesExt->toBinTable(); } else if(i->m_sUri == L"{BBE1A952-AA13-448e-AADC-164F8A28A991}") { @@ -795,7 +795,7 @@ namespace OOX else if(i->m_sUri == L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}") { if(i->m_oSlicerListExt.IsInit()) - ptr->m_SLICERSEX = i->m_oSlicerListExt->toBin(); + ptr->m_TABLESLICERSEX = i->m_oSlicerListExt->toBinTable(); } } return objectPtr; @@ -813,6 +813,7 @@ namespace OOX OOX::Drawing::COfficeArtExtension *oExt = new OOX::Drawing::COfficeArtExtension(); oExt->m_sUri = L"{46BE6895-7355-4a93-B00E-2C351335B9C9}"; oExt->m_oSlicerCachesExt = ptr->m_TABLESLICERCACHEIDS; + oExt->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; if (oExt) m_arrExt.push_back( oExt ); diff --git a/OOXML/XlsxFormat/Slicer/Slicer.cpp b/OOXML/XlsxFormat/Slicer/Slicer.cpp index a187f302c69..54bc570237a 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.cpp +++ b/OOXML/XlsxFormat/Slicer/Slicer.cpp @@ -200,13 +200,12 @@ XLS::BaseObjectPtr CSlicer::toBin() if(m_oRowHeight.IsInit()) ptr->dxRowHeight = m_oRowHeight.get(); - if(m_oName.IsInit()) + if(m_oName.IsInit()) ptr->stName = m_oName.get(); else if(m_oUid.IsInit()) ptr->stName = m_oUid.get(); else - ptr->stName = 0xFFFFFFFF; - + ptr->stName = 0xFFFFFFFF; if(m_oCache.IsInit()) ptr->stSlicerCacheName = m_oCache.get(); else diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 46faf77b862..c23219d961f 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -47,6 +47,9 @@ #include "../../XlsbFormat/Biff12_unions/SLICERCACHEIDS.h" #include "../../XlsbFormat/Biff12_unions/SLICERCACHEID.h" #include "../../XlsbFormat/Biff12_records/BeginSlicerCacheID.h" +#include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEIDS.h" +#include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEID.h" +#include "../../XlsbFormat/Biff12_records/TableSlicerCacheID.h" #include "../../Binary/Presentation/XmlWriter.h" #include "../../Binary/Presentation/BinReaderWriterDefines.h" @@ -574,6 +577,18 @@ XLS::BaseObjectPtr CSlicerCache::toBin() } return objectPtr; } +XLS::BaseObjectPtr CSlicerCache::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERCACHEID); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oRId.IsInit()) + { + auto ptr1(new XLSB::TableSlicerCacheID); + ptr->m_BrtTableSlicerCacheID = XLS::BaseObjectPtr{ptr1}; + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + } + return objectPtr; +} void CSlicerCache::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -623,13 +638,23 @@ void CSlicerCache::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) } XLS::BaseObjectPtr CSlicerRef::toBin() { - auto ptr(new XLSB::SLICEREX); - XLS::BaseObjectPtr objectPtr(ptr); - auto ptr1(new XLSB::BeginSlicerEx); - ptr1->FRTheader.relID.relId = m_oRId->GetValue(); - ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; + auto ptr(new XLSB::SLICEREX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerEx); + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; + + return objectPtr; +} +XLS::BaseObjectPtr CSlicerRef::toBinTable() +{ + auto ptr(new XLSB::TABLESLICEREX); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSlicerEx); + ptr1->FRTheader.relID.relId = m_oRId->GetValue(); + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; - return objectPtr; + return objectPtr; } void CSlicerRef::fromBin(XLS::BaseObjectPtr &obj) { @@ -844,6 +869,17 @@ XLS::BaseObjectPtr CSlicerCaches::toBin() return objectPtr; } +XLS::BaseObjectPtr CSlicerCaches::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERCACHEIDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_oSlicerCache) + { + ptr->m_arTABLESLICERCACHEID.push_back(i.toBinTable()); + } + return objectPtr; +} + void CSlicerCaches::fromBin(XLS::BaseObjectPtr &obj) { auto ptr = static_cast(obj.get()); @@ -908,6 +944,17 @@ XLS::BaseObjectPtr CSlicerRefs::toBin() } return objectPtr; } +XLS::BaseObjectPtr CSlicerRefs::toBinTable() +{ + auto ptr(new XLSB::TABLESLICERSEX); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_oSlicer) + { + ptr->m_arTABLESLICEREX.push_back(i.toBinTable()); + } + return objectPtr; +} void CSlicerRefs::fromBin(XLS::BaseObjectPtr &obj) { if(obj->get_type() == XLS::typeSLICERSEX) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h index a56af42276d..e2992f220c3 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.h @@ -186,6 +186,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -212,6 +213,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; @@ -265,6 +267,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer, const std::wstring& sName, const std::wstring& sPrefix) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void fromBin(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -290,6 +293,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinTable(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); virtual EElementType getType() const { From dd0ede140549c7f23e15e5d84db453a68e7fcd06 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 4 Oct 2023 19:20:42 +0300 Subject: [PATCH 165/794] Remove nodiscard --- DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/logic/elements/ContText.h | 2 +- DocxRenderer/src/logic/elements/TextLine.cpp | 2 +- DocxRenderer/src/logic/elements/TextLine.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 80e0ba48315..4feb830e3fb 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -99,7 +99,7 @@ namespace NSDocxRenderer } } - [[nodiscard]] eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept { if(oSrc->m_eType != ElemType::etContText) return CBaseItem::GetVerticalCrossingType(oSrc); diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 0f1346f3c31..fa27923c124 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -64,7 +64,7 @@ namespace NSDocxRenderer virtual void AddContent(CBaseItem* pObj) override final {}; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - [[nodiscard]] virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; CContText& operator= (const CContText& rCont); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index a67a072ce41..d8e39d0e4ce 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -204,7 +204,7 @@ namespace NSDocxRenderer pPrev->ToXml(oWriter); } - [[nodiscard]] eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept { if(oSrc->m_eType != ElemType::etContText) return CBaseItem::GetVerticalCrossingType(oSrc); diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index d3d247d6c90..ca023f4fff5 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -31,7 +31,7 @@ namespace NSDocxRenderer virtual void Clear() override final; virtual void AddContent(CBaseItem* pObj) override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - [[nodiscard]] virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; void CheckLineToNecessaryToUse(); void MergeConts(); From dc09bd4e0137518de8fd15fd360660b906ecb9cd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 11 Oct 2023 19:30:01 +0600 Subject: [PATCH 166/794] Add external links binary writing --- .../ExternalLinks/ExternalLinks.cpp | 19 ++++++++++++++++--- .../XlsxFormat/ExternalLinks/ExternalLinks.h | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index 12dccca9c1c..e7e4f7c4a83 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -65,7 +65,7 @@ #include "../../XlsbFormat/Biff12_records/SupName.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" - +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include namespace OOX @@ -1685,7 +1685,7 @@ namespace Spreadsheet CExternalLink::~CExternalLink() { } - XLS::BaseObjectPtr CExternalLink::writeBin() + XLS::BaseObjectPtr CExternalLink::writeBin() const { XLSB::ExternalLinkStreamPtr externalLinkStreamStream(new XLSB::ExternalLinkStream); @@ -1812,6 +1812,14 @@ namespace Spreadsheet } void CExternalLink::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = writeBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L""); sXml.WriteString(L"(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::ExternalLinksBin; + } return OOX::Spreadsheet::FileTypes::ExternalLinks; } const CPath CExternalLink::DefaultDirectory() const diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index 355359effe6..cfb69a2ac57 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -464,7 +464,7 @@ namespace OOX CExternalLink(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath, const std::wstring & rId); virtual ~CExternalLink(); - XLS::BaseObjectPtr writeBin(); + XLS::BaseObjectPtr writeBin() const; void readBin(const CPath& oPath); virtual void read(const CPath& oPath); From 832a57bed10c8844e86456cb28a5118d06a27f58 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 13 Oct 2023 20:47:35 +0600 Subject: [PATCH 167/794] Add comments conversion --- OOXML/XlsxFormat/Comments/Comments.h | 4 + OOXML/XlsxFormat/Comments/XlsxComments.cpp | 91 +++++++++++++++++++++- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 4 +- 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Comments/Comments.h b/OOXML/XlsxFormat/Comments/Comments.h index 4aa90a91a72..679287e201d 100644 --- a/OOXML/XlsxFormat/Comments/Comments.h +++ b/OOXML/XlsxFormat/Comments/Comments.h @@ -88,6 +88,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -112,6 +113,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -141,6 +143,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -156,6 +159,7 @@ namespace OOX virtual ~CComments(); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index babca8545ed..9a3682e79c7 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -49,6 +49,8 @@ #include "../SharedStrings/Si.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -122,6 +124,18 @@ namespace OOX } } } + XLS::BaseObjectPtr CAuthors::toBin() + { + auto ptr(new XLSB::COMMENTAUTHORS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + auto author(new XLSB::CommentAuthor); + author->author = i; + ptr->m_arBrtCommentAuthor.push_back(XLS::BaseObjectPtr{author}); + } + return objectPtr; + } EElementType CAuthors::getType () const { return et_x_Authors; @@ -194,6 +208,46 @@ namespace OOX } } } + XLS::BaseObjectPtr CComment::toBin() + { + auto ptr(new XLSB::COMMENT); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginComment); + ptr->m_BrtBeginComment = XLS::BaseObjectPtr{ptr1}; + + if(m_oRef.IsInit()) + ptr1->rfx = m_oRef->GetValue(); + if(m_oAuthorId.IsInit()) + ptr1->iauthor = m_oAuthorId->GetValue(); + if(m_oUid.IsInit()) + ptr1->guid = m_oUid->ToString(); + if(m_oText.IsInit()) + { + auto type = m_oText->getType(); + auto text(new XLSB::CommentText); + if(type == OOX::et_x_Si) + { + text->text.fExtStr = false; + text->text.fRichStr = false; + text->text.str = m_oText->ToString(); + } + else if(type == OOX::et_x_rPh) + { + text->text.fExtStr = true; + text->text.fRichStr = false; + text->text.phoneticStr = m_oText->ToString(); + } + else if(type == OOX::et_x_rPr) + { + text->text.fExtStr = false; + text->text.fRichStr = true; + } + text->text.str = m_oText->ToString(); + ptr->m_BrtCommentText = XLS::BaseObjectPtr{text}; + } + + return objectPtr; + } EElementType CComment::getType () const { return et_x_Comment; @@ -275,6 +329,14 @@ namespace OOX } } } + XLS::BaseObjectPtr CCommentList::toBin() + { + auto ptr(new XLSB::COMMENTLIST); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arCOMMENT.push_back(i->toBin()); + return objectPtr; + } EElementType CCommentList::getType () const { return et_x_CommentList; @@ -332,6 +394,20 @@ namespace OOX //commentsStream.reset(); } } + XLS::BaseObjectPtr CComments::WriteBin() const + { + XLSB::CommentsStreamPtr commentsStream(new XLSB::CommentsStream); + auto ptr(new XLSB::COMMENTS); + commentsStream->m_COMMENTS = XLS::BaseObjectPtr{ptr}; + + if(m_oAuthors.IsInit()) + ptr->m_COMMENTAUTHORS = m_oAuthors->toBin(); + + if(m_oCommentList.IsInit()) + ptr->m_COMMENTLIST = m_oCommentList->toBin(); + + return XLS::BaseObjectPtr{commentsStream}; + } void CComments::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -379,6 +455,14 @@ namespace OOX } void CComments::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"\ "); std::wstring sPath = oPath.GetPath(); NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); - + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write(oPath, oDirectory, oContent); } const OOX::FileType CComments::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::CommentsBin; + } return OOX::Spreadsheet::FileTypes::Comments; } const CPath CComments::DefaultDirectory() const diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 221a81170d1..5203cd010d1 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -350,7 +350,9 @@ namespace OOX } void CWorksheet::PrepareAfterRead() { - PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if (!(xlsb) && (xlsb->m_bWriteToXlsb)) + PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); PrepareConditionalFormatting(); PrepareDataValidations(); } From c343625e6f2996efaefc8c9cb5caec9f7fe77fd4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 13 Oct 2023 21:14:26 +0600 Subject: [PATCH 168/794] Add connections conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 14 +- OOXML/DocxFormat/Drawing/DrawingExt.h | 1 + OOXML/XlsxFormat/Table/Connections.cpp | 250 +++++++++++++++++++++++- OOXML/XlsxFormat/Table/Connections.h | 10 + 4 files changed, 268 insertions(+), 7 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 3cd31942a5a..f1c4573a141 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -249,7 +249,7 @@ namespace OOX OOX::Spreadsheet::CConditionalFormatting* pConditionalFormatting = new OOX::Spreadsheet::CConditionalFormatting(); *pConditionalFormatting = oReader; m_arrConditionalFormatting.push_back(pConditionalFormatting); - } + } } else if (sName == L"dataValidations") { @@ -646,6 +646,18 @@ namespace OOX return sResult; } + XLS::BaseObjectPtr COfficeArtExtensionList::toBinConnections() + { + auto ptr(new XLSB::FRTEXTCONNECTIONS); + for(auto i:m_arrExt) + { + if(i->m_sUri == L"{DE250136-89BD-433C-8126-D09CA5730AF9}") + { + ptr->m_EXTCONN15 = i->m_oConnection->toBin(); + } + } + return XLS::BaseObjectPtr{ptr}; + } XLS::BaseObjectPtr COfficeArtExtensionList::toBinWorkBook() { auto ptr(new XLSB::FRTWORKBOOK); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 48cfb8d7bad..40659fd3273 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -193,6 +193,7 @@ namespace OOX XLS::BaseObjectPtr toBinTable(); XLS::BaseObjectPtr toBinSlicerCache(); XLS::BaseObjectPtr toBinPivotCache(); + XLS::BaseObjectPtr toBinConnections(); virtual EElementType getType() const; std::vector m_arrExt; diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index bcf807f5d28..ec86aeb199d 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -55,6 +55,8 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" +#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -85,6 +87,15 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CTextField::toBin() + { + auto ptr(new XLSB::BeginECTwFldInfo); + if(m_oPosition.IsInit()) + ptr->data.fieldStart = m_oPosition.get(); + if(m_oType.IsInit()) + ptr->data.fieldType = m_oType->GetValue(); + return XLS::BaseObjectPtr{ptr}; + } EElementType CTextField::getType() const { return et_x_textField; @@ -158,6 +169,14 @@ namespace OOX m_arrItems.push_back(new CTextField(textField)); } } + XLS::BaseObjectPtr CTextFields::toBin() + { + auto ptr(new XLSB::ECTWFLDINFOLST); + for(auto i:m_arrItems) + ptr->m_arBrtBeginECTwFldInfo.push_back(i->toBin()); + + return XLS::BaseObjectPtr{ptr}; + } EElementType CTextFields::getType() const { return et_x_textFields; @@ -295,6 +314,13 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CRangePr::toBin() + { + auto ptr(new XLSB::RangePr15); + if(m_oSourceName.IsInit()) + ptr->irstSourceName = m_oSourceName.get(); + return XLS::BaseObjectPtr{ptr}; + } EElementType CRangePr::getType() const { return et_x_rangePr; @@ -348,6 +374,20 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECDbProps); } } + XLS::BaseObjectPtr CDbPr::toBin() + { + auto ptr1(new XLSB::ECDBPROPS); + auto ptr(new XLSB::BeginECDbProps); + if(m_oConnection.IsInit()) + ptr->stConn = m_oConnection.get(); + if(m_oCommand.IsInit()) + ptr->stCmd = m_oCommand.get(); + if(m_oServerCommand.IsInit()) + ptr->stCmdSvr = m_oServerCommand.get(); + if(m_oCommandType.IsInit()) + ptr->icmdtype = m_oCommandType.get(); + return XLS::BaseObjectPtr{ptr1}; + } EElementType CDbPr::getType() const { return et_x_dbPr; @@ -416,6 +456,30 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECOlapProps); } } + XLS::BaseObjectPtr COlapPr::toBin() + { + auto ptr1(new XLSB::ECOLAPPROPS); + auto ptr(new XLSB::BeginECOlapProps); + ptr1->m_BrtBeginECOlapProps = XLS::BaseObjectPtr{ptr}; + + if(m_oLocalConnection.IsInit()) + ptr->stConnLocal = m_oLocalConnection.get(); + if(m_oRowDrillCount.IsInit()) + ptr->nDrillthroughRows = m_oRowDrillCount.get(); + if(m_oLocal.IsInit()) + ptr->fLocalConn = m_oLocal.get(); + if(m_oLocalRefresh.IsInit()) + ptr->fNoRefreshCube = m_oLocalRefresh.get(); + if(m_oSendLocale.IsInit()) + ptr->fUseOfficeLcid = m_oSendLocale.get(); + if(m_oServerNumberFormat.IsInit()) + ptr->fSrvFmtNum = m_oServerNumberFormat.get(); + if(m_oServerFont.IsInit()) + ptr->fSrvFmtFlags = m_oServerFont.get(); + if(m_oServerFontColor.IsInit()) + ptr->fSrvFmtFore = m_oServerFontColor.get(); + return XLS::BaseObjectPtr{ptr1}; + } EElementType COlapPr::getType() const { return et_x_olapPr; @@ -510,6 +574,38 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginECWebProps); } } + XLS::BaseObjectPtr CWebPr::toBin() + { + auto ptr1(new XLSB::ECWEBPROPS); + auto ptr(new XLSB::BeginECWebProps); + ptr1->m_BrtBeginECWebProps = XLS::BaseObjectPtr{ptr}; + + if(m_oUrl.IsInit()) + ptr->stURL = m_oUrl.get(); + if(m_oPost.IsInit()) + ptr->stWebPost = m_oPost.get(); + if(m_oEditPage.IsInit()) + ptr->stEditWebPage = m_oEditPage.get(); + if(m_oXml.IsInit()) + ptr->fSrcIsXML = m_oXml.get(); + if(m_oSourceData.IsInit()) + ptr->fImportSourceData = m_oSourceData.get(); + if(m_oConsecutive.IsInit()) + ptr->fConsecDelim = m_oConsecutive.get(); + if(m_oFirstRow.IsInit()) + ptr->fSameSettings = m_oFirstRow.get(); + if(m_oXl97.IsInit()) + ptr->fXL97Format = m_oXl97.get(); + if(m_oTextDates.IsInit()) + ptr->fNoDateRecog = m_oTextDates.get(); + if(m_oXl2000.IsInit()) + ptr->fRefreshedInXL9 = m_oXl2000.get(); + if(m_oHtmlTables.IsInit()) + ptr->fTablesOnlyHTML = m_oHtmlTables.get(); + if(m_oHtmlFormat.IsInit()) + ptr->wHTMLFmt = m_oHtmlFormat->GetValue(); + return XLS::BaseObjectPtr{ptr1}; + } EElementType CWebPr::getType() const { return et_x_webPr; @@ -623,6 +719,47 @@ namespace OOX m_oTextFields = ptr->m_ECTWFLDINFOLST; } } + XLS::BaseObjectPtr CTextPr::toBin() + { + auto ptr1(new XLSB::ECTXTWIZ); + auto ptr(new XLSB::BeginECTxtWiz); + + if(m_oSourceFile.IsInit()) + ptr->stFile = m_oSourceFile.get(); + if(m_oFileType.IsInit()) + { + ptr->data.iCpid = m_oFileType->m_eValue; + ptr->data.iCpidNew = m_oFileType->m_eValue; + } + if(m_oDecimal.IsInit()) + ptr->data.chDecimal = std::stoi(m_oDecimal.get()); + if(m_oDelimiter.IsInit()) + ptr->data.chCustom = std::stoi(m_oDelimiter.get()); + if(m_oThousands.IsInit()) + ptr->data.chThousSep = std::stoi(m_oThousands.get()); + if(m_oFirstRow.IsInit()) + ptr->data.rowStartAt = m_oFirstRow.get(); + if(m_oQualifier.IsInit()) + ptr->data.fTextDelim = m_oQualifier->GetValue(); + if(m_oPrompt.IsInit()) + ptr->data.fPromptForFile = m_oPrompt.get(); + if(m_oDelimited.IsInit()) + ptr->data.fDelimited = m_oDelimited.get(); + if(m_oTab.IsInit()) + ptr->data.fTab = m_oTab.get(); + if(m_oSpace.IsInit()) + ptr->data.fSpace = m_oSpace.get(); + if(m_oComma.IsInit()) + ptr->data.fComma = m_oComma.get(); + if(m_oSemicolon.IsInit()) + ptr->data.fSemiColon = m_oSemicolon.get(); + if(m_oConsecutive.IsInit()) + ptr->data.fConsecutive = m_oConsecutive.get(); + + if(m_oTextFields.IsInit()) + ptr1->m_ECTWFLDINFOLST = m_oTextFields->toBin(); + return XLS::BaseObjectPtr{ptr1}; + } EElementType CTextPr::getType() const { return et_x_textPr; @@ -798,6 +935,81 @@ namespace OOX } } } + XLS::BaseObjectPtr CConnection::toBin() + { + XLS::BaseObjectPtr objectPtr; + if(m_oRangePr.IsInit()) + { + auto ptr(new XLSB::EXTCONN15); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConn15); + ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; + ptr->m_source = m_oRangePr->toBin(); + } + else + { + auto ptr(new XLSB::EXTCONNECTION); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConnection); + ptr->m_BrtBeginExtConnection = XLS::BaseObjectPtr{ptr1}; + + if(m_oDbPr.IsInit()) + ptr->m_ECDBPROPS = m_oDbPr->toBin(); + if(m_oOlapPr.IsInit()) + ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); + if(m_oTextPr.IsInit()) + ptr->m_ECTXTWIZ = m_oTextPr->toBin(); + if(m_oWebPr.IsInit()) + ptr->m_ECWEBPROPS = m_oWebPr->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); + + if(m_oType.IsInit()) + ptr1->idbtype = m_oType.get(); + if(m_oName.IsInit()) + ptr1->stConnName = m_oName.get(); + if(m_oId.IsInit()) + ptr1->dwConnID = m_oId->GetValue(); + if(m_oCredentials.IsInit()) + ptr1->iCredMethod = m_oCredentials->GetValue(); + if(m_oBackground.IsInit()) + ptr1->fBackgroundQuery = m_oBackground.get(); + if(m_oDeleted.IsInit()) + ptr1->fDeleted = m_oDeleted.get(); + if(m_oDescription.IsInit()) + ptr1->stConnDesc = m_oDescription.get(); + if(m_oInterval.IsInit()) + ptr1->wInterval = m_oInterval.get(); + if(m_oKeepAlive.IsInit()) + ptr1->fMaintain = m_oKeepAlive.get(); + if(m_oMinRefreshableVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oMinRefreshableVersion.get(); + if(m_oNew.IsInit()) + ptr1->fNewQuery = m_oNew.get(); + if(m_oOdcFile.IsInit()) + ptr1->stConnectionFile = m_oOdcFile.get(); + if(m_oOnlyUseConnectionFile.IsInit()) + ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); + if(m_oReconnectionMethod.IsInit()) + ptr1->irecontype = m_oReconnectionMethod.get(); + if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshed = m_oRefreshedVersion.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); + if(m_oSaveData.IsInit()) + ptr1->fSaveData = m_oSaveData.get(); + if(m_oSavePassword.IsInit()) + { + ptr1->pc = m_oSavePassword.get(); + } + if(m_oSingleSignOnId.IsInit()) + ptr1->stSso = m_oSingleSignOnId.get(); + if(m_oSourceFile.IsInit()) + ptr1->stDataFile = m_oSourceFile.get(); + } + + return objectPtr; + } EElementType CConnection::getType() const { return et_x_Connection; @@ -945,6 +1157,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(new CConnection(connection)); } } + XLS::BaseObjectPtr CConnections::toBin() + { + auto ptr(new XLSB::EXTCONNECTIONS); + for(auto i:m_arrItems) + ptr->m_arEXTCONNECTION.push_back(i->toBin()); + return XLS::BaseObjectPtr{ptr}; + } EElementType CConnections::getType() const { return et_x_Connections; @@ -974,6 +1193,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" CPath oRootPath; read(oRootPath, oPath); } + XLS::BaseObjectPtr CConnectionsFile::WriteBin() const + { + XLSB::ConnectionsStreamPtr connectionsStream(new XLSB::ConnectionsStream); + if(m_oConnections.IsInit()) + connectionsStream->m_EXTCONNECTIONS = m_oConnections->toBin(); + return XLS::BaseObjectPtr{connectionsStream}; + } void CConnectionsFile::readBin(const CPath& oPath) { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); @@ -1016,19 +1242,31 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if (false == m_oConnections.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oConnections->toXML(sXml); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oConnections->toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); IFileContainer::Write(oPath, oDirectory, oContent); } const OOX::FileType CConnectionsFile::type() const { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::ConnectionsBin; + } return OOX::Spreadsheet::FileTypes::Connections; } const CPath CConnectionsFile::DefaultDirectory() const diff --git a/OOXML/XlsxFormat/Table/Connections.h b/OOXML/XlsxFormat/Table/Connections.h index 6fa2dc9f048..00107d26f2f 100644 --- a/OOXML/XlsxFormat/Table/Connections.h +++ b/OOXML/XlsxFormat/Table/Connections.h @@ -73,6 +73,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -95,6 +96,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -161,6 +163,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -184,6 +187,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -212,6 +216,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -241,6 +246,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -277,6 +283,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -320,6 +327,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -372,6 +380,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; @@ -389,6 +398,7 @@ namespace OOX virtual void read(const CPath& oPath); void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; From eec0075e549067c42ffffa673ce982b85c70d186 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 13 Oct 2023 18:18:06 +0300 Subject: [PATCH 169/794] =?UTF-8?q?=D0=A1hange=20of=20architecture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 29 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 42 +- .../StarMath2OOXML/cstarmathpars.cpp | 1249 +++++------------ .../Converter/StarMath2OOXML/cstarmathpars.h | 221 +-- .../Converter/StarMath2OOXML/typeselements.h | 73 +- 5 files changed, 479 insertions(+), 1135 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index f0988e010bc..fcb9c297fbe 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -1,7 +1,7 @@ #include "cconversionsmtoooxml.h" #include "../../../../DesktopEditor/common/File.h" #include -namespace StarMath { +/*namespace StarMath { CConversionSMtoOOXML::CConversionSMtoOOXML() { } @@ -14,17 +14,17 @@ namespace StarMath { ConversionOneElement(m_oTempElement); } EndConversion(); -// NSFile::CFileBinary oFile; -// oFile.CreateFileW(L"Test.txt"); -// oFile.WriteStringUTF8(m_oXmlWrite.GetXmlString()); -// oFile.CloseFile(); + NSFile::CFileBinary oFile; + oFile.CreateFileW(L"Test.txt"); + oFile.WriteStringUTF8(m_oXmlWrite.GetXmlString()); + oFile.CloseFile(); } void CConversionSMtoOOXML::ConversionOneElement(CElement *m_oElement) { switch (m_oElement->GetType()) { - case Number: - ConversNumber(dynamic_cast(m_oElement)); + case Text: + ConversText(dynamic_cast(m_oElement)); break; case BinOperator: ConversBinOperator(dynamic_cast (m_oElement)); @@ -40,7 +40,7 @@ namespace StarMath { { if(m_oElement->GetTypeBin() == plus || m_oElement->GetTypeBin() == minus || m_oElement->GetTypeBin() == multipl || m_oElement->GetTypeBin() == cdot || m_oElement->GetTypeBin() == times || m_oElement->GetTypeBin() == div || m_oElement->GetTypeBin() == odivide || m_oElement->GetTypeBin() == oplus || m_oElement->GetTypeBin() == ominus || m_oElement->GetTypeBin() == odot || m_oElement->GetTypeBin() == otimes) { - ConversionOneElement(m_oElement->GetLeftArg()); + ConversionOneElement(m_oElement->GetFirstElement()); m_oXmlWrite.WriteNodeBegin(L"m:r",false); StandartProperties(); m_oXmlWrite.WriteNodeBegin(L"m:t",false); @@ -80,9 +80,9 @@ namespace StarMath { default: break; } - if(m_oElement->GetTypeRight() == Number) + if(m_oElement->GetTypeSecondElement() == Text) { - CNumber* m_oNumber = dynamic_cast (m_oElement->GetRightArg()); + CText* m_oNumber = dynamic_cast (m_oElement->GetSecondElement()); m_oXmlWrite.WriteString(m_oNumber->GetValue()); m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); @@ -91,7 +91,7 @@ namespace StarMath { { m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); - ConversionOneElement(m_oElement->GetRightArg()); + ConversionOneElement(m_oElement->GetSecondElement()); } } @@ -100,12 +100,12 @@ namespace StarMath { m_oXmlWrite.WriteNodeBegin(L"m:f",false); if(m_oElement->GetTypeBin() == division) PropertiesMFPR(true,L"lin"); else PropertiesMFPR(false,L""); - BlockRecording(L"m:num",m_oElement->GetLeftArg()); - BlockRecording(L"m:den",m_oElement->GetRightArg()); + BlockRecording(L"m:num",m_oElement->GetFirstElement()); + BlockRecording(L"m:den",m_oElement->GetSecondElement()); m_oXmlWrite.WriteNodeEnd(L"m:f",false,false); } } - void CConversionSMtoOOXML::ConversNumber(CNumber *m_oElement) + void CConversionSMtoOOXML::ConversText(CText *m_oElement) { m_oXmlWrite.WriteNodeBegin(L"m:r",false); StandartProperties(); @@ -225,3 +225,4 @@ namespace StarMath { m_oXmlWrite.WriteNodeEnd(L"m:oMathPara",false,false); } } +*/ diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 6c47b84ddff..1aa8b5f4118 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -5,25 +5,25 @@ -namespace StarMath { - class CConversionSMtoOOXML - { - public: - CConversionSMtoOOXML(); - //friend class StarMath::CStarMathPars; - void StartConversion(std::vector arPars); - void StandartProperties(); - void PropertiesMFPR(bool bType,const std::wstring& wsType); - void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup); - void ConversionOneElement(CElement* m_oElement); - void ConversBinOperator(CBinaryOperator* m_oElement); - void ConversNumber(CNumber* m_oElement); - void ConversOperator(COperator* m_oElement); - void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock); - void EndConversion(); - std::wstring GetOOXML() ; - private: - XmlUtils::CXmlWriter m_oXmlWrite; - }; -} +//namespace StarMath { +// class CConversionSMtoOOXML +// { +// public: +// CConversionSMtoOOXML(); +// //friend class StarMath::CStarMathPars; +// void StartConversion(std::vector arPars); +// void StandartProperties(); +// void PropertiesMFPR(bool bType,const std::wstring& wsType); +// void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup); +// void ConversionOneElement(CElement* m_oElement); +// void ConversBinOperator(CBinaryOperator* m_oElement); +// void ConversText(CText* m_oElement); +// void ConversOperator(COperator* m_oElement); +// void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock); +// void EndConversion(); +// std::wstring GetOOXML() ; +// private: +// XmlUtils::CXmlWriter m_oXmlWrite; +// }; +//} #endif // CCONVERSIONSMTOOOXML_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index fd5de25f4ea..65344bf0397 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1,62 +1,42 @@ #include "cstarmathpars.h" namespace StarMath { -//Class methods CStarMathPars - CStarMathPars::CStarMathPars() +//class methods CParsStarMath + std::vector CParseStarMathString::Parse(std::wstring& wsParseString) { - } - - CStarMathPars::~CStarMathPars() - { - for(CElement* ReleaseObject: m_arParsLine) + std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); + while(itStart != itEnd) { - delete ReleaseObject; + arEquation.push_back(ParsElement(itStart,itEnd)); } + return arEquation; } - void CStarMathPars::PrintAr() - { - for(int i = 0;iGetType(); - } - } -//Test version (works correctly only with operators, does not work correctly with attributes) - CElement* CStarMathPars::ReadWithoutBrackets(std::wstring::iterator &itFirst, std::wstring::iterator &itEnd,std::vector& arParsLine) + CElement* CParseStarMathString::ParsElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) { - CElement* m_oOneElement = ParsElement(itFirst,itEnd,arParsLine); - if(m_oOneElement->GetType() != Bracket) + CElement* pElement; + std::wstring wsToken = GetElement(itStart,itEnd); + std::vector arAttributes; + TypeElement enTypeToken = CAttribute::IsAttribute(wsToken); + while(enTypeToken != TypeElement::undefine && itStart != itEnd) { - std::vector arTempValue; - arTempValue.push_back(m_oOneElement); - while(CheckingTheNextElement(itFirst,itEnd,CheckBinOperator)|| CheckingTheNextElement(itFirst,itEnd,CheckPlusOrMinus)||CheckingTheNextElement(itFirst,itEnd,CheckBinOperatorLowPriority)) - { - arTempValue.push_back(ParsElement(itFirst,itEnd,arTempValue)); - } - if(arTempValue.size()== 1) return m_oOneElement = arTempValue.back(); - else - { - CBracket* m_oBracket = new CBracket; - m_oBracket->SetBracketVal(arTempValue); - m_oBracket->SetTypeBracket(L"brace"); - return m_oBracket; - } + if(enTypeToken != TypeElement::color) arAttributes.push_back(new CAttribute(enTypeToken)); + wsToken = GetElement(itStart,itEnd); + enTypeToken = CAttribute::IsAttribute(wsToken); } - else return m_oOneElement; - } - void CStarMathPars::Pars(std::wstring& wsStarMathLine) - { - std::wstring::iterator itFirst = wsStarMathLine.begin(), itEnd = wsStarMathLine.end(); - while(itFirst != itEnd) + if(L"left" == wsToken) pElement = CElement::CreateElement(GetElement(itStart,itEnd)); + else pElement = CElement::CreateElement(wsToken); + + if(pElement != nullptr) { - m_arParsLine.push_back(ParsElement(itFirst,itEnd,m_arParsLine)); - //std::wcout << GetElement(itFirst,itEnd)<SetAttribute(arAttributes); + pElement->Pars(itStart,itEnd); + return pElement; } - - //PrintAr(); + else return pElement; } - std::wstring CStarMathPars::GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) + std::wstring CParseStarMathString::GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) { std::wstring m_wsElement{}; for(; itFirst != itEnd;itFirst++) @@ -85,936 +65,411 @@ namespace StarMath if(!m_wsElement.empty()) return m_wsElement; else return {}; } - CElement* CStarMathPars::ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,std::vector& arParsLine) - { - CAttribute* m_oAttribute = new CAttribute; - std::wstring wsOneElement = GetElement(itFirst,itEnd); - while((L"color" == wsOneElement && CheckingTheNextElement(itFirst,itEnd,CheckColorAttribute))|| CheckPropertiesAttribute(wsOneElement) || CheckTopAttribute(wsOneElement)) - { - if(wsOneElement == L"color") wsOneElement = GetElement(itFirst,itEnd); - m_oAttribute->SetTypeAtt(wsOneElement); - wsOneElement = GetElement(itFirst,itEnd); - } - - if(CheckDigit(wsOneElement)) - { - CNumber* m_oCNumber = new CNumber(wsOneElement); - m_oCNumber->SetAttribute(m_oAttribute); - return m_oCNumber; - } - else if(CheckSpecialCharacter(wsOneElement) || CheckSpecialOperation(wsOneElement) || CheckSpecialConnection(wsOneElement)) return new CSpecialSymbol(wsOneElement); - else if(CheckFunction(wsOneElement)) - { - CFunction* m_oFunction = new CFunction; - m_oFunction->SetTypeFunction(wsOneElement); - if(L"ln" == wsOneElement) m_oFunction->SetArgument(ReadWithoutBrackets(itFirst,itEnd,arParsLine)); - else m_oFunction->SetArgument(ParsElement(itFirst,itEnd,arParsLine)); - m_oFunction->SetAttribute(m_oAttribute); - return m_oFunction; - } - else if(CheckIndex(wsOneElement)) - { - CIndex* m_oIndex = new CIndex(wsOneElement); - m_oIndex->SetArgument(arParsLine.back()); - m_oIndex->SetIndex(ParsElement(itFirst,itEnd,arParsLine)); - return m_oIndex; - } - else if(CheckMatrix(wsOneElement)) - { - CMatrix* m_oMatrix = new CMatrix(wsOneElement); - m_oMatrix->SetArgument(ParsElement(itFirst,itEnd,arParsLine)); - m_oMatrix->SetAttribute(m_oAttribute); - return m_oMatrix; - } - else if(CheckBinOperator(wsOneElement) || CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) - { - if(!arParsLine.empty()) - { - CBinaryOperator* m_pBinOp = new CBinaryOperator(wsOneElement); - CElement* m_oTempElement{ParsElement(itFirst,itEnd,arParsLine)}; - m_pBinOp->SetArgument(arParsLine.back()); - arParsLine.pop_back(); - if(((CheckPlusOrMinus(wsOneElement) || CheckBinOperatorLowPriority(wsOneElement)) && (CheckingTheNextElement(itFirst, itEnd,CheckBinOperator)||CheckingTheNextElement(itFirst, itEnd, CheckIndex))) || (CheckBinOperator(wsOneElement) && CheckingTheNextElement(itFirst, itEnd,CheckIndex))) - { - arParsLine.push_back(m_oTempElement); - m_pBinOp->SetRightArg(ParsElement(itFirst,itEnd,arParsLine)); - } - else m_pBinOp->SetRightArg(m_oTempElement); - m_pBinOp->SetAttribute(m_oAttribute); - return m_pBinOp; - } - return NULL; - } - else if(CheckBracketOpen(wsOneElement) || CheckScalable_NotScalableBracketLeft(wsOneElement) || (L"left" == wsOneElement && CheckingTheNextElement(itFirst,itEnd,CheckScalable_NotScalableBracketLeft))) - { - CBracket* m_oBracket = new CBracket; - std::wstring wsTypeBracket; - std::vector arValueBrecket; - if(L"left" == wsOneElement) - { - m_oBracket->SetScalable(); - wsOneElement = GetElement(itFirst,itEnd); - wsTypeBracket = wsOneElement; - } - else wsTypeBracket = wsOneElement; - while(!CheckingTheNextElement(itFirst,itEnd,CheckBracketClose) && !CheckingTheNextElement(itFirst,itEnd,CheckScalable_NotScalableBracketRight)) - { - arValueBrecket.push_back(ParsElement(itFirst,itEnd,arValueBrecket)); - } - wsOneElement = GetElement(itFirst,itEnd); - if(L"right" == wsOneElement) wsOneElement = GetElement(itFirst,itEnd); - m_oBracket->SetBracketVal(arValueBrecket); - m_oBracket->SetTypeBracket(wsTypeBracket); - m_oBracket ->SetAttribute(m_oAttribute); - return m_oBracket; - } - else if(CheckOperator(wsOneElement)) - { - COperator* oTempOp = new COperator(wsOneElement); - std::vector arValueBrecket; - std::wstring::iterator itSavePos; - do - { - itSavePos = itFirst; - wsOneElement = GetElement(itFirst,itEnd); - if( wsOneElement == L"from") - oTempOp->SetFrom(ParsElement(itFirst,itEnd,arValueBrecket)); - else if(wsOneElement == L"to") - oTempOp->SetTo(ParsElement(itFirst,itEnd,arValueBrecket)); - else - break; - }while(true); - oTempOp->SetValueOp(ParsElement(itSavePos,itEnd,arValueBrecket)); - oTempOp->SetAttribute(m_oAttribute); - return oTempOp; - } - } - - bool CStarMathPars::CheckDigit(const std::wstring &wsCheckToken) - { - for(char Check: wsCheckToken) - { - if(!isdigit(Check)) return false; - } - return true; - } - bool CStarMathPars::CheckScalable_NotScalableBracketLeft(const std::wstring &wsCheckToken) - { - return(L"ldbracket" == wsCheckToken || L"lbrace" == wsCheckToken || L"langle" == wsCheckToken || L"lceil" == wsCheckToken || L"lfloor" == wsCheckToken || L"lline" == wsCheckToken || L"ldline" == wsCheckToken); - } - bool CStarMathPars::CheckScalable_NotScalableBracketRight(const std::wstring &wsCheckToken) - { - return(L"rdbracket" == wsCheckToken || L"rbrace" == wsCheckToken || L"rangle" == wsCheckToken || L"rceil" == wsCheckToken || L"rfloor" == wsCheckToken || L"rline" == wsCheckToken || L"rdline" == wsCheckToken || L"right" == wsCheckToken); - } -////////////////Requires improvement - /*bool CStarMathPars::CheckUnarSign(std::wstring &wsCheckToken,CUnarySign& m_oUnarSign) - { - std::wstring wsTempValueUnarSign; - bool UnarSign = false; - for(int i = 0;i<2;i++) - { - if(wsCheckToken[i] == '+' || wsCheckToken[i] == '-') - { - wsTempValueUnarSign.push_back(wsCheckToken[i]); - UnarSign = true; - } - } - if(!wsTempValueUnarSign.empty() && UnarSign) - { - m_arParsLine.push_back(m_oUnarSign.GetUnarSign(wsTempValueUnarSign)); - wsCheckToken = wsCheckToken.substr(wsTempValueUnarSign.size()); - } - return UnarSign; - }*/ - bool CStarMathPars::CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)) + bool CParseStarMathString::CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)) { std::wstring::iterator itTempVal = itFirst; - bool bResult = func(GetElement(itFirst,itEnd)); + std::wstring wsAttributeToken = GetElement(itFirst,itEnd); +// while(true) +// { +// if(wsAttributeToken == L"color") wsAttributeToken = GetElement(itFirst,itEnd); +// wsAttributeToken = GetElement(itFirst,itEnd); +// } itFirst = itTempVal; - return bResult; - } - bool CStarMathPars::CheckBinOperator(const std::wstring &wsCheckToken) - { - return(L"*" ==wsCheckToken || L"/" == wsCheckToken || wsCheckToken == L"over" || wsCheckToken == L"cdot" || wsCheckToken == L"times" || wsCheckToken == L"div" || wsCheckToken == L"odot" || wsCheckToken == L"otimes" || wsCheckToken == L"odivide" || wsCheckToken == L"wideslash" || wsCheckToken == L"widebslash"); - } - bool CStarMathPars::CheckBinOperatorLowPriority(const std::wstring &wsCheckToken) - { - return (wsCheckToken == L"oplus" || wsCheckToken == L"ominus"|| wsCheckToken == L"circ"); - } - bool CStarMathPars::CheckPlusOrMinus(const std::wstring &wsCheckToken) - { - switch (wsCheckToken[0]) - { - case L'+': - return true; - case L'-': - return true; - default: - return false; - } - } - bool CStarMathPars::CheckOperator(const std::wstring &wsCheckToken) - { - return(wsCheckToken == L"lim" || wsCheckToken == L"sum"); - } - bool CStarMathPars::CheckIndex(const std::wstring &wsCheckToken) - { - return (wsCheckToken == L"_" || wsCheckToken == L"^" || L"lsup" == wsCheckToken || L"lsub" == wsCheckToken || L"csup" == wsCheckToken || L"csub" == wsCheckToken); - } - bool CStarMathPars::CheckIndexOp(const std::wstring &wsCheckToken) - { - return(L"from" == wsCheckToken || L"to" == wsCheckToken); - } - bool CStarMathPars::CheckBracketOpen(const std::wstring& wsCheckToken) - { - switch (wsCheckToken[0]) { - case '{': - return true; - case '(': - return true; - case '[': - return true; - default: - return false; - } - } - bool CStarMathPars::CheckBracketClose(const std::wstring& wsCheckToken) - { - switch (wsCheckToken[0]) {; - case '}': - return true; - case ')': - return true; - case ']': - return true; - default: - return false; - } - } - bool CStarMathPars::CheckTopAttribute(const std::wstring& wsCheckToken) - { - return(L"acute" == wsCheckToken || L"breve" == wsCheckToken || L"dot" == wsCheckToken || L"dddot" == wsCheckToken || L"vec" == wsCheckToken || L"tilde" == wsCheckToken || L"check" == wsCheckToken || L"grave" == wsCheckToken || L"circle" == wsCheckToken || L"ddot" == wsCheckToken || L"bar" == wsCheckToken || L"harpoon" == wsCheckToken || L"hat" == wsCheckToken || L"widevec" == wsCheckToken || L"widetilde" == wsCheckToken || L"overline" == wsCheckToken || L"overstrike" == wsCheckToken || L"wideharpoon" == wsCheckToken || L"widehat" == wsCheckToken || L"underline" == wsCheckToken); - } - bool CStarMathPars::CheckPropertiesAttribute(const std::wstring& wsCheckToken) - { - return(L"ital" == wsCheckToken || L"bold" == wsCheckToken || L"phantom" == wsCheckToken); - } - bool CStarMathPars::CheckColorAttribute(const std::wstring &wsCheckToken) - { - return (L"violet" == wsCheckToken || L"black" == wsCheckToken || L"green" == wsCheckToken || L"aqua" == wsCheckToken || L"yellow" == wsCheckToken || L"lime" == wsCheckToken || L"navy" == wsCheckToken || L"purple" == wsCheckToken || L"teal" == wsCheckToken || L"blue" == wsCheckToken || L"red" == wsCheckToken || L"fuchsia" == wsCheckToken || L"gray" == wsCheckToken || L"maroon" == wsCheckToken || L"olive" == wsCheckToken || L"silver" == wsCheckToken || L"coral" == wsCheckToken || L"midnightblue" == wsCheckToken || L"crimson" == wsCheckToken || L"violet" == wsCheckToken); - } - bool CStarMathPars::CheckSpecialCharacter(const std::wstring &wsCheckToken) - { - return (L"mline" == wsCheckToken || L"#" == wsCheckToken || L"##" == wsCheckToken); + if(func(wsAttributeToken)) return true; + else return false; } - bool CStarMathPars::CheckSpecialOperation(const std::wstring &wsCheckToken) - { - return(L"intersection" == wsCheckToken || L"union" == wsCheckToken || L"setminus" == wsCheckToken || L"setquoyient" == wsCheckToken || L"subseteq" == wsCheckToken || L"subset" == wsCheckToken || L"supset" == wsCheckToken || L"supseteq" == wsCheckToken || L"nsubset" == wsCheckToken || L"nsupseteq" == wsCheckToken || L"nsupset" == wsCheckToken || L"nsubseteq" == wsCheckToken || L"in" == wsCheckToken || L"notin" == wsCheckToken || L"owns" == wsCheckToken); - } - bool CStarMathPars::CheckSpecialConnection(const std::wstring &wsCheckToken) - { - return(L"approx" == wsCheckToken || L"sim" == wsCheckToken || L"simeq" == wsCheckToken || L"equiv" == wsCheckToken || L"prop" == wsCheckToken || L"parallel" == wsCheckToken || L"ortho" == wsCheckToken || L"divides" == wsCheckToken || L"ndivides" == wsCheckToken || L"toward" == wsCheckToken || L"transl" == wsCheckToken || L"transr" == wsCheckToken || L"def" == wsCheckToken || L"=" == wsCheckToken || L"<>" == wsCheckToken || L"<" == wsCheckToken || L"<=" == wsCheckToken || L"leslant" == wsCheckToken || L">" == wsCheckToken || L">=" == wsCheckToken || L"geslant" == wsCheckToken || L"<<" == wsCheckToken || L">>" == wsCheckToken || L"prec" == wsCheckToken || L"succ" == wsCheckToken || L"preccurlyeq" == wsCheckToken || L"succcurlyeq" == wsCheckToken || L"precsim" == wsCheckToken || L"succsim" == wsCheckToken || L"nprec" == wsCheckToken || L"nsucc" == wsCheckToken || L"dlarrow" == wsCheckToken || L"dlrarrow" == wsCheckToken || L"drarrow" == wsCheckToken); - } - std::vector CStarMathPars::GetVector() - { - return m_arParsLine; - } - bool CStarMathPars::CheckFunction(const std::wstring &wsCheckToken) - { - return(L"sin" == wsCheckToken || L"cos" == wsCheckToken || L"ln" == wsCheckToken || L"tan" == wsCheckToken || L"cot" == wsCheckToken || L"sinh" == wsCheckToken || L"cosh" == wsCheckToken || L"tanh" == wsCheckToken || L"coth" == wsCheckToken || L"arcsin" == wsCheckToken || L"arccos" == wsCheckToken || L"arctan" == wsCheckToken || L"arccot" == wsCheckToken || L"arsinh" == wsCheckToken || L"arcosh" == wsCheckToken || L"artanh" == wsCheckToken || L"arcoth" == wsCheckToken || L"abs" == wsCheckToken || L"fact" == wsCheckToken || L"sqrt" == wsCheckToken || L"nroot" == wsCheckToken); - } - bool CStarMathPars::CheckOperation(const std::wstring &wsCheckToken) - { - return(L"intersection" == wsCheckToken || L"union" == wsCheckToken || L"setminus" == wsCheckToken || L"setquoytient" == wsCheckToken || L"subseteq" == wsCheckToken || L"subset" == wsCheckToken); - } - bool CStarMathPars::CheckMatrix(const std::wstring &wsCheckToken) - { - return (L"stack" == wsCheckToken || L"matrix" == wsCheckToken || L"binom" == wsCheckToken); - } -//Class methods CNumber - CNumber::CNumber() - { - } - CNumber::CNumber(const std::wstring &wsValue) - { - this->m_wsValueNumber = wsValue; - } - CNumber::~CNumber() - { - } - - std::wstring CNumber::GetValue() - { - return m_wsValueNumber; - } - TypeElement CNumber::GetType() - { - return Number; - } -//Class methods CUnarySign - CUnarySign* CUnarySign::GetUnarSign(const std::wstring& wsUnarToken) - { - CUnarySign* oSign = new CUnarySign; - oSign->m_wsUnar = wsUnarToken; - return oSign; - } - - std::wstring CUnarySign::GetValue() - { - return m_wsUnar; - } - TypeElement CUnarySign::GetType() - { - return m_enUnarType; - } - CUnarySign::CUnarySign() +//class methods CAttribute + CAttribute::~CAttribute() {} - CUnarySign::~CUnarySign() + CAttribute::CAttribute(const TypeElement &enType) + { + enTypeAttr = enType; + } + TypeElement CAttribute::GetType() + { + return enTypeAttr; + } +//нет phantom, rgb, 16 , гарнитуры и кегля + TypeElement CAttribute::IsAttribute(const std::wstring &wsToken) + { + if(L"acute" == wsToken) return TypeElement::acute; + else if(L"color" == wsToken) return TypeElement::color; + else if(L"breve" == wsToken) return TypeElement::breve; + else if(L"dot" == wsToken) return TypeElement::dot; + else if(L"dddot" == wsToken) return TypeElement::dddot; + else if(L"vec" == wsToken) return TypeElement::vec; + else if(L"tilde" == wsToken) return TypeElement::tilde; + else if(L"check" == wsToken) return TypeElement::check; + else if(L"grave" == wsToken) return TypeElement::grave; + else if(L"circle" == wsToken) return TypeElement::circle; + else if(L"ddot" == wsToken) return TypeElement::ddot; + else if(L"bar" == wsToken) return TypeElement::bar; + else if(L"harpoon" == wsToken) return TypeElement::harpoon; + else if(L"hat" == wsToken) return TypeElement::hat; + else if(L"widevec" == wsToken) return TypeElement::widevec; + else if(L"widetilde" == wsToken) return TypeElement::widetilde; + else if(L"overline" == wsToken) return TypeElement::overline; + else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; + else if(L"widehat" == wsToken) return TypeElement::widehat; + else if(L"underline" == wsToken) return TypeElement::underline; + else if(L"ital" == wsToken) return TypeElement::ital; + else if(L"bold" == wsToken) return TypeElement::bold; + else if(L"black" == wsToken) return TypeElement::black; + else if(L"green" == wsToken) return TypeElement::green; + else if(L"aqua" == wsToken) return TypeElement::aqua; + else if(L"yellow" == wsToken) return TypeElement::yellow; + else if(L"lime" == wsToken) return TypeElement::lime; + else if(L"navy" == wsToken) return TypeElement::navy; + else if(L"purple" == wsToken) return TypeElement::purple; + else if(L"teal" == wsToken) return TypeElement::teal; + else if(L"blue" == wsToken) return TypeElement::blue; + else if(L"red" == wsToken) return TypeElement::red; + else if(L"fuchsia" == wsToken) return TypeElement::fuchsia; + else if(L"gray" == wsToken) return TypeElement::gray; + else if(L"maroon" == wsToken) return TypeElement::maroon; + else if(L"olive" == wsToken) return TypeElement::olive; + else if(L"silver" == wsToken) return TypeElement::silver; + else if(L"coral" == wsToken) return TypeElement::coral; + else if(L"midnightblue" == wsToken) return TypeElement::midnightblue; + else if(L"crimson" == wsToken) return TypeElement::crimson; + else if(L"violet" == wsToken) return TypeElement::violet; + else if(L"orange" == wsToken) return TypeElement::orange; + else if(L"seagreen" == wsToken) return TypeElement::seagreen; + else if(L"hotpink" == wsToken) return TypeElement::hotpink; + else if(L"orangered" == wsToken) return TypeElement::orangered; + else if(L"indigo" == wsToken) return TypeElement::indigo; + else if(L"lavender" == wsToken) return TypeElement::lavender; + else return TypeElement::undefine; + } +//class methods CElement + CElement::~CElement() {} -//Class methods CBinaryOperator - CBinaryOperator::CBinaryOperator() - { - oRightArg = nullptr; - } - CBinaryOperator::CBinaryOperator(const std::wstring& wsToken) - { - if(wsToken == L"+") - { - enTypeBinOp = plus; - } - else if(wsToken == L"-") - { - enTypeBinOp = minus; - } - else if(wsToken == L"*") - { - enTypeBinOp = multipl; - } - else if(wsToken == L"/") - { - enTypeBinOp = division; - } - else if(wsToken == L"over") - { - enTypeBinOp = over; - } - else if(wsToken == L"cdot") - { - enTypeBinOp = cdot; - } - else if(wsToken == L"times") - { - enTypeBinOp = times; - } - else if(wsToken == L"frac") + CElement::CElement() + {} +// TypeElement CElement::GetTypeElement(const std::wstring& wsToken) +// { +// if (wsToken == L"+") +// { +// return TypeElement::plus; +// } +// else if (wsToken == L"-") +// { +// return TypeElement::minus; +// } +// else if (wsToken == L"*") +// { +// return TypeElement::multipl; +// } +// else if (wsToken == L"/") +// { +// return TypeElement::division; +// } +// else if (wsToken == L"over") +// { +// return TypeElement::over; +// } +// else if (wsToken == L"cdot") +// { +// return TypeElement::cdot; +// } +// else if (wsToken == L"times") +// { +// return TypeElement::times; +// } +// else if (wsToken == L"frac") +// { +// return TypeElement::frac; +// } +// else if (wsToken == L"div") +// { +// return TypeElement::div; +// } +// else if (wsToken == L"oplus") +// { +// return TypeElement::oplus; +// } +// else if (wsToken == L"ominus") +// { +// return TypeElement::ominus; +// } +// else if (wsToken == L"odot") +// { +// return TypeElement::odot; +// } +// else if (wsToken == L"otimes") +// { +// return TypeElement::otimes; +// } +// else if (wsToken == L"odivide") +// { +// return TypeElement::odivide; +// } +// else if (wsToken == L"circ") +// { +// return TypeElement::circ; +// } +// else if (wsToken == L"wideslash") +// { +// return TypeElement::wideslash; +// } +// else if (wsToken == L"widebslash") +// { +// return TypeElement::widebslash; +// } +// else if(L"{" == wsToken) return TypeElement::brace; +// else if(L"(" == wsToken) return TypeElement::round; +// else if(L"[" == wsToken) return TypeElement::square; +// else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; +// else if(L"lbrace" == wsToken) return TypeElement::lbrace; +// else if(L"langle" == wsToken) return TypeElement::langle; +// else if(L"lceil" == wsToken) return TypeElement::lceil; +// else if(L"lfloor" == wsToken) return TypeElement::lfloor; +// else if(L"lline" == wsToken) return TypeElement::lline; +// else if(L"ldline" == wsToken) return TypeElement::ldline; +// else return TypeElement::undefine; +// } + CElement* CElement::CreateElement(const std::wstring& wsToken) + { + //binop + if (wsToken == L"+") + { + return new CElementBinOperator(TypeElement::plus); + } + else if (wsToken == L"-") + { + return new CElementBinOperator(TypeElement::minus); + } + else if (wsToken == L"*") + { + return new CElementBinOperator(TypeElement::multipl); + } + else if (wsToken == L"/") + { + return new CElementBinOperator(TypeElement::division); + } + else if (wsToken == L"over") + { + return new CElementBinOperator(TypeElement::over); + } + else if (wsToken == L"cdot") + { + return new CElementBinOperator(TypeElement::cdot); + } + else if (wsToken == L"times") + { + return new CElementBinOperator(TypeElement::times); + } + else if (wsToken == L"frac") { - enTypeBinOp = frac; + return new CElementBinOperator(TypeElement::frac); } - else if(wsToken == L"div") + else if (wsToken == L"div") { - enTypeBinOp = div; + return new CElementBinOperator(TypeElement::div); } - else if(wsToken == L"oplus") + else if (wsToken == L"oplus") { - enTypeBinOp = oplus; + return new CElementBinOperator(TypeElement::oplus); } - else if(wsToken == L"ominus") + else if (wsToken == L"ominus") { - enTypeBinOp = ominus; + return new CElementBinOperator(TypeElement::ominus); } - else if(wsToken == L"odot") + else if (wsToken == L"odot") { - enTypeBinOp = odot; + return new CElementBinOperator(TypeElement::odot); } - else if(wsToken == L"otimes") + else if (wsToken == L"otimes") { - enTypeBinOp = otimes; + return new CElementBinOperator(TypeElement::otimes); } - else if(wsToken == L"odivide") + else if (wsToken == L"odivide") { - enTypeBinOp = odivide; + return new CElementBinOperator(TypeElement::odivide); } - else if(wsToken == L"circ") + else if (wsToken == L"circ") { - enTypeBinOp = circ; + return new CElementBinOperator(TypeElement::circ); } - else if(wsToken == L"wideslash") + else if (wsToken == L"wideslash") { - enTypeBinOp = wideslash; + return new CElementBinOperator(TypeElement::wideslash); } - else if(wsToken == L"widebslash") + else if (wsToken == L"widebslash") { - enTypeBinOp = widebslash; + return new CElementBinOperator(TypeElement::widebslash); } - oRightArg = nullptr; - } - CBinaryOperator::~CBinaryOperator() - { - delete oRightArg; - } - TypeElement CBinaryOperator::GetType() - { - return BinOperator; + //brace + else if(L"{" == wsToken) return new CElementBracket(TypeElement::brace); +// else if(L"(" == wsToken) return TypeElement::round; +// else if(L"[" == wsToken) return TypeElement::square; +// else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; +// else if(L"lbrace" == wsToken) return TypeElement::lbrace; +// else if(L"langle" == wsToken) return TypeElement::langle; +// else if(L"lceil" == wsToken) return TypeElement::lceil; +// else if(L"lfloor" == wsToken) return TypeElement::lfloor; +// else if(L"lline" == wsToken) return TypeElement::lline; +// else if(L"ldline" == wsToken) return TypeElement::ldline; + else if(CElementString::IsDigit(wsToken)) return new CElementString(wsToken); + else return nullptr; } - std::wstring CBinaryOperator::GetValue() + void CElement::SetAttribute(const std::vector arAttr) { - return {}; + arElementAttributes = arAttr; } - TypeBinOperator CBinaryOperator::GetTypeBin() +//class methods CElementString + CElementString::CElementString(const std::wstring& wsTokenString) { - return enTypeBinOp; + wsString = wsTokenString; } - void CBinaryOperator::SetRightArg(CElement *oArgument) + CElementString::~CElementString() + {} + void CElementString::SetString(const std::wstring& wsTokenString) { - oRightArg = oArgument; + wsString = wsTokenString; } - void CBinaryOperator::SetTypeBin(const TypeBinOperator &enType) + void CElementString::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) { - this->enTypeBinOp = enType; } - CElement* CBinaryOperator::GetRightArg() + std::wstring CElementString::GetString() { - return oRightArg; + return wsString; } - TypeElement CBinaryOperator::GetTypeRight() + bool CElementString::IsDigit(const std::wstring &wsToken) { - return oRightArg->GetType(); - } -//Class methods COperator - COperator::COperator(): oFromValue(NULL),oToValue(NULL),oValueOp(NULL) - {} - COperator::COperator(const std::wstring& wsToken): oFromValue(NULL), oToValue(NULL), oValueOp(NULL) - { - if(wsToken== L"lim") - { - enTypeOp = lim; - } - else if(wsToken == L"sum") + for(char cOneElement: wsToken) { - enTypeOp = sum; + if(!isdigit(cOneElement)) return false; } + return true; } - COperator::~COperator() - { - delete oFromValue; - delete oToValue; - delete oValueOp; - } - TypeElement COperator::GetType() - { - return Operator; - } - std::wstring COperator::GetValue() - { - return {}; - } - TypeOperator COperator::GetTypeOp() - { - return enTypeOp; - } - void COperator::SetFrom(CElement *oFrom) - { - oFromValue = oFrom; - } - void COperator::SetTo(CElement *oTo) +//class methods CElementBinOperator + CElementBinOperator::CElementBinOperator(const TypeElement& enType) { - oToValue = oTo; + enTypeBinOp = enType; } - void COperator::SetValueOp(CElement *oValue) + CElementBinOperator::~CElementBinOperator() { - oValueOp = oValue; + delete pLeftArgument; + delete pRightArgument; } - void COperator::SetTypeOp(const TypeOperator& enType) + void CElementBinOperator::SetLeftArg(CElement *pElement) { - enTypeOp = enType; + pLeftArgument = pElement; } - CElement* COperator::GetValueOp() + void CElementBinOperator::SetRightArg(CElement *pElement) { - return oValueOp; + pRightArgument = pElement; } - CElement* COperator::GetFrom() + void CElementBinOperator::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) { - return oFromValue; + SetRightArg(CParseStarMathString::ParsElement(itStart,itEnd)); } - CElement* COperator::GetTo() + void CElementBinOperator::SetTypeBinOP(const TypeElement &enType) { - return oToValue; + enTypeBinOp = enType; } -//Class methods CBracket - CBracket::CBracket() - {} - CBracket::CBracket(const std::vector& arValue,const std::wstring& wsCheckToken) + bool CElementBinOperator::IsBinOperator(const TypeElement& enCheckType) { - arBrecketVal = arValue; - if (L"{" == wsCheckToken) enTypeBracket =brace; - else if (L"(" == wsCheckToken) enTypeBracket = round; - else if (L"[" == wsCheckToken) enTypeBracket = square; - else if(wsCheckToken == L"ldbracket") + switch (enCheckType) { - enTypeBracket = ldbracket; - } - else if(wsCheckToken == L"lbrace") - { - enTypeBracket = lbrace; - } - else if(wsCheckToken == L"langle") - { - enTypeBracket = langle; - } - else if(wsCheckToken == L"lceil") - { - enTypeBracket = lceil; - } - else if(wsCheckToken == L"lfloor") - { - enTypeBracket = lfloor; - } - else if(wsCheckToken == L"lline") - { - enTypeBracket = lline; - } - else if(wsCheckToken == L"ldline") - { - enTypeBracket = ldline; + case TypeElement::plus: + return true; + case TypeElement::minus: + return true; + case TypeElement::over: + return true; + case TypeElement::multipl: + return true; + case TypeElement::division: + return true; + case TypeElement::cdot: + return true; + case TypeElement::times: + return true; + case TypeElement::frac: + return true; + case TypeElement::div: + return true; + case TypeElement::oplus: + return true; + case TypeElement::ominus: + return true; + case TypeElement::odot: + return true; + case TypeElement::otimes: + return true; + case TypeElement::odivide: + return true; + case TypeElement::circ: + return true; + case TypeElement::wideslash: + return true; + case TypeElement::widebslash: + return true; + default: + return false; } } - CBracket::~CBracket() + bool CElementBinOperator::IsLowPriorityBinOp(const TypeElement &enType) { - for(CElement* ReleaseObject: arBrecketVal) + switch (enType) { - delete ReleaseObject; + case TypeElement::plus: + return true; + case TypeElement::minus: + return true; + case TypeElement::oplus: + return true; + case TypeElement::ominus: + return true; + case TypeElement::circ: + return true; + default: + return false; } } - TypeElement CBracket::GetType() + bool CElementBinOperator::IsHighPriorityBinOp(const TypeElement &enType) { - for(CElement* enTemp: arBrecketVal) + switch(enType) { - std::wcout<< enTemp->GetType() << std::endl; + case TypeElement::over: + return true; + default: + return false; } - return Bracket; } - std::wstring CBracket::GetValue() +//class methods CElementBracket + CElementBracket::CElementBracket(const TypeElement& enType) { - return {}; + enTypeBracket = enType; } - void CBracket::SetScalable() + CElementBracket::~CElementBracket() { - bScalable = true; + for(CElement* pTemp:arBrecketValue) delete pTemp; } - void CBracket::SetBracketVal(const std::vector &arBrecketValue) + void CElementBracket::SetBracketValue(const std::vector &arValue) { - arBrecketVal = arBrecketValue; + arBrecketValue = arValue; } - void CBracket::SetTypeBracket(const std::wstring& wsCheckToken) - { - if (L"{" == wsCheckToken) enTypeBracket = brace; - else if (L"(" == wsCheckToken) enTypeBracket = round; - else if (L"[" == wsCheckToken) enTypeBracket = square; - else if(wsCheckToken == L"ldbracket") - { - enTypeBracket = ldbracket; - } - else if(wsCheckToken == L"lbrace") - { - enTypeBracket = lbrace; - } - else if(wsCheckToken == L"langle") - { - enTypeBracket = langle; - } - else if(wsCheckToken == L"lceil") - { - enTypeBracket = lceil; - } - else if(wsCheckToken == L"lfloor") - { - enTypeBracket = lfloor; - } - else if(wsCheckToken == L"lline") - { - enTypeBracket = lline; - } - else if(wsCheckToken == L"ldline") - { - enTypeBracket = ldline; - } - } -//Class methods CAttribute - CAttribute::CAttribute() + bool CElementBracket::IsBracketClose(const std::wstring &wsToken) { + if(L"}" == wsToken) return true; + else if(L")" == wsToken) return true; + else if(L"]" == wsToken) return true; + else return false; } - CAttribute::CAttribute(const TypeAttributeTop &enType) + //нужно поправить GetElement(беру его тут + в методе ParsElement) + void CElementBracket::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) { - enTypeTop = enType; - } - CAttribute::~CAttribute() - { - } - void CAttribute::SetTypeAtt(const std::wstring& wsCheckToken) - { - if(wsCheckToken == L"phantom") - { - bPhantom = true; - } - else if(wsCheckToken == L"bold") - { - bBold = true; - } - else if(wsCheckToken == L"ital") - { - bItal = true; - } - else if(wsCheckToken == L"black") - { - enTypeColor = black; - } - else if(wsCheckToken == L"green") - { - enTypeColor = green; - } - else if(wsCheckToken == L"aqua") - { - enTypeColor = aqua; - } - else if(wsCheckToken == L"yellow") - { - enTypeColor = yellow; - } - else if(wsCheckToken == L"lime") - { - enTypeColor = lime; - } - else if(wsCheckToken == L"navy") - { - enTypeColor = navy; - } - else if(wsCheckToken == L"purple") - { - enTypeColor = purple; - } - else if(wsCheckToken == L"teal") - { - enTypeColor = teal; - } - else if(wsCheckToken == L"blue") - { - enTypeColor = blue; - } - else if(wsCheckToken == L"red") - { - enTypeColor = red; - } - else if(wsCheckToken == L"fuchsia") - { - enTypeColor = fuchsia; - } - else if(wsCheckToken == L"gray") - { - enTypeColor = gray; - } - else if(wsCheckToken == L"maroon") - { - enTypeColor = maroon; - } - else if(wsCheckToken == L"olive") - { - enTypeColor = olive; - } - else if(wsCheckToken == L"silver") - { - enTypeColor = silver; - } - else if(wsCheckToken == L"coral") - { - enTypeColor = coral; - } - else if(wsCheckToken == L"midnightblue") - { - enTypeColor = midnightblue; - } - else if(wsCheckToken == L"crimson") - { - enTypeColor = crimson; - } - else if(wsCheckToken == L"violet") - { - enTypeColor = violet; - } - else if(wsCheckToken == L"acute") - { - enTypeTop = acute; - } - else if(wsCheckToken == L"breve") - { - enTypeTop = breve; - } - else if(wsCheckToken == L"dot") - { - enTypeTop = dot; - } - else if(wsCheckToken == L"dddot") - { - enTypeTop = dddot; - } - else if(wsCheckToken == L"vec") - { - enTypeTop = vec; - } - else if(wsCheckToken == L"tilde") - { - enTypeTop = tilde; - } - else if(wsCheckToken == L"check") - { - enTypeTop = check; - } - else if(wsCheckToken == L"grave") + std::wstring wsToken = CParseStarMathString::GetElement(itStart,itEnd) ; + while(L"right" != wsToken && !IsBracketClose(wsToken)) { - enTypeTop = grave; + arBrecketValue.push_back(CParseStarMathString::ParsElement(itStart,itEnd)); + wsToken = CParseStarMathString::GetElement(itStart,itEnd); } - else if(wsCheckToken == L"circle") - { - enTypeTop = circle; - } - else if(wsCheckToken == L"ddot") - { - enTypeTop = ddot; - } - else if(wsCheckToken == L"bar") - { - enTypeTop = bar; - } - else if(wsCheckToken == L"harpoon") - { - enTypeTop = harpoon; - } - else if(wsCheckToken == L"hat") - { - enTypeTop = hat; - } - else if(wsCheckToken == L"widevec") - { - enTypeTop = widevec; - } - else if(wsCheckToken == L"widetilde") - { - enTypeTop = widetilde; - } - else if(wsCheckToken == L"overline") - { - enTypeTop = overline; - } - else if(wsCheckToken == L"overstrike") - { - enTypeTop = overstrike; - } - else if(wsCheckToken == L"wideharpoon") - { - enTypeTop = wideharpoon; - } - else if(wsCheckToken == L"widehat") - { - enTypeTop = widehat; - } - else if(wsCheckToken == L"underline") - { - enTypeTop = underline; - } - } - TypeAttributeTop CAttribute::GetTypeAtt() - { - return enTypeTop; - } -//Class methods CElement - CElement::~CElement() - { } - void CElement::SetAttribute(CAttribute* m_oCAttribute) - { - oCAttribute = m_oCAttribute; - } - TypeAttributeTop CElement::GetTypeAttribute() - { - return oCAttribute->GetTypeAtt(); - } -//Class methods CSpecial - CSpecialSymbol::CSpecialSymbol(const std::wstring& wsToken) - { - if(L"mline" == wsToken) enTypeSpecial = mline; - else if(L"#" == wsToken) enTypeSpecial = grid; - else if(L"##" == wsToken) enTypeSpecial = dlgrid; - else if(L"intersection" == wsToken) enTypeSpecial = intersection; - else if(L"union" == wsToken) enTypeSpecial = Union; - else if(L"setminus" == wsToken) enTypeSpecial = setminus; - else if(L"setquoyient" == wsToken) enTypeSpecial = setquoyient; - else if(L"subseteg" == wsToken) enTypeSpecial = subseteq; - else if(L"subset" == wsToken) enTypeSpecial = subset; - else if(L"supset" == wsToken) enTypeSpecial = supset; - else if(L"supseteq" == wsToken) enTypeSpecial = supseteq; - else if(L"nsubset" == wsToken) enTypeSpecial = nsubset; - else if(L"nsubseteq" == wsToken) enTypeSpecial = nsubseteq; - else if(L"nsupseteq" == wsToken) enTypeSpecial = nsupseteq; - else if(L"nsupset" == wsToken) enTypeSpecial = nsupset; - else if(L"in" == wsToken) enTypeSpecial = in; - else if(L"notin" == wsToken) enTypeSpecial = notin; - else if(L"owns" == wsToken) enTypeSpecial = owns; - else if(L"approx" == wsToken) enTypeSpecial = approx; - else if(L"sim" == wsToken) enTypeSpecial = sim; - else if(L"simeq" == wsToken) enTypeSpecial = simeq; - else if(L"equiv" == wsToken) enTypeSpecial = equiv; - else if(L"prop" == wsToken) enTypeSpecial = prop; - else if(L"parallel" == wsToken) enTypeSpecial = parallel; - else if(L"ortho" == wsToken) enTypeSpecial = ortho; - else if(L"divides" == wsToken) enTypeSpecial = divides; - else if(L"ndivides" == wsToken) enTypeSpecial = ndivides; - else if(L"toward" == wsToken) enTypeSpecial = toward; - else if(L"transl" == wsToken) enTypeSpecial = transl; - else if(L"transr" == wsToken) enTypeSpecial = transr; - else if(L"def" == wsToken) enTypeSpecial = def; - else if(L"=" == wsToken) enTypeSpecial = equals; - else if(L"<>" == wsToken) enTypeSpecial = notequals; - else if(L"<" == wsToken) enTypeSpecial = learrow; - else if(L"<=" == wsToken) enTypeSpecial = learrowequals; - else if(L"leslant" == wsToken) enTypeSpecial = leslant; - else if(L">" == wsToken) enTypeSpecial = riarrow; - else if(L">=" == wsToken) enTypeSpecial = riarrowequals; - else if(L"geslant" == wsToken) enTypeSpecial = geslant; - else if(L"<<" == wsToken) enTypeSpecial = dllearrow; - else if(L">>" == wsToken) enTypeSpecial = dlriarrow; - else if(L"prec" == wsToken) enTypeSpecial = prec; - else if(L"succ" == wsToken) enTypeSpecial = succ; - else if(L"preccurlyeq" == wsToken) enTypeSpecial = preccurlyeq; - else if(L"succcurlyeq" == wsToken) enTypeSpecial = succcurlyeq; - else if(L"precsim" == wsToken) enTypeSpecial = precsim; - else if(L"succsim" == wsToken) enTypeSpecial = succsim; - else if(L"nprec" == wsToken) enTypeSpecial = nprec; - else if(L"nsucc" == wsToken) enTypeSpecial = nsucc; - else if(L"dlarrow" == wsToken) enTypeSpecial = dlarrow; - else if(L"dlrarrow" == wsToken) enTypeSpecial = dlrarrow; - else if(L"drarrow" == wsToken) enTypeSpecial = drarrow; - SetAttribute(nullptr); - } - CSpecialSymbol::~CSpecialSymbol() - {} - std::wstring CSpecialSymbol::GetValue() - { - return {}; - } - TypeElement CSpecialSymbol::GetType() - { - return SpecialSymbol; - } -//class methods CFunction - CFunction::CFunction() - {} - CFunction::~CFunction() - { - } - std::wstring CFunction::GetValue() - { - return L""; - } - TypeElement CFunction::GetType() - { - return Function; - } - TypeFunction CFunction::GetTypeFun() - { - return enTypeFun; - } - void CFunction::SetTypeFunction(const std::wstring &wsCheckToken) - { - if(L"sin" == wsCheckToken) enTypeFun = sin; - else if(L"abs" == wsCheckToken) enTypeFun = abs; - else if(L"fact" == wsCheckToken) enTypeFun = fact; - else if(L"sqrt" == wsCheckToken) enTypeFun = sqrt; - else if(L"cos" == wsCheckToken) enTypeFun = cos; - else if(L"tan" == wsCheckToken) enTypeFun = tan; - else if(L"cot" == wsCheckToken) enTypeFun = cot; - else if(L"sinh" == wsCheckToken) enTypeFun = sinh; - else if(L"cosh" == wsCheckToken) enTypeFun = cosh; - else if(L"tanh" == wsCheckToken) enTypeFun = tanh; - else if(L"coth" == wsCheckToken) enTypeFun = coth; - else if(L"arcsin" == wsCheckToken) enTypeFun = arcsin; - else if(L"arccos" == wsCheckToken) enTypeFun = arccos; - else if(L"arctan" == wsCheckToken) enTypeFun = arctan; - else if(L"arccot" == wsCheckToken) enTypeFun = arccot; - else if(L"arsinh" == wsCheckToken) enTypeFun = arsinh; - else if(L"arcosh" == wsCheckToken) enTypeFun = arcosh; - else if(L"artanh" == wsCheckToken) enTypeFun = artanh; - else if(L"arcoth" == wsCheckToken) enTypeFun = arcoth; - else if(L"ln" == wsCheckToken) enTypeFun = ln; - } -//class methods CArgumentContainer - CArgumentContainer::CArgumentContainer() - { - oArgument = nullptr; - } - CArgumentContainer::~CArgumentContainer() - { - delete oArgument; - } - std::wstring CArgumentContainer::GetValue() - { - return L""; - } - TypeElement CArgumentContainer::GetType() - { - return TwoArgumentContainer; - } - void CArgumentContainer::SetArgument(CElement *oValue) - { - oArgument = oValue; - } - CElement* CArgumentContainer::GetArgument() - { - return oArgument; - } -//class methods CIndex - CIndex::CIndex(const std::wstring& wsToken) - { - if(L"^" == wsToken) enTypeIn = upper; - else if(L"_" == wsToken) enTypeIn = lower; - else if(L"lsup" == wsToken) enTypeIn = lsup; - else if(L"lsub" == wsToken) enTypeIn = lsub; - else if(L"csup" == wsToken) enTypeIn = csup; - else if(L"csub" == wsToken) enTypeIn = csub; - SetAttribute(nullptr); - } - CIndex::~CIndex() - { - delete oIndex; - } - std::wstring CIndex::GetValue() - { - return {}; - } - TypeElement CIndex::GetType() - { - return Index; - } - void CIndex::SetIndex(CElement *oValueIndex) - { - oIndex = oValueIndex; - } -//class methods CMatrix - CMatrix::CMatrix(const std::wstring& wsToken) - { - if (L"binom" == wsToken) enTypeMatrix = binom; - else if(L"stack" == wsToken) enTypeMatrix = stack; - else if(L"matrix" == wsToken) enTypeMatrix = matrix; - } - CMatrix::~CMatrix() - {} - std::wstring CMatrix::GetValue() - { - return {}; - } - TypeElement CMatrix::GetType() - { - return Matrix; - } } - diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 1d594a53566..613a5caf882 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -11,203 +11,82 @@ namespace StarMath class CAttribute { public: - CAttribute(); - CAttribute(const TypeAttributeTop& enType); - virtual ~CAttribute(); - void SetTypeAtt(const std::wstring& wsCheckToken); - TypeAttributeTop GetTypeAtt(); + CAttribute(const TypeElement& enType); + ~CAttribute(); + static TypeElement IsAttribute(const std::wstring& wsToken); + TypeElement GetType(); private: - TypeAttributeTop enTypeTop{noneTop}; - TypeAttributeColor enTypeColor{noneColor}; - bool bBold{false}; - bool bItal{false}; - bool bPhantom{false}; + TypeElement enTypeAttr; }; - class CElement { public: + CElement(); virtual ~CElement(); - virtual std::wstring GetValue() = 0; - virtual TypeElement GetType() = 0; - void SetAttribute(CAttribute* m_oCAttribute); - TypeAttributeTop GetTypeAttribute(); - private: - CAttribute* oCAttribute; - }; - class CSpecialSymbol: public CElement - { - public: - CSpecialSymbol(const std::wstring& wsToken); - virtual ~CSpecialSymbol(); - std::wstring GetValue() override; - TypeElement GetType() override; - private: - TypeSymbol enTypeSpecial; - }; - class CNumber: public CElement - { - public: - CNumber(); - CNumber(const std::wstring& wsValue); - virtual ~CNumber(); - std::wstring GetValue() override; - TypeElement GetType() override ; - private: - std::wstring m_wsValueNumber; - }; - - class CUnarySign: public CElement - { - public: - CUnarySign(); - ~CUnarySign(); - std::wstring GetValue() override; - TypeElement GetType() override; - CUnarySign* GetUnarSign(const std::wstring& wsUnarToken); + virtual void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) = 0; + //принимает подтип (over, frac и т.д) и создает нужный нам класс(внутри уже идет проверка по классам) + static CElement* CreateElement(const std::wstring& wsToken); + //static TypeElement GetTypeElement(const std::wstring& wsToken); + void SetAttribute(const std::vector arAttr); private: - std::wstring m_wsUnar; - TypeElement m_enUnarType = UnarSign; + std::vector arElementAttributes; }; - class CArgumentContainer: public CElement + class CElementString: public CElement { public: - CArgumentContainer(); - virtual ~CArgumentContainer(); - std::wstring GetValue() override; - TypeElement GetType() override; - void SetArgument(CElement* oValue); - CElement* GetArgument(); + CElementString(const std::wstring& wsTokenString); + virtual ~CElementString(); + void SetString(const std::wstring& wsTokenString); + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; + std::wstring GetString(); + static bool IsDigit(const std::wstring& wsCheckToken); private: - CElement* oArgument; + std::wstring wsString; }; - class CBinaryOperator: public CArgumentContainer + class CElementBinOperator: public CElement { public: - CBinaryOperator(); - CBinaryOperator(const std::wstring& wsToken); - virtual ~CBinaryOperator(); - std::wstring GetValue() override; - TypeElement GetType() override; - TypeBinOperator GetTypeBin(); - void SetRightArg(CElement* oArgument); - void SetTypeBin(const TypeBinOperator& enType); + CElementBinOperator(const TypeElement& enType); + virtual ~CElementBinOperator(); + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; + void SetLeftArg(CElement* pElement); + void SetRightArg(CElement* pElement); + void SetTypeBinOP(const TypeElement& enType); CElement* GetRightArg(); - TypeElement GetTypeRight(); - private: - CElement* oRightArg; - TypeBinOperator enTypeBinOp; - }; - class COperator: public CElement - { - public: - COperator(); - COperator(const std::wstring& wsToken); - virtual ~COperator(); - std::wstring GetValue() override; - TypeElement GetType() override; - TypeOperator GetTypeOp(); - void SetTypeOp(const TypeOperator& enType); - void SetFrom(CElement* oFrom); - void SetTo(CElement* oTo); - void SetValueOp(CElement* oValue); - CElement* GetValueOp(); - CElement* GetFrom(); - CElement* GetTo(); - private: - TypeOperator enTypeOp; - CElement* oFromValue{nullptr}; - CElement* oToValue{nullptr}; - CElement* oValueOp{nullptr}; - }; - class CBracket: public CElement - { - public: - CBracket(); - CBracket(const std::vector& arValue,const std::wstring& wsCheckToken); - virtual ~CBracket(); - std::wstring GetValue() override; - TypeElement GetType() override; - void SetScalable(); - void SetBracketVal(const std::vector& arBrecketValue); - void SetTypeBracket(const std::wstring& wsCheckToken); - private: - bool bScalable{false}; - TypeBracket enTypeBracket; - std::vector arBrecketVal; - }; - class CFunction: public CArgumentContainer - { - public: - CFunction(); - virtual ~CFunction(); - std::wstring GetValue() override; - TypeElement GetType() override; - TypeFunction GetTypeFun(); - void SetTypeFunction(const std::wstring& wsCheckToken); - private: - TypeFunction enTypeFun; - }; - class CIndex: public CArgumentContainer - { - public: - CIndex(const std::wstring& wsToken); - virtual ~CIndex(); - std::wstring GetValue() override; - TypeElement GetType() override; - void SetIndex(CElement* oValueIndex); - CElement* GetIndex(); + CElement* GetLeftArg(); + static bool IsBinOperator(const TypeElement& enCheckType); private: - TypeIndex enTypeIn; - CElement* oIndex; + bool IsLowPriorityBinOp(const TypeElement& enType); + bool IsHighPriorityBinOp(const TypeElement& enType); + CElement* pLeftArgument; + CElement* pRightArgument; + TypeElement enTypeBinOp; }; - class CMatrix: public CArgumentContainer + + class CElementBracket: public CElement { public: - CMatrix(const std::wstring& wsToken); - virtual ~CMatrix(); - std::wstring GetValue() override; - TypeElement GetType() override; + CElementBracket(const TypeElement& enType); + virtual ~CElementBracket(); + void SetBracketValue(const std::vector& arValue); + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; private: - TypeMatrix enTypeMatrix; + static bool IsBracketClose(const std::wstring& wsToken); + TypeElement enTypeBracket; + std::vector arBrecketValue; }; - class CStarMathPars + + class CParseStarMathString { public: - CStarMathPars(); - virtual ~CStarMathPars(); - std::vector GetVector(); - void Pars(std::wstring& wsStarMathLine); - std::wstring GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd); - CElement* ParsElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, std::vector& arParsLine); - CElement* ReadWithoutBrackets(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,std::vector& arParsLine); - bool CheckDigit(const std::wstring& wsCheckToken); - //bool CheckUnarSign(std::wstring& wsCheckToken,CUnarySign& oUnarSign); - static bool CheckBinOperator(const std::wstring& wsCheckToken); - static bool CheckBinOperatorLowPriority(const std::wstring& wsCheckToken); - static bool CheckPlusOrMinus(const std::wstring& wsCheckToken); - bool CheckOperator(const std::wstring& wsCheckToken); - static bool CheckIndex(const std::wstring& wsCheckToken); - bool CheckIndexOp(const std::wstring& wsCheckToken); - bool CheckBracketOpen(const std::wstring& wsCheckToken); - static bool CheckBracketClose(const std::wstring& wsCheckToken); - static bool CheckScalable_NotScalableBracketLeft(const std::wstring& wsCheckToken); - static bool CheckScalable_NotScalableBracketRight(const std::wstring& wsCheckToken); - bool CheckTopAttribute(const std::wstring& wsCheckToken); - bool CheckPropertiesAttribute(const std::wstring& wsCheckToken); - static bool CheckColorAttribute(const std::wstring& wsCheckToken); - bool CheckSpecialCharacter(const std::wstring& wsCheckToken); - bool CheckSpecialOperation(const std::wstring& wsCheckToken);//doing first - bool CheckSpecialConnection(const std::wstring& wsCheckToken);// doint first - bool CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd,bool (&func)(const std::wstring& wsCheckToken)); - bool CheckFunction(const std::wstring& wsCheckToken); - bool CheckOperation(const std::wstring& wsCheckToken); - bool CheckMatrix(const std::wstring& wsCheckToken); - void PrintAr(); + std::vector Parse(std::wstring& wsParseString); + static CElement* ParsElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd); + static std::wstring GetElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); + static bool CheckingTheNextElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)); private: - std::vector m_arParsLine; + std::vector arEquation; }; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 80e0cf70565..8cb8406ea5f 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -2,8 +2,10 @@ #define TYPESELEMENTS_H namespace StarMath { -enum TypeElement{ - Number, +enum class TypeElement{ + undefine, + //global + String, BinOperator, Operator, Bracket, @@ -15,9 +17,7 @@ enum TypeElement{ Operation, Index, Matrix, -}; -enum TypeBinOperator -{ + //binoop cdot, times, over, @@ -35,14 +35,10 @@ enum TypeBinOperator circ, wideslash, widebslash, -}; -enum TypeOperator -{ + //op lim, sum, -}; -enum TypeBracket -{ + //brace brace, round, square, @@ -53,10 +49,10 @@ enum TypeBracket lfloor, lline, ldline, -}; -enum TypeAttributeTop -{ - noneTop, + //attribute + ital, + bold, + //top element acute, breve, dot, @@ -77,10 +73,7 @@ enum TypeAttributeTop wideharpoon, widehat, underline,//top elements -}; -enum TypeAttributeColor -{ - noneColor, + color, black, green, aqua, @@ -99,10 +92,14 @@ enum TypeAttributeColor coral, midnightblue, crimson, - violet,//color(without rgb and hex) -}; -enum TypeSymbol -{ + violet, + orange, + seagreen, + hotpink, + orangered, + indigo, + lavender, + //color(without rgb and hex) mline, grid, dlgrid, @@ -155,9 +152,27 @@ enum TypeSymbol dlarrow, dlrarrow, drarrow, -}; -enum TypeFunction -{ + emptyset, + aleph, + setN, + setZ, + setQ, + setR, + setC, + infinity, + partial, + nabla, + exists, + notexists, + forall, + hbar, + lambdabar, + Re, + Im, + wp, + laplace, + fourier, + backepsilon, abs, fact, sqrt, @@ -181,18 +196,12 @@ enum TypeFunction ln, exp, log, -}; -enum TypeIndex -{ upper, lower, lsup, lsub, csup, csub, -}; -enum TypeMatrix -{ binom, stack, matrix, From 5b0516e398d83dc761f44941bc83c67577faee36 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 27 Oct 2023 17:23:25 +0300 Subject: [PATCH 170/794] Architecture refinement (adding connections, functions and operators) --- .../StarMath2OOXML/cstarmathpars.cpp | 493 +++++++++++++++--- .../Converter/StarMath2OOXML/cstarmathpars.h | 113 +++- .../Converter/StarMath2OOXML/typeselements.h | 9 +- 3 files changed, 527 insertions(+), 88 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 65344bf0397..83507abcc4e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -5,9 +5,18 @@ namespace StarMath std::vector CParseStarMathString::Parse(std::wstring& wsParseString) { std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); + while(itStart != itEnd) { - arEquation.push_back(ParsElement(itStart,itEnd)); + CElement* pTempElement = ParsElement(itStart,itEnd); + if(nullptr == pTempElement) + break; + if(!arEquation.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations || pTempElement->GetBaseType() == TypeElement::Connection) ) + { + AddLeftArgument(arEquation.back(),pTempElement); + arEquation.pop_back(); + } + arEquation.push_back(pTempElement); } return arEquation; } @@ -32,6 +41,12 @@ namespace StarMath { pElement->SetAttribute(arAttributes); pElement->Pars(itStart,itEnd); + if(CheckingTheNextElement(itStart,itEnd,CIndex::IsIndex)) + { + CIndex* pIndex = CIndex::CreateIndex(GetElement(itStart,itEnd)); + pIndex->SetValueIndex(ParsElement(itStart,itEnd)); + pElement->SetIndex(pIndex); + } return pElement; } else return pElement; @@ -47,7 +62,7 @@ namespace StarMath itFirst++; break; } - else if(!m_wsElement.empty() && (*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || (iswdigit(*itFirst) && !iswdigit(m_wsElement.back())) || (iswalpha(*itFirst) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *itFirst || L'>' == *itFirst || L'=' == *itFirst)))) + else if(!m_wsElement.empty() && (*itFirst == L'(' || L')' == *itFirst || *itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || (iswdigit(*itFirst) && !iswdigit(m_wsElement.back())) || (iswalpha(*itFirst) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *itFirst || L'>' == *itFirst || L'=' == *itFirst)))) { return m_wsElement; } @@ -68,16 +83,58 @@ namespace StarMath bool CParseStarMathString::CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)) { std::wstring::iterator itTempVal = itFirst; - std::wstring wsAttributeToken = GetElement(itFirst,itEnd); -// while(true) -// { -// if(wsAttributeToken == L"color") wsAttributeToken = GetElement(itFirst,itEnd); -// wsAttributeToken = GetElement(itFirst,itEnd); -// } + std::wstring wsToken = GetElement(itFirst,itEnd); + TypeElement enTypeAttr = CAttribute::IsAttribute(wsToken); + while(enTypeAttr != TypeElement::undefine && (itFirst != itEnd)) + { + wsToken = GetElement(itFirst,itEnd); + enTypeAttr = CAttribute::IsAttribute(wsToken); + } itFirst = itTempVal; - if(func(wsAttributeToken)) return true; + if(func(wsToken)) return true; else return false; } + bool CParseStarMathString::MoveToNextElement(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + if(itStart !=itEnd) + { + std::wstring wsNextElement = CParseStarMathString::GetElement(itStart,itEnd); + if(L"right" == wsNextElement && (itStart!=itEnd)) wsNextElement = CParseStarMathString::GetElement(itStart,itEnd); + return true; + } + return false; + } + template + void CParseStarMathString::SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) + { + T* pBinOpElement = dynamic_cast(pElementWhichAdd); + pBinOpElement->SetLeftArg(pLeftArg); + pElementWhichAdd = pBinOpElement; + } + + void CParseStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) + { + switch(pElementWhichAdd->GetBaseType()) + { + case TypeElement::BinOperator: + { + SetLeft(pLeftArg, pElementWhichAdd); + break; + } + case TypeElement::SetOperations: + { + SetLeft(pLeftArg, pElementWhichAdd); + break; + } + case TypeElement::Connection: + { + SetLeft(pLeftArg,pElementWhichAdd); + break; + } + default: + break; + } + } //class methods CAttribute CAttribute::~CAttribute() {} @@ -145,7 +202,7 @@ namespace StarMath //class methods CElement CElement::~CElement() {} - CElement::CElement() + CElement::CElement(): pElementIndex(nullptr) {} // TypeElement CElement::GetTypeElement(const std::wstring& wsToken) // { @@ -236,6 +293,7 @@ namespace StarMath { return new CElementBinOperator(TypeElement::plus); } + else if(CElementString::IsDigit(wsToken)) return new CElementString(wsToken); else if (wsToken == L"-") { return new CElementBinOperator(TypeElement::minus); @@ -302,22 +360,104 @@ namespace StarMath } //brace else if(L"{" == wsToken) return new CElementBracket(TypeElement::brace); -// else if(L"(" == wsToken) return TypeElement::round; -// else if(L"[" == wsToken) return TypeElement::square; -// else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; -// else if(L"lbrace" == wsToken) return TypeElement::lbrace; -// else if(L"langle" == wsToken) return TypeElement::langle; -// else if(L"lceil" == wsToken) return TypeElement::lceil; -// else if(L"lfloor" == wsToken) return TypeElement::lfloor; -// else if(L"lline" == wsToken) return TypeElement::lline; -// else if(L"ldline" == wsToken) return TypeElement::ldline; - else if(CElementString::IsDigit(wsToken)) return new CElementString(wsToken); + else if(L"(" == wsToken) return new CElementBracket(TypeElement::round); + else if(L"[" == wsToken) return new CElementBracket(TypeElement::square); + else if(L"ldbracket" == wsToken) return new CElementBracket(TypeElement::ldbracket); + else if(L"lbrace" == wsToken) return new CElementBracket(TypeElement::lbrace); + else if(L"langle" == wsToken) return new CElementBracket(TypeElement::langle); + else if(L"lceil" == wsToken) return new CElementBracket(TypeElement::lceil); + else if(L"lfloor" == wsToken) return new CElementBracket(TypeElement::lfloor); + else if(L"lline" == wsToken) return new CElementBracket(TypeElement::lline); + else if(L"ldline" == wsToken) return new CElementBracket(TypeElement::ldline); + else if(L"intersection" == wsToken) return new CElementSetOperations(TypeElement::intersection); + else if(L"union" == wsToken) return new CElementSetOperations(TypeElement::Union); + else if(L"setminus" == wsToken) return new CElementSetOperations(TypeElement::setminus); + else if(L"setquoyient" == wsToken) return new CElementSetOperations(TypeElement::setquoyient); + else if(L"subseteq" == wsToken) return new CElementSetOperations(TypeElement::subseteq); + else if(L"subset" == wsToken) return new CElementSetOperations(TypeElement::subset); + else if(L"supset" == wsToken) return new CElementSetOperations(TypeElement::supset); + else if(L"supseteq" == wsToken) return new CElementSetOperations(TypeElement::supseteq); + else if(L"nsubset" == wsToken) return new CElementSetOperations(TypeElement::nsubset); + else if(L"nsubseteq" == wsToken) return new CElementSetOperations(TypeElement::nsubseteq); + else if(L"nsupset" == wsToken) return new CElementSetOperations(TypeElement::nsupset); + else if(L"nsubseteq" == wsToken) return new CElementSetOperations(TypeElement::nsubseteq); + else if(L"in" == wsToken) return new CElementSetOperations(TypeElement::in); + else if(L"notin" == wsToken) return new CElementSetOperations(TypeElement::notin); + else if(L"owns" == wsToken) return new CElementSetOperations(TypeElement::owns); + else if(L"approx" == wsToken) return new CElementConnection(TypeElement::approx); + else if(L"sim" == wsToken) return new CElementConnection(TypeElement::sim); + else if(L"simeq" == wsToken) return new CElementConnection(TypeElement::simeq); + else if(L"equiv" == wsToken) return new CElementConnection(TypeElement::equiv); + else if(L"prop" == wsToken) return new CElementConnection(TypeElement::prop); + else if(L"parallel" == wsToken) return new CElementConnection(TypeElement::parallel);\ + else if(L"ortho" == wsToken) return new CElementConnection(TypeElement::ortho); + else if(L"divides" == wsToken) return new CElementConnection(TypeElement::divides); + else if(L"ndivides" == wsToken) return new CElementConnection(TypeElement::ndivides); + else if(L"toward" == wsToken) return new CElementConnection(TypeElement::toward); + else if(L"transl" == wsToken) return new CElementConnection(TypeElement::transl); + else if(L"transr" == wsToken) return new CElementConnection(TypeElement::transr); + else if(L"def" == wsToken) return new CElementConnection(TypeElement::def); + else if(L"=" == wsToken) return new CElementConnection(TypeElement::equals); + else if(L"<>" == wsToken) return new CElementConnection(TypeElement::notequals); + else if(L"<" == wsToken) return new CElementConnection(TypeElement::learrow); + else if(L"<=" == wsToken) return new CElementConnection(TypeElement::learrowequals); + else if(L"leslant" == wsToken) return new CElementConnection(TypeElement::leslant); + else if(L">" == wsToken) return new CElementConnection(TypeElement::riarrow); + else if(L">=" == wsToken) return new CElementConnection(TypeElement::riarrowequals); + else if(L"geslant" == wsToken) return new CElementConnection(TypeElement::geslant); + else if(L"<<" == wsToken) return new CElementConnection(TypeElement::dllearrow); + else if(L">>" == wsToken) return new CElementConnection(TypeElement::dlriarrow); + else if(L"prec" == wsToken) return new CElementConnection(TypeElement::prec); + else if(L"succ" == wsToken) return new CElementConnection(TypeElement::succ); + else if(L"preccurlyeq" == wsToken) return new CElementConnection(TypeElement::preccurlyeq); + else if(L"succcurlyeq" == wsToken) return new CElementConnection(TypeElement::succcurlyeq); + else if(L"precsim" == wsToken) return new CElementConnection(TypeElement::precsim); + else if(L"succsim" == wsToken) return new CElementConnection(TypeElement::succsim); + else if(L"nprec" == wsToken) return new CElementConnection(TypeElement::nprec); + else if(L"nsucc" == wsToken) return new CElementConnection(TypeElement::nsucc); + else if(L"dlarrow" == wsToken) return new CElementConnection(TypeElement::dlarrow); + else if(L"dlrarrow" == wsToken) return new CElementConnection(TypeElement::dlrarrow); + else if(L"drarrow" == wsToken) return new CElementConnection(TypeElement::drarrow); + else if(L"abs" == wsToken) return new CElementFunction(TypeElement::abs); + else if(L"fact" == wsToken) return new CElementFunction(TypeElement::fact); + else if(L"sqrt" == wsToken) return new CElementFunction(TypeElement::sqrt); + else if(L"sin" == wsToken) return new CElementFunction(TypeElement::sin); + else if(L"cos" == wsToken) return new CElementFunction(TypeElement::cos); + else if(L"tan" == wsToken) return new CElementFunction(TypeElement::tan); + else if(L"cot" == wsToken) return new CElementFunction(TypeElement::cot); + else if(L"sinh" == wsToken) return new CElementFunction(TypeElement::sinh); + else if(L"cosh" == wsToken) return new CElementFunction(TypeElement::cosh); + else if(L"tanh" == wsToken) return new CElementFunction(TypeElement::tanh); + else if(L"coth" == wsToken) return new CElementFunction(TypeElement::coth); + else if(L"arcsin" == wsToken) return new CElementFunction(TypeElement::arcsin); + else if(L"arccos" == wsToken) return new CElementFunction(TypeElement::arccos); + else if(L"arctan" == wsToken) return new CElementFunction(TypeElement::arctan); + else if(L"arccot" == wsToken) return new CElementFunction(TypeElement::arccot); + else if(L"arsinh" == wsToken) return new CElementFunction(TypeElement::arsinh); + else if(L"arcosh" == wsToken) return new CElementFunction(TypeElement::arcosh); + else if(L"artanh" == wsToken) return new CElementFunction(TypeElement::artanh); + else if(L"arcoth" == wsToken) return new CElementFunction(TypeElement::arcoth); + else if(L"ln" == wsToken) return new CElementFunction(TypeElement::ln); + else if(L"exp" == wsToken) return new CElementFunction(TypeElement::exp); + else if(L"log" == wsToken) return new CElementFunction(TypeElement::log); else return nullptr; } void CElement::SetAttribute(const std::vector arAttr) { arElementAttributes = arAttr; } + void CElement::SetIndex(CIndex *pIndex) + { + pElementIndex = pIndex; + } + TypeElement CElement::GetBaseType() + { + return enBaseType; + } + void CElement::SetBaseType(const TypeElement &enType) + { + enBaseType = enType; + } //class methods CElementString CElementString::CElementString(const std::wstring& wsTokenString) { @@ -348,6 +488,7 @@ namespace StarMath CElementBinOperator::CElementBinOperator(const TypeElement& enType) { enTypeBinOp = enType; + SetBaseType(TypeElement::BinOperator); } CElementBinOperator::~CElementBinOperator() { @@ -364,82 +505,58 @@ namespace StarMath } void CElementBinOperator::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) { - SetRightArg(CParseStarMathString::ParsElement(itStart,itEnd)); +// нужно сделать функцию для чтения без скобок +// if(enTypeBinOp == TypeElement::frac) +// { + +// } + CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + if(IsBinOperatorLowPrior() && CParseStarMathString::CheckingTheNextElement(itStart,itEnd,IsBinOperatorHightPrior)) + { + CElement* pBinOp = CParseStarMathString::ParsElement(itStart,itEnd); + CParseStarMathString::AddLeftArgument(pTempElement,pBinOp); + SetRightArg(pBinOp); + } + else + SetRightArg(pTempElement); } void CElementBinOperator::SetTypeBinOP(const TypeElement &enType) { enTypeBinOp = enType; } - bool CElementBinOperator::IsBinOperator(const TypeElement& enCheckType) + bool CElementBinOperator::IsBinOperatorHightPrior(const std::wstring& wsToken) { - switch (enCheckType) - { + if(L"cdot" == wsToken) return true; + else if(L"times" == wsToken) return true; + else if(L"over" == wsToken) return true; +// else if(L"frac" == wsToken) return true; + else if(L"div" == wsToken) return true; + else if(L"multipl" == wsToken) return true; + else if(L"division" == wsToken) return true; + else if(L"odot" == wsToken) return true; + else if(L"otimes" == wsToken) return true; + else if(L"odivide" == wsToken) return true; + else if(L"circ" == wsToken) return true; + else if(L"wideslash" == wsToken) return true; + else if(L"widebslash" == wsToken) return true; + } + bool CElementBinOperator::IsBinOperatorLowPrior() + { + switch (enTypeBinOp) { case TypeElement::plus: return true; case TypeElement::minus: return true; - case TypeElement::over: - return true; - case TypeElement::multipl: - return true; - case TypeElement::division: - return true; - case TypeElement::cdot: - return true; - case TypeElement::times: - return true; - case TypeElement::frac: - return true; - case TypeElement::div: - return true; case TypeElement::oplus: return true; case TypeElement::ominus: return true; - case TypeElement::odot: - return true; - case TypeElement::otimes: - return true; - case TypeElement::odivide: - return true; case TypeElement::circ: return true; - case TypeElement::wideslash: - return true; - case TypeElement::widebslash: - return true; default: return false; } } - bool CElementBinOperator::IsLowPriorityBinOp(const TypeElement &enType) - { - switch (enType) - { - case TypeElement::plus: - return true; - case TypeElement::minus: - return true; - case TypeElement::oplus: - return true; - case TypeElement::ominus: - return true; - case TypeElement::circ: - return true; - default: - return false; - } - } - bool CElementBinOperator::IsHighPriorityBinOp(const TypeElement &enType) - { - switch(enType) - { - case TypeElement::over: - return true; - default: - return false; - } - } //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) { @@ -458,17 +575,231 @@ namespace StarMath if(L"}" == wsToken) return true; else if(L")" == wsToken) return true; else if(L"]" == wsToken) return true; + else if(L"rdbracket" == wsToken) return true; + else if(L"rbrace" == wsToken) return true; + else if(L"rangle" == wsToken) return true; + else if(L"rceil" == wsToken) return true; + else if(L"rfloor" == wsToken) return true; + else if(L"rline" == wsToken) return true; + else if(L"rdline" == wsToken) return true; + else if(L"right" == wsToken) return true; else return false; } - //нужно поправить GetElement(беру его тут + в методе ParsElement) + // правка if void CElementBracket::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) { - std::wstring wsToken = CParseStarMathString::GetElement(itStart,itEnd) ; - while(L"right" != wsToken && !IsBracketClose(wsToken)) + while(!CParseStarMathString::CheckingTheNextElement(itStart,itEnd,IsBracketClose)) { - arBrecketValue.push_back(CParseStarMathString::ParsElement(itStart,itEnd)); - wsToken = CParseStarMathString::GetElement(itStart,itEnd); + CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + if(!arBrecketValue.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations) ) + { + CParseStarMathString::AddLeftArgument(arBrecketValue.back(),pTempElement); + arBrecketValue.pop_back(); + } + arBrecketValue.push_back(pTempElement); } + //доработать() + if(!CParseStarMathString::MoveToNextElement(itStart,itEnd)); + } +//class methods CElementSpecialSymbol + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) + { + enTypeSpecial = enType; + } + CElementSpecialSymbol::~CElementSpecialSymbol() + {} + void CElementSpecialSymbol::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + } +//class methods CElementSetOperations + CElementSetOperations::CElementSetOperations(const TypeElement &enType) + { + enTypeSet = enType; + SetBaseType(TypeElement::SetOperations); + } + CElementSetOperations::~CElementSetOperations() + { + delete pLeftArgument; + delete pRightArgument; + } + void CElementSetOperations::SetLeftArg(CElement *pElement) + { + pLeftArgument = pElement; + } + CElement* CElementSetOperations::GetLeftArg() + { + return pLeftArgument; + } + void CElementSetOperations::SetRightArg(CElement *pElement) + { + pRightArgument = pElement; + } + CElement* CElementSetOperations::GetRightArg() + { + return pRightArgument; + } + void CElementSetOperations::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + if(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior)) + { + CElement* pBinOpElement = CParseStarMathString::ParsElement(itStart,itEnd); + CParseStarMathString::AddLeftArgument(pTempElement,pBinOpElement); + SetRightArg(pBinOpElement); + } + else SetRightArg(pTempElement); + } + bool CElementSetOperations::IsSetOperation(const std::wstring &wsToken) + { + if(L"union" == wsToken) return true; + else return false; + } +//class methods CElementConnection + CElementConnection::CElementConnection(const TypeElement& enType) + { + enTypeCon = enType; + SetBaseType(TypeElement::Connection); + } + CElementConnection::~CElementConnection() + { + delete pLeftArgument; + delete pRightArgument; + } + void CElementConnection::SetRightArg(CElement *pElement) + { + pRightArgument = pElement; + } + CElement* CElementConnection::GetRightArg() + { + return pRightArgument; + } + void CElementConnection::SetLeftArg(CElement *pElement) + { + pLeftArgument = pElement; + } + CElement* CElementConnection::GetLeftArg() + { + return pLeftArgument; + } + void CElementConnection::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + if(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior)) + { + CElement* pBinOp = CParseStarMathString::ParsElement(itStart,itEnd); + CParseStarMathString::AddLeftArgument(pTempElement,pBinOp); + SetRightArg(pBinOp); + } + else SetRightArg(pTempElement); + } + bool CElementConnection::IsConnection(const std::wstring& wsToken) + { + if(L"def" == wsToken) return true; + else return false; + } +//class methods CIndex + CIndex::CIndex(const TypeElement& enType) + { + enTypeIndex = enType; + } + CIndex::~CIndex() + { + delete pValueIndex; + } + void CIndex::SetValueIndex(CElement *pElement) + { + pValueIndex = pElement; + } + CElement* CIndex::GetValueIndex() + { + return pValueIndex; + } + bool CIndex::IsIndex(const std::wstring &wsCheckToken) + { + if(L"^" == wsCheckToken) return true; + else if(L"_" == wsCheckToken) return true; + else if(L"lsup" == wsCheckToken) return true; + else if(L"lsub" == wsCheckToken) return true; + else if(L"csup" == wsCheckToken) return true; + else if(L"csub" == wsCheckToken) return true; + else return false; + } + CIndex* CIndex::CreateIndex(const std::wstring &wsToken) + { + if(L"^" == wsToken) return new CIndex(TypeElement::upper); + else if(L"_" == wsToken) return new CIndex(TypeElement::lower); + else if(L"lsup" == wsToken) return new CIndex(TypeElement::lsup); + else if(L"lsub" == wsToken) return new CIndex(TypeElement::lsub); + else if(L"csup" == wsToken) return new CIndex(TypeElement::csup); + else if(L"csub" == wsToken) return new CIndex(TypeElement::csub); + else return nullptr; + } +//class methods CElementFunction + CElementFunction::CElementFunction(const TypeElement &enType) + { + enTypeFunction = enType; + SetBaseType(TypeElement::Function); + } + CElementFunction::~CElementFunction() + { + delete pValue; + } + void CElementFunction::SetValueFunction(CElement *pElement) + { + pValue = pElement; + } + CElement* CElementFunction::GetValueFunction() + { + return pValue; + } + + void CElementFunction::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + SetValueFunction(CParseStarMathString::ParsElement(itStart,itEnd)); + } +//class methods CElementOperation + CElementOperator::CElementOperator(const TypeElement &enType) + { + enTypeOperator = enType; + SetBaseType(TypeElement::Operation); + } + CElementOperator::~CElementOperator() + { + delete pValueOperator; + delete pValueFrom; + delete pValueTo; + } + void CElementOperator::SetValueOperator(CElement *pElement) + { + pValueOperator = pElement; + } + CElement* CElementOperator::GetValueOperator() + { + return pValueOperator; + } + void CElementOperator::SetFromValue(CElement *pElement) + { + pValueFrom = pElement; + } + CElement* CElementOperator::GetFromValue() + { + return pValueFrom; + } + void CElementOperator::SetToValue(CElement *pElement) + { + pValueTo = pElement; + } + CElement* CElementOperator::GetToValue() + { + return pValueTo; + } + void CElementOperator::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + { + do + { + CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + + }while(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior) || CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementSetOperations::IsSetOperation) || CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementConnection::IsConnection)); } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 613a5caf882..f60e0ae9e63 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -18,6 +18,9 @@ namespace StarMath private: TypeElement enTypeAttr; }; + + class CIndex; + class CElement { public: @@ -28,8 +31,27 @@ namespace StarMath static CElement* CreateElement(const std::wstring& wsToken); //static TypeElement GetTypeElement(const std::wstring& wsToken); void SetAttribute(const std::vector arAttr); + void SetIndex(CIndex* pIndex); + void SetBaseType(const TypeElement& enType); + TypeElement GetBaseType(); private: + CIndex* pElementIndex; std::vector arElementAttributes; + TypeElement enBaseType; + }; + + class CIndex + { + public: + CIndex(const TypeElement& enType); + ~CIndex(); + void SetValueIndex(CElement* pElement); + CElement* GetValueIndex(); + static bool IsIndex(const std::wstring& wsCheckToken); + static CIndex* CreateIndex(const std::wstring& wsToken); + private: + CElement* pValueIndex; + TypeElement enTypeIndex; }; class CElementString: public CElement @@ -38,10 +60,10 @@ namespace StarMath CElementString(const std::wstring& wsTokenString); virtual ~CElementString(); void SetString(const std::wstring& wsTokenString); - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; std::wstring GetString(); static bool IsDigit(const std::wstring& wsCheckToken); private: + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; std::wstring wsString; }; @@ -50,34 +72,109 @@ namespace StarMath public: CElementBinOperator(const TypeElement& enType); virtual ~CElementBinOperator(); - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; void SetLeftArg(CElement* pElement); void SetRightArg(CElement* pElement); void SetTypeBinOP(const TypeElement& enType); CElement* GetRightArg(); CElement* GetLeftArg(); - static bool IsBinOperator(const TypeElement& enCheckType); + static bool IsBinOperatorHightPrior(const std::wstring& wsToken); private: - bool IsLowPriorityBinOp(const TypeElement& enType); - bool IsHighPriorityBinOp(const TypeElement& enType); + bool IsBinOperatorLowPrior(); + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; CElement* pLeftArgument; CElement* pRightArgument; TypeElement enTypeBinOp; }; + class CElementOperator: public CElement + { + public: + CElementOperator(const TypeElement& enType); + virtual ~CElementOperator(); + void SetValueOperator(CElement* pElement); + CElement* GetValueOperator(); + void SetFromValue(CElement* pElement); + CElement* GetFromValue(); + void SetToValue(CElement* pElement); + CElement* GetToValue(); + private: + void Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) override; + CElement* pValueOperator; + CElement* pValueFrom; + CElement* pValueTo; + TypeElement enTypeOperator; + }; + class CElementBracket: public CElement { public: CElementBracket(const TypeElement& enType); virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; private: + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; static bool IsBracketClose(const std::wstring& wsToken); TypeElement enTypeBracket; std::vector arBrecketValue; }; + class CElementSetOperations: public CElement + { + public: + CElementSetOperations(const TypeElement& enType); + virtual ~CElementSetOperations(); + void SetLeftArg(CElement* pElement); + CElement* GetLeftArg(); + void SetRightArg(CElement* pElement); + CElement* GetRightArg(); + static bool IsSetOperation(const std::wstring& wsToken); + private: + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; + CElement* pLeftArgument; + CElement* pRightArgument; + TypeElement enTypeSet; + }; + + class CElementConnection: public CElement + { + public: + CElementConnection(const TypeElement& enType); + virtual ~CElementConnection(); + void SetRightArg(CElement* pElement); + CElement* GetRightArg(); + void SetLeftArg(CElement* pElement); + CElement* GetLeftArg(); + static bool IsConnection(const std::wstring& wsToken); + private: + void Pars(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) override; + CElement* pLeftArgument; + CElement* pRightArgument; + TypeElement enTypeCon; + }; + + class CElementFunction: public CElement + { + public: + CElementFunction(const TypeElement& enType); + virtual ~CElementFunction(); + void SetValueFunction(CElement* pElement); + CElement* GetValueFunction(); + private: + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; + CElement* pValue; + TypeElement enTypeFunction; + }; + + class CElementSpecialSymbol: public CElement + { + public: + CElementSpecialSymbol(const TypeElement& enType); + virtual ~CElementSpecialSymbol(); + private: + void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; + TypeElement enTypeSpecial; + }; + class CParseStarMathString { public: @@ -85,6 +182,10 @@ namespace StarMath static CElement* ParsElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd); static std::wstring GetElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); static bool CheckingTheNextElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)); + static bool MoveToNextElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); + static void AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); + template + static void SetLeft(CElement* pLeftArg, CElement* pElementWhichaAdd); private: std::vector arEquation; }; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 8cb8406ea5f..c46f56ffd8d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -7,16 +7,17 @@ enum class TypeElement{ //global String, BinOperator, + SetOperations, Operator, Bracket, UnarSign, Attribute, SpecialSymbol, Function, - TwoArgumentContainer, Operation, Index, Matrix, + Connection, //binoop cdot, times, @@ -103,6 +104,7 @@ enum class TypeElement{ mline, grid, dlgrid, + //setopetions intersection, Union, setminus, @@ -118,6 +120,7 @@ enum class TypeElement{ in, notin, owns, + //connection approx, sim, simeq, @@ -152,6 +155,7 @@ enum class TypeElement{ dlarrow, dlrarrow, drarrow, + // emptyset, aleph, setN, @@ -173,6 +177,7 @@ enum class TypeElement{ laplace, fourier, backepsilon, + //function abs, fact, sqrt, @@ -196,12 +201,14 @@ enum class TypeElement{ ln, exp, log, + //index upper, lower, lsup, lsub, csup, csub, + // binom, stack, matrix, From 6374e3ba2307315e99d12dcb89944fe6c6beb77a Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 31 Oct 2023 17:17:17 +0300 Subject: [PATCH 171/794] Refactoring --- DocxRenderer/src/logic/Page.cpp | 72 +++++++++-------- DocxRenderer/src/logic/Page.h | 39 ++++----- DocxRenderer/src/logic/elements/BaseItem.cpp | 61 +++++++------- DocxRenderer/src/logic/elements/BaseItem.h | 81 +++++++++++-------- DocxRenderer/src/logic/elements/Cell.cpp | 40 +++------ DocxRenderer/src/logic/elements/Cell.h | 6 +- DocxRenderer/src/logic/elements/ContText.cpp | 34 ++++---- DocxRenderer/src/logic/elements/ContText.h | 45 +++++------ DocxRenderer/src/logic/elements/Converter.cpp | 61 ++++++-------- DocxRenderer/src/logic/elements/Converter.h | 18 ++--- DocxRenderer/src/logic/elements/DropCap.cpp | 2 +- DocxRenderer/src/logic/elements/DropCap.h | 6 +- DocxRenderer/src/logic/elements/Image.cpp | 9 +-- DocxRenderer/src/logic/elements/Image.h | 6 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 6 +- DocxRenderer/src/logic/elements/Paragraph.h | 8 +- DocxRenderer/src/logic/elements/Shape.cpp | 32 ++++---- DocxRenderer/src/logic/elements/Shape.h | 27 +++---- DocxRenderer/src/logic/elements/Table.cpp | 25 ++---- DocxRenderer/src/logic/elements/Table.h | 12 +-- DocxRenderer/src/logic/elements/TextLine.cpp | 42 +++++----- DocxRenderer/src/logic/elements/TextLine.h | 8 +- 22 files changed, 293 insertions(+), 347 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index cfc9fce688b..669c53b4a13 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -44,8 +44,12 @@ namespace NSDocxRenderer void CPage::Clear() { + for(auto& val : m_arConts) + delete val; + m_arConts.clear(); + for(auto& val : m_arTextLine) - delete val; + delete val; m_arTextLine.clear(); for(auto& val : m_arDiacriticalSymbol) @@ -53,11 +57,11 @@ namespace NSDocxRenderer m_arDiacriticalSymbol.clear(); for(auto& val : m_arImages) - delete val; + delete val; m_arImages.clear(); for(auto& val : m_arShapes) - delete val; + delete val; m_arShapes.clear(); for(auto& val : m_arOutputObjects) @@ -364,7 +368,6 @@ namespace NSDocxRenderer auto pCont = new CContText(m_pFontManager); - pCont->m_dLeft = dTextX; pCont->m_dBaselinePos = dBaseLinePos; @@ -394,10 +397,8 @@ namespace NSDocxRenderer // собираем отдельно, т.к. такие символы не имею размера m_dWidth if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) m_arDiacriticalSymbol.push_back(pCont); - - // остальные символы сразу добавляем в текстовые линии else - AddContToTextLine(pCont); + m_arConts.push_back(pCont); } void CPage::AddContToTextLine(CContText *pCont) @@ -435,6 +436,7 @@ namespace NSDocxRenderer void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) { + CreateTextLines(); AnalyzeCollectedShapes(); AnalyzeCollectedTextLines(); TryMergeShapes(); @@ -442,6 +444,17 @@ namespace NSDocxRenderer WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } + void CPage::SortConts() + { + } + + void CPage::CreateTextLines() + { + CBaseItem::SortTopLeft(m_arConts); + for(auto&& cont : m_arConts) + AddContToTextLine(cont); + } + void CPage::TryMergeShapes() { if(m_arShapes.empty()) @@ -914,8 +927,8 @@ namespace NSDocxRenderer //todo для увеличения производительности можно попробовать использовать другие контейнеры CBaseItem::SortByBaseline(m_arTextLine); - for (size_t i = 0; i < m_arTextLine.size(); ++i) - CBaseItem::SortByLeft(m_arTextLine[i]->m_arConts); +// for(auto&& line: m_arTextLine) +// CBaseItem::SortByLeft(line->m_arConts); AnalyzeDropCaps(); AnalyzeCollectedConts(); @@ -928,7 +941,7 @@ namespace NSDocxRenderer SingletonInstance().BuildLines(m_arTextLine); SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, - CBaseItem::ElemType::etParagraph, + COutputObject::eOutputType::etParagraph, m_arTextLine, m_arTables, m_arOutputObjects, m_pParagraphStyleManager); } @@ -1582,10 +1595,10 @@ namespace NSDocxRenderer } } - SingletonInstance().BuildLines(pCell->m_arTextLine); - SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, CBaseItem::ElemType::etCell, - pCell->m_arTextLine, pCell->m_arOutputObjects, - m_pParagraphStyleManager); +// SingletonInstance().BuildLines(pCell->m_arTextLine); +// SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, COutputObject::eOutputType::etCell, +// pCell->m_arTextLine, pCell->m_arOutputObjects, +// m_pParagraphStyleManager); pRow->AddContent(pCell); } @@ -1617,7 +1630,7 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - if (m_arOutputObjects[i]->m_eType == CBaseItem::ElemType::etShape) + if (m_arOutputObjects[i]->m_eType == COutputObject::eOutputType::etShape) { bIsTextShapePresent = true; break; @@ -1649,14 +1662,9 @@ namespace NSDocxRenderer { auto pObj = m_arOutputObjects[i]; - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etShape: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } + CShape* pSahpe = nullptr; + if((pSahpe = dynamic_cast(pObj)) != nullptr) + pSahpe->ToXml(oWriter); } } @@ -1669,17 +1677,13 @@ namespace NSDocxRenderer { auto pObj = m_arOutputObjects[i]; - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - case CBaseItem::ElemType::etTable: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } + CParagraph* pParagraph = nullptr; + if((pParagraph = dynamic_cast(pObj)) != nullptr) + pParagraph->ToXml(oWriter); + + CTable* pTable = nullptr; + if((pTable = dynamic_cast(pObj)) != nullptr) + pTable->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 6135741dd41..c48f7e212cd 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -38,8 +38,9 @@ namespace NSDocxRenderer std::vector m_arDiacriticalSymbol; std::vector m_arTextLine; std::vector m_arShapes; + std::vector m_arConts; - std::vector m_arOutputObjects; + std::vector m_arOutputObjects; std::vector m_arPeaks; std::vector m_arCells; @@ -56,7 +57,6 @@ namespace NSDocxRenderer bool m_bIsRecalcFontSize {true}; LONG m_lLastCommand = 0; - public: CPage(NSFonts::IApplicationFonts* pFonts); ~CPage(); void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, @@ -92,36 +92,39 @@ namespace NSDocxRenderer void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, const double& fX, const double& fY, const double& fWidth, const double& fHeight, const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); - void AddContToTextLine(CContText *pCont); void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); - void AnalyzeCollectedShapes(); - void BuildTables(); - void CollectPeaks(); - void CreatCells(); - void BuildRows(); - void SelectCurrentRow(const CCell *pCell); - void DetermineLinesType(); + private: + void SortConts(); + void CreateTextLines(); + void AddContToTextLine(CContText *pCont); - //Собранные для текущей страницы данные нужно проанализировать и сгруппировать, лишнее удалить void AnalyzeCollectedTextLines(); void AnalyzeCollectedConts(); void DetermineStrikeoutsUnderlinesHighlights(); - bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + + void AnalyzeDropCaps(); void AddDiacriticalSymbols(); void MergeLinesByVertAlignType(); void DetermineTextColumns(); - void DetermineDominantGraphics(); + + bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + + void AnalyzeCollectedShapes(); + void BuildTables(); + void CollectPeaks(); + void CreatCells(); + void BuildRows(); + void SelectCurrentRow(const CCell *pCell); + void DetermineLinesType(); void TryMergeShapes(); - void AnalyzeDropCaps(); - //конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку + // конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку void ToXml(NSStringUtils::CStringBuilder& oWriter); - void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); }; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index ed61cd34a4f..14fa15ed689 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -11,7 +11,7 @@ namespace NSDocxRenderer return *this; } - m_eType = oSrc.m_eType; +// m_eType = oSrc.m_eType; m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; m_dLeft = oSrc.m_dLeft; @@ -24,30 +24,7 @@ namespace NSDocxRenderer return *this; } - void CBaseItem::AddContent(CBaseItem* pObj) - { - m_dBaselinePos = std::max(m_dBaselinePos, pObj->m_dBaselinePos); - - if ((pObj->m_dLeft < m_dLeft) || (pObj->m_dLeft > 0 && m_dLeft == 0.0)) - { - m_dLeft = pObj->m_dLeft; - } - - if ((pObj->m_dRight > m_dRight) || (pObj->m_dRight > 0 && m_dRight == 0.0)) - { - m_dRight = pObj->m_dRight; - } - - if (m_dTop > pObj->m_dTop || m_dTop == 0.0) - { - m_dTop = pObj->m_dTop; - } - - m_dWidth = m_dRight - m_dLeft; - m_dHeight = m_dBaselinePos - m_dTop; - } - - eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) + eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc) const { if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos) { @@ -99,7 +76,7 @@ namespace NSDocxRenderer } } - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) + eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) const { if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) { @@ -151,7 +128,7 @@ namespace NSDocxRenderer } } - bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) + bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept { eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); @@ -159,7 +136,7 @@ namespace NSDocxRenderer eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); } - bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) + bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept { eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); @@ -167,11 +144,6 @@ namespace NSDocxRenderer eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext); } - double CBaseItem::CalculateBeforeSpacing(double dPreviousBaseline) - { - return m_dTop - dPreviousBaseline; - } - bool CBaseItem::IsCurrentLeftOfNext(const CBaseItem* oSrc) { return m_dLeft < oSrc->m_dLeft; @@ -181,4 +153,27 @@ namespace NSDocxRenderer { return m_dBaselinePos < oSrc->m_dBaselinePos; } + + void CBaseItem::AddContent(CBaseItem* pItem) + { + m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos); + + if ((pItem->m_dLeft < m_dLeft) || (pItem->m_dLeft > 0 && m_dLeft == 0.0)) + m_dLeft = pItem->m_dLeft; + + if ((pItem->m_dRight > m_dRight) || (pItem->m_dRight > 0 && m_dRight == 0.0)) + m_dRight = pItem->m_dRight; + + if (m_dTop > pItem->m_dTop || m_dTop == 0.0) + m_dTop = pItem->m_dTop; + + m_dWidth = m_dRight - m_dLeft; + m_dHeight = m_dBaselinePos - m_dTop; + } + + COutputObject& COutputObject::operator= (const COutputObject& oObj) + { + m_eType = oObj.m_eType; + return *this; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 118b8548c96..39714c5cbcc 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,5 +1,6 @@ #pragma once #include "../DesktopEditor/common/StringBuilder.h" +#include "src/resources/Constants.h" #include namespace NSDocxRenderer @@ -39,52 +40,32 @@ namespace NSDocxRenderer class CBaseItem { public: - enum class ElemType - { - etContText = 0, - etTextLine = 1, - etParagraph = 2, - etImage = 3, - etShape = 4, - etCell = 5, - etRow = 6, - etTable = 7, - etDropCap = 8, - }; - - ElemType m_eType; - bool m_bIsNotNecessaryToUse {false}; - //General - double m_dLeft {0.0}; double m_dTop {0.0}; - double m_dWidth {0.0}; + double m_dBaselinePos {0.0}; double m_dHeight {0.0}; - //Secondary - double m_dBaselinePos {0.0}; + double m_dLeft {0.0}; double m_dRight {0.0}; + double m_dWidth {0.0}; - public: - CBaseItem(const ElemType& eType): m_eType(eType) {} - virtual ~CBaseItem() {} - virtual void Clear() = 0; - - CBaseItem& operator=(const CBaseItem& oSrc); + CBaseItem() = default; + virtual ~CBaseItem() = default; - virtual void AddContent(CBaseItem* pObj); - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; + virtual void Clear() = 0; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; + virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; + virtual void AddContent(CBaseItem* pItem); - bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj); - bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj); + bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept; + bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept; - double CalculateBeforeSpacing(double dPreviousBaseline); + CBaseItem& operator=(const CBaseItem& oSrc); - template + template static void SortByLeft(std::vector& oArray) { std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { @@ -92,7 +73,7 @@ namespace NSDocxRenderer }); } - template + template static void SortByBaseline(std::vector& oArray) { std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { @@ -100,8 +81,38 @@ namespace NSDocxRenderer }); } + template + static void SortTopLeft(std::vector& oArray) + { + std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { + if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + return a->m_dLeft < b->m_dLeft; + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + } + private: bool IsCurrentLeftOfNext(const CBaseItem* oSrc); bool IsCurrentAboveOfNext(const CBaseItem* oSrc); }; + + class COutputObject : public CBaseItem + { + public: + enum class eOutputType + { + etAny = 0, + etParagraph = 1, + etShape = 2, + etTable = 3 + }; + + COutputObject() : m_eType(eOutputType::etAny) {} + COutputObject(eOutputType eType) : m_eType(eType) {} + virtual ~COutputObject() = default; + + COutputObject& operator= (const COutputObject& oObj); + + eOutputType m_eType; + }; } diff --git a/DocxRenderer/src/logic/elements/Cell.cpp b/DocxRenderer/src/logic/elements/Cell.cpp index 2f739b8bdd6..d178107c76a 100644 --- a/DocxRenderer/src/logic/elements/Cell.cpp +++ b/DocxRenderer/src/logic/elements/Cell.cpp @@ -3,10 +3,6 @@ namespace NSDocxRenderer { - CCell::CCell() : CBaseItem(ElemType::etCell) - { - } - CCell::~CCell() { Clear(); @@ -15,32 +11,19 @@ namespace NSDocxRenderer void CCell::Clear() { m_arTextLine.clear(); + for(size_t i = 0; i < m_arOutputObjects.size(); ++i) - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->Clear(); - break; - default: - pObj->Clear(); - break; - } - } + m_arOutputObjects[i]->Clear(); m_arOutputObjects.clear(); } - void CCell::AddContent(CBaseItem* pObj) + void CCell::AddContent(CBaseItem* pItem) { - CBaseItem::AddContent(pObj); - - m_arTextLine.push_back(dynamic_cast(pObj)); + CBaseItem::AddContent(pItem); + m_arTextLine.push_back(dynamic_cast(pItem)); } - void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) + void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) const { if (m_bIsNotNecessaryToUse) { @@ -113,14 +96,9 @@ namespace NSDocxRenderer { auto pObj = m_arOutputObjects[i]; - switch(pObj->m_eType) - { - case CBaseItem::ElemType::etParagraph: - dynamic_cast(pObj)->ToXml(oWriter); - break; - default: - break; - } + CParagraph* pParagraph = nullptr; + if((pParagraph = dynamic_cast(pObj)) != nullptr) + pParagraph->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/elements/Cell.h b/DocxRenderer/src/logic/elements/Cell.h index c47f8d8e7d3..43f492bad8d 100644 --- a/DocxRenderer/src/logic/elements/Cell.h +++ b/DocxRenderer/src/logic/elements/Cell.h @@ -76,11 +76,11 @@ namespace NSDocxRenderer std::vector m_arOutputObjects; public: - CCell(); + CCell() = default; virtual ~CCell(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void AddContent(CBaseItem* pItem) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void SetParameters(CPeak *pPeak, eCorners eCorner); }; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 4feb830e3fb..2441bf82309 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,13 +5,7 @@ namespace NSDocxRenderer { - CContText::CContText(CFontManager* pManager): - CBaseItem(ElemType::etContText), m_pManager(pManager) - { - } - - CContText::CContText(const CContText& rCont): - CBaseItem(ElemType::etContText) + CContText::CContText(const CContText& rCont) { *this = rCont; } @@ -99,34 +93,36 @@ namespace NSDocxRenderer } } - eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* pItem) const noexcept { - if(oSrc->m_eType != ElemType::etContText) - return CBaseItem::GetVerticalCrossingType(oSrc); + const CContText* pCont = nullptr; + if((pCont = dynamic_cast(pItem)) == nullptr) + return CBaseItem::GetVerticalCrossingType(pItem); auto m_dTop_copy = m_dTop; - auto m_dTop_copy_src = oSrc->m_dTop; + auto m_dTop_copy_src = pCont->m_dTop; - m_dTop = m_dBaselinePos - m_dTrueHeight; - const_cast(oSrc)->m_dTop = oSrc->m_dBaselinePos - static_cast(oSrc)->m_dTrueHeight; + // call CBaseItem::GetVerticalCrossingType(oSrc) and not create copy, so const_cast was used + const_cast(pCont)->m_dTop = m_dBaselinePos - m_dTrueHeight; + const_cast(pCont)->m_dTop = pCont->m_dBaselinePos - pCont->m_dTrueHeight; - auto vert_cross = CBaseItem::GetVerticalCrossingType(oSrc); + auto vert_cross = CBaseItem::GetVerticalCrossingType(pCont); if(vert_cross == eVerticalCrossingType::vctCurrentAboveNext && - (m_dBaselinePos - oSrc->m_dTop < m_dTrueHeight * 0.3)) + (m_dBaselinePos - pCont->m_dTop < m_dTrueHeight * 0.3)) vert_cross = eVerticalCrossingType::vctNoCrossingCurrentAboveNext; if(vert_cross == eVerticalCrossingType::vctCurrentBelowNext && - (oSrc->m_dBaselinePos - m_dTop < static_cast(oSrc)->m_dTrueHeight * 0.3)) + (pCont->m_dBaselinePos - m_dTop < pCont->m_dTrueHeight * 0.3)) vert_cross = eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - m_dTop = m_dTop_copy; - const_cast(oSrc)->m_dTop = m_dTop_copy_src; + const_cast(pCont)->m_dTop = m_dTop_copy; + const_cast(pCont)->m_dTop = m_dTop_copy_src; return vert_cross; } - void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) const { if (m_bIsNotNecessaryToUse) { diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index fa27923c124..99d5da30595 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -23,48 +23,47 @@ namespace NSDocxRenderer public: std::shared_ptr m_pFontStyle {nullptr}; - bool m_bIsStrikeoutPresent {false}; - bool m_bIsDoubleStrikeout {false}; + bool m_bIsStrikeoutPresent{false}; + bool m_bIsDoubleStrikeout{false}; - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; + bool m_bIsHighlightPresent{false}; + LONG m_lHighlightColor{c_iBlackColor}; - bool m_bIsUnderlinePresent {false}; - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; + bool m_bIsUnderlinePresent{false}; + eLineType m_eUnderlineType{eLineType::ltUnknown}; + LONG m_lUnderlineColor{c_iBlackColor}; - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; + bool m_bIsShadowPresent{false}; + bool m_bIsOutlinePresent{false}; + bool m_bIsEmbossPresent{false}; + bool m_bIsEngravePresent{false}; NSStringUtils::CStringUTF32 m_oText; - double m_dSpaceWidthMM {0}; - bool m_bSpaceIsNotNeeded {false}; + double m_dSpaceWidthMM{0}; + bool m_bSpaceIsNotNeeded{false}; - double m_dWidthSelected {0}; - double m_dSpaceWidthSelected {0}; + double m_dWidthSelected{0}; + double m_dSpaceWidthSelected{0}; eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CFontManager* m_pManager {nullptr}; + CFontManager* m_pManager{nullptr}; - CShape* m_pShape {nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - const CContText* m_pCont {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + CShape* m_pShape{nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. + const CContText* m_pCont{nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - UINT m_iNumDuplicates {0}; + UINT m_iNumDuplicates{0}; double m_dTrueHeight{0}; public: - CContText(CFontManager* pManager); + CContText(CFontManager* pManager) : m_pManager(pManager) {} CContText(const CContText& rCont); virtual ~CContText(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final {}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override final; CContText& operator= (const CContText& rCont); diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index d3caa1b7005..5381e245046 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -70,9 +70,9 @@ namespace NSDocxRenderer } } - void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, CBaseItem::ElemType eBaseType, + void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, std::vector& rTextLines, - std::vector& rOutputObjects, + std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager) { std::vector oStubVector; //просто объект-заглушка @@ -82,8 +82,8 @@ namespace NSDocxRenderer // eBaseType == etCell или etParagraph // eType == 2 - 5 из TextAssociationType void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects, + COutputObject::eOutputType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager) { CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; @@ -95,7 +95,7 @@ namespace NSDocxRenderer eVerticalCrossingType eCrossingType; bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; - bool bIsNeedParagraphToShape = eType == TextAssociationType::tatParagraphToShape && eBaseType == CBaseItem::ElemType::etParagraph; + bool bIsNeedParagraphToShape = eType == TextAssociationType::tatParagraphToShape && eBaseType == COutputObject::eOutputType::etParagraph; // CTable* pCurrTable = nullptr; // size_t nTableIndex = 0; @@ -184,14 +184,11 @@ namespace NSDocxRenderer // } dPrevBeforeSpacing = dCurrBeforeSpacing; - if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) - { - dCurrBeforeSpacing = 0; - } - else - { - dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight - dPreviousStringBaseline; - } +// if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) +// { +// dCurrBeforeSpacing = 0; +// } + dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight - dPreviousStringBaseline; dPreviousStringBaseline = pCurrLine->m_dBaselinePos; //Если у текущей линии есть дубликаты, то создаем из них шейпы @@ -338,9 +335,9 @@ namespace NSDocxRenderer if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) { pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) { @@ -351,9 +348,9 @@ namespace NSDocxRenderer else { pParagraph->m_dLeft = pCurrLine->m_dLeft; - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; pParagraph->m_dRight = pCurrLine->m_dRight; - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pCurrLine->m_dWidth; pParagraph->m_bIsNeedFirstLineIndent = false; @@ -418,9 +415,9 @@ namespace NSDocxRenderer pParagraph->m_nNumLines++; pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : pParagraph->m_dLeft; + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = eBaseType == CBaseItem::ElemType::etCell ? 0 : dPageWidth - pParagraph->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; @@ -438,7 +435,7 @@ namespace NSDocxRenderer dPrevBeforeSpacing = dCurrBeforeSpacing; dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing)/2; //наверное лучше так... текст может быть уже, чем в оригинале + dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing) / 2; //наверное лучше так... текст может быть уже, чем в оригинале if (pNextLine) { @@ -513,7 +510,7 @@ namespace NSDocxRenderer } void CConverter::CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, - const double *pBeforeSpacing, std::vector& rOutputObjects) + const double *pBeforeSpacing, std::vector& rOutputObjects) { auto pParagraph = new CParagraph(); pParagraph->m_arLines.push_back(pLine); @@ -542,7 +539,7 @@ namespace NSDocxRenderer rOutputObjects.push_back(pParagraph); } - void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector &rOutputObjects) + void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects) { auto pParagraph = new CParagraph(); @@ -569,7 +566,7 @@ namespace NSDocxRenderer } void CConverter::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText, double dPageWidth, - std::vector &rOutputObjects) + std::vector& rOutputObjects) { if (!pParagraph) { @@ -579,9 +576,9 @@ namespace NSDocxRenderer bool bIsShapesPresent = false; CShape* pBackShape = nullptr; - for (size_t i = 0; i < rOutputObjects.size(); ++i) + for (size_t i = 0; i < rOutputObjects.size(); ++i) { - if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) { continue; } @@ -629,7 +626,7 @@ namespace NSDocxRenderer } } - void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) + void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) { if (!pTable) { @@ -653,11 +650,11 @@ namespace NSDocxRenderer rOutputObjects.push_back(pShape); } - void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) + void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) { for (size_t i = 0; i < rOutputObjects.size(); ++i) { - if (rOutputObjects[i]->m_eType != CBaseItem::ElemType::etShape) + if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) { continue; } @@ -677,7 +674,7 @@ namespace NSDocxRenderer switch(pObj->m_eType) { - case CBaseItem::ElemType::etParagraph: + case COutputObject::eOutputType::etParagraph: { auto pParagraph = dynamic_cast(pObj); @@ -692,12 +689,6 @@ namespace NSDocxRenderer pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; } break; - case CBaseItem::ElemType::etTable: - { - auto pTable = dynamic_cast(pObj); - //todo - } - break; default: break; } diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h index 8225ca40ef5..de9ae01631b 100644 --- a/DocxRenderer/src/logic/elements/Converter.h +++ b/DocxRenderer/src/logic/elements/Converter.h @@ -11,17 +11,17 @@ namespace NSDocxRenderer void DetermineDominantGraphics(std::vector& rTextLines); void BuildParagraphes(double dPageWidth, TextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector &rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); + COutputObject::eOutputType eBaseType, std::vector& rTextLines, + std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); void BuildParagraphes(double dPageWidth, TextAssociationType eType, - CBaseItem::ElemType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector &rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); + COutputObject::eOutputType eBaseType, std::vector& rTextLines, + std::vector& rTables, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); - void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector &rOutputObjects); - void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); - void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector &rOutputObjects); - void CreateShapeFormTable(CTable* pParagraph, std::vector &rOutputObjects); - void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); + void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector& rOutputObjects); + void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); + void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector& rOutputObjects); + void CreateShapeFormTable(CTable* pParagraph, std::vector& rOutputObjects); + void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); private: CTextLine* GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking = nullptr); diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp index 4c65e3c513e..6a9edf606c0 100644 --- a/DocxRenderer/src/logic/elements/DropCap.cpp +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -3,7 +3,7 @@ namespace NSDocxRenderer { - void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) const { oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h index 99594dfe1cb..10db91e644d 100644 --- a/DocxRenderer/src/logic/elements/DropCap.h +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -5,7 +5,7 @@ namespace NSDocxRenderer { - class CDropCap : public CBaseItem + class CDropCap : public COutputObject { public: size_t nLines; @@ -15,10 +15,10 @@ namespace NSDocxRenderer LONG nFontSize; // Pt * 2 LONG nOffset; - CDropCap() : CBaseItem(ElemType::etDropCap) {} +// CDropCap() : CBaseItem(ElemType::etDropCap) {} ~CDropCap() = default; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override; virtual void Clear() override {} }; } diff --git a/DocxRenderer/src/logic/elements/Image.cpp b/DocxRenderer/src/logic/elements/Image.cpp index 7137ee2c49d..5dd6951de9a 100644 --- a/DocxRenderer/src/logic/elements/Image.cpp +++ b/DocxRenderer/src/logic/elements/Image.cpp @@ -4,16 +4,13 @@ namespace NSDocxRenderer { - CImage::CImage() : CBaseItem(ElemType::etImage) - { - } - CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etImage), - m_oImageInfo(oInfo), m_strPath(strDstMedia) + CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) + : m_oImageInfo(oInfo), m_strPath(strDstMedia) { } void CImage::Clear(){} - void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) const { if (m_bIsNotNecessaryToUse) { diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index ac2cc28ab18..ea4dbb02859 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -18,11 +18,9 @@ namespace NSDocxRenderer double m_dRotate {0.0}; public: - CImage(); + CImage() = default; CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); void Clear() override final; - void AddContent(CBaseItem* pObj) override final{}; - - void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; }; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 47c22a725c5..e48fda11a2c 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -4,10 +4,6 @@ namespace NSDocxRenderer { - CParagraph::CParagraph(): CBaseItem(ElemType::etParagraph) - { - } - CParagraph::~CParagraph() { Clear(); @@ -18,7 +14,7 @@ namespace NSDocxRenderer m_arLines.clear(); } - void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const { if (m_bIsNotNecessaryToUse) { diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index cbd9b23ae83..d47885b038d 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -5,7 +5,7 @@ namespace NSDocxRenderer { - class CParagraph : public CBaseItem + class CParagraph : public COutputObject { public: enum TextAlignmentType @@ -39,12 +39,10 @@ namespace NSDocxRenderer std::wstring m_wsStyleId; public: - CParagraph(); + CParagraph() : COutputObject(COutputObject::eOutputType::etParagraph) {} virtual ~CParagraph(); virtual void Clear() override final; - - virtual void AddContent(CBaseItem* pObj) override final{}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void RemoveHighlightColor(); void MergeLines(); diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 6e88a62868b..cb749cb9f7f 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -8,13 +8,14 @@ namespace NSDocxRenderer { UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; - CShape::CShape() : CBaseItem(ElemType::etShape) + CShape::CShape() { + COutputObject::m_eType = COutputObject::eOutputType::etShape; m_nRelativeHeight = m_gRelativeHeight; m_gRelativeHeight += c_iStandartRelativeHeight; } - CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : CBaseItem(ElemType::etShape), + CShape::CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia) : m_strDstMedia(strDstMedia), m_pImageInfo(pInfo) { m_nRelativeHeight = m_gRelativeHeight; @@ -35,7 +36,7 @@ namespace NSDocxRenderer m_oVector.Clear(); } - UINT CShape::GenerateShapeId() + UINT CShape::GenerateShapeId() const { static UINT iId = 0; iId++; @@ -141,7 +142,7 @@ namespace NSDocxRenderer return false; } - std::wstring CShape::PathToWString() + std::wstring CShape::PathToWString() const { auto arData = m_oVector.GetData(); @@ -641,7 +642,7 @@ namespace NSDocxRenderer } } - void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) + void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) const { //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст //todo добавить все возможные параметры/атрибуты @@ -663,7 +664,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L""); oWriter.WriteString(L""); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML - oWriter.WriteString(L""); - m_nShapeId = GenerateShapeId(); - oWriter.WriteString(L""); } - void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L""); @@ -774,7 +772,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L""); @@ -798,7 +796,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L""); @@ -836,7 +834,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -854,13 +852,13 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const { //todo добавить реализацию oWriter.WriteString(L""); } - void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const { std::wstring strPath = PathToWString(); //отвечает за размеры прямоугольного фрейма шейпа @@ -960,7 +958,7 @@ namespace NSDocxRenderer } } - void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) + void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const { if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) { diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 1b80846b9a1..e206762cce3 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -15,7 +15,7 @@ namespace NSDocxRenderer gtNoGraphics, }; - class CShape : public CBaseItem + class CShape : public COutputObject { public: enum class eShapeType @@ -47,7 +47,7 @@ namespace NSDocxRenderer eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; eLineType m_eLineType {eLineType::ltUnknown}; - std::vector m_arOutputObjects; + std::vector m_arOutputObjects; std::shared_ptr m_pImageInfo {nullptr}; @@ -62,12 +62,11 @@ namespace NSDocxRenderer CShape(std::shared_ptr pInfo, const std::wstring& strDstMedia); virtual ~CShape(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final{}; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void SetVector(CVectorGraphics&& oVector); bool TryMergeShape(CShape* pShape); - std::wstring PathToWString(); + std::wstring PathToWString() const; void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); bool IsItFitLine(); bool IsCorrelated(const CShape* pShape); @@ -77,18 +76,18 @@ namespace NSDocxRenderer bool IsSide(); void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); - void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter); - void BuildTextBox(NSStringUtils::CStringBuilder &oWriter); + void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; + void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; static void ResetRelativeHeight(); private: - UINT GenerateShapeId(); + UINT GenerateShapeId() const; }; } diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp index a43e625148e..cea4644dd1f 100644 --- a/DocxRenderer/src/logic/elements/Table.cpp +++ b/DocxRenderer/src/logic/elements/Table.cpp @@ -2,10 +2,6 @@ namespace NSDocxRenderer { - CRow::CRow() : CBaseItem(ElemType::etTable) - { - } - CRow::~CRow() { Clear(); @@ -16,16 +12,10 @@ namespace NSDocxRenderer m_arCells.clear(); } - void CRow::AddContent(CBaseItem* pObj) + void CRow::AddContent(CBaseItem* pItem) { - CBaseItem::AddContent(pObj); - - m_arCells.push_back(dynamic_cast(pObj)); - } - - CTable::CTable() : CBaseItem(ElemType::etTable) - { - + CBaseItem::AddContent(pItem); + m_arCells.push_back(dynamic_cast(pItem)); } CTable::~CTable() @@ -38,14 +28,13 @@ namespace NSDocxRenderer m_arRows.clear(); } - void CTable::AddContent(CBaseItem* pObj) + void CTable::AddContent(CBaseItem* pItem) { - CBaseItem::AddContent(pObj); - - m_arRows.push_back(dynamic_cast(pObj)); + CBaseItem::AddContent(pItem); + m_arRows.push_back(dynamic_cast(pItem)); } - void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) + void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) const { if (m_bIsNotNecessaryToUse) { diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h index d660274e6f8..e42703bb51f 100644 --- a/DocxRenderer/src/logic/elements/Table.h +++ b/DocxRenderer/src/logic/elements/Table.h @@ -9,14 +9,14 @@ namespace NSDocxRenderer std::vector m_arCells; public: - CRow(); + CRow() = default; virtual ~CRow(); virtual void Clear() override final; virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final {} + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final {} }; - class CTable : public CBaseItem + class CTable : public COutputObject { public: std::vector m_arColumnWidths; //общее количество колонок в таблице @@ -28,11 +28,11 @@ namespace NSDocxRenderer bool m_bIsNeedSpacing {false}; public: - CTable(); + CTable() = default; virtual ~CTable(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; + virtual void AddContent(CBaseItem* pItem) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; double CalculateBeforeSpacing(double dPreviousStringBaseline) { diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index d8e39d0e4ce..71d500e440a 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -5,14 +5,8 @@ namespace NSDocxRenderer { - CTextLine::CTextLine() : CBaseItem(ElemType::etTextLine) - { - } - void CTextLine::Clear() { - for(auto& val : m_arConts) - delete val; m_arConts.clear(); } @@ -21,17 +15,15 @@ namespace NSDocxRenderer Clear(); } - void CTextLine::AddContent(CBaseItem *pObj) + void CTextLine::AddContent(CBaseItem *pItem) { - CBaseItem::AddContent(pObj); - m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(pObj)->m_dTrueHeight); + CBaseItem::AddContent(pItem); + m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(pItem)->m_dTrueHeight); - if (dynamic_cast(pObj)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) - { - m_eVertAlignType = dynamic_cast(pObj)->m_eVertAlignType; - } + if (dynamic_cast(pItem)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) + m_eVertAlignType = dynamic_cast(pItem)->m_eVertAlignType; - m_arConts.push_back(dynamic_cast(pObj)); + m_arConts.push_back(dynamic_cast(pItem)); } void CTextLine::CheckLineToNecessaryToUse() @@ -166,7 +158,7 @@ namespace NSDocxRenderer fabs(m_pDominantShape->m_dWidth - pLine->m_pDominantShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM); } - void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) + void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) const { if (m_bIsNotNecessaryToUse) { @@ -204,21 +196,23 @@ namespace NSDocxRenderer pPrev->ToXml(oWriter); } - eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* oSrc) noexcept + eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* pItem) const noexcept { - if(oSrc->m_eType != ElemType::etContText) - return CBaseItem::GetVerticalCrossingType(oSrc); + const CContText* pLine = nullptr; + if((pLine = dynamic_cast(pItem)) == nullptr) + return CBaseItem::GetVerticalCrossingType(pItem); auto m_dTop_copy = m_dTop; - auto m_dTop_copy_src = oSrc->m_dTop; + auto m_dTop_copy_src = pItem->m_dTop; - m_dTop = m_dBaselinePos - m_dTrueHeight; - const_cast(oSrc)->m_dTop = oSrc->m_dBaselinePos - static_cast(oSrc)->m_dTrueHeight; + // call CBaseItem::GetVerticalCrossingType(oSrc) and not create copy, so const_cast was used + const_cast(pLine)->m_dTop = m_dBaselinePos - m_dTrueHeight; + const_cast(pLine)->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; - auto vert_cross = CBaseItem::GetVerticalCrossingType(oSrc); + auto vert_cross = CBaseItem::GetVerticalCrossingType(pLine); - m_dTop = m_dTop_copy; - const_cast(oSrc)->m_dTop = m_dTop_copy_src; + const_cast(pLine)->m_dTop = m_dTop_copy; + const_cast(pLine)->m_dTop = m_dTop_copy_src; return vert_cross; } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index ca023f4fff5..dd1a0082ad8 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -26,12 +26,12 @@ namespace NSDocxRenderer double m_dTrueHeight{0}; public: - CTextLine(); + CTextLine() = default; virtual ~CTextLine(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) override final; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) noexcept override final; + virtual void AddContent(CBaseItem* pItem) override final; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override; void CheckLineToNecessaryToUse(); void MergeConts(); From 83e37ba5f06feaa94a18a981953814f992d0d8a8 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 2 Nov 2023 14:12:58 +0300 Subject: [PATCH 172/794] Refactoring (in progress) --- DocxRenderer/DocxRenderer.pro | 1 + DocxRenderer/src/logic/Page.cpp | 1466 ++++++++--------- DocxRenderer/src/logic/Page.h | 85 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 10 +- DocxRenderer/src/logic/elements/BaseItem.h | 15 +- DocxRenderer/src/logic/elements/Cell.cpp | 378 +++-- DocxRenderer/src/logic/elements/Cell.h | 152 +- DocxRenderer/src/logic/elements/ContText.cpp | 337 ++-- DocxRenderer/src/logic/elements/ContText.h | 100 +- DocxRenderer/src/logic/elements/Converter.cpp | 199 ++- DocxRenderer/src/logic/elements/Converter.h | 8 +- DocxRenderer/src/logic/elements/DropCap.h | 2 +- DocxRenderer/src/logic/elements/Image.cpp | 7 - DocxRenderer/src/logic/elements/Image.h | 2 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 60 +- DocxRenderer/src/logic/elements/Shape.cpp | 19 +- DocxRenderer/src/logic/elements/Shape.h | 7 +- DocxRenderer/src/logic/elements/Table.cpp | 418 ++--- DocxRenderer/src/logic/elements/Table.h | 74 +- DocxRenderer/src/logic/elements/TextLine.cpp | 148 +- DocxRenderer/src/logic/elements/TextLine.h | 20 +- 21 files changed, 1639 insertions(+), 1869 deletions(-) diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 7894edc12f2..6214538089c 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -4,6 +4,7 @@ VERSION = 1.0.0.4 TARGET = DocxRenderer TEMPLATE = lib +CONFIG += c++11 CONFIG += shared CONFIG += plugin diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 669c53b4a13..1c6efe934e1 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -31,7 +31,7 @@ namespace NSDocxRenderer m_pParagraphStyleManager = pParagraphStyleManager; m_pCurrentLine = nullptr; - m_pCurrentRow = nullptr; +// m_pCurrentRow = nullptr; CShape::ResetRelativeHeight(); } @@ -44,42 +44,24 @@ namespace NSDocxRenderer void CPage::Clear() { - for(auto& val : m_arConts) - delete val; m_arConts.clear(); - - for(auto& val : m_arTextLine) - delete val; - m_arTextLine.clear(); - - for(auto& val : m_arDiacriticalSymbol) - delete val; - m_arDiacriticalSymbol.clear(); - - for(auto& val : m_arImages) - delete val; + m_arTextLines.clear(); + m_arDiacriticalSymbols.clear(); m_arImages.clear(); - - for(auto& val : m_arShapes) - delete val; m_arShapes.clear(); - for(auto& val : m_arOutputObjects) - delete val; - m_arOutputObjects.clear(); - ClearTables(); m_pCurrentLine = nullptr; - m_pCurrentRow = nullptr; +// m_pCurrentRow = nullptr; m_oVector.Clear(); } void CPage::ClearTables() { - m_arPeaks.clear(); - m_arCells.clear(); - m_arRows.clear(); - m_arTables.clear(); +// m_arPeaks.clear(); +// m_arCells.clear(); +// m_arRows.clear(); +// m_arTables.clear(); } CPage::~CPage() @@ -90,24 +72,15 @@ namespace NSDocxRenderer void CPage::DeleteTextClipPage() { if (m_bIsDeleteTextClipPage) - { - // удалим все линии, которые выходят за границы страницы - for (size_t i = 0; i < m_arTextLine.size(); ++i) - { - auto pLine = m_arTextLine[i]; - - if (pLine->m_dTop >= m_dHeight || pLine->m_dBaselinePos <= 0) - { - pLine->m_bIsNotNecessaryToUse = true; - } - } - } + for (auto& line : m_arTextLines) + if (line->m_dTop >= m_dHeight || line->m_dBaselinePos <= 0) + line = nullptr; } // image commands void CPage::WriteImage(const std::shared_ptr pInfo, double& fX, double& fY, double& fWidth, double& fHeight) { - auto pImage = new CShape(pInfo, L""); + auto pImage = std::make_shared(pInfo, L""); pImage->m_eType = CShape::eShapeType::stPicture; double dRotation = m_pTransform->z_Rotation(); @@ -263,7 +236,7 @@ namespace NSDocxRenderer } } - auto pShape = new CShape(); + auto pShape = std::make_shared(); if (pInfo) { @@ -322,9 +295,6 @@ namespace NSDocxRenderer m_pTransform->TransformPoint(dTextX, dTextY); m_pTransform->TransformPoint(dTextR, dTextB); - double dTextW; // = dTextR - dTextX; - double dTextH; // = dTextB - dTextY; - NSStringUtils::CStringUTF32 oText((uint32_t*)pUnicodes, nCount); if ((pUnicodes != nullptr) && (pGids != nullptr)) @@ -361,28 +331,26 @@ namespace NSDocxRenderer m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); } - dTextW = _w; //} - dTextH = m_pFontManager->GetFontHeight(); double dBaseLinePos = dTextY + fBaseLineOffset; - auto pCont = new CContText(m_pFontManager); - - pCont->m_dLeft = dTextX; - pCont->m_dBaselinePos = dBaseLinePos; + auto pCont = std::make_shared(m_pFontManager); auto oMetrics = m_pFontManager->GetFontMetrics(); auto oParams = m_pFontManager->GetFontSelectParams(); m_pFontSelector->SelectFont(oParams, oMetrics, oText); + //_h = m_pFontManager->GetFontHeight(); - pCont->m_dTop = dBaseLinePos - dTextH - oMetrics.dBaselineOffset; - pCont->m_dWidth = dTextW; - pCont->m_dHeight = dTextH; - pCont->m_dRight = dTextX + dTextW; - pCont->m_dTrueHeight = _h - oMetrics.dBaselineOffset; + pCont->m_dBaselinePos = dBaseLinePos; + pCont->m_dTop = pCont->m_dBaselinePos - _h; // - oMetrics.dBaselineOffset; + pCont->m_dHeight = pCont->m_dBaselinePos - pCont->m_dTop; + + pCont->m_dLeft = dTextX; + pCont->m_dWidth = _w; + pCont->m_dRight = dTextX + _w; - pCont->m_oText = oText; + pCont->m_oText = oText; // первичное получение стиля для текущего символа // при дальнейшем анализе может измениться @@ -394,452 +362,472 @@ namespace NSDocxRenderer pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); - // собираем отдельно, т.к. такие символы не имею размера m_dWidth + // собираем отдельно, т.к. такие символы не имеют размера m_dWidth if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) - m_arDiacriticalSymbol.push_back(pCont); + m_arDiacriticalSymbols.push_back(pCont); else m_arConts.push_back(pCont); } - void CPage::AddContToTextLine(CContText *pCont) + void CPage::AddContToTextLine(std::shared_ptr pCont) { if (nullptr == m_pCurrentLine) { - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->AddContent(pCont); - m_arTextLine.push_back(pLine); + auto pLine = std::make_shared(); + m_pCurrentLine = pLine.get(); + m_pCurrentLine->RecalcWithNewItem(pCont.get()); + m_arTextLines.push_back(pLine); return; } if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) { - m_pCurrentLine->AddContent(pCont); + m_pCurrentLine->RecalcWithNewItem(pCont.get()); return; } - for (size_t i = 0; i < m_arTextLine.size(); ++i) + for (size_t i = 0; i < m_arTextLines.size(); ++i) { - if (fabs(m_arTextLine[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(m_arTextLines[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) { - m_pCurrentLine = m_arTextLine[i]; - m_pCurrentLine->AddContent(pCont); + m_pCurrentLine = m_arTextLines[i].get(); + m_pCurrentLine->RecalcWithNewItem(pCont); return; } } - auto pLine = new CTextLine(); - m_pCurrentLine = pLine; - m_pCurrentLine->AddContent(pCont); - m_arTextLine.push_back(pLine); + auto pLine = std::make_shared(); + m_pCurrentLine = pLine.get(); + m_pCurrentLine->RecalcWithNewItem(pCont); + m_arTextLines.push_back(pLine); } void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) { - CreateTextLines(); - AnalyzeCollectedShapes(); - AnalyzeCollectedTextLines(); - TryMergeShapes(); + // build text lines from m_arConts + BuildTextLines(); + + // analyze shapes (get type of lines etc) + AnalyzeShapes(); + + // analyze text lines and conts inside + AnalyzeTextLines(); + + // merge conts in text lines + + // build paragraphs from m_arTextLines + + // merge conts in paragraphes + // MergeContsInParagraphes + + // merge shapes + MergeShapes(); + + // calc sizes on selected fonts for m_arConts + CalcSelected(); ToXml(oWriter); WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } - void CPage::SortConts() + void CPage::BuildTextLines() { - } + std::sort(m_arConts.begin(), m_arConts.end(), [] (const auto& a, const auto& b) { + if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + return a->m_dLeft < b->m_dLeft; + return a->m_dBaselinePos < b->m_dBaselinePos; + }); - void CPage::CreateTextLines() - { - CBaseItem::SortTopLeft(m_arConts); for(auto&& cont : m_arConts) AddContToTextLine(cont); } - void CPage::TryMergeShapes() + void CPage::MergeShapes() { if(m_arShapes.empty()) return; for(size_t i = 0; i < m_arShapes.size() - 1; i++) { - bool bIsMerged = false; auto& val = m_arShapes[i]; auto& nextVal = m_arShapes[i + 1]; - if(!val->m_bIsNotNecessaryToUse && !nextVal->m_bIsNotNecessaryToUse) - bIsMerged = nextVal->TryMergeShape(val); - - if(bIsMerged) - val->m_bIsNotNecessaryToUse = true; + if(val && nextVal) + nextVal->TryMergeShape(val); } } - void CPage::AnalyzeCollectedShapes() + void CPage::CalcSelected() { - //BuildTables(); - DetermineLinesType(); - } - - void CPage::BuildTables() - { - //Графика таблиц парсится в условные 2 типа: - //1 - С выделение отдельных узлов (peak) в местах пересечения линий - //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки - //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек - - //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа - //Для реализации 2го - нужно сначала создать peak в местах пересечения линий - //Основная причина почему так - нужно удалять все шейпы после парсинга - - //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) - //todo реализовать парсинг таблиц 2-го типа - //todo необходимо в созданные cells добавить содержимое из m_arTextLine по геометрическому признаку (буквы должны находится внутри ячеек) - //todo зетем собрать TextLine и Paragraph для каждой ячейки - //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape - - CollectPeaks(); - CreatCells(); - BuildRows(); - - CTable* pCurrTable = nullptr; - CRow* pFirstRow = nullptr; - - if (!m_arRows.empty()) - { - pCurrTable = new CTable(); - m_arTables.push_back(pCurrTable); - - pFirstRow = m_arRows.front(); - pCurrTable->AddContent(pFirstRow); - } - - for (size_t i = 1; i < m_arRows.size(); ++i) - { - auto pCurrRow = m_arRows[i]; - - eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); - eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); - - bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; - bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; - - if (bIf1 && bIf2) - { - pCurrTable->AddContent(pCurrRow); - pFirstRow = pCurrRow; - } - else - { - pCurrTable = new CTable(); - m_arTables.push_back(pCurrTable); - - pFirstRow = pCurrRow; - pCurrTable->AddContent(pFirstRow); - } - } - - for (size_t i = 0; i < m_arTables.size(); ++i) - { - m_arTables[i]->CalculateColumnWidth(); - } - } - - void CPage::CollectPeaks() - { - for (size_t i = 0; i< m_arShapes.size(); ++i) - { - auto pCurrShape = m_arShapes[i]; - - if (pCurrShape->m_bIsNotNecessaryToUse) - { - continue; - } - - //нашли вершину - if (pCurrShape->IsPeak()) - { - CPeak* pCurrPeak = nullptr; - - //ищем стороны - for (size_t j = 0; j < m_arShapes.size(); ++j) - { - auto pNextShape = m_arShapes[j]; - - if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) - { - continue; - } - - eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); - eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); - - //проверяем, подходит ли сторона - bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && - (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); - bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && - (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); - - if (bIf1 || bIf2) - { - if (!pCurrPeak) - { - pCurrPeak = new CPeak(pCurrShape); - pCurrShape->m_bIsNotNecessaryToUse = true; - pCurrShape->m_bIsUseInTable = true; - m_arPeaks.push_back(pCurrPeak); - } - - if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) - { - if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) - { - pCurrPeak->m_pLines[CPeak::dI] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) - { - pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - } - if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) - { - if (eVType == eVerticalCrossingType::vctCurrentAboveNext) - { - pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) - { - pCurrPeak->m_pLines[CPeak::dII] = pNextShape; - pNextShape->m_bIsUseInTable = true; - } - } - } - } - } - } + for(auto& cont : m_arConts) + cont->CalcSelected(); } - void CPage::CreatCells() + void CPage::AnalyzeShapes() { - //Cells - // II | I - // | - //-----Peak--- - // | - // III | IV - //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку - CCell *pCellI, *pCellII, *pCellIII, *pCellIV; - - for (size_t i = 0; i < m_arPeaks.size(); ++i) - { - CPeak* pPeak = m_arPeaks[i]; - pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; - //Lines from peak - // VI II V - // | - // III <- Peak -> I - // | - // VII IV VIII - - //Corners - //Обозначение углов в ячейке - // IV------III - // | | - // | Cell | - // | | - // I--------II - - bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия - bool bIsII = pPeak->m_pLines[CPeak::dII]; - bool bIsIII = pPeak->m_pLines[CPeak::dIII]; - bool bIsIV = pPeak->m_pLines[CPeak::dIV]; - - //Если ячейки уже есть - //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) - //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются - //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных - for (size_t j = 0; j < m_arCells.size(); ++j) - { - auto pSaveCell = m_arCells[j]; - for (size_t k = 0; k < CCell::cNumCorners; ++k) - { - auto pSavePeak = pSaveCell->m_pPeaks[k]; - if (pSavePeak) - { - if (pPeak->m_pLines[CPeak::dI] && - pSavePeak->m_pLines[CPeak::dIII] && - pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) - { - if (k == CCell::cII) - { - pCellI = pSaveCell; - pCellI->SetParameters(pPeak, CCell::cI); - } - else if (k == CCell::cIII) - { - pCellIV = pSaveCell; - pCellIV->SetParameters(pPeak, CCell::cIV); - } - } - - if (pPeak->m_pLines[CPeak::dII] && - pSavePeak->m_pLines[CPeak::dIV] && - pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) - { - if (k == CCell::cIII) - { - pCellII = pSaveCell; - pCellII->SetParameters(pPeak, CCell::cII); - } - else if (k == CCell::cIV) - { - pCellI = pSaveCell; - pCellI->SetParameters(pPeak, CCell::cI); - } - } - - if (pPeak->m_pLines[CPeak::dIII] && - pSavePeak->m_pLines[CPeak::dI] && - pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) - { - if (k == CCell::cI) - { - pCellII = pSaveCell; - pCellII->SetParameters(pPeak, CCell::cII); - } - else if (k == CCell::cIV) - { - pCellIII = pSaveCell; - pCellIII->SetParameters(pPeak, CCell::cIII); - } - } - - if (pPeak->m_pLines[CPeak::dIV] && - pSavePeak->m_pLines[CPeak::dII] && - pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) - { - if (k == CCell::cI) - { - pCellIV = pSaveCell; - pCellIV->SetParameters(pPeak, CCell::cIV); - } - else if (k == CCell::cII) - { - pCellIII = pSaveCell; - pCellIII->SetParameters(pPeak, CCell::cIII); - } - } - } - } - } - - //Если ячейка еще не построена по заданным углам - создаем ячейку - if (bIsI && bIsII) - { - if (!pCellI) - { - pCellI = new CCell(); - pCellI->SetParameters(pPeak, CCell::cI); - m_arCells.push_back(pCellI); - } - } - if (bIsII && bIsIII) - { - if (!pCellII) - { - pCellII = new CCell(); - pCellII->SetParameters(pPeak, CCell::cII); - m_arCells.push_back(pCellII); - } - } - if (bIsIII && bIsIV) - { - if (!pCellIII) - { - pCellIII = new CCell(); - pCellIII->SetParameters(pPeak, CCell::cIII); - m_arCells.push_back(pCellIII); - } - } - if (bIsIV && bIsI) - { - if (!pCellIV) - { - pCellIV = new CCell(); - pCellIV->SetParameters(pPeak, CCell::cIV); - m_arCells.push_back(pCellIV); - } - } - } - - //удаляем использованные шейпы - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - if (m_arShapes[i]->m_bIsUseInTable) - { - m_arShapes[i]->m_bIsNotNecessaryToUse = true; - } - } - } - - void CPage::BuildRows() - { - //когда созданы все ячейки, собираем их в ряды - for (size_t i = 0; i < m_arCells.size(); ++i) - { - auto pCell = m_arCells[i]; - - if (pCell->m_bIsNotNecessaryToUse) - { - continue; - } - - SelectCurrentRow(pCell); - m_pCurrentRow->AddContent(pCell); - } - - CBaseItem::SortByBaseline(m_arRows); - for (size_t i = 0; i < m_arRows.size(); ++i) - { - CBaseItem::SortByLeft(m_arRows[i]->m_arCells); - } + //BuildTables(); + DetermineLinesType(); } - void CPage::SelectCurrentRow(const CCell *pCell) - { - //логика аналогична AddContToTextLine - //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала - if (nullptr == m_pCurrentRow) - { - auto pRow = new CRow(); - m_pCurrentRow = pRow; - m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; - m_arRows.push_back(pRow); - return; - } - - if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - return; - } - - for (size_t i = 0; i < m_arRows.size(); ++i) - { - if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - m_pCurrentRow = m_arRows[i]; - return; - } - } - - auto pRow = new CRow(); - m_pCurrentRow = pRow; - m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; - m_arRows.push_back(pRow); - return; - } +// void CPage::BuildTables() +// { +// //Графика таблиц парсится в условные 2 типа: +// //1 - С выделение отдельных узлов (peak) в местах пересечения линий +// //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки +// //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек + +// //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа +// //Для реализации 2го - нужно сначала создать peak в местах пересечения линий +// //Основная причина почему так - нужно удалять все шейпы после парсинга + +// //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) +// //todo реализовать парсинг таблиц 2-го типа +// //todo необходимо в созданные cells добавить содержимое из m_arTextLines по геометрическому признаку (буквы должны находится внутри ячеек) +// //todo зетем собрать TextLine и Paragraph для каждой ячейки +// //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape + +// CollectPeaks(); +// CreatCells(); +// BuildRows(); + +// CTable* pCurrTable = nullptr; +// CRow* pFirstRow = nullptr; + +// if (!m_arRows.empty()) +// { +// pCurrTable = new CTable(); +// m_arTables.push_back(pCurrTable); + +// pFirstRow = m_arRows.front(); +// pCurrTable->RecalcWithNewItem(pFirstRow); +// } + +// for (size_t i = 1; i < m_arRows.size(); ++i) +// { +// auto pCurrRow = m_arRows[i]; + +// eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); +// eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); + +// bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; +// bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; + +// if (bIf1 && bIf2) +// { +// pCurrTable->RecalcWithNewItem(pCurrRow); +// pFirstRow = pCurrRow; +// } +// else +// { +// pCurrTable = new CTable(); +// m_arTables.push_back(pCurrTable); + +// pFirstRow = pCurrRow; +// pCurrTable->RecalcWithNewItem(pFirstRow); +// } +// } + +// for (size_t i = 0; i < m_arTables.size(); ++i) +// { +// m_arTables[i]->CalculateColumnWidth(); +// } +// } + +// void CPage::CollectPeaks() +// { +// for (size_t i = 0; i< m_arShapes.size(); ++i) +// { +// auto pCurrShape = m_arShapes[i]; + +// if (pCurrShape->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// //нашли вершину +// if (pCurrShape->IsPeak()) +// { +// CPeak* pCurrPeak = nullptr; + +// //ищем стороны +// for (size_t j = 0; j < m_arShapes.size(); ++j) +// { +// auto pNextShape = m_arShapes[j]; + +// if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) +// { +// continue; +// } + +// eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); +// eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); + +// //проверяем, подходит ли сторона +// bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && +// (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); +// bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && +// (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); + +// if (bIf1 || bIf2) +// { +// if (!pCurrPeak) +// { +// pCurrPeak = new CPeak(pCurrShape); +// pCurrShape->m_bIsNotNecessaryToUse = true; +// pCurrShape->m_bIsUseInTable = true; +// m_arPeaks.push_back(pCurrPeak); +// } + +// if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) +// { +// if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) +// { +// pCurrPeak->m_pLines[CPeak::dI] = pNextShape; +// pNextShape->m_bIsUseInTable = true; +// } +// else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) +// { +// pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; +// pNextShape->m_bIsUseInTable = true; +// } +// } +// if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) +// { +// if (eVType == eVerticalCrossingType::vctCurrentAboveNext) +// { +// pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; +// pNextShape->m_bIsUseInTable = true; +// } +// else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) +// { +// pCurrPeak->m_pLines[CPeak::dII] = pNextShape; +// pNextShape->m_bIsUseInTable = true; +// } +// } +// } +// } +// } +// } +// } + +// void CPage::CreatCells() +// { +// //Cells +// // II | I +// // | +// //-----Peak--- +// // | +// // III | IV +// //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку +// CCell *pCellI, *pCellII, *pCellIII, *pCellIV; + +// for (size_t i = 0; i < m_arPeaks.size(); ++i) +// { +// CPeak* pPeak = m_arPeaks[i]; +// pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; +// //Lines from peak +// // VI II V +// // | +// // III <- Peak -> I +// // | +// // VII IV VIII + +// //Corners +// //Обозначение углов в ячейке +// // IV------III +// // | | +// // | Cell | +// // | | +// // I--------II + +// bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия +// bool bIsII = pPeak->m_pLines[CPeak::dII]; +// bool bIsIII = pPeak->m_pLines[CPeak::dIII]; +// bool bIsIV = pPeak->m_pLines[CPeak::dIV]; + +// //Если ячейки уже есть +// //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) +// //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются +// //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных +// for (size_t j = 0; j < m_arCells.size(); ++j) +// { +// auto pSaveCell = m_arCells[j]; +// for (size_t k = 0; k < CCell::cNumCorners; ++k) +// { +// auto pSavePeak = pSaveCell->m_pPeaks[k]; +// if (pSavePeak) +// { +// if (pPeak->m_pLines[CPeak::dI] && +// pSavePeak->m_pLines[CPeak::dIII] && +// pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) +// { +// if (k == CCell::cII) +// { +// pCellI = pSaveCell; +// pCellI->SetParameters(pPeak, CCell::cI); +// } +// else if (k == CCell::cIII) +// { +// pCellIV = pSaveCell; +// pCellIV->SetParameters(pPeak, CCell::cIV); +// } +// } + +// if (pPeak->m_pLines[CPeak::dII] && +// pSavePeak->m_pLines[CPeak::dIV] && +// pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) +// { +// if (k == CCell::cIII) +// { +// pCellII = pSaveCell; +// pCellII->SetParameters(pPeak, CCell::cII); +// } +// else if (k == CCell::cIV) +// { +// pCellI = pSaveCell; +// pCellI->SetParameters(pPeak, CCell::cI); +// } +// } + +// if (pPeak->m_pLines[CPeak::dIII] && +// pSavePeak->m_pLines[CPeak::dI] && +// pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) +// { +// if (k == CCell::cI) +// { +// pCellII = pSaveCell; +// pCellII->SetParameters(pPeak, CCell::cII); +// } +// else if (k == CCell::cIV) +// { +// pCellIII = pSaveCell; +// pCellIII->SetParameters(pPeak, CCell::cIII); +// } +// } + +// if (pPeak->m_pLines[CPeak::dIV] && +// pSavePeak->m_pLines[CPeak::dII] && +// pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) +// { +// if (k == CCell::cI) +// { +// pCellIV = pSaveCell; +// pCellIV->SetParameters(pPeak, CCell::cIV); +// } +// else if (k == CCell::cII) +// { +// pCellIII = pSaveCell; +// pCellIII->SetParameters(pPeak, CCell::cIII); +// } +// } +// } +// } +// } + +// //Если ячейка еще не построена по заданным углам - создаем ячейку +// if (bIsI && bIsII) +// { +// if (!pCellI) +// { +// pCellI = new CCell(); +// pCellI->SetParameters(pPeak, CCell::cI); +// m_arCells.push_back(pCellI); +// } +// } +// if (bIsII && bIsIII) +// { +// if (!pCellII) +// { +// pCellII = new CCell(); +// pCellII->SetParameters(pPeak, CCell::cII); +// m_arCells.push_back(pCellII); +// } +// } +// if (bIsIII && bIsIV) +// { +// if (!pCellIII) +// { +// pCellIII = new CCell(); +// pCellIII->SetParameters(pPeak, CCell::cIII); +// m_arCells.push_back(pCellIII); +// } +// } +// if (bIsIV && bIsI) +// { +// if (!pCellIV) +// { +// pCellIV = new CCell(); +// pCellIV->SetParameters(pPeak, CCell::cIV); +// m_arCells.push_back(pCellIV); +// } +// } +// } + +// //удаляем использованные шейпы +// for (size_t i = 0; i < m_arShapes.size(); ++i) +// { +// if (m_arShapes[i]->m_bIsUseInTable) +// { +// m_arShapes[i]->m_bIsNotNecessaryToUse = true; +// } +// } +// } + +// void CPage::BuildRows() +// { +// //когда созданы все ячейки, собираем их в ряды +// for (size_t i = 0; i < m_arCells.size(); ++i) +// { +// auto pCell = m_arCells[i]; + +// if (pCell->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// SelectCurrentRow(pCell); +// m_pCurrentRow->RecalcWithNewItem(pCell); +// } + +// CBaseItem::SortByBaseline(m_arRows); +// for (size_t i = 0; i < m_arRows.size(); ++i) +// { +// CBaseItem::SortByLeft(m_arRows[i]->m_arCells); +// } +// } + +// void CPage::SelectCurrentRow(const CCell *pCell) +// { +// //логика аналогична AddContToTextLine +// //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала +// if (nullptr == m_pCurrentRow) +// { +// auto pRow = new CRow(); +// m_pCurrentRow = pRow; +// m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; +// m_arRows.push_back(pRow); +// return; +// } + +// if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) +// { +// return; +// } + +// for (size_t i = 0; i < m_arRows.size(); ++i) +// { +// if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) +// { +// m_pCurrentRow = m_arRows[i]; +// return; +// } +// } + +// auto pRow = new CRow(); +// m_pCurrentRow = pRow; +// m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; +// m_arRows.push_back(pRow); +// return; +// } void CPage::DetermineLinesType() { @@ -921,17 +909,16 @@ namespace NSDocxRenderer } } - void CPage::AnalyzeCollectedTextLines() + void CPage::AnalyzeTextLines() { //вся логика основана на отсортированных списках объектов //todo для увеличения производительности можно попробовать использовать другие контейнеры - CBaseItem::SortByBaseline(m_arTextLine); -// for(auto&& line: m_arTextLine) + CBaseItem::SortByBaseline(m_arTextLines); +// for(auto&& line: m_arTextLines) // CBaseItem::SortByLeft(line->m_arConts); AnalyzeDropCaps(); - AnalyzeCollectedConts(); DetermineStrikeoutsUnderlinesHighlights(); AddDiacriticalSymbols(); MergeLinesByVertAlignType(); @@ -939,10 +926,10 @@ namespace NSDocxRenderer //DetermineTextColumns(); - SingletonInstance().BuildLines(m_arTextLine); + SingletonInstance().BuildLines(m_arTextLines); SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, COutputObject::eOutputType::etParagraph, - m_arTextLine, m_arTables, m_arOutputObjects, + m_arTextLines, m_arTables, m_arOutputObjects, m_pParagraphStyleManager); } @@ -950,14 +937,14 @@ namespace NSDocxRenderer { double avg_font_size = m_pParagraphStyleManager->GetAvgFontSize(); - std::vector> possible_caps; - std::vector drop_caps; + std::vector, std::shared_ptr>> possible_caps; + std::vector> drop_caps; - for(size_t i = 0; i < m_arTextLine.size(); i++) + for(size_t i = 0; i < m_arTextLines.size(); i++) { - auto& line = m_arTextLine[i]; + auto& line = m_arTextLines[i]; for(auto& cont : line->m_arConts) - if(!cont->m_bIsNotNecessaryToUse && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) + if(cont && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) possible_caps.push_back({cont, line}); } @@ -968,9 +955,9 @@ namespace NSDocxRenderer size_t num_of_lines = 0; - for(auto& line : m_arTextLine) + for(auto& line : m_arTextLines) { - if(line == drop_cap_line || line->m_bIsNotNecessaryToUse) + if(!line || line == drop_cap_line) continue; // буквица должна быть левее @@ -994,18 +981,20 @@ namespace NSDocxRenderer } if(num_of_lines) { - CDropCap* drop_cap = new CDropCap(); - *static_cast(drop_cap) = *drop_cap_cont; + auto drop_cap = std::make_unique(); + *static_cast(drop_cap.get()) = *drop_cap_cont; drop_cap->nLines = num_of_lines; drop_cap->wsFont = drop_cap_cont->m_pFontStyle->wsFontName; drop_cap->wsText = drop_cap_cont->m_oText.ToStdWString(); drop_cap->nFontSize = static_cast(drop_cap_cont->m_pFontStyle->dFontSize * 2); - drop_caps.push_back(drop_cap); + drop_caps.push_back(std::move(drop_cap)); - drop_cap_cont->m_bIsNotNecessaryToUse = true; - drop_cap_line->CheckLineToNecessaryToUse(); - if(!drop_cap_line->m_bIsNotNecessaryToUse) + drop_cap_cont = nullptr; + if(drop_cap_line->IsCanBeDeleted()) + drop_cap_line = nullptr; + + if(drop_cap_line) drop_cap_line->RecalcSizes(); } } @@ -1013,7 +1002,7 @@ namespace NSDocxRenderer // шейпы из буквиц for(auto&& drop_cap : drop_caps) { - auto shape = new CShape(); + auto shape = std::make_shared(); shape->m_eType = CShape::eShapeType::stTextBox; // перемерим на подобранном шрифте @@ -1043,34 +1032,29 @@ namespace NSDocxRenderer m_arShapes.push_back(shape); } } - void CPage::AnalyzeCollectedConts() + void CPage::AnalyzeConts() { - // определение различных эффектов на основании взаимного расположения символов - // идем по всем текстовым линиям - for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) + for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLines.size(); ++uCurrLineIndex) { - // берем текущую линию - auto pCurrLine = m_arTextLine[uCurrLineIndex]; - if (pCurrLine->m_bIsNotNecessaryToUse) + auto& pCurrLine = m_arTextLines[uCurrLineIndex]; + if (!pCurrLine) continue; - // символы в текущей линии for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) { - // берем символ в текущей линии - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - if (pCurrCont->m_bIsNotNecessaryToUse) + auto& pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + if (!pCurrCont) continue; // берем вторую линию, если символ последний - то начиная со следуюущей, иначе с той же for (size_t uNextLineIndex = uCurrContIndex >= pCurrLine->m_arConts.size() - 1 ? - uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLine.size(); ++uNextLineIndex) + uCurrLineIndex + 1 : uCurrLineIndex; uNextLineIndex < m_arTextLines.size(); ++uNextLineIndex) { - auto pNextLine = m_arTextLine[uNextLineIndex]; + auto& pNextLine = m_arTextLines[uNextLineIndex]; // значительно ускоряет работу, то есть если никак не перескается - некст - if (pNextLine->m_bIsNotNecessaryToUse || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine)) + if (!pNextLine || pCurrLine->AreObjectsNoCrossingByVertically(pNextLine.get())) continue; // посимвольно смотрим некст линию - если та же то следующий символ, если другая - то с нуля @@ -1079,19 +1063,21 @@ namespace NSDocxRenderer { // берем символ во второй линии auto pNextCont = pNextLine->m_arConts[uNextContIndex]; - if (pNextCont->m_bIsNotNecessaryToUse) + if (!pNextCont) continue; - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont); + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont.get()); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont.get()); - if (pCurrCont->IsThereAreFontEffects(pNextCont, eVType, eHType)) + if (CContText::CheckFontEffects(pCurrCont, pNextCont, eVType, eHType)) { - pCurrLine->CheckLineToNecessaryToUse(); + pNextCont = nullptr; + if(pNextLine->IsCanBeDeleted()) + pNextLine = nullptr; break; } - if (pCurrCont->IsVertAlignTypeBetweenConts(pNextCont, eVType, eHType)) + if (CContText::CheckVertAlignTypeBetweenConts(pCurrCont, pNextCont, eVType, eHType)) { pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); @@ -1105,13 +1091,16 @@ namespace NSDocxRenderer break; } - if (pCurrCont->IsDuplicate(pNextCont, eVType)) + if (pCurrCont->IsDuplicate(pNextCont.get(), eVType)) { + pNextCont = nullptr; + pCurrCont->m_iNumDuplicates++; break; } } - pNextLine->CheckLineToNecessaryToUse(); + if(pNextLine->IsCanBeDeleted()) + pNextLine = nullptr; } } } @@ -1128,9 +1117,9 @@ namespace NSDocxRenderer if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || pShape->m_bIsNotNecessaryToUse) continue; - for (size_t j = 0; j < m_arTextLine.size(); ++j) + for (size_t j = 0; j < m_arTextLines.size(); ++j) { - auto pCurrLine = m_arTextLine[j]; + auto pCurrLine = m_arTextLines[j]; if (pCurrLine->m_bIsNotNecessaryToUse || (pCurrLine->AreObjectsNoCrossingByVertically(pShape) && @@ -1292,37 +1281,25 @@ namespace NSDocxRenderer void CPage::AddDiacriticalSymbols() { - for (size_t i = 0; i < m_arDiacriticalSymbol.size(); ++i) + for (auto& d_sym : m_arDiacriticalSymbols) { - auto pDiacriticalCont = m_arDiacriticalSymbol[i]; - if (pDiacriticalCont->m_bIsNotNecessaryToUse) - { + if (!d_sym) continue; - } bool isBreak = false; - for (size_t j = 0; j < m_arTextLine.size(); ++j) + for (auto& line : m_arTextLines) { - auto pCurrLine = m_arTextLine[j]; - - if (pCurrLine->m_bIsNotNecessaryToUse || - pCurrLine->AreObjectsNoCrossingByVertically(pDiacriticalCont)) - { + if (!line || line->AreObjectsNoCrossingByVertically(d_sym.get())) continue; - } - for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) + for (auto& cont : line->m_arConts) { - auto pCurrCont = pCurrLine->m_arConts[k]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { + if (!cont) continue; - } - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pDiacriticalCont); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pDiacriticalCont); + eVerticalCrossingType eVType = cont->GetVerticalCrossingType(d_sym.get()); + eHorizontalCrossingType eHType = cont->GetHorizontalCrossingType(d_sym.get()); if (eVType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && eVType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext && @@ -1365,18 +1342,17 @@ namespace NSDocxRenderer void CPage::MergeLinesByVertAlignType() { - for (size_t i = 0; i < m_arTextLine.size(); ++i) + for (auto& line : m_arTextLines) { - auto pCurrLine = m_arTextLine[i]; - if (pCurrLine->m_bIsNotNecessaryToUse) + if (!line) continue; - if (pCurrLine->m_eVertAlignType == eVertAlignType::vatSuperscript) + if (line->m_eVertAlignType == eVertAlignType::vatSuperscript) { - auto pBaseLine = pCurrLine->m_pLine; + auto& pBaseLine = line->m_pLine; if (pBaseLine) { - for (auto& pCont : pCurrLine->m_arConts) + for (auto& pCont : line->m_arConts) { if (pBaseLine->m_dLeft > pCont->m_dLeft) pBaseLine->m_dLeft = pCont->m_dLeft; @@ -1387,13 +1363,18 @@ namespace NSDocxRenderer pBaseLine->m_arConts.push_back(pCont); pCont = nullptr; } - CBaseItem::SortByLeft(pBaseLine->m_arConts); - pCurrLine->m_bIsNotNecessaryToUse = true; + + using cont_ptr = std::shared_ptr; + std::sort(pBaseLine->m_arConts.begin(), pBaseLine->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + return a->m_dLeft < b->m_dLeft; + }); + + line = nullptr; } } - else if (pCurrLine->m_eVertAlignType == eVertAlignType::vatBase) + else if (line->m_eVertAlignType == eVertAlignType::vatBase) { - auto pSubLine = pCurrLine->m_pLine; + auto& pSubLine = line->m_pLine; if (pSubLine) { for (auto& pCont : pSubLine->m_arConts) @@ -1401,229 +1382,234 @@ namespace NSDocxRenderer if (pCont == nullptr) continue; - if (pCurrLine->m_dLeft > pCont->m_dLeft) - pCurrLine->m_dLeft = pCont->m_dLeft; - if (pCurrLine->m_dRight < pCont->m_dRight) - pCurrLine->m_dRight = pCont->m_dRight; + if (line->m_dLeft > pCont->m_dLeft) + line->m_dLeft = pCont->m_dLeft; + if (line->m_dRight < pCont->m_dRight) + line->m_dRight = pCont->m_dRight; - pCurrLine->m_dWidth = pCurrLine->m_dRight - pCurrLine->m_dLeft; - pCurrLine->m_arConts.push_back(pCont); + line->m_dWidth = line->m_dRight - line->m_dLeft; + line->m_arConts.push_back(pCont); pCont = nullptr; } - CBaseItem::SortByLeft(pCurrLine->m_arConts); - pSubLine->m_bIsNotNecessaryToUse = true; - } - } - } - } - void CPage::DetermineTextColumns() - { - std::vector keys; - std::vector arConts; - CTable* pTable = nullptr; - - //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу - //Выбирается первая строка и относительно нее проверяются все последующие строки - - //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, - //то добавляем uFirstContIndex в keys. - //Todo улучшить локигу определения keys - for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLine.size(); ++uFirstLineIndex) - { - auto pFirstLine = m_arTextLine[uFirstLineIndex]; + using cont_ptr = std::shared_ptr; + std::sort(line->m_arConts.begin(), line->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + return a->m_dLeft < b->m_dLeft; + }); - if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLine.size() - 1) - { - continue; - } - - CTextLine* pFlagLine = nullptr; - - //первоначальное определение индексов pFirstLine, где могут присутствовать колонки - for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) - { - auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; - - if (pFirtsCont->m_bIsNotNecessaryToUse) - { - continue; + pSubLine = nullptr; } - - for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLine.size(); ++uCurrLineIndex) - { - auto pCurrLine = m_arTextLine[uCurrLineIndex]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - auto pPrevLine = m_arTextLine[uCurrLineIndex-1]; - - if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) - { - //Нашли линию, до которой будет таблица/ряд - pFlagLine = pCurrLine; - break; - } - - size_t numConts = arConts.size(); - - for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) - { - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); - - if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || - eHType == eHorizontalCrossingType::hctLeftBorderMatch) - { - //Добавили Cont-ориентир - arConts.push_back(pCurrCont); - break; - } - } - - if (numConts == arConts.size()) - { - //не было добавления Cont, значит дальше можно не проверять - break; - } - } - - if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) - { - keys.push_back(uFirstContIndex); - arConts.clear(); - } - } - - size_t uLastLineIndexInCell = 0; - - //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то - //начинаем распределять символы из всех строк до pFlagLine по высоте и - //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) - //Повторяем это действие, пока не пробежимся по всем keys - if (keys.size() > 1) - { - auto pRow = new CRow(); - - for (size_t i = 0; i < keys.size(); ++i) - { - auto pCell = new CCell(); - - for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLine.size(); ++uLineIndex) - { - auto pCurrLine = m_arTextLine[uLineIndex]; - - if (pCurrLine->m_bIsNotNecessaryToUse) - { - continue; - } - - if (pFlagLine == pCurrLine) - { - uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); - break; - } - - CTextLine* pCellLine = nullptr; - CContText* pFlagCont = nullptr; - CContText* pFirstCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i]]; - - if (i < keys.size() - 1) - { - pFlagCont = m_arTextLine[uFirstLineIndex]->m_arConts[keys[i+1]]; - } - - for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) - { - auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { - continue; - } - - eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); - - if (pFlagCont) - { - eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); - if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && - eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - if (!pCellLine) - { - pCellLine = new CTextLine(); - } - pCellLine->AddContent(new CContText(*pCurrCont)); - pCurrCont->m_bIsNotNecessaryToUse = true; - } - else - { - break; - } - } - else - { - if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) - { - if (!pCellLine) - { - pCellLine = new CTextLine(); - } - pCellLine->AddContent(new CContText(*pCurrCont)); - pCurrCont->m_bIsNotNecessaryToUse = true; - } - } - } - - if (pCellLine) - { - pCell->AddContent(pCellLine); - } - - if (i >= keys.size() - 1) - { - pCurrLine->CheckLineToNecessaryToUse(); - } - } - -// SingletonInstance().BuildLines(pCell->m_arTextLine); -// SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, COutputObject::eOutputType::etCell, -// pCell->m_arTextLine, pCell->m_arOutputObjects, -// m_pParagraphStyleManager); - - pRow->AddContent(pCell); - } - - if (pFlagLine) - { - uFirstLineIndex = uLastLineIndexInCell; - } - - //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы - if (!pTable) - { - pTable = new CTable(); - m_arTables.push_back(pTable); - } - - pTable->AddContent(pRow); - pTable->CalculateColumnWidth(); } - - keys.clear(); - arConts.clear(); } } +// void CPage::DetermineTextColumns() +// { +// std::vector keys; +// std::vector arConts; +// CTable* pTable = nullptr; + +// //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу +// //Выбирается первая строка и относительно нее проверяются все последующие строки - +// //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, +// //то добавляем uFirstContIndex в keys. +// //Todo улучшить локигу определения keys +// for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLines.size(); ++uFirstLineIndex) +// { +// auto pFirstLine = m_arTextLines[uFirstLineIndex]; + +// if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLines.size() - 1) +// { +// continue; +// } + +// CTextLine* pFlagLine = nullptr; + +// //первоначальное определение индексов pFirstLine, где могут присутствовать колонки +// for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) +// { +// auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; + +// if (pFirtsCont->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLines.size(); ++uCurrLineIndex) +// { +// auto pCurrLine = m_arTextLines[uCurrLineIndex]; + +// if (pCurrLine->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// auto pPrevLine = m_arTextLines[uCurrLineIndex-1]; + +// if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) +// { +// //Нашли линию, до которой будет таблица/ряд +// pFlagLine = pCurrLine; +// break; +// } + +// size_t numConts = arConts.size(); + +// for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) +// { +// auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + +// if (pCurrCont->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); + +// if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || +// eHType == eHorizontalCrossingType::hctLeftBorderMatch) +// { +// //Добавили Cont-ориентир +// arConts.push_back(pCurrCont); +// break; +// } +// } + +// if (numConts == arConts.size()) +// { +// //не было добавления Cont, значит дальше можно не проверять +// break; +// } +// } + +// if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) +// { +// keys.push_back(uFirstContIndex); +// arConts.clear(); +// } +// } + +// size_t uLastLineIndexInCell = 0; + +// //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то +// //начинаем распределять символы из всех строк до pFlagLine по высоте и +// //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) +// //Повторяем это действие, пока не пробежимся по всем keys +// if (keys.size() > 1) +// { +// auto pRow = new CRow(); + +// for (size_t i = 0; i < keys.size(); ++i) +// { +// auto pCell = new CCell(); + +// for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLines.size(); ++uLineIndex) +// { +// auto pCurrLine = m_arTextLines[uLineIndex]; + +// if (pCurrLine->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// if (pFlagLine == pCurrLine) +// { +// uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); +// break; +// } + +// CTextLine* pCellLine = nullptr; +// CContText* pFlagCont = nullptr; +// CContText* pFirstCont = m_arTextLines[uFirstLineIndex]->m_arConts[keys[i]]; + +// if (i < keys.size() - 1) +// { +// pFlagCont = m_arTextLines[uFirstLineIndex]->m_arConts[keys[i+1]]; +// } + +// for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) +// { +// auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + +// if (pCurrCont->m_bIsNotNecessaryToUse) +// { +// continue; +// } + +// eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); + +// if (pFlagCont) +// { +// eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); +// if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && +// eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) +// { +// if (!pCellLine) +// { +// pCellLine = new CTextLine(); +// } +// pCellLine->RecalcWithNewItem(new CContText(*pCurrCont)); +// pCurrCont->m_bIsNotNecessaryToUse = true; +// } +// else +// { +// break; +// } +// } +// else +// { +// if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) +// { +// if (!pCellLine) +// { +// pCellLine = new CTextLine(); +// } +// pCellLine->RecalcWithNewItem(new CContText(*pCurrCont)); +// pCurrCont->m_bIsNotNecessaryToUse = true; +// } +// } +// } + +// if (pCellLine) +// { +// pCell->RecalcWithNewItem(pCellLine); +// } + +// if (i >= keys.size() - 1) +// { +// pCurrLine->CheckLineToNecessaryToUse(); +// } +// } + +//// SingletonInstance().BuildLines(pCell->m_arTextLines); +//// SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, COutputObject::eOutputType::etCell, +//// pCell->m_arTextLines, pCell->m_arOutputObjects, +//// m_pParagraphStyleManager); + +// pRow->RecalcWithNewItem(pCell); +// } + +// if (pFlagLine) +// { +// uFirstLineIndex = uLastLineIndexInCell; +// } + +// //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы +// if (!pTable) +// { +// pTable = new CTable(); +// m_arTables.push_back(pTable); +// } + +// pTable->RecalcWithNewItem(pRow); +// pTable->CalculateColumnWidth(); +// } + +// keys.clear(); +// arConts.clear(); +// } +// } + void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) { bool bIsTextShapePresent = false; @@ -1661,9 +1647,8 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { auto pObj = m_arOutputObjects[i]; - CShape* pSahpe = nullptr; - if((pSahpe = dynamic_cast(pObj)) != nullptr) + if((pSahpe = dynamic_cast(pObj.get())) != nullptr) pSahpe->ToXml(oWriter); } } @@ -1676,14 +1661,13 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { auto pObj = m_arOutputObjects[i]; - CParagraph* pParagraph = nullptr; - if((pParagraph = dynamic_cast(pObj)) != nullptr) + if((pParagraph = dynamic_cast(pObj.get())) != nullptr) pParagraph->ToXml(oWriter); - CTable* pTable = nullptr; - if((pTable = dynamic_cast(pObj)) != nullptr) - pTable->ToXml(oWriter); +// CTable* pTable = nullptr; +// if((pTable = dynamic_cast(pObj)) != nullptr) +// pTable->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index c48f7e212cd..0ec04b3b653 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -8,48 +8,46 @@ #include "styles/ParagraphStyle.h" #include "elements/DropCap.h" - namespace NSDocxRenderer { class CPage { public: - NSStructures::CFont* m_pFont {nullptr}; - NSStructures::CPen* m_pPen {nullptr}; - NSStructures::CBrush* m_pBrush {nullptr}; - NSStructures::CShadow* m_pShadow {nullptr}; - NSStructures::CEdgeText* m_pEdgeText {nullptr}; - - Aggplus::CMatrix* m_pTransform {nullptr}; - Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter {nullptr}; - - CFontStyleManager* m_pFontStyleManager {nullptr}; - CParagraphStyleManager* m_pParagraphStyleManager {nullptr}; - CFontManager* m_pFontManager {nullptr}; - CFontSelector* m_pFontSelector {nullptr}; - CVectorGraphics m_oVector; - double m_dWidth {0.0}; double m_dHeight {0.0}; - LONG m_lCurrentCommand {0}; + LONG m_lCurrentCommand {0}; - std::vector m_arImages; - std::vector m_arDiacriticalSymbol; - std::vector m_arTextLine; - std::vector m_arShapes; - std::vector m_arConts; + NSStructures::CFont* m_pFont {nullptr}; + NSStructures::CPen* m_pPen {nullptr}; + NSStructures::CBrush* m_pBrush {nullptr}; + NSStructures::CShadow* m_pShadow {nullptr}; + NSStructures::CEdgeText* m_pEdgeText {nullptr}; - std::vector m_arOutputObjects; + Aggplus::CMatrix* m_pTransform {nullptr}; + Aggplus::CGraphicsPathSimpleConverter* m_pSimpleGraphicsConverter{nullptr}; - std::vector m_arPeaks; - std::vector m_arCells; - std::vector m_arRows; - std::vector m_arTables; + CFontStyleManager* m_pFontStyleManager {nullptr}; + CParagraphStyleManager* m_pParagraphStyleManager{nullptr}; + CFontManager* m_pFontManager {nullptr}; + CFontSelector* m_pFontSelector {nullptr}; + CVectorGraphics m_oVector; - CTextLine* m_pCurrentLine {nullptr}; - CRow* m_pCurrentRow {nullptr}; + std::vector> m_arConts; + std::vector> m_arTextLines; + std::vector> m_arDiacriticalSymbols; + std::vector> m_arImages; + std::vector> m_arShapes; + + std::vector> m_arOutputObjects; +// std::vector m_arPeaks; +// std::vector m_arCells; +// std::vector m_arRows; +// std::vector m_arTables; + + CTextLine* m_pCurrentLine {nullptr}; +// CRow* m_pCurrentRow {nullptr}; TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; @@ -96,12 +94,14 @@ namespace NSDocxRenderer void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); private: - void SortConts(); - void CreateTextLines(); - void AddContToTextLine(CContText *pCont); - void AnalyzeCollectedTextLines(); - void AnalyzeCollectedConts(); + // methods to build text lines + void BuildTextLines(); + void AddContToTextLine(std::shared_ptr pCont); + void AddContToTextLine(std::shared_ptr&& pCont); + + void AnalyzeTextLines(); + void AnalyzeConts(); void DetermineStrikeoutsUnderlinesHighlights(); void AnalyzeDropCaps(); @@ -113,15 +113,18 @@ namespace NSDocxRenderer bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); - void AnalyzeCollectedShapes(); - void BuildTables(); - void CollectPeaks(); - void CreatCells(); - void BuildRows(); - void SelectCurrentRow(const CCell *pCell); + void AnalyzeShapes(); void DetermineLinesType(); - void TryMergeShapes(); +// void BuildTables(); +// void CollectPeaks(); +// void CreatCells(); +// void BuildRows(); +// void SelectCurrentRow(const CCell *pCell); + + + void MergeShapes(); + void CalcSelected(); // конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку void ToXml(NSStringUtils::CStringBuilder& oWriter); diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 14fa15ed689..b34bf7cd2a4 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -7,12 +7,7 @@ namespace NSDocxRenderer CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc) { if (this == &oSrc) - { return *this; - } - -// m_eType = oSrc.m_eType; - m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse; m_dLeft = oSrc.m_dLeft; m_dTop = oSrc.m_dTop; @@ -75,7 +70,6 @@ namespace NSDocxRenderer return eVerticalCrossingType::vctUnknown; } } - eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc) const { if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight) @@ -135,7 +129,6 @@ namespace NSDocxRenderer return (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); } - bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept { eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); @@ -148,13 +141,12 @@ namespace NSDocxRenderer { return m_dLeft < oSrc->m_dLeft; } - bool CBaseItem::IsCurrentAboveOfNext(const CBaseItem* oSrc) { return m_dBaselinePos < oSrc->m_dBaselinePos; } - void CBaseItem::AddContent(CBaseItem* pItem) + void CBaseItem::RecalcWithNewItem(const CBaseItem* pItem) { m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos); diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 39714c5cbcc..f4261a7f6ce 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -2,6 +2,7 @@ #include "../DesktopEditor/common/StringBuilder.h" #include "src/resources/Constants.h" #include +#include namespace NSDocxRenderer { @@ -40,8 +41,6 @@ namespace NSDocxRenderer class CBaseItem { public: - bool m_bIsNotNecessaryToUse {false}; - double m_dTop {0.0}; double m_dBaselinePos {0.0}; double m_dHeight {0.0}; @@ -58,7 +57,7 @@ namespace NSDocxRenderer virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; - virtual void AddContent(CBaseItem* pItem); + virtual void RecalcWithNewItem(const CBaseItem* pObj); bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept; bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept; @@ -81,16 +80,6 @@ namespace NSDocxRenderer }); } - template - static void SortTopLeft(std::vector& oArray) - { - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) - return a->m_dLeft < b->m_dLeft; - return a->m_dBaselinePos < b->m_dBaselinePos; - }); - } - private: bool IsCurrentLeftOfNext(const CBaseItem* oSrc); bool IsCurrentAboveOfNext(const CBaseItem* oSrc); diff --git a/DocxRenderer/src/logic/elements/Cell.cpp b/DocxRenderer/src/logic/elements/Cell.cpp index d178107c76a..4c2beeb2578 100644 --- a/DocxRenderer/src/logic/elements/Cell.cpp +++ b/DocxRenderer/src/logic/elements/Cell.cpp @@ -1,192 +1,186 @@ -#include "Cell.h" -#include "Shape.h" - -namespace NSDocxRenderer -{ - CCell::~CCell() - { - Clear(); - } - - void CCell::Clear() - { - m_arTextLine.clear(); - for(size_t i = 0; i < m_arOutputObjects.size(); ++i) - - m_arOutputObjects[i]->Clear(); - m_arOutputObjects.clear(); - } - - void CCell::AddContent(CBaseItem* pItem) - { - CBaseItem::AddContent(pItem); - m_arTextLine.push_back(dynamic_cast(pItem)); - } - - void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) const - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"dxa\"/>"); - - if (m_bIsvMergeStart) - { - oWriter.WriteString(L""); - } - else if (m_bIsvMerge) - { - oWriter.WriteString(L""); - } - - if (m_uGridSpan > 1) - { - oWriter.WriteString(L""); - } - if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || - !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) - { - oWriter.WriteString(L""); - if (!m_bIsTopBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsLeftBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsBottomBorder) - { - oWriter.WriteString(L""); - } - if (!m_bIsRightBorder) - { - oWriter.WriteString(L""); - } - if (m_bIsDiagonalDownBorder) - { - oWriter.WriteString(L""); - } - if (m_bIsDiagonalUpBorder) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - if (m_arOutputObjects.empty()) - { - oWriter.WriteString(L""); - } - else - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - - CParagraph* pParagraph = nullptr; - if((pParagraph = dynamic_cast(pObj)) != nullptr) - pParagraph->ToXml(oWriter); - } - } - - oWriter.WriteString(L""); - } - - void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) - { - m_pPeaks[eCorner] = pPeak; - - switch (eCorner) - { - case cI: - if (pPeak->m_pLines[CPeak::dI]) - { - m_bIsLeftBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dII]) - { - m_bIsBottomBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cII: - if (pPeak->m_pLines[CPeak::dII]) - { - m_bIsRightBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dIII]) - { - m_bIsBottomBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; - m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cIII: - if (pPeak->m_pLines[CPeak::dIV]) - { - m_bIsRightBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dIII]) - { - m_bIsTopBorder = true; - - m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - case cIV: - if (pPeak->m_pLines[CPeak::dIV]) - { - m_bIsLeftBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - if (pPeak->m_pLines[CPeak::dI]) - { - m_bIsTopBorder = true; - - m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; - m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; - } - break; - default: - break; - } - - if (m_dLeft != 0 && m_dRight != 0) - { - m_dWidth = m_dRight - m_dLeft; - } - - if (m_dTop != 0 && m_dBaselinePos != 0) - { - m_dHeight = m_dBaselinePos - m_dTop; - } - } -} +//#include "Cell.h" +//#include "Shape.h" + +//namespace NSDocxRenderer +//{ +// CCell::~CCell() +// { +// Clear(); +// } + +// void CCell::Clear() +// { +// m_arTextLines.clear(); +// for(size_t i = 0; i < m_arOutputObjects.size(); ++i) + +// m_arOutputObjects[i]->Clear(); +// m_arOutputObjects.clear(); +// } + +// void CCell::AddContent(CBaseItem* pItem) +// { +// CBaseItem::AddContent(pItem); +// m_arTextLines.push_back(dynamic_cast(pItem)); +// } + +// void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) const +// { +// oWriter.WriteString(L""); +// oWriter.WriteString(L""); +// oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); +// oWriter.WriteString(L"\" w:type=\"dxa\"/>"); + +// if (m_bIsvMergeStart) +// { +// oWriter.WriteString(L""); +// } +// else if (m_bIsvMerge) +// { +// oWriter.WriteString(L""); +// } + +// if (m_uGridSpan > 1) +// { +// oWriter.WriteString(L""); +// } +// if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || +// !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) +// { +// oWriter.WriteString(L""); +// if (!m_bIsTopBorder) +// { +// oWriter.WriteString(L""); +// } +// if (!m_bIsLeftBorder) +// { +// oWriter.WriteString(L""); +// } +// if (!m_bIsBottomBorder) +// { +// oWriter.WriteString(L""); +// } +// if (!m_bIsRightBorder) +// { +// oWriter.WriteString(L""); +// } +// if (m_bIsDiagonalDownBorder) +// { +// oWriter.WriteString(L""); +// } +// if (m_bIsDiagonalUpBorder) +// { +// oWriter.WriteString(L""); +// } + +// oWriter.WriteString(L""); +// } + +// oWriter.WriteString(L""); + +// if (m_arOutputObjects.empty()) +// { +// oWriter.WriteString(L""); +// } +// else +// { +// for (size_t i = 0; i < m_arOutputObjects.size(); ++i) +// { +// auto pObj = m_arOutputObjects[i]; + +// CParagraph* pParagraph = nullptr; +// if((pParagraph = dynamic_cast(pObj)) != nullptr) +// pParagraph->ToXml(oWriter); +// } +// } + +// oWriter.WriteString(L""); +// } + +// void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) +// { +// m_pPeaks[eCorner] = pPeak; + +// switch (eCorner) +// { +// case cI: +// if (pPeak->m_pLines[CPeak::dI]) +// { +// m_bIsLeftBorder = true; + +// m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// if (pPeak->m_pLines[CPeak::dII]) +// { +// m_bIsBottomBorder = true; + +// m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// break; +// case cII: +// if (pPeak->m_pLines[CPeak::dII]) +// { +// m_bIsRightBorder = true; + +// m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// if (pPeak->m_pLines[CPeak::dIII]) +// { +// m_bIsBottomBorder = true; + +// m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; +// m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// break; +// case cIII: +// if (pPeak->m_pLines[CPeak::dIV]) +// { +// m_bIsRightBorder = true; + +// m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// if (pPeak->m_pLines[CPeak::dIII]) +// { +// m_bIsTopBorder = true; + +// m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; +// m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// break; +// case cIV: +// if (pPeak->m_pLines[CPeak::dIV]) +// { +// m_bIsLeftBorder = true; + +// m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// if (pPeak->m_pLines[CPeak::dI]) +// { +// m_bIsTopBorder = true; + +// m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; +// m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; +// } +// break; +// default: +// break; +// } + +// if (m_dLeft != 0 && m_dRight != 0) +// { +// m_dWidth = m_dRight - m_dLeft; +// } + +// if (m_dTop != 0 && m_dBaselinePos != 0) +// { +// m_dHeight = m_dBaselinePos - m_dTop; +// } +// } +//} diff --git a/DocxRenderer/src/logic/elements/Cell.h b/DocxRenderer/src/logic/elements/Cell.h index 43f492bad8d..edfb81436ec 100644 --- a/DocxRenderer/src/logic/elements/Cell.h +++ b/DocxRenderer/src/logic/elements/Cell.h @@ -1,87 +1,87 @@ -#pragma once -#include "Paragraph.h" +//#pragma once +//#include "Paragraph.h" -namespace NSDocxRenderer -{ - class CPeak - { - public: - // - // VI II V - // | - // III <- Peak -> I - // | - // VII IV VIII - //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) - enum eDirections - { - dI = 0, - dII = 1, - dIII = 2, - dIV = 3, - dV = 4, - dVI = 5, - dVII = 6, - dVIII = 7, - dNumDirections = 8 - }; +//namespace NSDocxRenderer +//{ +// class CPeak +// { +// public: +// // +// // VI II V +// // | +// // III <- Peak -> I +// // | +// // VII IV VIII +// //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) +// enum eDirections +// { +// dI = 0, +// dII = 1, +// dIII = 2, +// dIV = 3, +// dV = 4, +// dVI = 5, +// dVII = 6, +// dVIII = 7, +// dNumDirections = 8 +// }; - public: - CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak - CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон +// public: +// CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak +// CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон - public: - CPeak(CShape* pPeak) : m_pPeak(pPeak) {} - }; +// public: +// CPeak(CShape* pPeak) : m_pPeak(pPeak) {} +// }; - class CCell : public CBaseItem - { - public: - //Corners - // IV------III - // | | - // | Cell | - // | | - // I--------II - //У каждой ячейки может быть только 4 угла ) - enum eCorners - { - cI = 0, - cII = 1, - cIII = 2, - cIV = 3, - cNumCorners = 4 - }; - public: - bool m_bIsvMergeStart {false}; - bool m_bIsvMerge {false}; +// class CCell : public CBaseItem +// { +// public: +// //Corners +// // IV------III +// // | | +// // | Cell | +// // | | +// // I--------II +// //У каждой ячейки может быть только 4 угла ) +// enum eCorners +// { +// cI = 0, +// cII = 1, +// cIII = 2, +// cIV = 3, +// cNumCorners = 4 +// }; +// public: +// bool m_bIsvMergeStart {false}; +// bool m_bIsvMerge {false}; - bool m_bIsTopBorder {false}; - bool m_bIsLeftBorder {false}; - bool m_bIsBottomBorder {false}; - bool m_bIsRightBorder {false}; +// bool m_bIsTopBorder {false}; +// bool m_bIsLeftBorder {false}; +// bool m_bIsBottomBorder {false}; +// bool m_bIsRightBorder {false}; - bool m_bIsDiagonalDownBorder {false}; - bool m_bIsDiagonalUpBorder {false}; +// bool m_bIsDiagonalDownBorder {false}; +// bool m_bIsDiagonalUpBorder {false}; - UINT m_uGridSpan {1}; +// UINT m_uGridSpan {1}; - CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки +// CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки - //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами - //- дополнительное выделение памяти. Возможно нужно просто делать move. - std::vector m_arTextLine; - //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. - //Возможно подойдет вывод из CShape::BuildPictureProperties - std::vector m_arOutputObjects; +// //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами +// //- дополнительное выделение памяти. Возможно нужно просто делать move. +// std::vector m_arTextLines; +// //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. +// //Возможно подойдет вывод из CShape::BuildPictureProperties +// std::vector m_arOutputObjects; - public: - CCell() = default; - virtual ~CCell(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pItem) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; +// public: +// CCell() = default; +// virtual ~CCell(); +// virtual void Clear() override final; +// virtual void AddContent(CBaseItem* pItem) override final; +// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - void SetParameters(CPeak *pPeak, eCorners eCorner); - }; -} +// void SetParameters(CPeak *pPeak, eCorners eCorner); +// }; +//} diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 2441bf82309..bd6c7811031 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,6 +5,18 @@ namespace NSDocxRenderer { + CSelectedSizes::CSelectedSizes(const CSelectedSizes& oSelectedSizes) + { + *this = oSelectedSizes; + } + CSelectedSizes& CSelectedSizes::operator=(const CSelectedSizes& oSelectedSizes) + { + dWidth = oSelectedSizes.dWidth; + dSpaceWidth = oSelectedSizes.dSpaceWidth; + dHeight = oSelectedSizes.dHeight; + return *this; + } + CContText::CContText(const CContText& rCont) { *this = rCont; @@ -33,27 +45,20 @@ namespace NSDocxRenderer m_bIsStrikeoutPresent = rCont.m_bIsStrikeoutPresent; m_bIsDoubleStrikeout = rCont.m_bIsDoubleStrikeout; - m_bIsHighlightPresent = rCont.m_bIsHighlightPresent; m_lHighlightColor = rCont.m_lHighlightColor; - m_bIsUnderlinePresent = rCont.m_bIsUnderlinePresent; m_eUnderlineType = rCont.m_eUnderlineType; m_lUnderlineColor = rCont.m_lUnderlineColor; - m_bIsShadowPresent = rCont.m_bIsShadowPresent; m_bIsOutlinePresent = rCont.m_bIsOutlinePresent; m_bIsEmbossPresent = rCont.m_bIsEmbossPresent; m_bIsEngravePresent = rCont.m_bIsEngravePresent; - m_oText =rCont.m_oText; + m_oText = rCont.m_oText; + m_oSelectedSizes = rCont.m_oSelectedSizes; m_dSpaceWidthMM = rCont.m_dSpaceWidthMM; - m_bSpaceIsNotNeeded = rCont.m_bSpaceIsNotNeeded; - - m_dSpaceWidthSelected = rCont.m_dSpaceWidthSelected; - m_dWidthSelected = rCont.m_dWidthSelected; - m_eVertAlignType = rCont.m_eVertAlignType; m_pManager = rCont.m_pManager; @@ -66,11 +71,8 @@ namespace NSDocxRenderer return *this; } - void CContText::CalcSelectedWidth() + void CContText::CalcSelected() noexcept { - if(m_bIsNotNecessaryToUse) - return; - if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { // нужно перемерять... @@ -88,8 +90,11 @@ namespace NSDocxRenderer m_pManager->SetStringGid(0); m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition); - m_dWidthSelected = dBoxWidth; - m_dSpaceWidthSelected = m_pManager->GetSpaceWidthMM(); + + m_oSelectedSizes.dWidth = dBoxWidth; + m_oSelectedSizes.dHeight = dBoxHeight; + if(!m_oSelectedSizes.dSpaceWidth) + m_oSelectedSizes.dSpaceWidth = m_pManager->GetSpaceWidthMM(); } } @@ -99,39 +104,24 @@ namespace NSDocxRenderer if((pCont = dynamic_cast(pItem)) == nullptr) return CBaseItem::GetVerticalCrossingType(pItem); - auto m_dTop_copy = m_dTop; - auto m_dTop_copy_src = pCont->m_dTop; - - // call CBaseItem::GetVerticalCrossingType(oSrc) and not create copy, so const_cast was used - const_cast(pCont)->m_dTop = m_dBaselinePos - m_dTrueHeight; - const_cast(pCont)->m_dTop = pCont->m_dBaselinePos - pCont->m_dTrueHeight; - auto vert_cross = CBaseItem::GetVerticalCrossingType(pCont); if(vert_cross == eVerticalCrossingType::vctCurrentAboveNext && - (m_dBaselinePos - pCont->m_dTop < m_dTrueHeight * 0.3)) + (m_dBaselinePos - pCont->m_dTop < m_dHeight * 0.3)) vert_cross = eVerticalCrossingType::vctNoCrossingCurrentAboveNext; if(vert_cross == eVerticalCrossingType::vctCurrentBelowNext && - (pCont->m_dBaselinePos - m_dTop < pCont->m_dTrueHeight * 0.3)) + (pCont->m_dBaselinePos - m_dTop < pCont->m_dHeight * 0.3)) vert_cross = eVerticalCrossingType::vctNoCrossingCurrentBelowNext; - const_cast(pCont)->m_dTop = m_dTop_copy; - const_cast(pCont)->m_dTop = m_dTop_copy_src; - return vert_cross; } void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) const { - if (m_bIsNotNecessaryToUse) - { - return; - } - oWriter.WriteString(L""); oWriter.WriteString(L""); - //oWriter.WriteString(L""); + oWriter.WriteString(L""); oWriter.WriteString(L"wsFontStyleId); @@ -141,7 +131,7 @@ namespace NSDocxRenderer if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { - double dSpacing = (m_dWidth - m_dWidthSelected) / (m_oText.length()); + double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length()); dSpacing *= c_dMMToDx; //mm to points * 20 @@ -159,42 +149,29 @@ namespace NSDocxRenderer } if (m_bIsEmbossPresent) - { oWriter.WriteString(L""); - } else if (m_bIsEngravePresent) - { oWriter.WriteString(L""); - } else { if (m_bIsOutlinePresent) - { oWriter.WriteString(L""); - } if (m_bIsShadowPresent) - { oWriter.WriteString(L""); - } } if (m_bIsStrikeoutPresent) { if (m_bIsDoubleStrikeout) - { oWriter.WriteString(L""); - } else - { oWriter.WriteString(L""); - } } if (m_bIsUnderlinePresent) { oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L""); oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); oWriter.WriteString(L""); - - oWriter.WriteString(L""); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - - oWriter.WriteString(L"wsFontStyleId); - oWriter.WriteString(L"\"/>"); - - double dSpaceMMSize = m_dSpaceWidthMM; - LONG lCalculatedSpacing = static_cast((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L""); - } - - if (m_bIsEmbossPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else if (m_bIsEngravePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - else - { - if (m_bIsOutlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - if (m_bIsShadowPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - } - - if (m_bIsStrikeoutPresent && bIsNeedSaveFormat) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L""); - } - else - { - oWriter.WriteString(L""); - } - } - - if (m_bIsUnderlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L""); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L" "); - oWriter.WriteString(L""); - oWriter.WriteString(L""); } - bool CContText::IsEqual(const CContText *pCont) + bool CContText::IsEqual(const CContText *pCont) const noexcept { bool bIf1 = m_pFontStyle->wsFontStyleId == pCont->m_pFontStyle->wsFontStyleId; bool bIf2 = m_bIsStrikeoutPresent == pCont->m_bIsStrikeoutPresent; @@ -360,54 +241,31 @@ namespace NSDocxRenderer bIf8 && bIf9 && bIf10 && bIf11 && bIf12 && (bIf13 || bIf14 || bIf15)); } - UINT CContText::GetNumberOfFeatures() + UINT CContText::GetNumberOfFeatures() const noexcept { UINT ret = 0; - if (m_pFontStyle->bBold) - { - ret++; - } - if (m_pFontStyle->bItalic) - { - ret++; - } - if (m_bIsStrikeoutPresent) - { - ret++; - } - if (m_bIsDoubleStrikeout) - { - ret++; - } - if (m_bIsHighlightPresent) - { - ret++; - } - if (m_bIsUnderlinePresent) - { - ret++; - } - if (m_eVertAlignType != eVertAlignType::vatUnknown) - { - ret++; - } - + if (m_pFontStyle->bBold) ret++; + if (m_pFontStyle->bItalic) ret++; + if (m_bIsStrikeoutPresent) ret++; + if (m_bIsDoubleStrikeout) ret++; + if (m_bIsHighlightPresent) ret++; + if (m_bIsUnderlinePresent) ret++; + if (m_eVertAlignType != eVertAlignType::vatUnknown) ret++; return ret; } - bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) + bool CContText::IsDuplicate(CContText* pCont, eVerticalCrossingType eVType) const noexcept { - if (eVType == eVerticalCrossingType::vctDublicate && - m_oText == pCont->m_oText) - { - pCont->m_bIsNotNecessaryToUse = true; - m_iNumDuplicates++; + if (eVType == eVerticalCrossingType::vctDublicate && m_oText == pCont->m_oText) return true; - } return false; } - bool CContText::IsThereAreFontEffects(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) + bool CContText::CheckFontEffects + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) noexcept { //Условие пересечения по вертикали bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше @@ -418,53 +276,51 @@ namespace NSDocxRenderer bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; //текущий cont правее //Размеры шрифта и текст должны бать одинаковыми - bool bIf5 = m_pFontStyle->dFontSize == m_pFontStyle->dFontSize; - bool bIf6 = m_oText == pCont->m_oText; + bool bIf5 = pFirstCont->m_pFontStyle->dFontSize == pSecondCont->m_pFontStyle->dFontSize; + bool bIf6 = pFirstCont->m_oText == pSecondCont->m_oText; //Цвет тени должен быть серым - bool bIf7 = m_pFontStyle->oBrush.Color1 == c_iGreyColor; - bool bIf8 = pCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; - bool bIf9 = m_pFontStyle->oBrush.Color1 == c_iBlackColor; - bool bIf10 = pCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; - bool bIf11 = m_pFontStyle->oBrush.Color1 == c_iGreyColor2; - bool bIf12 = pCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; + bool bIf7 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf8 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + + bool bIf9 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; + bool bIf10 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iBlackColor; + + bool bIf11 = pFirstCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; + bool bIf12 = pSecondCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor2; //note Каждый символ с Emboss или Engrave разбиваются на 3 символа с разными цветами //note Логика подобрана для конкретного примера - возможно нужно будет ее обобщить. //todo существует проблема неправильного определением FontEffects с физически пересекаемыми строчками - файл generaltest.pdf p.14 if (bIf5 && bIf6) { - if (m_bIsEmbossPresent && bIf12) - { + if (bIf12) if (bIf1 && bIf3) { - m_bIsEmbossPresent = true; - pCont->m_bIsNotNecessaryToUse = true; + pFirstCont->m_bIsEmbossPresent = true; + pSecondCont = nullptr; return true; } - } - if (m_bIsEngravePresent && bIf10) - { + if (bIf10) if (bIf1 && bIf3) { - m_bIsEngravePresent = true; - pCont->m_bIsNotNecessaryToUse = true; + pFirstCont->m_bIsEngravePresent = true; + pSecondCont = nullptr; return true; } - } //Shadow if (bIf1 && bIf3 && bIf8) { - m_bIsShadowPresent = true; - pCont->m_bIsNotNecessaryToUse = true; + pFirstCont->m_bIsShadowPresent = true; + pSecondCont = nullptr; return true; } else if (bIf2 && bIf4 && bIf7) { - pCont->m_bIsShadowPresent = true; - m_bIsNotNecessaryToUse = true; + pSecondCont->m_bIsShadowPresent = true; + pFirstCont = nullptr; return true; } @@ -473,85 +329,90 @@ namespace NSDocxRenderer //c_iBlackColor -> c_iBlackColor -> c_iGreyColor2 else if (bIf1 && bIf3 && bIf9) { - pCont->m_bIsEmbossPresent = true; - m_bIsNotNecessaryToUse = true; + pSecondCont->m_bIsEmbossPresent = true; + pFirstCont = nullptr; return true; } //Engrave else if (bIf1 && bIf3 && bIf11) { - pCont->m_bIsEngravePresent = true; - m_bIsNotNecessaryToUse = true; + pSecondCont->m_bIsEngravePresent = true; + pFirstCont = nullptr; return true; } } return false; } - bool CContText::IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) + bool CContText::CheckVertAlignTypeBetweenConts + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) noexcept { - //Условие пересечения по вертикали + bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || - eVType == eVerticalCrossingType::vctCurrentInsideNext; + eVType == eVerticalCrossingType::vctCurrentInsideNext; + bool bIf2 = eVType == eVerticalCrossingType::vctCurrentBelowNext; - //Условие пересечения по горизонтали + bool bIf3 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || - eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && - fabs(m_dRight - pCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; + eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) && + fabs(pFirstCont->m_dRight - pSecondCont->m_dLeft) < c_dTHE_STRING_X_PRECISION_MM * 3; + bool bIf4 = (eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext) && - fabs(m_dLeft - pCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; + fabs(pFirstCont->m_dLeft - pSecondCont->m_dRight) < c_dTHE_STRING_X_PRECISION_MM * 3; + //Размеры шрифта должны бать разными - bool bIf5 = m_pFontStyle->dFontSize * 0.7 > pCont->m_pFontStyle->dFontSize; - bool bIf6 = m_pFontStyle->dFontSize < pCont->m_pFontStyle->dFontSize * 0.7; + bool bIf5 = pFirstCont->m_pFontStyle->dFontSize * 0.7 > pSecondCont->m_pFontStyle->dFontSize; + bool bIf6 = pFirstCont->m_pFontStyle->dFontSize < pSecondCont->m_pFontStyle->dFontSize * 0.7; if (bIf3 || bIf4) { if (bIf1 && bIf5) { - pCont->m_eVertAlignType = eVertAlignType::vatSubscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pSecondCont->m_pCont = pFirstCont; + pFirstCont->m_eVertAlignType = eVertAlignType::vatBase; + pFirstCont->m_pCont = pSecondCont; return true; } else if (bIf2 && bIf5) { - pCont->m_eVertAlignType = eVertAlignType::vatSuperscript; - pCont->m_pCont = this; - m_eVertAlignType = eVertAlignType::vatBase; - m_pCont = pCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pSecondCont->m_pCont = pFirstCont; + pFirstCont->m_eVertAlignType = eVertAlignType::vatBase; + pFirstCont->m_pCont = pSecondCont; return true; } else if (bIf1 && bIf6) { - m_eVertAlignType = eVertAlignType::vatSuperscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; + pFirstCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; return true; } else if (bIf2 && bIf6) { - m_eVertAlignType = eVertAlignType::vatSubscript; - m_pCont = pCont; - pCont->m_eVertAlignType = eVertAlignType::vatBase; - pCont->m_pCont = this; + pFirstCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; return true; } } return false; } - double CContText::CalculateWideSpace() + double CContText::CalculateWideSpace() const noexcept { - //note подобранное условие - не везде хорошо работает return m_dSpaceWidthMM * 3; } - double CContText::CalculateThinSpace() + double CContText::CalculateThinSpace() const noexcept { - //note подобранное условие - не везде хорошо работает - return m_dSpaceWidthMM * 0.3; + return m_dSpaceWidthMM * 0.35; } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 99d5da30595..5eb174e48f1 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -18,66 +18,88 @@ namespace NSDocxRenderer vatSuperscript }; + // sizes in selected font + struct CSelectedSizes + { + double dWidth{0}; + double dSpaceWidth{0}; + double dHeight{0}; + + CSelectedSizes() = default; + ~CSelectedSizes() = default; + CSelectedSizes(const CSelectedSizes& oSelectedSizes); + CSelectedSizes& operator=(const CSelectedSizes& oSelectedSizes); + }; + class CContText : public CBaseItem { public: - std::shared_ptr m_pFontStyle {nullptr}; - bool m_bIsStrikeoutPresent{false}; - bool m_bIsDoubleStrikeout{false}; + // utils + std::shared_ptr m_pFontStyle{nullptr}; + CFontManager* m_pManager {nullptr}; - bool m_bIsHighlightPresent{false}; - LONG m_lHighlightColor{c_iBlackColor}; + // background graphics + std::shared_ptr m_pShape {nullptr}; - bool m_bIsUnderlinePresent{false}; - eLineType m_eUnderlineType{eLineType::ltUnknown}; - LONG m_lUnderlineColor{c_iBlackColor}; + // super/sub script + std::shared_ptr m_pCont {nullptr}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - bool m_bIsShadowPresent{false}; - bool m_bIsOutlinePresent{false}; - bool m_bIsEmbossPresent{false}; - bool m_bIsEngravePresent{false}; + // highlights + bool m_bIsStrikeoutPresent {false}; + bool m_bIsDoubleStrikeout {false}; + bool m_bIsHighlightPresent {false}; + LONG m_lHighlightColor {c_iBlackColor}; + bool m_bIsUnderlinePresent {false}; + eLineType m_eUnderlineType {eLineType::ltUnknown}; + LONG m_lUnderlineColor {c_iBlackColor}; + bool m_bIsShadowPresent {false}; + bool m_bIsOutlinePresent {false}; + bool m_bIsEmbossPresent {false}; + bool m_bIsEngravePresent {false}; - NSStringUtils::CStringUTF32 m_oText; + // sizes double m_dSpaceWidthMM{0}; - bool m_bSpaceIsNotNeeded{false}; - - double m_dWidthSelected{0}; - double m_dSpaceWidthSelected{0}; - - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - - CFontManager* m_pManager{nullptr}; - - CShape* m_pShape{nullptr}; //Если не nullptr, то есть фоновая графика - можно анализировать. - const CContText* m_pCont{nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + CSelectedSizes m_oSelectedSizes{}; + NSStringUtils::CStringUTF32 m_oText{}; UINT m_iNumDuplicates{0}; - double m_dTrueHeight{0}; - public: + CContText() = default; CContText(CFontManager* pManager) : m_pManager(pManager) {} CContText(const CContText& rCont); virtual ~CContText(); + virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override final; + + // calc sizes in selected font (uses m_pFontStyle & m_pManager) + void CalcSelected() noexcept; + + CContText& operator=(const CContText& rCont); + bool IsEqual(const CContText* pCont) const noexcept; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override final; + UINT GetNumberOfFeatures() const noexcept; + bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType) const noexcept; - CContText& operator= (const CContText& rCont); + // check font effect and delete not needed cont + // return true if was deleted + static bool CheckFontEffects + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) noexcept; - void AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat = false); - bool IsEqual(const CContText* pCont); - UINT GetNumberOfFeatures(); - bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType); - bool IsThereAreFontEffects(CContText *pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - bool IsVertAlignTypeBetweenConts(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType); - void CalcSelectedWidth(); + static bool CheckVertAlignTypeBetweenConts + (std::shared_ptr& pFirstCont, + std::shared_ptr& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType) noexcept; - double CalculateWideSpace(); - double CalculateThinSpace(); + double CalculateWideSpace() const noexcept; + double CalculateThinSpace() const noexcept; }; } diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp index 5381e245046..50e0313d825 100644 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ b/DocxRenderer/src/logic/elements/Converter.cpp @@ -11,19 +11,18 @@ namespace NSDocxRenderer for (size_t i = 0; i < rTextLines.size(); ++i) { auto pCurrLine = rTextLines[i]; - if (pCurrLine->m_bIsNotNecessaryToUse) + if (!pCurrLine) continue; for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) { auto pCurrCont = pCurrLine->m_arConts[j]; - if (pCurrCont->m_bIsNotNecessaryToUse) + if (!pCurrCont) continue; if (pCurrCont->m_iNumDuplicates > 0) pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); } - pCurrLine->MergeConts(); } @@ -32,23 +31,19 @@ namespace NSDocxRenderer void CConverter::DetermineDominantGraphics(std::vector& rTextLines) { - CShape* pDominantShape = nullptr; + std::shared_ptr pDominantShape = nullptr; for (size_t i = 0; i < rTextLines.size(); ++i) { auto pLine = rTextLines[i]; - if (pLine->m_bIsNotNecessaryToUse) - { + if (!pLine) continue; - } for (size_t j = 0; j < pLine->m_arConts.size(); ++j) { auto pCont = pLine->m_arConts[j]; - if (pCont->m_bIsNotNecessaryToUse) - { + if (!pCont) continue; - } if (pCont->m_pShape && pCont->m_pShape != pDominantShape) { @@ -70,20 +65,20 @@ namespace NSDocxRenderer } } - void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, - std::vector& rTextLines, - std::vector& rOutputObjects, - CParagraphStyleManager* pParagraphStyleManager) - { - std::vector oStubVector; //просто объект-заглушка - BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects, pParagraphStyleManager); - } +// void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, +// std::vector& rTextLines, +// std::vector& rOutputObjects, +// CParagraphStyleManager* pParagraphStyleManager) +// { +// std::vector oStubVector; //просто объект-заглушка +// BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects, pParagraphStyleManager); +// } // eBaseType == etCell или etParagraph // eType == 2 - 5 из TextAssociationType - void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, - COutputObject::eOutputType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector& rOutputObjects, + void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, + std::vector& rTextLines, + std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager) { CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; @@ -134,12 +129,10 @@ namespace NSDocxRenderer for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) { pCurrLine = rTextLines[nIndex]; - avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dTrueHeight / (n + 1)); + avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); - if (pCurrLine->m_bIsNotNecessaryToUse) - { + if (!pCurrLine) continue; - } if (eType == TextAssociationType::tatShapeLine) { @@ -188,13 +181,13 @@ namespace NSDocxRenderer // { // dCurrBeforeSpacing = 0; // } - dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight - dPreviousStringBaseline; + dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight - dPreviousStringBaseline; dPreviousStringBaseline = pCurrLine->m_dBaselinePos; //Если у текущей линии есть дубликаты, то создаем из них шейпы if (pCurrLine->m_iNumDuplicates > 0) { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dTrueHeight; + dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; auto iNumDuplicates = pCurrLine->m_iNumDuplicates; CreateSingleLineShape(pCurrLine, rOutputObjects); @@ -229,14 +222,14 @@ namespace NSDocxRenderer { case eVerticalCrossingType::vctCurrentInsideNext: case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dTrueHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; dPreviousStringBaseline = pNextLine->m_dBaselinePos; bIsPassed = true; break; case eVerticalCrossingType::vctCurrentOutsideNext: case eVerticalCrossingType::vctCurrentAboveNext: case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dTrueHeight; + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; bIsPassed = true; break; default: @@ -263,11 +256,11 @@ namespace NSDocxRenderer //Логика определения параметров для DetermineTextAlignmentType if (pNextLine) { - dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dTrueHeight - dPreviousStringBaseline; + dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dHeight - dPreviousStringBaseline; //dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dTrueHeight - pNextLine->m_dTrueHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //расстрояние между строк тоже одинаково bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //или @@ -288,19 +281,19 @@ namespace NSDocxRenderer if (pNextNextLine) { //double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dTrueHeight - dPreviousStringBaseline; + double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dHeight - dPreviousStringBaseline; if (bIf1 && (bIf2 || bIf3)) { if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) { - if (fabs(pNextLine->m_dTrueHeight - pNextNextLine->m_dTrueHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) { pNextNextLine = nullptr; } } else { - if (fabs(pNextLine->m_dTrueHeight - pNextNextLine->m_dTrueHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { @@ -357,9 +350,9 @@ namespace NSDocxRenderer pParagraph->m_dFirstLine = 0; } - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight; + pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - pParagraph->m_dHeight = pCurrLine->m_dTrueHeight; + pParagraph->m_dHeight = pCurrLine->m_dHeight; //размер строк во всем параграфе // pParagraph->m_dLineHeight = avg_height; //pCurrLine->m_dHeight; @@ -385,7 +378,7 @@ namespace NSDocxRenderer pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; dPreviousStringBaseline = pCurrLine->m_dBaselinePos; double dCorrectionBeforeSpacing = dCurrBeforeSpacing; @@ -393,7 +386,7 @@ namespace NSDocxRenderer { if (pNextLine) { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой @@ -433,13 +426,13 @@ namespace NSDocxRenderer pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); dPreviousStringBaseline = pCurrLine->m_dBaselinePos; dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing) / 2; //наверное лучше так... текст может быть уже, чем в оригинале if (pNextLine) { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dTrueHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой @@ -516,12 +509,12 @@ namespace NSDocxRenderer pParagraph->m_arLines.push_back(pLine); pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; + pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; pParagraph->m_dFirstLine = 0; pParagraph->m_dRight = pLine->m_dRight; pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dTrueHeight; + pParagraph->m_dHeight = pLine->m_dHeight; if (*pBeforeSpacing < 0) { pParagraph->m_dHeight += *pBeforeSpacing; @@ -541,7 +534,7 @@ namespace NSDocxRenderer void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects) { - auto pParagraph = new CParagraph(); + auto pParagraph = std::make_shared(); pParagraph->m_arLines.push_back(pLine); pParagraph->m_dRightBorder = 0; @@ -557,9 +550,9 @@ namespace NSDocxRenderer pShape->m_arOutputObjects.push_back(pParagraph); pShape->m_eType = CShape::eShapeType::stTextBox; pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; + pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dTrueHeight; + pShape->m_dHeight = pLine->m_dHeight; pShape->m_bIsBehindDoc = false; rOutputObjects.push_back(pShape); @@ -626,76 +619,76 @@ namespace NSDocxRenderer } } - void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) - { - if (!pTable) - { - return; - } +// void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) +// { +// if (!pTable) +// { +// return; +// } - CShape* pShape; +// CShape* pShape; - pShape = new CShape(); - pShape->m_dHeight = pTable->m_dHeight; - pShape->m_dLeft = pTable->m_dLeft; - pShape->m_dTop =pTable->m_dTop; - pShape->m_dRight = pTable->m_dRight; - pShape->m_dBaselinePos = pTable->m_dBaselinePos; - pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); +// pShape = new CShape(); +// pShape->m_dHeight = pTable->m_dHeight; +// pShape->m_dLeft = pTable->m_dLeft; +// pShape->m_dTop =pTable->m_dTop; +// pShape->m_dRight = pTable->m_dRight; +// pShape->m_dBaselinePos = pTable->m_dBaselinePos; +// pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); - pShape->m_arOutputObjects.push_back(pTable); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_bIsBehindDoc = false; +// pShape->m_arOutputObjects.push_back(pTable); +// pShape->m_eType = CShape::eShapeType::stTextBox; +// pShape->m_bIsBehindDoc = false; - rOutputObjects.push_back(pShape); - } +// rOutputObjects.push_back(pShape); +// } - void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) - { - for (size_t i = 0; i < rOutputObjects.size(); ++i) - { - if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) - { - continue; - } +// void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) +// { +// for (size_t i = 0; i < rOutputObjects.size(); ++i) +// { +// if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) +// { +// continue; +// } - auto pShape = dynamic_cast(rOutputObjects[i]); +// auto pShape = dynamic_cast(rOutputObjects[i]); - if (pShape->m_bIsNotNecessaryToUse || - pShape->m_eType != CShape::eShapeType::stTextBox || - pShape->m_arOutputObjects.empty()) - { - continue; - } +// if (pShape->m_bIsNotNecessaryToUse || +// pShape->m_eType != CShape::eShapeType::stTextBox || +// pShape->m_arOutputObjects.empty()) +// { +// continue; +// } - for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) - { - auto pObj = pShape->m_arOutputObjects[j]; +// for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) +// { +// auto pObj = pShape->m_arOutputObjects[j]; - switch(pObj->m_eType) - { - case COutputObject::eOutputType::etParagraph: - { - auto pParagraph = dynamic_cast(pObj); +// switch(pObj->m_eType) +// { +// case COutputObject::eOutputType::etParagraph: +// { +// auto pParagraph = dynamic_cast(pObj); - if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) - { - pParagraph->m_bIsNeedFirstLineIndent = true; - pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; - pParagraph->m_dLeft = 0; - } +// if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) +// { +// pParagraph->m_bIsNeedFirstLineIndent = true; +// pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; +// pParagraph->m_dLeft = 0; +// } - pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; - pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; - } - break; - default: - break; - } +// pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; +// pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; +// } +// break; +// default: +// break; +// } - } - } - } +// } +// } +// } CTextLine* CConverter::GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking) { diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h index de9ae01631b..0e9504323bf 100644 --- a/DocxRenderer/src/logic/elements/Converter.h +++ b/DocxRenderer/src/logic/elements/Converter.h @@ -13,14 +13,14 @@ namespace NSDocxRenderer void BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, std::vector& rTextLines, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); - void BuildParagraphes(double dPageWidth, TextAssociationType eType, - COutputObject::eOutputType eBaseType, std::vector& rTextLines, - std::vector& rTables, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); +// void BuildParagraphes(double dPageWidth, TextAssociationType eType, +// COutputObject::eOutputType eBaseType, std::vector& rTextLines, +// std::vector& rTables, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector& rOutputObjects); void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector& rOutputObjects); - void CreateShapeFormTable(CTable* pParagraph, std::vector& rOutputObjects); +// void CreateShapeFormTable(CTable* pParagraph, std::vector& rOutputObjects); void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); private: diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h index 10db91e644d..5d4ec09db2a 100644 --- a/DocxRenderer/src/logic/elements/DropCap.h +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -15,7 +15,7 @@ namespace NSDocxRenderer LONG nFontSize; // Pt * 2 LONG nOffset; -// CDropCap() : CBaseItem(ElemType::etDropCap) {} + CDropCap() = default; ~CDropCap() = default; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override; diff --git a/DocxRenderer/src/logic/elements/Image.cpp b/DocxRenderer/src/logic/elements/Image.cpp index 5dd6951de9a..815f24923c4 100644 --- a/DocxRenderer/src/logic/elements/Image.cpp +++ b/DocxRenderer/src/logic/elements/Image.cpp @@ -8,17 +8,10 @@ namespace NSDocxRenderer : m_oImageInfo(oInfo), m_strPath(strDstMedia) { } - void CImage::Clear(){} void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) const { - if (m_bIsNotNecessaryToUse) - { - return; - } - oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -142,39 +137,34 @@ namespace NSDocxRenderer auto pLastCont = pLine->m_arConts.back(); size_t iNumConts = pLine->m_arConts.size() - 1; - while (pLastCont->m_bIsNotNecessaryToUse) - { + while (!pLastCont) pLastCont = pLine->m_arConts[--iNumConts]; - } - //Добавляем пробел в конец каждой строки +// //Добавляем пробел в конец каждой строки pLastCont->m_oText += L" "; - pLastCont->m_bSpaceIsNotNeeded = true; - pLastCont->m_dWidth += pLine->m_arConts.back()->m_dSpaceWidthSelected; - - auto pNext = m_arLines[i]; - auto pCont = pNext->m_arConts.front(); - - if (pLastCont->IsEqual(pCont)) - { - pLastCont->m_oText += pCont->m_oText; - pLastCont->m_dWidth += pCont->m_dWidth; - pLastCont->m_dRight = pCont->m_dRight; - - pLastCont->m_bSpaceIsNotNeeded = false; - pCont->m_bIsNotNecessaryToUse = true; - } - - for (size_t j = 0; j < pNext->m_arConts.size(); ++j) - { - auto& pCont = pNext->m_arConts[j]; - if (!pCont->m_bIsNotNecessaryToUse) - { - pLine->m_arConts.push_back(pCont); - pCont = nullptr; - } - } - pNext->m_bIsNotNecessaryToUse = true; + pLastCont->m_dWidth += pLine->m_arConts.back()->m_oSelectedSizes.dSpaceWidth; + +// auto pNext = m_arLines[i]; +// auto pCont = pNext->m_arConts.front(); + +// if (pLastCont->IsEqual(pCont)) +// { +// pLastCont->m_oText += pCont->m_oText; +// pLastCont->m_dWidth += pCont->m_dWidth; +// pLastCont->m_dRight = pCont->m_dRight; +// pCont->m_bIsNotNecessaryToUse = true; +// } + +// for (size_t j = 0; j < pNext->m_arConts.size(); ++j) +// { +// auto& pCont = pNext->m_arConts[j]; +// if (!pCont->m_bIsNotNecessaryToUse) +// { +// pLine->m_arConts.push_back(pCont); +// pCont = nullptr; +// } +// } +// pNext->m_bIsNotNecessaryToUse = true; } } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index cb749cb9f7f..eefc93beabe 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -29,9 +29,6 @@ namespace NSDocxRenderer void CShape::Clear() { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - delete m_arOutputObjects[i]; - m_arOutputObjects.clear(); m_oVector.Clear(); } @@ -92,7 +89,7 @@ namespace NSDocxRenderer m_dRight = m_dLeft + m_dWidth; } - bool CShape::TryMergeShape(CShape* pShape) + bool CShape::TryMergeShape(std::shared_ptr pShape) { // можно попробовать подбирать динамически, например в зависимости от размера double dHorNearby = 30; @@ -133,8 +130,9 @@ namespace NSDocxRenderer fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby || fabs(pShape->m_dTop - this->m_dTop) < dVerNearby)) { - CBaseItem::AddContent(pShape); + CBaseItem::RecalcWithNewItem(pShape.get()); m_oVector.Join(std::move(pShape->m_oVector)); + pShape = nullptr; this->m_eGraphicsType = eGraphicsType::gtComplicatedFigure; return true; @@ -300,7 +298,7 @@ namespace NSDocxRenderer CShape* pModObject; CShape* pDataObject; - if (pShape->m_bIsNotNecessaryToUse) + if (!pShape) { pModObject = this; pDataObject = pShape; @@ -647,20 +645,11 @@ namespace NSDocxRenderer //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст //todo добавить все возможные параметры/атрибуты - if (m_bIsNotNecessaryToUse) - { - return; - } oWriter.WriteString(L""); - oWriter.WriteString(L""); //отключение проверки орфографии - oWriter.WriteString(L""); - BuildGeneralProperties(oWriter); - oWriter.WriteString(L""); - oWriter.WriteString(L""); } diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index e206762cce3..ab7509f5b7c 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -47,8 +47,7 @@ namespace NSDocxRenderer eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; eLineType m_eLineType {eLineType::ltUnknown}; - std::vector m_arOutputObjects; - + std::vector> m_arOutputObjects; std::shared_ptr m_pImageInfo {nullptr}; private: @@ -65,7 +64,9 @@ namespace NSDocxRenderer virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void SetVector(CVectorGraphics&& oVector); - bool TryMergeShape(CShape* pShape); + + // tries merge shape, return true if ok and pShape was deleted + bool TryMergeShape(std::shared_ptr pShape); std::wstring PathToWString() const; void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); bool IsItFitLine(); diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp index cea4644dd1f..27065c05716 100644 --- a/DocxRenderer/src/logic/elements/Table.cpp +++ b/DocxRenderer/src/logic/elements/Table.cpp @@ -1,209 +1,209 @@ -#include "Table.h" - -namespace NSDocxRenderer -{ - CRow::~CRow() - { - Clear(); - } - - void CRow::Clear() - { - m_arCells.clear(); - } - - void CRow::AddContent(CBaseItem* pItem) - { - CBaseItem::AddContent(pItem); - m_arCells.push_back(dynamic_cast(pItem)); - } - - CTable::~CTable() - { - Clear(); - } - - void CTable::Clear() - { - m_arRows.clear(); - } - - void CTable::AddContent(CBaseItem* pItem) - { - CBaseItem::AddContent(pItem); - m_arRows.push_back(dynamic_cast(pItem)); - } - - void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) const - { - if (m_bIsNotNecessaryToUse) - { - return; - } - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - if (m_bIsNeedSpacing) - { - oWriter.WriteString(L" 0) - { - oWriter.WriteString(L" w:before=\""); - oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dSpaceAfter > 0) - { - oWriter.WriteString(L" w:after=\""); - oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dLineHeight > 0) - { - oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки - } - oWriter.WriteString(L"/>"); //конец w:spacing - - oWriter.WriteString(L""); - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"dxa\"/>"); - } - else - { - oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\" w:tblpY=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); - oWriter.WriteString(L"\" w:type=\"auto\"/>"); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - for (size_t i = 0; i < m_arColumnWidths.size(); ++i) - { - oWriter.WriteString(L""); - } - oWriter.WriteString(L""); - - for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) - { - auto pRow = m_arRows[nRow]; - - oWriter.WriteString(L""); - - oWriter.WriteString(L""); - oWriter.WriteString(L"m_dHeight * c_dMMToDx); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L""); - - for (size_t j = 0; j < pRow->m_arCells.size(); ++j) - { - pRow->m_arCells[j]->ToXml(oWriter); - } - - oWriter.WriteString(L""); - } - - oWriter.WriteString(L""); - } - - //note: для полной таблицы, составляющей в сумме ячеек прямоугольник - void CTable::CalculateColumnWidth() - { - m_arColumnWidths.clear(); - - if (m_arRows.empty()) - { - return; - } - - //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают - //if (m_arRows.size() == 1) - { - for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) - { - m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); - } - return; - } - - double dMinWidth = 0; - double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы - CCell* pCurrCellWithMinWidth = nullptr; - - //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать - //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы - while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! - { - //находим минимальный width после текущей dCurrLeftBorder - for (size_t i = 0; i < m_arRows.size(); ++i) - { - for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) - { - auto pCell = m_arRows[i]->m_arCells[j]; - - if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) - { - if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) - { - dMinWidth = pCell->m_dRight - dCurrLeftBorder; - pCurrCellWithMinWidth = pCell; - } - break; - } - } - } - - m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); - - //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки - for (size_t i = 0; i < m_arRows.size(); ++i) - { - for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) - { - auto pCell = m_arRows[i]->m_arCells[j]; - - if (dCurrLeftBorder < pCell->m_dRight && - fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && - pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && - fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) - { - ++pCell->m_uGridSpan; - break; - } - } - } - - //сдвигаем dCurrLeftBorder - dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; - } - } -} +//#include "Table.h" + +//namespace NSDocxRenderer +//{ +// CRow::~CRow() +// { +// Clear(); +// } + +// void CRow::Clear() +// { +// m_arCells.clear(); +// } + +// void CRow::AddContent(CBaseItem* pItem) +// { +// CBaseItem::AddContent(pItem); +// m_arCells.push_back(dynamic_cast(pItem)); +// } + +// CTable::~CTable() +// { +// Clear(); +// } + +// void CTable::Clear() +// { +// m_arRows.clear(); +// } + +// void CTable::AddContent(CBaseItem* pItem) +// { +// CBaseItem::AddContent(pItem); +// m_arRows.push_back(dynamic_cast(pItem)); +// } + +// void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) const +// { +// if (m_bIsNotNecessaryToUse) +// { +// return; +// } + +// oWriter.WriteString(L""); + +// oWriter.WriteString(L""); +// oWriter.WriteString(L""); + +// if (m_bIsNeedSpacing) +// { +// oWriter.WriteString(L" 0) +// { +// oWriter.WriteString(L" w:before=\""); +// oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); +// oWriter.WriteString(L"\""); +// } + +// if (m_dSpaceAfter > 0) +// { +// oWriter.WriteString(L" w:after=\""); +// oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); +// oWriter.WriteString(L"\""); +// } + +// if (m_dLineHeight > 0) +// { +// oWriter.WriteString(L" w:line=\""); +// oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); +// oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки +// } +// oWriter.WriteString(L"/>"); //конец w:spacing + +// oWriter.WriteString(L""); +// oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); +// oWriter.WriteString(L"\" w:type=\"dxa\"/>"); +// } +// else +// { +// oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); +// oWriter.WriteString(L"\" w:tblpY=\""); +// oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); +// oWriter.WriteString(L"\"/>"); +// } + +// oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); +// oWriter.WriteString(L"\" w:type=\"auto\"/>"); + +// oWriter.WriteString(L""); +// oWriter.WriteString(L""); + +// oWriter.WriteString(L""); +// for (size_t i = 0; i < m_arColumnWidths.size(); ++i) +// { +// oWriter.WriteString(L""); +// } +// oWriter.WriteString(L""); + +// for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) +// { +// auto pRow = m_arRows[nRow]; + +// oWriter.WriteString(L""); + +// oWriter.WriteString(L""); +// oWriter.WriteString(L"m_dHeight * c_dMMToDx); +// oWriter.WriteString(L"\"/>"); +// oWriter.WriteString(L""); + +// for (size_t j = 0; j < pRow->m_arCells.size(); ++j) +// { +// pRow->m_arCells[j]->ToXml(oWriter); +// } + +// oWriter.WriteString(L""); +// } + +// oWriter.WriteString(L""); +// } + +// //note: для полной таблицы, составляющей в сумме ячеек прямоугольник +// void CTable::CalculateColumnWidth() +// { +// m_arColumnWidths.clear(); + +// if (m_arRows.empty()) +// { +// return; +// } + +// //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают +// //if (m_arRows.size() == 1) +// { +// for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) +// { +// m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); +// } +// return; +// } + +// double dMinWidth = 0; +// double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы +// CCell* pCurrCellWithMinWidth = nullptr; + +// //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать +// //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы +// while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! +// { +// //находим минимальный width после текущей dCurrLeftBorder +// for (size_t i = 0; i < m_arRows.size(); ++i) +// { +// for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) +// { +// auto pCell = m_arRows[i]->m_arCells[j]; + +// if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) +// { +// if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) +// { +// dMinWidth = pCell->m_dRight - dCurrLeftBorder; +// pCurrCellWithMinWidth = pCell; +// } +// break; +// } +// } +// } + +// m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); + +// //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки +// for (size_t i = 0; i < m_arRows.size(); ++i) +// { +// for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) +// { +// auto pCell = m_arRows[i]->m_arCells[j]; + +// if (dCurrLeftBorder < pCell->m_dRight && +// fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && +// pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && +// fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) +// { +// ++pCell->m_uGridSpan; +// break; +// } +// } +// } + +// //сдвигаем dCurrLeftBorder +// dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; +// } +// } +//} diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h index e42703bb51f..13b05c150df 100644 --- a/DocxRenderer/src/logic/elements/Table.h +++ b/DocxRenderer/src/logic/elements/Table.h @@ -1,43 +1,43 @@ -#pragma once -#include "Cell.h" +//#pragma once +//#include "Cell.h" -namespace NSDocxRenderer -{ - class CRow : public CBaseItem - { - public: - std::vector m_arCells; +//namespace NSDocxRenderer +//{ +// class CRow : public CBaseItem +// { +// public: +// std::vector m_arCells; - public: - CRow() = default; - virtual ~CRow(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pObj) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final {} - }; +// public: +// CRow() = default; +// virtual ~CRow(); +// virtual void Clear() override final; +// virtual void AddContent(CBaseItem* pObj) override final; +// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final {} +// }; - class CTable : public COutputObject - { - public: - std::vector m_arColumnWidths; //общее количество колонок в таблице - std::vector m_arRows; +// class CTable : public COutputObject +// { +// public: +// std::vector m_arColumnWidths; //общее количество колонок в таблице +// std::vector m_arRows; - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dLineHeight {0.0}; - bool m_bIsNeedSpacing {false}; +// double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before +// double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after +// double m_dLineHeight {0.0}; +// bool m_bIsNeedSpacing {false}; - public: - CTable() = default; - virtual ~CTable(); - virtual void Clear() override final; - virtual void AddContent(CBaseItem* pItem) override final; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; +// public: +// CTable() = default; +// virtual ~CTable(); +// virtual void Clear() override final; +// virtual void AddContent(CBaseItem* pItem) override final; +// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - double CalculateBeforeSpacing(double dPreviousStringBaseline) - { - return m_dTop - dPreviousStringBaseline; - } - void CalculateColumnWidth(); - }; -} +// double CalculateBeforeSpacing(double dPreviousStringBaseline) +// { +// return m_dTop - dPreviousStringBaseline; +// } +// void CalculateColumnWidth(); +// }; +//} diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 71d500e440a..efa8be46232 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -5,34 +5,29 @@ namespace NSDocxRenderer { - void CTextLine::Clear() - { - m_arConts.clear(); - } CTextLine::~CTextLine() { Clear(); } - void CTextLine::AddContent(CBaseItem *pItem) + void CTextLine::Clear() { - CBaseItem::AddContent(pItem); - m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(pItem)->m_dTrueHeight); - - if (dynamic_cast(pItem)->m_pCont && m_eVertAlignType == eVertAlignType::vatUnknown) - m_eVertAlignType = dynamic_cast(pItem)->m_eVertAlignType; - - m_arConts.push_back(dynamic_cast(pItem)); + m_arConts.clear(); + } + void CTextLine::AddCont(std::shared_ptr oCont) + { + CBaseItem::RecalcWithNewItem(oCont.get()); + m_arConts.push_back(oCont); } - void CTextLine::CheckLineToNecessaryToUse() + bool CTextLine::IsCanBeDeleted() const { for (size_t i = 0; i < m_arConts.size(); ++i) - if (!m_arConts[i]->m_bIsNotNecessaryToUse) - return; + if (m_arConts[i]) + return false; - m_bIsNotNecessaryToUse = true; + return true; } void CTextLine::MergeConts() @@ -41,33 +36,55 @@ namespace NSDocxRenderer return; auto pFirst = m_arConts.front(); - for (size_t i = 1; i < m_arConts.size(); ++i) { auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { + if (!pCurrent) continue; - } double dSpaceDefaultSize = pCurrent->CalculateThinSpace(); double dSpaceWideSize = pCurrent->CalculateWideSpace(); - double dDifference = fabs(pCurrent->m_dLeft - pFirst->m_dRight); - //todo возможно стоит доработать логику - bool bIsEqual = pFirst->IsEqual(pCurrent); + bool bIsEqual = pFirst->IsEqual(pCurrent.get()); bool bIsBigDelta = dDifference > dSpaceDefaultSize; bool bIsVeryBigDelta = dDifference > dSpaceWideSize; if (bIsVeryBigDelta) { - pFirst->m_bSpaceIsNotNeeded = false; - pFirst = pCurrent; + auto wide_space = std::make_shared(pFirst->m_pManager); + + // sets all members for wide_space except highlight things + auto set_base = [&pFirst, &pCurrent, &wide_space] () { + wide_space->m_dLeft = pFirst->m_dRight; + wide_space->m_dRight = pCurrent->m_dLeft; + wide_space->m_dWidth = wide_space->m_dRight - wide_space->m_dLeft; + wide_space->m_oText = L" "; + wide_space->m_pFontStyle = pFirst->m_pFontStyle; + wide_space->m_pShape = nullptr; + wide_space->m_pCont = nullptr; + wide_space->m_iNumDuplicates = 0; + wide_space->CalcSelected(); + }; + + if(bIsEqual) + { + // assign all + *wide_space = *pFirst; + + // then set all for wide space + set_base(); + } + else + set_base(); + + m_arConts.insert(m_arConts.begin() + i, wide_space); + i++; + while(!m_arConts[i]) i++; + pFirst = m_arConts[i]; } - else if (bIsEqual) + else if(bIsEqual) { if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < dSpaceDefaultSize) { @@ -87,9 +104,7 @@ namespace NSDocxRenderer pFirst->m_pCont = pCurrent->m_pCont; pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; } - - pFirst->m_bSpaceIsNotNeeded = true; - pCurrent->m_bIsNotNecessaryToUse = true; + pCurrent = nullptr; } else { @@ -111,12 +126,6 @@ namespace NSDocxRenderer pCurrent->m_dWidth += (pCurrent->m_dLeft - pFirst->m_dRight); } } - - pFirst->m_bSpaceIsNotNeeded = true; - } - else - { - pFirst->m_bSpaceIsNotNeeded = false; } pFirst = pCurrent; } @@ -131,13 +140,13 @@ namespace NSDocxRenderer m_dHeight = 0.0; m_dBaselinePos = 0.0; m_dRight = 0.0; - m_dTrueHeight = 0.0; + m_dHeight = 0.0; - for(auto&& cont : m_arConts) - if(!cont->m_bIsNotNecessaryToUse) + for(const auto& cont : m_arConts) + if(cont) { - m_dTrueHeight = std::max(m_dTrueHeight, dynamic_cast(cont)->m_dTrueHeight); - CBaseItem::AddContent(cont); + m_dHeight = std::max(m_dHeight, dynamic_cast(cont.get())->m_dHeight); + CBaseItem::RecalcWithNewItem(cont.get()); } } @@ -160,60 +169,7 @@ namespace NSDocxRenderer void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) const { - if (m_bIsNotNecessaryToUse) - { - return; - } - - size_t nCountConts = m_arConts.size(); - - if (0 == nCountConts) - return; - - auto pPrev = m_arConts[0]; - double dDelta = 0; - - for (size_t i = 1; i < nCountConts; ++i) - { - auto pCurrent = m_arConts[i]; - - if (pCurrent->m_bIsNotNecessaryToUse) - { - continue; - } - - dDelta = pCurrent->m_dLeft - pPrev->m_dRight; - pPrev->CalcSelectedWidth(); - pPrev->ToXml(oWriter); - - if (!(dDelta < pPrev->CalculateWideSpace() || pPrev->m_bSpaceIsNotNeeded)) - pPrev->AddWideSpaceToXml(dDelta, oWriter, pPrev->IsEqual(pCurrent)); - - pPrev = pCurrent; - } - - pPrev->CalcSelectedWidth(); - pPrev->ToXml(oWriter); - - } - eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CBaseItem* pItem) const noexcept - { - const CContText* pLine = nullptr; - if((pLine = dynamic_cast(pItem)) == nullptr) - return CBaseItem::GetVerticalCrossingType(pItem); - - auto m_dTop_copy = m_dTop; - auto m_dTop_copy_src = pItem->m_dTop; - - // call CBaseItem::GetVerticalCrossingType(oSrc) and not create copy, so const_cast was used - const_cast(pLine)->m_dTop = m_dBaselinePos - m_dTrueHeight; - const_cast(pLine)->m_dTop = pLine->m_dBaselinePos - pLine->m_dTrueHeight; - - auto vert_cross = CBaseItem::GetVerticalCrossingType(pLine); - - const_cast(pLine)->m_dTop = m_dTop_copy; - const_cast(pLine)->m_dTop = m_dTop_copy_src; - - return vert_cross; + for (const auto& cont : m_arConts) + cont->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index dd1a0082ad8..63ad38ff692 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -17,26 +17,28 @@ namespace NSDocxRenderer atatByWidth }; - std::vector m_arConts; - AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - CTextLine* m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - CShape* m_pDominantShape {nullptr}; + std::vector> m_arConts; + + AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + + std::shared_ptr m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + std::shared_ptr m_pDominantShape {nullptr}; + UINT m_iNumDuplicates {0}; - double m_dTrueHeight{0}; public: CTextLine() = default; virtual ~CTextLine(); virtual void Clear() override final; - virtual void AddContent(CBaseItem* pItem) override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override; - void CheckLineToNecessaryToUse(); + void AddCont(std::shared_ptr pCont); + void MergeConts(); void RecalcSizes(); void SetVertAlignType(const eVertAlignType& oType); bool IsShadingPresent(const CTextLine* pLine); + bool IsCanBeDeleted() const; }; } From 8b9d5c9f51c54cb01d014be2600c9c4245b438bb Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 2 Nov 2023 18:34:45 +0300 Subject: [PATCH 173/794] Refactoring (still in porgress) --- DocxRenderer/DocxRenderer.pro | 2 - DocxRenderer/src/logic/Page.cpp | 982 ++++++++++++------ DocxRenderer/src/logic/Page.h | 14 +- DocxRenderer/src/logic/elements/BaseItem.cpp | 9 - DocxRenderer/src/logic/elements/BaseItem.h | 20 - DocxRenderer/src/logic/elements/ContText.h | 1 - DocxRenderer/src/logic/elements/Converter.cpp | 748 ------------- DocxRenderer/src/logic/elements/Converter.h | 31 - DocxRenderer/src/logic/elements/Paragraph.cpp | 33 +- DocxRenderer/src/logic/elements/Paragraph.h | 4 +- DocxRenderer/src/logic/elements/Shape.cpp | 404 ++++--- DocxRenderer/src/logic/elements/Shape.h | 19 +- DocxRenderer/src/logic/managers/FontManager.h | 30 +- DocxRenderer/src/resources/VectorGraphics.cpp | 8 +- DocxRenderer/src/resources/VectorGraphics.h | 8 +- 15 files changed, 926 insertions(+), 1387 deletions(-) delete mode 100644 DocxRenderer/src/logic/elements/Converter.cpp delete mode 100644 DocxRenderer/src/logic/elements/Converter.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 6214538089c..df9d98db082 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -28,7 +28,6 @@ HEADERS += \ src/logic/elements/BaseItem.h \ src/logic/elements/Cell.h \ src/logic/elements/ContText.h \ - src/logic/elements/Converter.h \ src/logic/elements/DropCap.h \ src/logic/elements/Image.h \ src/logic/elements/Paragraph.h \ @@ -57,7 +56,6 @@ SOURCES += \ src/logic/elements/BaseItem.cpp \ src/logic/elements/Cell.cpp \ src/logic/elements/ContText.cpp \ - src/logic/elements/Converter.cpp \ src/logic/elements/DropCap.cpp \ src/logic/elements/Image.cpp \ src/logic/elements/Paragraph.cpp \ diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 1c6efe934e1..57a46b1baa1 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1,5 +1,4 @@ #include "Page.h" -#include "elements/Converter.h" #include "../resources/Constants.h" #include "../resources/SingletonTemplate.h" #include "../resources/utils.h" @@ -340,10 +339,10 @@ namespace NSDocxRenderer auto oParams = m_pFontManager->GetFontSelectParams(); m_pFontSelector->SelectFont(oParams, oMetrics, oText); - //_h = m_pFontManager->GetFontHeight(); + _h = m_pFontManager->GetFontHeight(); pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dTop = pCont->m_dBaselinePos - _h; // - oMetrics.dBaselineOffset; + pCont->m_dTop = pCont->m_dBaselinePos - _h - oMetrics.dBaselineOffset; pCont->m_dHeight = pCont->m_dBaselinePos - pCont->m_dTop; pCont->m_dLeft = dTextX; @@ -375,14 +374,14 @@ namespace NSDocxRenderer { auto pLine = std::make_shared(); m_pCurrentLine = pLine.get(); - m_pCurrentLine->RecalcWithNewItem(pCont.get()); + m_pCurrentLine->AddCont(pCont); m_arTextLines.push_back(pLine); return; } if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) { - m_pCurrentLine->RecalcWithNewItem(pCont.get()); + m_pCurrentLine->AddCont(pCont); return; } @@ -391,14 +390,14 @@ namespace NSDocxRenderer if (fabs(m_arTextLines[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) { m_pCurrentLine = m_arTextLines[i].get(); - m_pCurrentLine->RecalcWithNewItem(pCont); + m_pCurrentLine->AddCont(pCont); return; } } auto pLine = std::make_shared(); m_pCurrentLine = pLine.get(); - m_pCurrentLine->RecalcWithNewItem(pCont); + m_pCurrentLine->AddCont(pCont); m_arTextLines.push_back(pLine); } @@ -414,11 +413,10 @@ namespace NSDocxRenderer AnalyzeTextLines(); // merge conts in text lines + BuildLines(); // build paragraphs from m_arTextLines - - // merge conts in paragraphes - // MergeContsInParagraphes + BuildParagraphes(); // merge shapes MergeShapes(); @@ -431,7 +429,8 @@ namespace NSDocxRenderer void CPage::BuildTextLines() { - std::sort(m_arConts.begin(), m_arConts.end(), [] (const auto& a, const auto& b) { + using cont_ptr = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) return a->m_dLeft < b->m_dLeft; return a->m_dBaselinePos < b->m_dBaselinePos; @@ -843,101 +842,97 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arShapes.size(); ++i) { - auto pCurrShape = m_arShapes[i]; - - if (pCurrShape->m_bIsNotNecessaryToUse || - pCurrShape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || //рассматриваем только тонкие объекты - (pCurrShape->m_eGraphicsType != eGraphicsType::gtRectangle && - pCurrShape->m_eGraphicsType != eGraphicsType::gtCurve)) + auto& curr_shape = m_arShapes[i]; + if (!curr_shape || curr_shape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || // рассматриваем только тонкие объекты + (curr_shape->m_eGraphicsType != eGraphicsType::gtRectangle && + curr_shape->m_eGraphicsType != eGraphicsType::gtCurve)) { continue; } - //Нужно собрать всю графику, которая находится на одной линии - std::vector arCurrShapes; - arCurrShapes.push_back(m_arShapes[i]); + std::vector> curr_shapes; + curr_shapes.push_back(curr_shape); for (size_t j = i+1; j < m_arShapes.size(); ++j) { - auto pNextShape = m_arShapes[j]; - if (pNextShape->m_bIsNotNecessaryToUse || pCurrShape->AreObjectsNoCrossingByVertically(pNextShape)) //note значительно ускоряет работу - { + auto& next_shape = m_arShapes[j]; + if (!next_shape || curr_shape->AreObjectsNoCrossingByVertically(next_shape.get())) // значительно ускоряет работу continue; - } - bool bIf1 = pCurrShape->IsCorrelated(pNextShape); - //note довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры - bool bIf2 = pCurrShape->m_oBrush.IsEqual(&pNextShape->m_oBrush); - bool bIf3 = pCurrShape->m_oPen.IsEqual(&pNextShape->m_oPen); - //линия должна быть одного размера по высоте - bool bIf4 = fabs(pCurrShape->m_dHeight - pNextShape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; - //все должно быть на одной линии - bool bIf5 = fabs(pCurrShape->m_dTop - pNextShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; + + bool bIf1 = curr_shape->IsCorrelated(next_shape); + + // довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры + bool bIf2 = curr_shape->m_oBrush.IsEqual(&next_shape->m_oBrush); + bool bIf3 = curr_shape->m_oPen.IsEqual(&next_shape->m_oPen); + + // линия должна быть одного размера по высоте + bool bIf4 = fabs(curr_shape->m_dHeight - next_shape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; + + // все должно быть на одной линии + bool bIf5 = fabs(curr_shape->m_dTop - next_shape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) //все должно быть на одной линии - { - arCurrShapes.push_back(pNextShape); - } + curr_shapes.push_back(next_shape); } - if (arCurrShapes.size() > 1) + if (curr_shapes.size() > 1) { - //Отсортируем собранный массив по x - CBaseItem::SortByLeft(arCurrShapes); - pCurrShape = arCurrShapes[0]; + using shape_ptr = std::shared_ptr; + std::sort(curr_shapes.begin(), curr_shapes.end(), [] (const shape_ptr& a, const shape_ptr& b) { + return a->m_dLeft < b->m_dLeft; + }); - //сравнение - for (size_t k = 1; k < arCurrShapes.size(); ++k) - { - auto pNextShape = arCurrShapes[k]; + curr_shape = curr_shapes[0]; - //note логика работатет только если arCurrShapes отсортирован по m_dLeft - pCurrShape->DetermineLineType(pNextShape, k == arCurrShapes.size() - 1); + for (size_t k = 1; k < curr_shapes.size(); ++k) + { + auto& next_shape = curr_shapes[k]; + CShape::CheckLineType(curr_shape, next_shape, k == curr_shapes.size() - 1); - if (pCurrShape->m_bIsNotNecessaryToUse) + if(!curr_shape) { - pCurrShape = pNextShape; + curr_shape = next_shape; k++; } } } - else if (arCurrShapes.size() == 1) - { - arCurrShapes[0]->DetermineLineType(); - } + else if (curr_shapes.size() == 1) + CShape::CheckLineType(curr_shapes[0]); - arCurrShapes.clear(); + curr_shapes.clear(); } } void CPage::AnalyzeTextLines() { - //вся логика основана на отсортированных списках объектов - //todo для увеличения производительности можно попробовать использовать другие контейнеры + // вся логика основана на отсортированных списках объектов - CBaseItem::SortByBaseline(m_arTextLines); -// for(auto&& line: m_arTextLines) -// CBaseItem::SortByLeft(line->m_arConts); + using line_ptr = std::shared_ptr; + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr& a, const line_ptr& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + // analyze drop caps (creates shapes) AnalyzeDropCaps(); + + // assign highlights to conts & delete shapes which is uses in highlights DetermineStrikeoutsUnderlinesHighlights(); + + // diacritical symbols AddDiacriticalSymbols(); - MergeLinesByVertAlignType(); - DeleteTextClipPage(); - //DetermineTextColumns(); + // super/subscript + MergeLinesByVertAlignType(); - SingletonInstance().BuildLines(m_arTextLines); - SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, - COutputObject::eOutputType::etParagraph, - m_arTextLines, m_arTables, m_arOutputObjects, - m_pParagraphStyleManager); + // delete lines out of page + DeleteTextClipPage(); } void CPage::AnalyzeDropCaps() { double avg_font_size = m_pParagraphStyleManager->GetAvgFontSize(); - std::vector, std::shared_ptr>> possible_caps; + std::vector&, std::shared_ptr&>> possible_caps; std::vector> drop_caps; for(size_t i = 0; i < m_arTextLines.size(); i++) @@ -1108,42 +1103,37 @@ namespace NSDocxRenderer void CPage::DetermineStrikeoutsUnderlinesHighlights() { - //определение различных эффектов на основании взаимного расположения символов и шейпов for (size_t i = 0; i < m_arShapes.size(); ++i) { - auto pShape = m_arShapes[i]; - - if (pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics || pShape->m_bIsNotNecessaryToUse) + auto& pShape = m_arShapes[i]; + if (!pShape || pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics) continue; for (size_t j = 0; j < m_arTextLines.size(); ++j) { - auto pCurrLine = m_arTextLines[j]; + auto& pCurrLine = m_arTextLines[j]; - if (pCurrLine->m_bIsNotNecessaryToUse || - (pCurrLine->AreObjectsNoCrossingByVertically(pShape) && - (pCurrLine->m_dTop > pShape->m_dBaselinePos || - pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) + if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(pShape.get()) && + (pCurrLine->m_dTop > pShape->m_dBaselinePos || + pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) { continue; } for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) { - auto pCurrCont = pCurrLine->m_arConts[k]; - - if (pCurrCont->m_bIsNotNecessaryToUse) - { + auto& pCurrCont = pCurrLine->m_arConts[k]; + if (!pCurrCont) continue; - } - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape); + + eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape.get()); + eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape.get()); bool bIsComplicatedFigure = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; - bool bIsLineCrossingText = IsLineCrossingText(pShape, pCurrCont, eHType); - bool bIsLineBelowText = IsLineBelowText(pShape, pCurrCont, eHType); - bool bIsItHighlightingBackground = IsItHighlightingBackground(pShape, pCurrCont, eHType); + bool bIsLineCrossingText = IsLineCrossingText(pShape.get(), pCurrCont.get(), eHType); + bool bIsLineBelowText = IsLineBelowText(pShape.get(), pCurrCont.get(), eHType); + bool bIsItHighlightingBackground = IsItHighlightingBackground(pShape.get(), pCurrCont.get(), eHType); if(bIsLineCrossingText) { @@ -1169,7 +1159,7 @@ namespace NSDocxRenderer // проверили - удаляем if (bIsComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) - pShape->m_bIsNotNecessaryToUse = true; + pShape = nullptr; if (!bIsComplicatedFigure) { @@ -1196,7 +1186,7 @@ namespace NSDocxRenderer pCurrCont->m_bIsOutlinePresent = true; } - pShape->m_bIsNotNecessaryToUse = true; + pShape = nullptr; } } } @@ -1319,23 +1309,21 @@ namespace NSDocxRenderer if ((bIf1 && bIf6) || (bIf2 && bIf7) || (bIf4 && bIf8) || (bIf5 && bIf7)) { - pCurrCont->m_oText += pDiacriticalCont->m_oText; + cont->m_oText += d_sym->m_oText; } else if (bIf3 && bIf7) { - NSStringUtils::CStringUTF32 oText(pDiacriticalCont->m_oText); - oText += pCurrCont->m_oText; - pCurrCont->m_oText = oText; + NSStringUtils::CStringUTF32 oText(d_sym->m_oText); + oText += cont->m_oText; + cont->m_oText = oText; } - pDiacriticalCont->m_bIsNotNecessaryToUse = true; + d_sym = nullptr; isBreak = true; break; } } if (isBreak) - { break; - } } } } @@ -1403,274 +1391,672 @@ namespace NSDocxRenderer } } -// void CPage::DetermineTextColumns() -// { -// std::vector keys; -// std::vector arConts; -// CTable* pTable = nullptr; - -// //Сначала определяем, подходят ли несколько текущих строк для распределения в таблицу -// //Выбирается первая строка и относительно нее проверяются все последующие строки - -// //сравнивается взаимное расположение символов. Если у них совпадает левая граница и таких совпадений больше 1, -// //то добавляем uFirstContIndex в keys. -// //Todo улучшить локигу определения keys -// for (size_t uFirstLineIndex = 0; uFirstLineIndex < m_arTextLines.size(); ++uFirstLineIndex) -// { -// auto pFirstLine = m_arTextLines[uFirstLineIndex]; + void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) + { + bool bIsTextShapePresent = false; -// if (pFirstLine->m_bIsNotNecessaryToUse || uFirstLineIndex == m_arTextLines.size() - 1) -// { -// continue; -// } + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + if (m_arOutputObjects[i]->m_eType == COutputObject::eOutputType::etShape) + { + bIsTextShapePresent = true; + break; + } + } -// CTextLine* pFlagLine = nullptr; + bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); -// //первоначальное определение индексов pFirstLine, где могут присутствовать колонки -// for (size_t uFirstContIndex = 0; uFirstContIndex < pFirstLine->m_arConts.size(); ++uFirstContIndex) -// { -// auto pFirtsCont = pFirstLine->m_arConts[uFirstContIndex]; + if (bIsNeedWP) + { + oWriter.WriteString(L""); + //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст + oWriter.WriteString(L""); + } -// if (pFirtsCont->m_bIsNotNecessaryToUse) -// { -// continue; -// } + for (size_t i = 0; i < m_arImages.size(); ++i) + { + m_arImages[i]->ToXml(oWriter); + } -// for (size_t uCurrLineIndex = uFirstLineIndex + 1 ; uCurrLineIndex < m_arTextLines.size(); ++uCurrLineIndex) -// { -// auto pCurrLine = m_arTextLines[uCurrLineIndex]; + for (size_t i = 0; i < m_arShapes.size(); ++i) + { + m_arShapes[i]->ToXml(oWriter); + } -// if (pCurrLine->m_bIsNotNecessaryToUse) -// { -// continue; -// } + if (bIsTextShapePresent) + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + CShape* pSahpe = nullptr; + if((pSahpe = dynamic_cast(pObj.get())) != nullptr) + pSahpe->ToXml(oWriter); + } + } -// auto pPrevLine = m_arTextLines[uCurrLineIndex-1]; + if (bIsNeedWP) + { + oWriter.WriteString(L""); + } -// if (pPrevLine->m_dBaselinePos + pPrevLine->m_dHeight < pCurrLine->m_dTop) -// { -// //Нашли линию, до которой будет таблица/ряд -// pFlagLine = pCurrLine; -// break; -// } + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + CParagraph* pParagraph = nullptr; + if((pParagraph = dynamic_cast(pObj.get())) != nullptr) + pParagraph->ToXml(oWriter); -// size_t numConts = arConts.size(); +// CTable* pTable = nullptr; +// if((pTable = dynamic_cast(pObj)) != nullptr) +// pTable->ToXml(oWriter); + } + } -// for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) -// { -// auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + void CPage::BuildLines() + { + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + auto& pCurrLine = m_arTextLines[i]; + if (!pCurrLine) + continue; -// if (pCurrCont->m_bIsNotNecessaryToUse) -// { -// continue; -// } + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto& pCurrCont = pCurrLine->m_arConts[j]; + if (!pCurrCont) + continue; -// eHorizontalCrossingType eHType = pFirtsCont->GetHorizontalCrossingType(pCurrCont); + if (pCurrCont->m_iNumDuplicates > 0) + pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); + } + pCurrLine->MergeConts(); + } + DetermineDominantGraphics(); + } -// if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch || -// eHType == eHorizontalCrossingType::hctLeftBorderMatch) -// { -// //Добавили Cont-ориентир -// arConts.push_back(pCurrCont); -// break; -// } -// } + void CPage::DetermineDominantGraphics() + { + std::shared_ptr pDominantShape = nullptr; -// if (numConts == arConts.size()) -// { -// //не было добавления Cont, значит дальше можно не проверять -// break; -// } -// } + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + auto pLine = m_arTextLines[i]; + if (!pLine) + continue; -// if (arConts.size() > 2 && uFirstContIndex < pFirstLine->m_arConts.size() - 1 ) -// { -// keys.push_back(uFirstContIndex); -// arConts.clear(); -// } -// } + for (size_t j = 0; j < pLine->m_arConts.size(); ++j) + { + auto pCont = pLine->m_arConts[j]; + if (!pCont) + continue; -// size_t uLastLineIndexInCell = 0; + if (pCont->m_pShape && pCont->m_pShape != pDominantShape) + { + if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && + pCont->m_pShape->m_dRight > pCont->m_dRight) + { + if (!pDominantShape || + (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && + pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) + { + pDominantShape = pCont->m_pShape; + } + } + } + } -// //Если добавленных индексов достаточно, т.е. это похоже на 2 и более колонок, то -// //начинаем распределять символы из всех строк до pFlagLine по высоте и -// //левее символа с индексом из keys[i+1] по ширине. Все отобранные символы удаляем из линий (m_bIsNotNecessaryToUse) -// //Повторяем это действие, пока не пробежимся по всем keys -// if (keys.size() > 1) -// { -// auto pRow = new CRow(); + pLine->m_pDominantShape = pDominantShape; + pDominantShape = nullptr; + } + } + void CPage::BuildParagraphes() + { + std::shared_ptr pCurrLine, pNextLine, pNextNextLine, pPrevLine; + double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; + double dBeforeSpacingWithShapes = 0; -// for (size_t i = 0; i < keys.size(); ++i) -// { -// auto pCell = new CCell(); + //note Все параграфы были сдвинуты на данное значение от верхнего края страницы + double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; + eVerticalCrossingType eCrossingType; -// for (size_t uLineIndex = uFirstLineIndex; uLineIndex < m_arTextLines.size(); ++uLineIndex) -// { -// auto pCurrLine = m_arTextLines[uLineIndex]; + bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; + bool bIsNeedParagraphToShape = m_eTextAssociationType == TextAssociationType::tatParagraphToShape; -// if (pCurrLine->m_bIsNotNecessaryToUse) -// { -// continue; -// } + size_t nIndexForCheking = c_nAntiZero; -// if (pFlagLine == pCurrLine) -// { -// uLastLineIndexInCell = std::max(uLineIndex-1, uLastLineIndexInCell); -// break; -// } + double avg_height = 0; + size_t n = 0; -// CTextLine* pCellLine = nullptr; -// CContText* pFlagCont = nullptr; -// CContText* pFirstCont = m_arTextLines[uFirstLineIndex]->m_arConts[keys[i]]; + for (size_t nIndex = 0; nIndex < m_arTextLines.size(); ++nIndex) + { + pCurrLine = m_arTextLines[nIndex]; + avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); -// if (i < keys.size() - 1) -// { -// pFlagCont = m_arTextLines[uFirstLineIndex]->m_arConts[keys[i+1]]; -// } + if (!pCurrLine) + continue; -// for (size_t uCurrContIndex = 0; uCurrContIndex < pCurrLine->m_arConts.size(); ++uCurrContIndex) -// { -// auto pCurrCont = pCurrLine->m_arConts[uCurrContIndex]; + if (m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + CreateSingleLineShape(pCurrLine); + continue; + } -// if (pCurrCont->m_bIsNotNecessaryToUse) -// { -// continue; -// } + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight - dPreviousStringBaseline; + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; -// eHorizontalCrossingType eHTypeFirst = pFirstCont->GetHorizontalCrossingType(pCurrCont); + //Если у текущей линии есть дубликаты, то создаем из них шейпы + if (pCurrLine->m_iNumDuplicates > 0) + { + dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; -// if (pFlagCont) -// { -// eHorizontalCrossingType eHTypeLast = pFlagCont->GetHorizontalCrossingType(pCurrCont); -// if (eHTypeLast == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext && -// eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) -// { -// if (!pCellLine) -// { -// pCellLine = new CTextLine(); -// } -// pCellLine->RecalcWithNewItem(new CContText(*pCurrCont)); -// pCurrCont->m_bIsNotNecessaryToUse = true; -// } -// else -// { -// break; -// } -// } -// else -// { -// if (eHTypeFirst != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext) -// { -// if (!pCellLine) -// { -// pCellLine = new CTextLine(); -// } -// pCellLine->RecalcWithNewItem(new CContText(*pCurrCont)); -// pCurrCont->m_bIsNotNecessaryToUse = true; -// } -// } -// } + auto iNumDuplicates = pCurrLine->m_iNumDuplicates; + CreateSingleLineShape(pCurrLine); + while (iNumDuplicates > 0) + { + CreateSingleLineShape(pCurrLine); + iNumDuplicates--; + } + continue; + } -// if (pCellLine) -// { -// pCell->RecalcWithNewItem(pCellLine); -// } + if (m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + CreateSingleLineParagraph(pCurrLine, m_dWidth, dCurrBeforeSpacing); + continue; + } -// if (i >= keys.size() - 1) -// { -// pCurrLine->CheckLineToNecessaryToUse(); -// } -// } + pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + if (bIsNeedParagraphToShape) + { + pPrevLine = GetPrevTextLine(nIndex); + } -//// SingletonInstance().BuildLines(pCell->m_arTextLines); -//// SingletonInstance().BuildParagraphes(m_dWidth, m_eTextAssociationType, COutputObject::eOutputType::etCell, -//// pCell->m_arTextLines, pCell->m_arOutputObjects, -//// m_pParagraphStyleManager); + //Если две линии пересекаются, то создаем из них шейпы + if (pNextLine) + { + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); + bool bIsPassed = false; + double dCurrentAdditive = 0.0; -// pRow->RecalcWithNewItem(pCell); -// } + switch (eCrossingType) + { + case eVerticalCrossingType::vctCurrentInsideNext: + case eVerticalCrossingType::vctCurrentBelowNext: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; + dPreviousStringBaseline = pNextLine->m_dBaselinePos; + bIsPassed = true; + break; + case eVerticalCrossingType::vctCurrentOutsideNext: + case eVerticalCrossingType::vctCurrentAboveNext: + case eVerticalCrossingType::vctDublicate: + dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; + bIsPassed = true; + break; + default: + break; + } -// if (pFlagLine) -// { -// uFirstLineIndex = uLastLineIndexInCell; -// } + if (bIsPassed) + { + CreateSingleLineShape(pCurrLine); + CreateSingleLineShape(pNextLine); -// //todo пока добавляется в одну таблицу - добавить логику разделения на разные таблицы -// if (!pTable) -// { -// pTable = new CTable(); -// m_arTables.push_back(pTable); -// } + dBeforeSpacingWithShapes += dCurrentAdditive; -// pTable->RecalcWithNewItem(pRow); -// pTable->CalculateColumnWidth(); -// } + nIndex++; + continue; + } + } -// keys.clear(); -// arConts.clear(); -// } -// } + dCurrBeforeSpacing += dBeforeSpacingWithShapes; + dBeforeSpacingWithShapes = 0; - void CPage::ToXml(NSStringUtils::CStringBuilder& oWriter) - { - bool bIsTextShapePresent = false; + bool bIsSingleLineParagraph = false; - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - if (m_arOutputObjects[i]->m_eType == COutputObject::eOutputType::etShape) + //Логика определения параметров для DetermineTextAlignmentType + if (pNextLine) { - bIsTextShapePresent = true; - break; + dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dHeight - dPreviousStringBaseline; + //dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); + + //Высота строк должна быть примерно одинаковой + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; + //расстрояние между строк тоже одинаково + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + //или + bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; + //нет отступа + bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + //есть отступ + bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; + //совпадают правые границы + bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + size_t nNextIndex = nIndex+1; + pNextNextLine = GetNextTextLine(nNextIndex); + + bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && + (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); + + if (pNextNextLine) + { + //double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); + double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dHeight - dPreviousStringBaseline; + if (bIf1 && (bIf2 || bIf3)) + { + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) + pNextNextLine = nullptr; + } + else + { + if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + pNextNextLine = nullptr; + else + bIsSingleLineParagraph = true; + } + else + pNextNextLine = nullptr; + } + } + } + } + + bool bIsUseNextNextLine = true; + CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( + pCurrLine, pNextLine, pNextNextLine, m_dWidth, bIsUseNextNextLine, bIsSingleLineParagraph); + + auto pParagraph = std::make_shared(); + + pParagraph->m_dLineHeight = avg_height; + avg_height = 0; + n = 0; + + pParagraph->m_eTextAlignmentType = eTextAlignmentType; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) + { + pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) + { + pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; + pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; + } + } + else + { + pParagraph->m_dLeft = pCurrLine->m_dLeft; + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; + pParagraph->m_dRight = pCurrLine->m_dRight; + pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pCurrLine->m_dWidth; + + pParagraph->m_bIsNeedFirstLineIndent = false; + pParagraph->m_dFirstLine = 0; + } + + pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; + pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; + pParagraph->m_dHeight = pCurrLine->m_dHeight; + + //размер строк во всем параграфе + // pParagraph->m_dLineHeight = avg_height; //pCurrLine->m_dHeight; + pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + + pParagraph->m_arLines.push_back(pCurrLine); + pParagraph->m_nNumLines++; + + if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + if (pCurrLine->IsShadingPresent(pNextLine.get())) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + double dCorrectionBeforeSpacing = dCurrBeforeSpacing; + + if (bIsUseNextNextLine) + { + if (pNextLine) + { + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + + //проверим, подходят ли следующие строчки для текущего pParagraph + while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) + { + pParagraph->m_arLines.push_back(pNextLine); + pParagraph->m_nNumLines++; + + pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); + pParagraph->m_dLeftBorder = pParagraph->m_dLeft; + pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); + pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; + pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; + + if (!pCurrLine->IsShadingPresent(pNextLine.get())) + { + pParagraph->m_bIsShadingPresent = false; + pParagraph->m_lColorOfShadingFill = c_iWhiteColor; + } + + //сдвигаем рабочую точку + nIndex++; + pCurrLine = pNextLine; + pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + + dPrevBeforeSpacing = dCurrBeforeSpacing; + dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); + dPreviousStringBaseline = pCurrLine->m_dBaselinePos; + dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing) / 2; //наверное лучше так... текст может быть уже, чем в оригинале + + if (pNextLine) + { + dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; + eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); + + bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой + bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково + bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || + (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); + bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); + } + } + } + + if (eCrossingType != eVerticalCrossingType::vctUnknown && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && + eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) + { + CreateSingleLineShape(pNextLine); + nIndex++; + } + + //коррекция + pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; + pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); + + pParagraph->RemoveHighlightColor(); + pParagraph->MergeLines(); + } + else + { + if (pCurrLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + } + + if (bIsNeedParagraphToShape) + { + bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; + CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); + } + else + { + pParagraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*pParagraph); + m_arOutputObjects.push_back(pParagraph); + } + + if (nIndexForCheking != c_nAntiZero) + { + nIndex = nIndexForCheking - 1; + nIndexForCheking = c_nAntiZero; } } - bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); + if (bIsNeedParagraphToShape) + { + CorrectionObjectesInShapes(m_dWidth); + } - if (bIsNeedWP) + using output_ptr = std::shared_ptr; + std::sort(m_arOutputObjects.begin(), m_arOutputObjects.end(), [] (const output_ptr& a, const output_ptr& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + } + + void CPage::CreateSingleLineParagraph(std::shared_ptr pLine, double dPageWidth, double pBeforeSpacing) + { + auto pParagraph = std::make_shared(); + pParagraph->m_arLines.push_back(pLine); + + pParagraph->m_dLeft = pLine->m_dLeft; + pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; + pParagraph->m_dFirstLine = 0; + pParagraph->m_dRight = pLine->m_dRight; + pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; + pParagraph->m_dWidth = pLine->m_dWidth; + pParagraph->m_dHeight = pLine->m_dHeight; + if (pBeforeSpacing < 0) { - oWriter.WriteString(L""); - //note при удалении строки откуда-то добавляется в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L""); + pParagraph->m_dHeight += pBeforeSpacing; } - for (size_t i = 0; i < m_arImages.size(); ++i) + pParagraph->m_dSpaceBefore = std::max(pBeforeSpacing, 0.0); + + if (pLine->m_pDominantShape) { - m_arImages[i]->ToXml(oWriter); + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); } - for (size_t i = 0; i < m_arShapes.size(); ++i) + m_arOutputObjects.push_back(std::dynamic_pointer_cast(pParagraph)); + } + + void CPage::CreateSingleLineShape(std::shared_ptr pLine) + { + auto pParagraph = std::make_shared(); + + pParagraph->m_arLines.push_back(pLine); + pParagraph->m_dRightBorder = 0; + + if (pLine->m_pDominantShape) { - m_arShapes[i]->ToXml(oWriter); + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); } - if (bIsTextShapePresent) + auto pShape = std::make_shared(); + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_dLeft = pLine->m_dLeft; + pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; + pShape->m_dWidth = pLine->m_dWidth; + pShape->m_dHeight = pLine->m_dHeight; + pShape->m_bIsBehindDoc = false; + + m_arOutputObjects.push_back(pShape); + } + + void CPage::CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText) + { + if (!pParagraph) + return; + + bool bIsShapesPresent = false; + std::shared_ptr pBackShape = nullptr; + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + if (m_arOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) + continue; + + bIsShapesPresent = true; + pBackShape = std::dynamic_pointer_cast(m_arOutputObjects[i]); + } + + std::shared_ptr pShape; + if (bIsSameTypeText && bIsShapesPresent) + { + pShape = pBackShape; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + } + else + { + pShape = std::make_shared(); + pParagraph->m_dSpaceBefore = 0; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines; + } + + pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; + pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; + pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; + pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; + pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + + pParagraph->m_dLeftBorder = 0; + pParagraph->m_dRightBorder = 0; + + pShape->m_arOutputObjects.push_back(pParagraph); + pShape->m_eType = CShape::eShapeType::stTextBox; + pShape->m_bIsBehindDoc = false; + + if (!bIsSameTypeText) + { + m_arOutputObjects.push_back(pShape); + } + } + + void CPage::CorrectionObjectesInShapes(double dPageWidth) + { + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + if (m_arOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) { - auto pObj = m_arOutputObjects[i]; - CShape* pSahpe = nullptr; - if((pSahpe = dynamic_cast(pObj.get())) != nullptr) - pSahpe->ToXml(oWriter); + continue; + } + + auto pShape = std::dynamic_pointer_cast(m_arOutputObjects[i]); + + if (!pShape || + pShape->m_eType != CShape::eShapeType::stTextBox || + pShape->m_arOutputObjects.empty()) + { + continue; + } + + for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) + { + auto pObj = pShape->m_arOutputObjects[j]; + + switch(pObj->m_eType) + { + case COutputObject::eOutputType::etParagraph: + { + auto pParagraph = std::dynamic_pointer_cast(m_arOutputObjects[i]); + + if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) + { + pParagraph->m_bIsNeedFirstLineIndent = true; + pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; + pParagraph->m_dLeft = 0; + } + + pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; + pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; + } + break; + default: + break; + } + } } + } - if (bIsNeedWP) + std::shared_ptr CPage::GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking) + { + std::shared_ptr pLine; + for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLines.size(); ++nIndex) { - oWriter.WriteString(L""); + pLine = m_arTextLines[nIndex]; + bool bIf1 = pLine == nullptr; + bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; + + if (bIf1 || bIf2) + { + if (bIf2) + { + if (*pIndexForCheking == c_nAntiZero) + *pIndexForCheking = nIndex; + } + + nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки + pLine = nullptr; + continue; + } + else + break; } + return pLine; + } - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + std::shared_ptr CPage::GetPrevTextLine(size_t nCurrentIndex) + { + std::shared_ptr pLine = nullptr; + + if (nCurrentIndex) { - auto pObj = m_arOutputObjects[i]; - CParagraph* pParagraph = nullptr; - if((pParagraph = dynamic_cast(pObj.get())) != nullptr) - pParagraph->ToXml(oWriter); + for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) + { + pLine = m_arTextLines[nIndex]; -// CTable* pTable = nullptr; -// if((pTable = dynamic_cast(pObj)) != nullptr) -// pTable->ToXml(oWriter); + if (!pLine) + { + pLine = nullptr; + continue; + } + else + break; + } } + return pLine; } + void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) { // section diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 0ec04b3b653..1089edc88b9 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -39,7 +39,7 @@ namespace NSDocxRenderer std::vector> m_arImages; std::vector> m_arShapes; - std::vector> m_arOutputObjects; + std::vector> m_arOutputObjects; // std::vector m_arPeaks; // std::vector m_arCells; @@ -122,6 +122,18 @@ namespace NSDocxRenderer // void BuildRows(); // void SelectCurrentRow(const CCell *pCell); + void BuildLines(); + void DetermineDominantGraphics(); + + void BuildParagraphes(); + + void CreateSingleLineParagraph(std::shared_ptr pLine, double dPageWidth, double pBeforeSpacing); + void CreateSingleLineShape(std::shared_ptr pLine); + void CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText); + void CorrectionObjectesInShapes(double dPageWidth); + + std::shared_ptr GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking = nullptr); + std::shared_ptr GetPrevTextLine(size_t nCurrentIndex); void MergeShapes(); void CalcSelected(); diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index b34bf7cd2a4..a5cc55b0b15 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -137,15 +137,6 @@ namespace NSDocxRenderer eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext); } - bool CBaseItem::IsCurrentLeftOfNext(const CBaseItem* oSrc) - { - return m_dLeft < oSrc->m_dLeft; - } - bool CBaseItem::IsCurrentAboveOfNext(const CBaseItem* oSrc) - { - return m_dBaselinePos < oSrc->m_dBaselinePos; - } - void CBaseItem::RecalcWithNewItem(const CBaseItem* pItem) { m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos); diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index f4261a7f6ce..6d00dbbf530 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -63,26 +63,6 @@ namespace NSDocxRenderer bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept; CBaseItem& operator=(const CBaseItem& oSrc); - - template - static void SortByLeft(std::vector& oArray) - { - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return a->IsCurrentLeftOfNext(b); - }); - } - - template - static void SortByBaseline(std::vector& oArray) - { - std::sort(oArray.begin(), oArray.end(), [](T* a, T* b) { - return a->IsCurrentAboveOfNext(b); - }); - } - - private: - bool IsCurrentLeftOfNext(const CBaseItem* oSrc); - bool IsCurrentAboveOfNext(const CBaseItem* oSrc); }; class COutputObject : public CBaseItem diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 5eb174e48f1..a97e774a5c0 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -34,7 +34,6 @@ namespace NSDocxRenderer class CContText : public CBaseItem { public: - // utils std::shared_ptr m_pFontStyle{nullptr}; CFontManager* m_pManager {nullptr}; diff --git a/DocxRenderer/src/logic/elements/Converter.cpp b/DocxRenderer/src/logic/elements/Converter.cpp deleted file mode 100644 index 50e0313d825..00000000000 --- a/DocxRenderer/src/logic/elements/Converter.cpp +++ /dev/null @@ -1,748 +0,0 @@ -#include "Converter.h" -#include "Shape.h" -#include "src/resources/utils.h" - - -namespace NSDocxRenderer -{ - //общая функция для сборки строк в любом текстовом объекте - void CConverter::BuildLines(std::vector& rTextLines) - { - for (size_t i = 0; i < rTextLines.size(); ++i) - { - auto pCurrLine = rTextLines[i]; - if (!pCurrLine) - continue; - - for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) - { - auto pCurrCont = pCurrLine->m_arConts[j]; - if (!pCurrCont) - continue; - - if (pCurrCont->m_iNumDuplicates > 0) - pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); - } - pCurrLine->MergeConts(); - } - - DetermineDominantGraphics(rTextLines); - } - - void CConverter::DetermineDominantGraphics(std::vector& rTextLines) - { - std::shared_ptr pDominantShape = nullptr; - - for (size_t i = 0; i < rTextLines.size(); ++i) - { - auto pLine = rTextLines[i]; - if (!pLine) - continue; - - for (size_t j = 0; j < pLine->m_arConts.size(); ++j) - { - auto pCont = pLine->m_arConts[j]; - if (!pCont) - continue; - - if (pCont->m_pShape && pCont->m_pShape != pDominantShape) - { - if (pCont->m_pShape->m_dLeft < pCont->m_dLeft && - pCont->m_pShape->m_dRight > pCont->m_dRight) - { - if (!pDominantShape || - (pCont->m_pShape->m_dLeft < pDominantShape->m_dLeft && - pCont->m_pShape->m_dRight > pDominantShape->m_dRight)) - { - pDominantShape = pCont->m_pShape; - } - } - } - } - - pLine->m_pDominantShape = pDominantShape; - pDominantShape = nullptr; - } - } - -// void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, -// std::vector& rTextLines, -// std::vector& rOutputObjects, -// CParagraphStyleManager* pParagraphStyleManager) -// { -// std::vector oStubVector; //просто объект-заглушка -// BuildParagraphes(dPageWidth, eType, eBaseType, rTextLines, oStubVector, rOutputObjects, pParagraphStyleManager); -// } - - // eBaseType == etCell или etParagraph - // eType == 2 - 5 из TextAssociationType - void CConverter::BuildParagraphes(double dPageWidth, TextAssociationType eType, COutputObject::eOutputType eBaseType, - std::vector& rTextLines, - std::vector& rOutputObjects, - CParagraphStyleManager* pParagraphStyleManager) - { - CTextLine* pCurrLine, *pNextLine, *pNextNextLine, *pPrevLine; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; - double dBeforeSpacingWithShapes = 0; - - //note Все параграфы были сдвинуты на данное значение от верхнего края страницы - double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; - eVerticalCrossingType eCrossingType; - - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; - bool bIsNeedParagraphToShape = eType == TextAssociationType::tatParagraphToShape && eBaseType == COutputObject::eOutputType::etParagraph; - -// CTable* pCurrTable = nullptr; -// size_t nTableIndex = 0; - - size_t nIndexForCheking = c_nAntiZero; - -// if (!rTables.empty()) -// { -// CBaseItem::SortByBaseline(rTables); -// pCurrTable = rTables.front(); -// nTableIndex = 0; - -// //Если линий нет, то добавлем сразу -// if (rTextLines.empty()) -// { -// for (size_t i = 0; i < rTables.size(); ++i) -// { -// if (bIsNeedParagraphToShape) -// { -// CreateShapeFormTable(pCurrTable, rOutputObjects); -// } -// else -// { -// rOutputObjects.push_back(rTables[i]); -// } -// } -// } -// } - - CBaseItem::SortByBaseline(rTextLines); - - - double avg_height = 0; - size_t n = 0; - - for (size_t nIndex = 0; nIndex < rTextLines.size(); ++nIndex) - { - pCurrLine = rTextLines[nIndex]; - avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); - - if (!pCurrLine) - continue; - - if (eType == TextAssociationType::tatShapeLine) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - continue; - } - - -// while (pCurrTable) -// { -// eCrossingType = pCurrLine->GetVerticalCrossingType(pCurrTable); - -// //добавляем таблицу в общий массив, если она идет после текущей строки -// if (eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext) -// { -// if (bIsNeedParagraphToShape) -// { -// CreateShapeFormTable(pCurrTable, rOutputObjects); -// } -// else -// { -// rOutputObjects.push_back(pCurrTable); -// } -// dCurrBeforeSpacing = pCurrTable->CalculateBeforeSpacing(dPreviousStringBaseline); -// pCurrTable->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); -// if (eType != TextAssociationType::tatParagraphToShape || eBaseType != CBaseItem::ElemType::etParagraph) -// { -// pCurrTable->m_bIsNeedSpacing = true; -// } -// dPreviousStringBaseline = pCurrTable->m_dBaselinePos; -// pCurrTable = nullptr; -// //таблицы отсортированы, можно сразу взять следующую для проверки -// for (size_t i = nTableIndex + 1; i < rTables.size(); ++i) -// { -// pCurrTable = rTables[i]; -// } -// } -// else -// { -// break; -// } -// } - - dPrevBeforeSpacing = dCurrBeforeSpacing; -// if (eBaseType == CBaseItem::ElemType::etCell && nIndex == 0) -// { -// dCurrBeforeSpacing = 0; -// } - dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight - dPreviousStringBaseline; - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - - //Если у текущей линии есть дубликаты, то создаем из них шейпы - if (pCurrLine->m_iNumDuplicates > 0) - { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; - - auto iNumDuplicates = pCurrLine->m_iNumDuplicates; - CreateSingleLineShape(pCurrLine, rOutputObjects); - while (iNumDuplicates > 0) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - iNumDuplicates--; - } - continue; - } - - if (eType == TextAssociationType::tatPlainLine) - { - CreateSingleLineParagraph(pCurrLine, dPageWidth, &dCurrBeforeSpacing, rOutputObjects); - continue; - } - - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - if (bIsNeedParagraphToShape) - { - pPrevLine = GetPrevTextLine(nIndex, rTextLines); - } - - //Если две линии пересекаются, то создаем из них шейпы - if (pNextLine) - { - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - bool bIsPassed = false; - double dCurrentAdditive = 0.0; - - switch (eCrossingType) - { - case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; - dPreviousStringBaseline = pNextLine->m_dBaselinePos; - bIsPassed = true; - break; - case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: - case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; - bIsPassed = true; - break; - default: - break; - } - - if (bIsPassed) - { - CreateSingleLineShape(pCurrLine, rOutputObjects); - CreateSingleLineShape(pNextLine, rOutputObjects); - - dBeforeSpacingWithShapes += dCurrentAdditive; - - nIndex++; - continue; - } - } - - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; - - bool bIsSingleLineParagraph = false; - - //Логика определения параметров для DetermineTextAlignmentType - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dHeight - dPreviousStringBaseline; - //dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - - //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; - //расстрояние между строк тоже одинаково - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - //или - bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; - //нет отступа - bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - //есть отступ - bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; - //совпадают правые границы - bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - size_t nNextIndex = nIndex+1; - pNextNextLine = GetNextTextLine(nNextIndex, rTextLines); - - bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && - (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); - - if (pNextNextLine) - { - //double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dHeight - dPreviousStringBaseline; - if (bIf1 && (bIf2 || bIf3)) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - pNextNextLine = nullptr; - } - } - else - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - pNextNextLine = nullptr; - } - else - { - bIsSingleLineParagraph = true; - } - } - else - { - pNextNextLine = nullptr; - } - } - } - } - } - - bool bIsUseNextNextLine = true; - CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( - pCurrLine, pNextLine, pNextNextLine, dPageWidth, bIsUseNextNextLine, bIsSingleLineParagraph); - - auto pParagraph = new CParagraph(); - - pParagraph->m_dLineHeight = avg_height; - avg_height = 0; - n = 0; - - pParagraph->m_eTextAlignmentType = eTextAlignmentType; - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) - { - pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) - { - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - } - } - else - { - pParagraph->m_dLeft = pCurrLine->m_dLeft; - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = pCurrLine->m_dRight; - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pCurrLine->m_dWidth; - - pParagraph->m_bIsNeedFirstLineIndent = false; - pParagraph->m_dFirstLine = 0; - } - - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - pParagraph->m_dHeight = pCurrLine->m_dHeight; - - //размер строк во всем параграфе - // pParagraph->m_dLineHeight = avg_height; //pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); - - pParagraph->m_arLines.push_back(pCurrLine); - pParagraph->m_nNumLines++; - - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - if (pCurrLine->IsShadingPresent(pNextLine)) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - double dCorrectionBeforeSpacing = dCurrBeforeSpacing; - - if (bIsUseNextNextLine) - { - if (pNextLine) - { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; - - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; - - if (!pCurrLine->IsShadingPresent(pNextLine)) - { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; - } - - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, rTextLines, &nIndexForCheking); - - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing) / 2; //наверное лучше так... текст может быть уже, чем в оригинале - - if (pNextLine) - { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - } - } - - if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - CreateSingleLineShape(pNextLine, rOutputObjects); - nIndex++; - } - - //коррекция - pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; - pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); - - pParagraph->RemoveHighlightColor(); - pParagraph->MergeLines(); - } - else - { - if (pCurrLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - } - - if (bIsNeedParagraphToShape) - { - bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText, dPageWidth, rOutputObjects); - } - else - { - pParagraph->m_wsStyleId = pParagraphStyleManager->GetDefaultParagraphStyleId(*pParagraph); - rOutputObjects.push_back(pParagraph); - } - - if (nIndexForCheking != c_nAntiZero) - { - nIndex = nIndexForCheking - 1; - nIndexForCheking = c_nAntiZero; - } - } - - if (bIsNeedParagraphToShape) - { - CorrectionObjectesInShapes(rOutputObjects, dPageWidth); - } - - std::sort(rOutputObjects.begin(), rOutputObjects.end(), [](CBaseItem* a, CBaseItem* b) { - return a->m_dBaselinePos < b->m_dBaselinePos; - }); - } - - void CConverter::CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, - const double *pBeforeSpacing, std::vector& rOutputObjects) - { - auto pParagraph = new CParagraph(); - pParagraph->m_arLines.push_back(pLine); - - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; - pParagraph->m_dFirstLine = 0; - pParagraph->m_dRight = pLine->m_dRight; - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pLine->m_dWidth; - pParagraph->m_dHeight = pLine->m_dHeight; - if (*pBeforeSpacing < 0) - { - pParagraph->m_dHeight += *pBeforeSpacing; - } - - pParagraph->m_dSpaceBefore = std::max(*pBeforeSpacing, 0.0); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - rOutputObjects.push_back(pParagraph); - } - - void CConverter::CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects) - { - auto pParagraph = std::make_shared(); - - pParagraph->m_arLines.push_back(pLine); - pParagraph->m_dRightBorder = 0; - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - auto pShape = new CShape(); - pShape->m_arOutputObjects.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; - pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; - pShape->m_bIsBehindDoc = false; - - rOutputObjects.push_back(pShape); - } - - void CConverter::CreateShapeFormParagraphs(CParagraph* pParagraph, bool bIsSameTypeText, double dPageWidth, - std::vector& rOutputObjects) - { - if (!pParagraph) - { - return; - } - - bool bIsShapesPresent = false; - CShape* pBackShape = nullptr; - - for (size_t i = 0; i < rOutputObjects.size(); ++i) - { - if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) - { - continue; - } - bIsShapesPresent = true; - pBackShape = dynamic_cast(rOutputObjects[i]); - } - - CShape* pShape; - - if (bIsSameTypeText && bIsShapesPresent) - { - pShape = pBackShape; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; - } - else - { - pShape = new CShape(); - pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines; - } - -// pShape->m_dLeft = pParagraph->m_dLeft; -// pShape->m_dTop = pParagraph->m_dTop; -// pShape->m_dRight = pParagraph->m_dRight; -// pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; -// pShape->m_dWidth = fabs(pParagraph->m_dRight - pParagraph->m_dLeft); -// pShape->m_dHeight = pParagraph->m_dTop - pParagraph->m_dBaselinePos; - - pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; - pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; - pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; - pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; - pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); - - pParagraph->m_dLeftBorder = 0; - pParagraph->m_dRightBorder = 0; - - pShape->m_arOutputObjects.push_back(pParagraph); - pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_bIsBehindDoc = false; - - if (!bIsSameTypeText) - { - rOutputObjects.push_back(pShape); - } - } - -// void CConverter::CreateShapeFormTable(CTable* pTable, std::vector &rOutputObjects) -// { -// if (!pTable) -// { -// return; -// } - -// CShape* pShape; - -// pShape = new CShape(); -// pShape->m_dHeight = pTable->m_dHeight; -// pShape->m_dLeft = pTable->m_dLeft; -// pShape->m_dTop =pTable->m_dTop; -// pShape->m_dRight = pTable->m_dRight; -// pShape->m_dBaselinePos = pTable->m_dBaselinePos; -// pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); - -// pShape->m_arOutputObjects.push_back(pTable); -// pShape->m_eType = CShape::eShapeType::stTextBox; -// pShape->m_bIsBehindDoc = false; - -// rOutputObjects.push_back(pShape); -// } - -// void CConverter::CorrectionObjectesInShapes(std::vector &rOutputObjects, double dPageWidth) -// { -// for (size_t i = 0; i < rOutputObjects.size(); ++i) -// { -// if (rOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) -// { -// continue; -// } - -// auto pShape = dynamic_cast(rOutputObjects[i]); - -// if (pShape->m_bIsNotNecessaryToUse || -// pShape->m_eType != CShape::eShapeType::stTextBox || -// pShape->m_arOutputObjects.empty()) -// { -// continue; -// } - -// for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) -// { -// auto pObj = pShape->m_arOutputObjects[j]; - -// switch(pObj->m_eType) -// { -// case COutputObject::eOutputType::etParagraph: -// { -// auto pParagraph = dynamic_cast(pObj); - -// if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) -// { -// pParagraph->m_bIsNeedFirstLineIndent = true; -// pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; -// pParagraph->m_dLeft = 0; -// } - -// pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; -// pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; -// } -// break; -// default: -// break; -// } - -// } -// } -// } - - CTextLine* CConverter::GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking) - { - CTextLine* pLine = nullptr; - - for (size_t nIndex = nCurrentIndex + 1; nIndex < rTextLines.size(); ++nIndex) - { - pLine = rTextLines[nIndex]; - bool bIf1 = pLine->m_bIsNotNecessaryToUse; - bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; - - if (bIf1 || bIf2) - { - if (bIf2) - { - if (*pIndexForCheking == c_nAntiZero) - { - *pIndexForCheking = nIndex; - } - } - - nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки - pLine = nullptr; - continue; - } - else - { - break; - } - } - return pLine; - } - - CTextLine* CConverter::GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines) - { - CTextLine* pLine = nullptr; - - if (nCurrentIndex) - { - for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) - { - pLine = rTextLines[nIndex]; - - if (pLine->m_bIsNotNecessaryToUse) - { - pLine = nullptr; - continue; - } - else - { - break; - } - } - } - return pLine; - } -} diff --git a/DocxRenderer/src/logic/elements/Converter.h b/DocxRenderer/src/logic/elements/Converter.h deleted file mode 100644 index 0e9504323bf..00000000000 --- a/DocxRenderer/src/logic/elements/Converter.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include "Table.h" -#include "../managers/ParagraphStyleManager.h" - -namespace NSDocxRenderer -{ - class CConverter - { - public: - void BuildLines(std::vector& rTextLines); - void DetermineDominantGraphics(std::vector& rTextLines); - - void BuildParagraphes(double dPageWidth, TextAssociationType eType, - COutputObject::eOutputType eBaseType, std::vector& rTextLines, - std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); -// void BuildParagraphes(double dPageWidth, TextAssociationType eType, -// COutputObject::eOutputType eBaseType, std::vector& rTextLines, -// std::vector& rTables, std::vector& rOutputObjects, CParagraphStyleManager* pParagraphStyleManager); - - void CreateSingleLineParagraph(CTextLine *pLine, double dPageWidth, const double *pBeforeSpacing, std::vector& rOutputObjects); - void CreateSingleLineShape(CTextLine *pLine, std::vector& rOutputObjects); - void CreateShapeFormParagraphs(CParagraph *pParagraph, bool bIsSameTypeText, double dPageWidth, std::vector& rOutputObjects); -// void CreateShapeFormTable(CTable* pParagraph, std::vector& rOutputObjects); - void CorrectionObjectesInShapes(std::vector& rOutputObjects, double dPageWidth); - - private: - CTextLine* GetNextTextLine(size_t& nCurrentIndex, std::vector& rTextLines, size_t* pIndexForCheking = nullptr); - CTextLine* GetPrevTextLine(size_t nCurrentIndex, std::vector& rTextLines); - }; - -} diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 14a46f605f0..c709744e596 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -130,45 +130,22 @@ namespace NSDocxRenderer void CParagraph::MergeLines() { - auto pLine = m_arLines.front(); - - for(size_t i = 1; i < m_arLines.size(); ++i) + for(size_t i = 0; i < m_arLines.size(); ++i) { - auto pLastCont = pLine->m_arConts.back(); + auto& pLine = m_arLines[i]; + auto& pLastCont = pLine->m_arConts.back(); size_t iNumConts = pLine->m_arConts.size() - 1; while (!pLastCont) pLastCont = pLine->m_arConts[--iNumConts]; -// //Добавляем пробел в конец каждой строки + //Добавляем пробел в конец каждой строки pLastCont->m_oText += L" "; pLastCont->m_dWidth += pLine->m_arConts.back()->m_oSelectedSizes.dSpaceWidth; - -// auto pNext = m_arLines[i]; -// auto pCont = pNext->m_arConts.front(); - -// if (pLastCont->IsEqual(pCont)) -// { -// pLastCont->m_oText += pCont->m_oText; -// pLastCont->m_dWidth += pCont->m_dWidth; -// pLastCont->m_dRight = pCont->m_dRight; -// pCont->m_bIsNotNecessaryToUse = true; -// } - -// for (size_t j = 0; j < pNext->m_arConts.size(); ++j) -// { -// auto& pCont = pNext->m_arConts[j]; -// if (!pCont->m_bIsNotNecessaryToUse) -// { -// pLine->m_arConts.push_back(pCont); -// pCont = nullptr; -// } -// } -// pNext->m_bIsNotNecessaryToUse = true; } } - CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) + CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(std::shared_ptr pCurrentLine, std::shared_ptr pNextLine, std::shared_ptr pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) { // поменять логику if (!pCurrentLine || !pNextLine) diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index d47885b038d..298dfaf166f 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -32,7 +32,7 @@ namespace NSDocxRenderer double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after double m_dLineHeight {0.0}; - std::vector m_arLines; + std::vector> m_arLines; size_t m_nNumLines {0}; @@ -47,7 +47,7 @@ namespace NSDocxRenderer void RemoveHighlightColor(); void MergeLines(); - static TextAlignmentType DetermineTextAlignmentType(CTextLine* pCurrentLine, CTextLine* pNextLine, CTextLine* pNextNextLine, + static TextAlignmentType DetermineTextAlignmentType(std::shared_ptr pCurrentLine, std::shared_ptr pNextLine, std::shared_ptr pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph); }; } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index eefc93beabe..aa8b3f632e3 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -61,19 +61,19 @@ namespace NSDocxRenderer for(auto& path_command : arData) switch (path_command.type) { - case CVectorGraphics::vgtMove: + case CVectorGraphics::eVectorGraphicsType::vgtMove: nPeacks++; break; - case CVectorGraphics::vgtLine: + case CVectorGraphics::eVectorGraphicsType::vgtLine: nPeacks++; break; - case CVectorGraphics::vgtCurve: + case CVectorGraphics::eVectorGraphicsType::vgtCurve: nCurves++; break; - case CVectorGraphics::vgtClose: + case CVectorGraphics::eVectorGraphicsType::vgtClose: default: break; } @@ -159,19 +159,19 @@ namespace NSDocxRenderer { switch (path_command.type) { - case CVectorGraphics::vgtMove: + case CVectorGraphics::eVectorGraphicsType::vgtMove: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtLine: + case CVectorGraphics::eVectorGraphicsType::vgtLine: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtCurve: + case CVectorGraphics::eVectorGraphicsType::vgtCurve: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtClose: + case CVectorGraphics::eVectorGraphicsType::vgtClose: default: break; } @@ -190,19 +190,19 @@ namespace NSDocxRenderer switch (path_command.type) { - case CVectorGraphics::vgtMove: + case CVectorGraphics::eVectorGraphicsType::vgtMove: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtLine: + case CVectorGraphics::eVectorGraphicsType::vgtLine: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtCurve: + case CVectorGraphics::eVectorGraphicsType::vgtCurve: oWriter.WriteString(L""); break; - case CVectorGraphics::vgtClose: + case CVectorGraphics::eVectorGraphicsType::vgtClose: default: break; } @@ -277,366 +277,334 @@ namespace NSDocxRenderer } } - bool CShape::IsItFitLine() + bool CShape::IsItFitLine() const noexcept { return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) || (m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave); } - bool CShape::IsCorrelated(const CShape *pShape) + bool CShape::IsCorrelated(std::shared_ptr pShape) const noexcept { return m_eGraphicsType == pShape->m_eGraphicsType; } - void CShape::ChangeGeometryOfDesiredShape(CShape *pShape) + void CShape::RecalcWithNewItem(const CBaseItem* pObj) { - if (!pShape) - { + if(!pObj) return; - } - CShape* pModObject; - CShape* pDataObject; - - if (!pShape) - { - pModObject = this; - pDataObject = pShape; - } - else if (m_bIsNotNecessaryToUse) - { - pModObject = pShape; - pDataObject = this; - } - else + const CShape* shape = dynamic_cast(pObj); + if(!shape) { + CBaseItem::RecalcWithNewItem(pObj); return; } - double dModRight = pModObject->m_dLeft + pModObject->m_dWidth; - double dDataRight = pDataObject->m_dLeft + pDataObject->m_dWidth; - double dModBottom = pModObject->m_dTop + pModObject->m_dHeight; - double dDataBottom = pDataObject->m_dTop + pDataObject->m_dHeight; - - if (pModObject->m_dTop == pDataObject->m_dTop || - (pModObject->m_dTop < pDataObject->m_dTop && pModObject->m_dHeight > pDataObject->m_dHeight) || - (pModObject->m_dTop > pDataObject->m_dTop && pModObject->m_dHeight < pDataObject->m_dHeight)) - { - pModObject->m_dHeight = std::max(pModObject->m_dHeight, pDataObject->m_dHeight); - } - else if (pModObject->m_dTop < pDataObject->m_dTop) + if(m_dTop == shape->m_dTop || + (m_dTop < shape->m_dTop && m_dHeight > shape->m_dHeight) || + (m_dTop > shape->m_dTop && m_dHeight < shape->m_dHeight)) { - pModObject->m_dHeight += pDataObject->m_dHeight + pDataObject->m_dTop - dModBottom; + m_dHeight = std::max(m_dHeight, shape->m_dHeight); } + else if(m_dTop < shape->m_dTop) + m_dHeight += shape->m_dHeight + shape->m_dTop - m_dBaselinePos; else - { - pModObject->m_dHeight += pDataObject->m_dHeight + dDataBottom - pModObject->m_dTop; - } + m_dHeight += shape->m_dHeight + shape->m_dBaselinePos - m_dTop; - if (pModObject->m_dLeft == pDataObject->m_dLeft || - (pModObject->m_dLeft < pDataObject->m_dLeft && dModRight > dDataRight) || - (pModObject->m_dLeft > pDataObject->m_dLeft && dModRight < dDataRight)) + if(m_dLeft == shape->m_dLeft || + (m_dLeft < shape->m_dLeft && m_dRight > shape->m_dRight) || + (m_dLeft > shape->m_dLeft && m_dRight < shape->m_dRight)) { - pModObject->m_dWidth = std::max(pModObject->m_dWidth, pDataObject->m_dWidth); - } - else if (pModObject->m_dLeft < pDataObject->m_dLeft) - { - pModObject->m_dWidth += pDataObject->m_dWidth + pDataObject->m_dLeft - dModRight; + m_dWidth = std::max(m_dWidth, shape->m_dWidth); } + else if(m_dLeft < shape->m_dLeft) + m_dWidth += shape->m_dWidth + shape->m_dLeft - m_dRight; else - { - pModObject->m_dWidth += pDataObject->m_dWidth + dDataRight - pModObject->m_dLeft; - } + m_dWidth += shape->m_dWidth + shape->m_dRight - m_dLeft; - //note m_dWidth иногда меняет знак на "-" - pModObject->m_dHeight = fabs(pModObject->m_dHeight); - pModObject->m_dWidth = fabs(pModObject->m_dWidth); - pModObject->m_dLeft = std::min(pModObject->m_dLeft, pDataObject->m_dLeft); - pModObject->m_dTop = std::min(pModObject->m_dTop, pDataObject->m_dTop); - pModObject->m_dBaselinePos = pModObject->m_dTop + pModObject->m_dHeight; - pModObject->m_dRight = pModObject->m_dLeft + pModObject->m_dWidth; + // m_dWidth иногда меняет знак на "-" + m_dHeight = fabs(m_dHeight); + m_dWidth = fabs(m_dWidth); + + m_dLeft = std::min(m_dLeft, shape->m_dLeft); + m_dTop = std::min(m_dTop, shape->m_dTop); + + m_dBaselinePos = m_dTop + m_dHeight; + m_dRight = m_dLeft + m_dWidth; } - bool CShape::IsPeak() + bool CShape::IsPeak() const noexcept { return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; } - bool CShape::IsSide() + bool CShape::IsSide() const noexcept { return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; } - void CShape::DetermineLineType(CShape *pShape, bool bIsLast) + void CShape::CheckLineType(std::shared_ptr& pFirstShape) noexcept { - if (!pShape) - { - //Если нашелся один шейп в линии - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } + if(!pFirstShape) return; - } - if (!IsItFitLine() || !pShape->IsItFitLine() || !IsCorrelated(pShape) || - fabs(m_dHeight - pShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) //линия должна быть одного размера по высоте + if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + + else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + } + void CShape::CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast) noexcept + { + if(!pFirstShape || !pSecondShape) + return; + + if (!pFirstShape->IsItFitLine() || !pSecondShape->IsItFitLine() || !pFirstShape->IsCorrelated(pSecondShape) || + fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) // линия должна быть одного размера по высоте { return; } - //Проверка на двойную линию - if (m_eLineType == eLineType::ltDouble || m_eLineType == eLineType::ltWavyDouble) + // проверка на двойную линию + if(pFirstShape->m_eLineType == eLineType::ltDouble || pFirstShape->m_eLineType == eLineType::ltWavyDouble) { - if (m_eLineType == eLineType::ltDouble) + if(pFirstShape->m_eLineType == eLineType::ltDouble) { - if (m_dTop < pShape->m_dTop) + if(pFirstShape->m_dTop < pSecondShape->m_dTop) { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->m_eLineType = eLineType::ltDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; } else { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pSecondShape->m_eLineType = eLineType::ltDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; } } - else if (m_eLineType == eLineType::ltWavyDouble) + else if(pFirstShape->m_eLineType == eLineType::ltWavyDouble) { - if (m_dTop < pShape->m_dTop) + if(pFirstShape->m_dTop < pSecondShape->m_dTop) { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->m_eLineType = eLineType::ltWavyDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; } else { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pSecondShape->m_eLineType = eLineType::ltWavyDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; } } return; } - else if (fabs(m_dTop - pShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && - fabs(m_dWidth - pShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && - fabs(m_dLeft - pShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) + else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 && + fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM && + fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM) { //Условие первого определения - if (m_eSimpleLineType == eSimpleLineType::sltHLongDash && pShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) { - if (m_dTop < pShape->m_dTop) + if (pFirstShape->m_dTop < pSecondShape->m_dTop) { - m_eLineType = eLineType::ltDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->m_eLineType = eLineType::ltDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; } else { - pShape->m_eLineType = eLineType::ltDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pSecondShape->m_eLineType = eLineType::ltDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; } } - else if (m_eSimpleLineType == eSimpleLineType::sltHWave && pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + else if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave) { - if (m_dTop < pShape->m_dTop) + if (pFirstShape->m_dTop < pSecondShape->m_dTop) { - m_eLineType = eLineType::ltWavyDouble; - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->m_eLineType = eLineType::ltWavyDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; } else { - pShape->m_eLineType = eLineType::ltWavyDouble; - m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pSecondShape->m_eLineType = eLineType::ltWavyDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; } } return; } - else if (fabs(m_dTop - pShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) + else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM) { - //все должно быть на одной линии + // все должно быть на одной линии return; } - //Теперь считаем, что графика находится на одной линии - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) + // теперь считаем, что графика находится на одной линии + if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5) { - //расстояние между объектами на одной линии должно быть небольшим - if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHLongDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } - else if (m_eLineType == eLineType::ltUnknown && m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } + // расстояние между объектами на одной линии должно быть небольшим + if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash) + pFirstShape->m_eLineType =pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + + else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + return; } if (bIsLast) { - //note Если имеем всего 2 шейпа в линии, то нужно специально определять тип - if (m_eLineType == eLineType::ltUnknown) + // если имеем всего 2 шейпа в линии, то нужно специально определять тип + if (pFirstShape->m_eLineType == eLineType::ltUnknown) { - switch (m_eSimpleLineType) + switch (pFirstShape->m_eSimpleLineType) { case eSimpleLineType::sltHDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - } + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + break; case eSimpleLineType::sltHDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - } + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + break; case eSimpleLineType::sltHLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7) - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - } + if (fabs(pFirstShape->m_dLeft + pFirstShape->m_dWidth - pSecondShape->m_dLeft) < 0.7) + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + else - { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - } + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + break; case eSimpleLineType::sltHWave: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHWave) - { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - } + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + break; default: break; } } - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; return; } - bool bIsConditionPassed = false; - - switch (m_eSimpleLineType) + bool passed = false; + switch (pFirstShape->m_eSimpleLineType) { case eSimpleLineType::sltHDot: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotted || - m_eLineType == eLineType::ltDottedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotted || + pFirstShape->m_eLineType == eLineType::ltDottedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDottedHeavy : eLineType::ltDotted; + passed = true; } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy || - m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) + else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy || + pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotDotHeavy : eLineType::ltDotDotDash; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; } } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) { - if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) + if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltHDash; - bIsConditionPassed = true; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash; + passed = true; } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) + else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltHDash; - bIsConditionPassed = true; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDash; + passed = true; } } break; + case eSimpleLineType::sltHDash: - if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDash) + if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDash) { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDash || - m_eLineType == eLineType::ltDashedHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDash || + pFirstShape->m_eLineType == eLineType::ltDashedHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashedHeavy : eLineType::ltDash; + passed = true; } - else if ((m_eLineType == eLineType::ltDotDash || m_eLineType == eLineType::ltDashDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) + else if ((pFirstShape->m_eLineType == eLineType::ltDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - bIsConditionPassed = true; + passed = true; } } - else if (pShape->m_eSimpleLineType == eSimpleLineType::sltHDot) + else if (pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHDot) { - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDotDash || - m_eLineType == eLineType::ltDashDotHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDotDash || + pFirstShape->m_eLineType == eLineType::ltDashDotHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashDotHeavy : eLineType::ltDotDash; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; } - else if ((m_eLineType == eLineType::ltDotDotDash || m_eLineType == eLineType::ltDashDotDotHeavy) && - pShape->m_eLineType == eLineType::ltUnknown) + else if ((pFirstShape->m_eLineType == eLineType::ltDotDotDash || pFirstShape->m_eLineType == eLineType::ltDashDotDotHeavy) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eSimpleLineType = eSimpleLineType::sltHDot; - bIsConditionPassed = true; + pFirstShape->m_eSimpleLineType = eSimpleLineType::sltHDot; + passed = true; } } break; case eSimpleLineType::sltHLongDash: - if (fabs(m_dLeft + m_dWidth - pShape->m_dLeft) < 0.7 || - m_eLineType == eLineType::ltThick || m_eLineType == eLineType::ltSingle) + if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) < 0.7 || + pFirstShape->m_eLineType == eLineType::ltThick || pFirstShape->m_eLineType == eLineType::ltSingle) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle; + passed = true; } - else if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltDashLong || - m_eLineType == eLineType::ltDashLongHeavy) && pShape->m_eLineType == eLineType::ltUnknown) + else if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltDashLong || + pFirstShape->m_eLineType == eLineType::ltDashLongHeavy) && pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_dHeight > 0.3 ? eLineType::ltDashLongHeavy : eLineType::ltDashLong; + passed = true; } break; case eSimpleLineType::sltHWave: - if ((m_eLineType == eLineType::ltUnknown || m_eLineType == eLineType::ltWave || - m_eLineType == eLineType::ltWavyHeavy || m_eLineType == eLineType::ltWavyDouble) && - pShape->m_eLineType == eLineType::ltUnknown) + if ((pFirstShape->m_eLineType == eLineType::ltUnknown || pFirstShape->m_eLineType == eLineType::ltWave || + pFirstShape->m_eLineType == eLineType::ltWavyHeavy || pFirstShape->m_eLineType == eLineType::ltWavyDouble) && + pSecondShape->m_eLineType == eLineType::ltUnknown) { - m_eLineType = m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; - bIsConditionPassed = true; + pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; + passed = true; } break; default: break; } - if (bIsConditionPassed) + if (passed) { - pShape->m_bIsNotNecessaryToUse = true; - ChangeGeometryOfDesiredShape(pShape); + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; } } diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index ab7509f5b7c..df679a3be1c 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -62,6 +62,7 @@ namespace NSDocxRenderer virtual ~CShape(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void RecalcWithNewItem(const CBaseItem* pObj) override final; void SetVector(CVectorGraphics&& oVector); @@ -69,13 +70,12 @@ namespace NSDocxRenderer bool TryMergeShape(std::shared_ptr pShape); std::wstring PathToWString() const; void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); - bool IsItFitLine(); - bool IsCorrelated(const CShape* pShape); - void ChangeGeometryOfDesiredShape(CShape* pShape); - bool IsPeak(); - bool IsSide(); - void DetermineLineType(CShape* pShape = nullptr, bool bIsLast = false); + bool IsItFitLine() const noexcept; + bool IsCorrelated(std::shared_ptr pShape) const noexcept; + + bool IsPeak() const noexcept; + bool IsSide() const noexcept; void BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const; @@ -88,6 +88,13 @@ namespace NSDocxRenderer static void ResetRelativeHeight(); + // check type of line and delete not needed shape + // one shape in line + static void CheckLineType(std::shared_ptr& pShape) noexcept; + + // many shapes in line + static void CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast = false) noexcept; + private: UINT GenerateShapeId() const; }; diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 628766f3750..62ba79d8812 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -129,23 +129,23 @@ namespace NSDocxRenderer void SetStringGid(const LONG& lGid); void MeasureString(const std::wstring& wsText, - double x, - double y, - double& dBoxX, - double& dBoxY, - double& dBoxWidth, - double& dBoxHeight, - MeasureType measureType) const; + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; void MeasureStringGids(unsigned int* pGids, - unsigned int count, - double x, - double y, - double& dBoxX, - double& dBoxY, - double& dBoxWidth, - double& dBoxHeight, - MeasureType measureType) const; + unsigned int count, + double x, + double y, + double& dBoxX, + double& dBoxY, + double& dBoxWidth, + double& dBoxHeight, + MeasureType measureType) const; void ClearCache(); private: diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index a29eab00965..9fc6673cf28 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -70,7 +70,7 @@ namespace NSDocxRenderer void CVectorGraphics::MoveTo(const double &x1, const double &y1) { Point point = {x1, y1}; - VectorGraphicsType type = vgtMove; + eVectorGraphicsType type = eVectorGraphicsType::vgtMove; m_arData.push_back({type, {point}}); CheckPoint(point); @@ -79,7 +79,7 @@ namespace NSDocxRenderer void CVectorGraphics::LineTo(const double &x1, const double &y1) { Point point = {x1, y1}; - VectorGraphicsType type = vgtLine; + eVectorGraphicsType type = eVectorGraphicsType::vgtLine; m_arData.push_back({type, {point}}); CheckPoint(point); @@ -90,7 +90,7 @@ namespace NSDocxRenderer const double &x3, const double &y3) { std::list points = {{x1, y1}, {x2, y2}, {x3, y3}}; - VectorGraphicsType type = vgtCurve; + eVectorGraphicsType type = eVectorGraphicsType::vgtCurve; m_arData.push_back({type, points}); for(auto& point : points) @@ -99,7 +99,7 @@ namespace NSDocxRenderer void CVectorGraphics::Close() { - VectorGraphicsType type = vgtClose; + eVectorGraphicsType type = eVectorGraphicsType::vgtClose; m_arData.push_back({type, {}}); } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index b982d650917..404c2ba9f62 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -6,7 +6,7 @@ namespace NSDocxRenderer class CVectorGraphics { public: - enum VectorGraphicsType + enum class eVectorGraphicsType { vgtMove = 0, vgtLine = 1, @@ -16,13 +16,13 @@ namespace NSDocxRenderer struct Point { - double x = 0; - double y = 0; + double x{0}; + double y{0}; }; struct PathCommand { - VectorGraphicsType type; + eVectorGraphicsType type; std::list points; }; From 91fad82d6ac3b9cc0848bfcacc2415a947fa1a07 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 2 Nov 2023 23:10:29 +0300 Subject: [PATCH 174/794] Refactoring in progress --- DocxRenderer/src/logic/Page.cpp | 238 ++++++++---------- DocxRenderer/src/logic/elements/ContText.cpp | 10 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 31 +-- DocxRenderer/src/logic/elements/Shape.h | 1 + DocxRenderer/src/logic/elements/TextLine.cpp | 22 +- .../logic/managers/ParagraphStyleManager.cpp | 2 +- 6 files changed, 144 insertions(+), 160 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 57a46b1baa1..86ec89a4e68 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -48,6 +48,7 @@ namespace NSDocxRenderer m_arDiacriticalSymbols.clear(); m_arImages.clear(); m_arShapes.clear(); + m_arOutputObjects.clear(); ClearTables(); m_pCurrentLine = nullptr; @@ -72,7 +73,7 @@ namespace NSDocxRenderer { if (m_bIsDeleteTextClipPage) for (auto& line : m_arTextLines) - if (line->m_dTop >= m_dHeight || line->m_dBaselinePos <= 0) + if (line && (line->m_dTop >= m_dHeight || line->m_dBaselinePos <= 0)) line = nullptr; } @@ -214,7 +215,7 @@ namespace NSDocxRenderer { if (!m_arShapes.empty()) { - auto pLastShape = m_arShapes.back(); + auto& pLastShape = m_arShapes.back(); if (pLastShape->m_dLeft == dLeft && pLastShape->m_dTop == dTop && @@ -830,76 +831,63 @@ namespace NSDocxRenderer void CPage::DetermineLinesType() { - //определяются типы только горизонтальных линий. - //Входные данные представляют собой набор прямоугольников на одной линии - //При определении типа линии используется крайний левый шейп, который - //увеличивается в размере на ширину последующих за ним шейпов. - //Последующие шейпы помечаются как m_bIsNotNecessaryToUse - - //todo добавить аналогичное определение для вертикальных линий - //нужно для определения границ таблицы - //note определение типов линий нужно сделать до распознования таблиц, когда линия несплошная - for (size_t i = 0; i < m_arShapes.size(); ++i) { - auto& curr_shape = m_arShapes[i]; - if (!curr_shape || curr_shape->m_dHeight > c_dMAX_LINE_HEIGHT_MM || // рассматриваем только тонкие объекты - (curr_shape->m_eGraphicsType != eGraphicsType::gtRectangle && - curr_shape->m_eGraphicsType != eGraphicsType::gtCurve)) + if (!m_arShapes[i] || m_arShapes[i]->m_dHeight > c_dMAX_LINE_HEIGHT_MM || // рассматриваем только тонкие объекты + (m_arShapes[i]->m_eGraphicsType != eGraphicsType::gtRectangle && + m_arShapes[i]->m_eGraphicsType != eGraphicsType::gtCurve)) { continue; } - std::vector> curr_shapes; - curr_shapes.push_back(curr_shape); + std::vector curr_shape_indexes; + curr_shape_indexes.push_back(i); - for (size_t j = i+1; j < m_arShapes.size(); ++j) + for (size_t j = i + 1; j < m_arShapes.size(); ++j) { - auto& next_shape = m_arShapes[j]; - if (!next_shape || curr_shape->AreObjectsNoCrossingByVertically(next_shape.get())) // значительно ускоряет работу + if (!m_arShapes[j] || m_arShapes[i]->AreObjectsNoCrossingByVertically(m_arShapes[j].get())) // значительно ускоряет работу continue; - bool bIf1 = curr_shape->IsCorrelated(next_shape); + bool bIf1 = m_arShapes[i]->IsCorrelated(m_arShapes[j]); // довольно странное поведение - в зависимости от толщины линии информация о графике записывается в разные структуры - bool bIf2 = curr_shape->m_oBrush.IsEqual(&next_shape->m_oBrush); - bool bIf3 = curr_shape->m_oPen.IsEqual(&next_shape->m_oPen); + bool bIf2 = m_arShapes[i]->m_oBrush.IsEqual(&m_arShapes[j]->m_oBrush); + bool bIf3 = m_arShapes[i]->m_oPen.IsEqual(&m_arShapes[j]->m_oPen); // линия должна быть одного размера по высоте - bool bIf4 = fabs(curr_shape->m_dHeight - next_shape->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; + bool bIf4 = fabs(m_arShapes[i]->m_dHeight - m_arShapes[j]->m_dHeight) < c_dGRAPHICS_ERROR_IN_LINES_MM; // все должно быть на одной линии - bool bIf5 = fabs(curr_shape->m_dTop - next_shape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; + bool bIf5 = fabs(m_arShapes[i]->m_dBaselinePos - m_arShapes[j]->m_dBaselinePos) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5; - if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) //все должно быть на одной линии - curr_shapes.push_back(next_shape); + if (bIf1 && (bIf2 || bIf3) && bIf4 && bIf5) // все должно быть на одной линии + curr_shape_indexes.push_back(j); } - if (curr_shapes.size() > 1) + if (curr_shape_indexes.size() > 1) { - using shape_ptr = std::shared_ptr; - std::sort(curr_shapes.begin(), curr_shapes.end(), [] (const shape_ptr& a, const shape_ptr& b) { - return a->m_dLeft < b->m_dLeft; + std::sort(curr_shape_indexes.begin(), curr_shape_indexes.end(), [this] (size_t a, size_t b) { + return m_arShapes[a]->m_dLeft < m_arShapes[b]->m_dLeft; }); - curr_shape = curr_shapes[0]; - - for (size_t k = 1; k < curr_shapes.size(); ++k) + size_t j = 0; + for (size_t k = 1; k < curr_shape_indexes.size(); ++k) { - auto& next_shape = curr_shapes[k]; - CShape::CheckLineType(curr_shape, next_shape, k == curr_shapes.size() - 1); + auto& first_shape = m_arShapes[curr_shape_indexes[j]]; + auto& second_shape = m_arShapes[curr_shape_indexes[k]]; - if(!curr_shape) + CShape::CheckLineType(first_shape, second_shape, k == curr_shape_indexes.size() - 1); + if(!m_arShapes[j]) { - curr_shape = next_shape; + j = k; k++; } } } - else if (curr_shapes.size() == 1) - CShape::CheckLineType(curr_shapes[0]); + else if (curr_shape_indexes.size() == 1) + CShape::CheckLineType(m_arShapes[curr_shape_indexes[0]]); - curr_shapes.clear(); + curr_shape_indexes.clear(); } } @@ -915,6 +903,9 @@ namespace NSDocxRenderer // analyze drop caps (creates shapes) AnalyzeDropCaps(); + // analyze conts in text lines + AnalyzeConts(); + // assign highlights to conts & delete shapes which is uses in highlights DetermineStrikeoutsUnderlinesHighlights(); @@ -1029,7 +1020,6 @@ namespace NSDocxRenderer } void CPage::AnalyzeConts() { - for (size_t uCurrLineIndex = 0; uCurrLineIndex < m_arTextLines.size(); ++uCurrLineIndex) { auto& pCurrLine = m_arTextLines[uCurrLineIndex]; @@ -1056,23 +1046,19 @@ namespace NSDocxRenderer for (size_t uNextContIndex = uNextLineIndex != uCurrLineIndex ? 0 : uCurrContIndex + 1; uNextContIndex < pNextLine->m_arConts.size(); ++uNextContIndex) { + if (!pCurrCont) + break; + // берем символ во второй линии - auto pNextCont = pNextLine->m_arConts[uNextContIndex]; + auto& pNextCont = pNextLine->m_arConts[uNextContIndex]; if (!pNextCont) continue; eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pNextCont.get()); eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pNextCont.get()); - if (CContText::CheckFontEffects(pCurrCont, pNextCont, eVType, eHType)) - { - pNextCont = nullptr; - if(pNextLine->IsCanBeDeleted()) - pNextLine = nullptr; - break; - } - - if (CContText::CheckVertAlignTypeBetweenConts(pCurrCont, pNextCont, eVType, eHType)) + bool is_font_effect = CContText::CheckFontEffects(pCurrCont, pNextCont, eVType, eHType); + if(!is_font_effect && CContText::CheckVertAlignTypeBetweenConts(pCurrCont, pNextCont, eVType, eHType)) { pCurrLine->SetVertAlignType(pCurrCont->m_eVertAlignType); pNextLine->SetVertAlignType(pNextCont->m_eVertAlignType); @@ -1083,88 +1069,93 @@ namespace NSDocxRenderer { pCurrLine->m_pLine = pNextLine; } - break; } - - if (pCurrCont->IsDuplicate(pNextCont.get(), eVType)) + else if(!is_font_effect && pCurrCont->IsDuplicate(pNextCont.get(), eVType)) { pNextCont = nullptr; pCurrCont->m_iNumDuplicates++; - break; } } - - if(pNextLine->IsCanBeDeleted()) + if(pNextLine && pNextLine->IsCanBeDeleted()) pNextLine = nullptr; } } + if(pCurrLine && pCurrLine->IsCanBeDeleted()) + pCurrLine = nullptr; } } void CPage::DetermineStrikeoutsUnderlinesHighlights() { - //определение различных эффектов на основании взаимного расположения символов и шейпов + // определение различных эффектов на основании взаимного расположения символов и шейпов for (size_t i = 0; i < m_arShapes.size(); ++i) { - auto& pShape = m_arShapes[i]; - if (!pShape || pShape->m_eGraphicsType == eGraphicsType::gtNoGraphics) + auto& shape = m_arShapes[i]; + if (!shape || shape->m_eGraphicsType == eGraphicsType::gtNoGraphics) continue; for (size_t j = 0; j < m_arTextLines.size(); ++j) { + if(!shape) + break; + auto& pCurrLine = m_arTextLines[j]; + bool shape_used = false; - if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(pShape.get()) && - (pCurrLine->m_dTop > pShape->m_dBaselinePos || - pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < pShape->m_dTop))) + if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(shape.get()) && + (pCurrLine->m_dTop > shape->m_dBaselinePos || + pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < shape->m_dTop))) { continue; } for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) { - auto& pCurrCont = pCurrLine->m_arConts[k]; - if (!pCurrCont) + if(!shape) + break; + + auto& curr_cont = pCurrLine->m_arConts[k]; + if (!curr_cont) continue; - eVerticalCrossingType eVType = pCurrCont->GetVerticalCrossingType(pShape.get()); - eHorizontalCrossingType eHType = pCurrCont->GetHorizontalCrossingType(pShape.get()); + eVerticalCrossingType eVType = curr_cont->GetVerticalCrossingType(shape.get()); + eHorizontalCrossingType eHType = curr_cont->GetHorizontalCrossingType(shape.get()); - bool bIsComplicatedFigure = pShape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; - bool bIsLineCrossingText = IsLineCrossingText(pShape.get(), pCurrCont.get(), eHType); - bool bIsLineBelowText = IsLineBelowText(pShape.get(), pCurrCont.get(), eHType); - bool bIsItHighlightingBackground = IsItHighlightingBackground(pShape.get(), pCurrCont.get(), eHType); + bool bIsNotComplicatedFigure = shape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; + bool bIsLineCrossingText = IsLineCrossingText(shape.get(), curr_cont.get(), eHType); + bool bIsLineBelowText = IsLineBelowText(shape.get(), curr_cont.get(), eHType); + bool bIsItHighlightingBackground = IsItHighlightingBackground(shape.get(), curr_cont.get(), eHType); if(bIsLineCrossingText) { - pCurrCont->m_bIsStrikeoutPresent = true; - if (pShape->m_eLineType == eLineType::ltDouble) - pCurrCont->m_bIsDoubleStrikeout = true; + curr_cont->m_bIsStrikeoutPresent = true; + if (shape->m_eLineType == eLineType::ltDouble) + curr_cont->m_bIsDoubleStrikeout = true; } if(bIsLineBelowText) { - pCurrCont->m_bIsUnderlinePresent = true; - pCurrCont->m_eUnderlineType = pShape->m_eLineType; - pCurrCont->m_lUnderlineColor = pShape->m_dHeight > 0.3 ? pShape->m_oBrush.Color1 : pShape->m_oPen.Color; + curr_cont->m_bIsUnderlinePresent = true; + curr_cont->m_eUnderlineType = shape->m_eLineType; + curr_cont->m_lUnderlineColor = shape->m_dHeight > 0.3 ? shape->m_oBrush.Color1 : shape->m_oPen.Color; } if(bIsItHighlightingBackground) { //Удовлетворяет расположением и размером - привязываем указатель на картинку - pCurrCont->m_pShape = pShape; - pCurrCont->m_bIsHighlightPresent = true; - pCurrCont->m_lHighlightColor = pShape->m_oBrush.Color1; + curr_cont->m_pShape = shape; + curr_cont->m_bIsHighlightPresent = true; + curr_cont->m_lHighlightColor = shape->m_oBrush.Color1; } // проверили - удаляем - if (bIsComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) - pShape = nullptr; + if (bIsNotComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) + shape_used = true; - if (!bIsComplicatedFigure) + if (!bIsNotComplicatedFigure) { - bool bIf1 = pCurrCont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; - bool bIf2 = pCurrCont->m_bIsShadowPresent && pCurrCont->m_bIsOutlinePresent; + bool bIf1 = curr_cont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf2 = curr_cont->m_bIsShadowPresent && curr_cont->m_bIsOutlinePresent; bool bIf3 = eVType == eVerticalCrossingType::vctCurrentOutsideNext; bool bIf4 = eHType == eHorizontalCrossingType::hctCurrentOutsideNext; bool bIf5 = eHType == eHorizontalCrossingType::hctCurrentRightOfNext; @@ -1173,23 +1164,24 @@ namespace NSDocxRenderer { if (!bIf2) { - auto oBrush = pCurrCont->m_pFontStyle->oBrush; - oBrush.Color1 = pShape->m_oPen.Color; + auto oBrush = curr_cont->m_pFontStyle->oBrush; + oBrush.Color1 = shape->m_oPen.Color; - pCurrCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(oBrush, - pCurrCont->m_pFontStyle->wsFontName, - pCurrCont->m_pFontStyle->dFontSize, - pCurrCont->m_pFontStyle->bItalic, - pCurrCont->m_pFontStyle->bBold); + curr_cont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(oBrush, + curr_cont->m_pFontStyle->wsFontName, + curr_cont->m_pFontStyle->dFontSize, + curr_cont->m_pFontStyle->bItalic, + curr_cont->m_pFontStyle->bBold); - pCurrCont->m_bIsShadowPresent = true; - pCurrCont->m_bIsOutlinePresent = true; + curr_cont->m_bIsShadowPresent = true; + curr_cont->m_bIsOutlinePresent = true; } - - pShape = nullptr; + shape_used = true; } } } + if(shape_used) + shape = nullptr; } } } @@ -1226,7 +1218,7 @@ namespace NSDocxRenderer pShape->m_eLineType != eLineType::ltUnknown; //Условие по вертикали - bool bIf2 = fabs(pShape->m_dTop - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.3; + bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.3; //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && @@ -1354,6 +1346,8 @@ namespace NSDocxRenderer using cont_ptr = std::shared_ptr; std::sort(pBaseLine->m_arConts.begin(), pBaseLine->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + if(!a || !b) + return false; return a->m_dLeft < b->m_dLeft; }); @@ -1382,9 +1376,10 @@ namespace NSDocxRenderer using cont_ptr = std::shared_ptr; std::sort(line->m_arConts.begin(), line->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + if(!a || !b) + return false; return a->m_dLeft < b->m_dLeft; }); - pSubLine = nullptr; } } @@ -1413,15 +1408,14 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - for (size_t i = 0; i < m_arImages.size(); ++i) - { - m_arImages[i]->ToXml(oWriter); - } + for (const auto& image : m_arImages) + if(image) + image->ToXml(oWriter); - for (size_t i = 0; i < m_arShapes.size(); ++i) - { - m_arShapes[i]->ToXml(oWriter); - } + + for (const auto& shape : m_arShapes) + if(shape) + shape->ToXml(oWriter); if (bIsTextShapePresent) { @@ -1441,14 +1435,10 @@ namespace NSDocxRenderer for (size_t i = 0; i < m_arOutputObjects.size(); ++i) { - auto pObj = m_arOutputObjects[i]; + auto& pObj = m_arOutputObjects[i]; CParagraph* pParagraph = nullptr; if((pParagraph = dynamic_cast(pObj.get())) != nullptr) pParagraph->ToXml(oWriter); - -// CTable* pTable = nullptr; -// if((pTable = dynamic_cast(pObj)) != nullptr) -// pTable->ToXml(oWriter); } } @@ -1530,11 +1520,10 @@ namespace NSDocxRenderer for (size_t nIndex = 0; nIndex < m_arTextLines.size(); ++nIndex) { pCurrLine = m_arTextLines[nIndex]; - avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); - if (!pCurrLine) continue; + avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); if (m_eTextAssociationType == TextAssociationType::tatShapeLine) { CreateSingleLineShape(pCurrLine); @@ -1980,8 +1969,7 @@ namespace NSDocxRenderer for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) { - auto pObj = pShape->m_arOutputObjects[j]; - + auto& pObj = pShape->m_arOutputObjects[j]; switch(pObj->m_eType) { case COutputObject::eOutputType::etParagraph: @@ -2013,18 +2001,13 @@ namespace NSDocxRenderer for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLines.size(); ++nIndex) { pLine = m_arTextLines[nIndex]; - bool bIf1 = pLine == nullptr; - bool bIf2 = pIndexForCheking && pLine->m_iNumDuplicates > 0; + if(pLine && (pIndexForCheking && pLine->m_iNumDuplicates > 0)) + if (*pIndexForCheking == c_nAntiZero) + *pIndexForCheking = nIndex; - if (bIf1 || bIf2) + if (!pLine || (pIndexForCheking && pLine->m_iNumDuplicates > 0)) { - if (bIf2) - { - if (*pIndexForCheking == c_nAntiZero) - *pIndexForCheking = nIndex; - } - - nCurrentIndex++; //note изменяем входной индекс, чтобы не выбирать те же строки + nCurrentIndex++; pLine = nullptr; continue; } @@ -2037,7 +2020,6 @@ namespace NSDocxRenderer std::shared_ptr CPage::GetPrevTextLine(size_t nCurrentIndex) { std::shared_ptr pLine = nullptr; - if (nCurrentIndex) { for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index bd6c7811031..4eca0859e87 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -148,9 +148,9 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); } - if (m_bIsEmbossPresent) + if(m_bIsEmbossPresent) oWriter.WriteString(L""); - else if (m_bIsEngravePresent) + else if(m_bIsEngravePresent) oWriter.WriteString(L""); else { @@ -168,7 +168,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - if (m_bIsUnderlinePresent) + if(m_bIsUnderlinePresent) { oWriter.WriteString(L""); - for(size_t i = 0; i < m_arLines.size(); ++i) - { - m_arLines[i]->ToXml(oWriter); - } + for(const auto& line : m_arLines) + if(line) + line->ToXml(oWriter); oWriter.WriteString(L""); } @@ -106,23 +105,19 @@ namespace NSDocxRenderer void CParagraph::RemoveHighlightColor() { if (!m_bIsShadingPresent) - { return; - } - for(size_t i = 0; i < m_arLines.size(); ++i) { - auto pLine = m_arLines[i]; - if (pLine->m_pDominantShape) + auto& pLine = m_arLines[i]; + if (pLine || pLine->m_pDominantShape) { for (size_t j = 0; j < pLine->m_arConts.size(); ++j) { - auto pCont = pLine->m_arConts[j]; - if (m_lColorOfShadingFill == pCont->m_lHighlightColor) - { - pCont->m_bIsHighlightPresent = false; - } + auto& pCont = pLine->m_arConts[j]; + if(pCont) + if (m_lColorOfShadingFill == pCont->m_lHighlightColor) + pCont->m_bIsHighlightPresent = false; } } } @@ -132,16 +127,16 @@ namespace NSDocxRenderer { for(size_t i = 0; i < m_arLines.size(); ++i) { - auto& pLine = m_arLines[i]; - auto& pLastCont = pLine->m_arConts.back(); + auto pLine = m_arLines[i]; + auto pLastCont = pLine->m_arConts.back(); size_t iNumConts = pLine->m_arConts.size() - 1; - while (!pLastCont) + while(!pLastCont) pLastCont = pLine->m_arConts[--iNumConts]; //Добавляем пробел в конец каждой строки pLastCont->m_oText += L" "; - pLastCont->m_dWidth += pLine->m_arConts.back()->m_oSelectedSizes.dSpaceWidth; + pLastCont->m_dWidth += pLastCont->m_oSelectedSizes.dSpaceWidth; } } diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index df679a3be1c..6cc68a568f7 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -1,5 +1,6 @@ #pragma once #include "Paragraph.h" +#include "TextLine.h" #include "../../resources/ImageInfo.h" #include "../../resources/LinesTable.h" #include "../../resources/VectorGraphics.h" diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index efa8be46232..3a6d04c9893 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -1,7 +1,7 @@ #include "TextLine.h" +#include "../../logic/elements/Shape.h" #include "../../resources/Constants.h" #include "../../resources/utils.h" -#include "src/logic/elements/Shape.h" namespace NSDocxRenderer { @@ -35,10 +35,15 @@ namespace NSDocxRenderer if (m_arConts.empty()) return; - auto pFirst = m_arConts.front(); - for (size_t i = 1; i < m_arConts.size(); ++i) + std::shared_ptr pFirst; + size_t j = 0; + + for(; j < m_arConts.size() && !pFirst; ++j) + pFirst = m_arConts[j]; + + for (size_t i = j; i < m_arConts.size(); ++i) { - auto pCurrent = m_arConts[i]; + auto& pCurrent = m_arConts[i]; if (!pCurrent) continue; @@ -50,7 +55,7 @@ namespace NSDocxRenderer bool bIsBigDelta = dDifference > dSpaceDefaultSize; bool bIsVeryBigDelta = dDifference > dSpaceWideSize; - if (bIsVeryBigDelta) + if(bIsVeryBigDelta) { auto wide_space = std::make_shared(pFirst->m_pManager); @@ -86,11 +91,11 @@ namespace NSDocxRenderer } else if(bIsEqual) { - if (fabs(pFirst->m_dRight - pCurrent->m_dLeft) < dSpaceDefaultSize) + if(!bIsBigDelta) { pFirst->m_oText += pCurrent->m_oText; } - else if (bIsBigDelta) + else { pFirst->m_oText += uint32_t(' '); pFirst->m_oText += pCurrent->m_oText; @@ -170,6 +175,7 @@ namespace NSDocxRenderer void CTextLine::ToXml(NSStringUtils::CStringBuilder& oWriter) const { for (const auto& cont : m_arConts) - cont->ToXml(oWriter); + if(cont) + cont->ToXml(oWriter); } } diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp index d5d62a1ae39..921aff52fa8 100644 --- a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -34,7 +34,7 @@ namespace NSDocxRenderer bool isHeading = true; for(auto& val : oParagraph.m_arLines[0]->m_arConts) - if(val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold) + if(val && val->m_pFontStyle->dFontSize <= m_dAvgFontSize + 1 && !val->m_pFontStyle->bBold) isHeading = false; return isHeading ? L"Heading1" : L"Normal"; From 29e44fb12c7b5951d7f78f1683c95f950f29a41d Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 3 Nov 2023 12:22:14 +0300 Subject: [PATCH 175/794] Refactoring - tables romoved (for now) - paragraph logic is broken (fix soon) --- DocxRenderer/DocxRenderer.pro | 5 - DocxRenderer/src/logic/Document.h | 2 +- DocxRenderer/src/logic/Page.cpp | 385 +----------------- DocxRenderer/src/logic/Page.h | 16 +- DocxRenderer/src/logic/elements/BaseItem.h | 2 +- DocxRenderer/src/logic/elements/Cell.cpp | 186 --------- DocxRenderer/src/logic/elements/Cell.h | 87 ---- DocxRenderer/src/logic/elements/ContText.cpp | 10 +- DocxRenderer/src/logic/elements/ContText.h | 34 +- DocxRenderer/src/logic/elements/DropCap.cpp | 11 - DocxRenderer/src/logic/elements/Image.h | 8 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 9 +- DocxRenderer/src/logic/elements/Paragraph.h | 33 +- DocxRenderer/src/logic/elements/Shape.cpp | 60 +-- DocxRenderer/src/logic/elements/Shape.h | 51 +-- DocxRenderer/src/logic/elements/Table.cpp | 209 ---------- DocxRenderer/src/logic/elements/Table.h | 43 -- DocxRenderer/src/logic/elements/TextLine.cpp | 5 +- DocxRenderer/src/logic/elements/TextLine.h | 11 +- .../src/logic/managers/FontManager.cpp | 4 +- DocxRenderer/src/logic/managers/FontManager.h | 18 +- .../src/logic/managers/ImageManager.cpp | 2 +- .../src/logic/managers/ImageManager.h | 4 +- DocxRenderer/src/logic/styles/FontStyle.h | 4 +- .../src/logic/styles/ParagraphStyle.h | 4 +- DocxRenderer/src/resources/Constants.h | 2 +- DocxRenderer/src/resources/ImageInfo.h | 2 +- DocxRenderer/src/resources/utils.h | 4 +- 28 files changed, 125 insertions(+), 1086 deletions(-) delete mode 100644 DocxRenderer/src/logic/elements/Cell.cpp delete mode 100644 DocxRenderer/src/logic/elements/Cell.h delete mode 100644 DocxRenderer/src/logic/elements/Table.cpp delete mode 100644 DocxRenderer/src/logic/elements/Table.h diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index df9d98db082..504cd24a730 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -26,13 +26,11 @@ LIBS += -lgdi32 \ HEADERS += \ src/logic/elements/BaseItem.h \ - src/logic/elements/Cell.h \ src/logic/elements/ContText.h \ src/logic/elements/DropCap.h \ src/logic/elements/Image.h \ src/logic/elements/Paragraph.h \ src/logic/elements/Shape.h \ - src/logic/elements/Table.h \ src/logic/elements/TextLine.h \ src/logic/managers/FontStyleManager.h \ src/logic/managers/ImageManager.h \ @@ -44,7 +42,6 @@ HEADERS += \ src/resources/Constants.h \ src/resources/ImageInfo.h \ src/resources/LinesTable.h \ - src/resources/SingletonTemplate.h \ src/resources/VectorGraphics.h \ src/resources/resources.h \ src/resources/utils.h \ @@ -54,13 +51,11 @@ HEADERS += \ SOURCES += \ src/logic/elements/BaseItem.cpp \ - src/logic/elements/Cell.cpp \ src/logic/elements/ContText.cpp \ src/logic/elements/DropCap.cpp \ src/logic/elements/Image.cpp \ src/logic/elements/Paragraph.cpp \ src/logic/elements/Shape.cpp \ - src/logic/elements/Table.cpp \ src/logic/elements/TextLine.cpp \ src/logic/managers/FontManager.cpp \ src/logic/managers/FontStyleManager.cpp \ diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index f867dcd95af..9050f4a630b 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -1,6 +1,6 @@ #pragma once #include "Page.h" -#include "../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/Directory.h" #include "../resources/resources.h" #include "managers/ImageManager.h" #include "managers/FontStyleManager.h" diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 86ec89a4e68..ab2a04e72f2 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -30,7 +30,6 @@ namespace NSDocxRenderer m_pParagraphStyleManager = pParagraphStyleManager; m_pCurrentLine = nullptr; -// m_pCurrentRow = nullptr; CShape::ResetRelativeHeight(); } @@ -50,20 +49,10 @@ namespace NSDocxRenderer m_arShapes.clear(); m_arOutputObjects.clear(); - ClearTables(); m_pCurrentLine = nullptr; -// m_pCurrentRow = nullptr; m_oVector.Clear(); } - void CPage::ClearTables() - { -// m_arPeaks.clear(); -// m_arCells.clear(); -// m_arRows.clear(); -// m_arTables.clear(); - } - CPage::~CPage() { Clear(); @@ -446,13 +435,16 @@ namespace NSDocxRenderer if(m_arShapes.empty()) return; + using shape_ref_ptr_t = std::reference_wrapper>; for(size_t i = 0; i < m_arShapes.size() - 1; i++) { - auto& val = m_arShapes[i]; - auto& nextVal = m_arShapes[i + 1]; + shape_ref_ptr_t val = m_arShapes[i]; + shape_ref_ptr_t next_val = m_arShapes[i + 1]; - if(val && nextVal) - nextVal->TryMergeShape(val); + if(!val.get() || ! next_val.get()) + continue; + + next_val.get()->TryMergeShape(val.get()); } } @@ -468,367 +460,6 @@ namespace NSDocxRenderer DetermineLinesType(); } -// void CPage::BuildTables() -// { -// //Графика таблиц парсится в условные 2 типа: -// //1 - С выделение отдельных узлов (peak) в местах пересечения линий -// //При этом графический шейп доходит до peak и прерывается. Каждая шейп-линия является стороной 1 ячейки -// //2 - Без выделения узлов - каждая линия тамблицы захватывает несколько ячеек - -// //Текущая логика постороения таблиц реализовывает парсинг таблиц 1-го типа -// //Для реализации 2го - нужно сначала создать peak в местах пересечения линий -// //Основная причина почему так - нужно удалять все шейпы после парсинга - -// //todo пока плохо работает для таблиц с неполными ячейками. причина - не заполнены все основные параметры (m_dTop, m_dLeft...) -// //todo реализовать парсинг таблиц 2-го типа -// //todo необходимо в созданные cells добавить содержимое из m_arTextLines по геометрическому признаку (буквы должны находится внутри ячеек) -// //todo зетем собрать TextLine и Paragraph для каждой ячейки -// //todo написать функцию и логику для добавления таблицы в шейп - нужно для режима tatParagraphToShape - -// CollectPeaks(); -// CreatCells(); -// BuildRows(); - -// CTable* pCurrTable = nullptr; -// CRow* pFirstRow = nullptr; - -// if (!m_arRows.empty()) -// { -// pCurrTable = new CTable(); -// m_arTables.push_back(pCurrTable); - -// pFirstRow = m_arRows.front(); -// pCurrTable->RecalcWithNewItem(pFirstRow); -// } - -// for (size_t i = 1; i < m_arRows.size(); ++i) -// { -// auto pCurrRow = m_arRows[i]; - -// eVerticalCrossingType eVType = pFirstRow->GetVerticalCrossingType(pCurrRow); -// eHorizontalCrossingType eHType = pFirstRow->GetHorizontalCrossingType(pCurrRow); - -// bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; -// bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch; - -// if (bIf1 && bIf2) -// { -// pCurrTable->RecalcWithNewItem(pCurrRow); -// pFirstRow = pCurrRow; -// } -// else -// { -// pCurrTable = new CTable(); -// m_arTables.push_back(pCurrTable); - -// pFirstRow = pCurrRow; -// pCurrTable->RecalcWithNewItem(pFirstRow); -// } -// } - -// for (size_t i = 0; i < m_arTables.size(); ++i) -// { -// m_arTables[i]->CalculateColumnWidth(); -// } -// } - -// void CPage::CollectPeaks() -// { -// for (size_t i = 0; i< m_arShapes.size(); ++i) -// { -// auto pCurrShape = m_arShapes[i]; - -// if (pCurrShape->m_bIsNotNecessaryToUse) -// { -// continue; -// } - -// //нашли вершину -// if (pCurrShape->IsPeak()) -// { -// CPeak* pCurrPeak = nullptr; - -// //ищем стороны -// for (size_t j = 0; j < m_arShapes.size(); ++j) -// { -// auto pNextShape = m_arShapes[j]; - -// if (pNextShape->m_bIsNotNecessaryToUse || !pNextShape->IsSide()) -// { -// continue; -// } - -// eVerticalCrossingType eVType = pCurrShape->GetVerticalCrossingType(pNextShape); -// eHorizontalCrossingType eHType = pCurrShape->GetHorizontalCrossingType(pNextShape); - -// //проверяем, подходит ли сторона -// bool bIf1 = eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch && -// (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext || eHType == eHorizontalCrossingType::hctCurrentRightOfNext); -// bool bIf2 = eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch && -// (eVType == eVerticalCrossingType::vctCurrentAboveNext || eVType == eVerticalCrossingType::vctCurrentBelowNext); - -// if (bIf1 || bIf2) -// { -// if (!pCurrPeak) -// { -// pCurrPeak = new CPeak(pCurrShape); -// pCurrShape->m_bIsNotNecessaryToUse = true; -// pCurrShape->m_bIsUseInTable = true; -// m_arPeaks.push_back(pCurrPeak); -// } - -// if (eVType == eVerticalCrossingType::vctTopAndBottomBordersMatch) -// { -// if (eHType == eHorizontalCrossingType::hctCurrentLeftOfNext) -// { -// pCurrPeak->m_pLines[CPeak::dI] = pNextShape; -// pNextShape->m_bIsUseInTable = true; -// } -// else if (eHType == eHorizontalCrossingType::hctCurrentRightOfNext) -// { -// pCurrPeak->m_pLines[CPeak::dIII] = pNextShape; -// pNextShape->m_bIsUseInTable = true; -// } -// } -// if (eHType == eHorizontalCrossingType::hctLeftAndRightBordersMatch) -// { -// if (eVType == eVerticalCrossingType::vctCurrentAboveNext) -// { -// pCurrPeak->m_pLines[CPeak::dIV] = pNextShape; -// pNextShape->m_bIsUseInTable = true; -// } -// else if (eVType == eVerticalCrossingType::vctCurrentBelowNext) -// { -// pCurrPeak->m_pLines[CPeak::dII] = pNextShape; -// pNextShape->m_bIsUseInTable = true; -// } -// } -// } -// } -// } -// } -// } - -// void CPage::CreatCells() -// { -// //Cells -// // II | I -// // | -// //-----Peak--- -// // | -// // III | IV -// //У каждого peak может быть до 4 углов, образованных выходящими линиями - обозначения согласно рисунку -// CCell *pCellI, *pCellII, *pCellIII, *pCellIV; - -// for (size_t i = 0; i < m_arPeaks.size(); ++i) -// { -// CPeak* pPeak = m_arPeaks[i]; -// pCellI = nullptr; pCellII = nullptr; pCellIII = nullptr; pCellIV = nullptr; -// //Lines from peak -// // VI II V -// // | -// // III <- Peak -> I -// // | -// // VII IV VIII - -// //Corners -// //Обозначение углов в ячейке -// // IV------III -// // | | -// // | Cell | -// // | | -// // I--------II - -// bool bIsI = pPeak->m_pLines[CPeak::dI]; //если true, то в направлении I есть линия -// bool bIsII = pPeak->m_pLines[CPeak::dII]; -// bool bIsIII = pPeak->m_pLines[CPeak::dIII]; -// bool bIsIV = pPeak->m_pLines[CPeak::dIV]; - -// //Если ячейки уже есть -// //todo если ячейка неполная - могут отсутсвовать некоторые основные параметры (m_dLeft...) -// //Скорее всего что в такой ячейке не все peak присутствуют в m_pPeaks и параметры не устанавливаются -// //Добавить на это проверку и просто вычислить отсутсвующие параметры из известных -// for (size_t j = 0; j < m_arCells.size(); ++j) -// { -// auto pSaveCell = m_arCells[j]; -// for (size_t k = 0; k < CCell::cNumCorners; ++k) -// { -// auto pSavePeak = pSaveCell->m_pPeaks[k]; -// if (pSavePeak) -// { -// if (pPeak->m_pLines[CPeak::dI] && -// pSavePeak->m_pLines[CPeak::dIII] && -// pPeak->m_pLines[CPeak::dI] == pSavePeak->m_pLines[CPeak::dIII]) -// { -// if (k == CCell::cII) -// { -// pCellI = pSaveCell; -// pCellI->SetParameters(pPeak, CCell::cI); -// } -// else if (k == CCell::cIII) -// { -// pCellIV = pSaveCell; -// pCellIV->SetParameters(pPeak, CCell::cIV); -// } -// } - -// if (pPeak->m_pLines[CPeak::dII] && -// pSavePeak->m_pLines[CPeak::dIV] && -// pPeak->m_pLines[CPeak::dII] == pSavePeak->m_pLines[CPeak::dIV]) -// { -// if (k == CCell::cIII) -// { -// pCellII = pSaveCell; -// pCellII->SetParameters(pPeak, CCell::cII); -// } -// else if (k == CCell::cIV) -// { -// pCellI = pSaveCell; -// pCellI->SetParameters(pPeak, CCell::cI); -// } -// } - -// if (pPeak->m_pLines[CPeak::dIII] && -// pSavePeak->m_pLines[CPeak::dI] && -// pPeak->m_pLines[CPeak::dIII] == pSavePeak->m_pLines[CPeak::dI]) -// { -// if (k == CCell::cI) -// { -// pCellII = pSaveCell; -// pCellII->SetParameters(pPeak, CCell::cII); -// } -// else if (k == CCell::cIV) -// { -// pCellIII = pSaveCell; -// pCellIII->SetParameters(pPeak, CCell::cIII); -// } -// } - -// if (pPeak->m_pLines[CPeak::dIV] && -// pSavePeak->m_pLines[CPeak::dII] && -// pPeak->m_pLines[CPeak::dIV] == pSavePeak->m_pLines[CPeak::dII]) -// { -// if (k == CCell::cI) -// { -// pCellIV = pSaveCell; -// pCellIV->SetParameters(pPeak, CCell::cIV); -// } -// else if (k == CCell::cII) -// { -// pCellIII = pSaveCell; -// pCellIII->SetParameters(pPeak, CCell::cIII); -// } -// } -// } -// } -// } - -// //Если ячейка еще не построена по заданным углам - создаем ячейку -// if (bIsI && bIsII) -// { -// if (!pCellI) -// { -// pCellI = new CCell(); -// pCellI->SetParameters(pPeak, CCell::cI); -// m_arCells.push_back(pCellI); -// } -// } -// if (bIsII && bIsIII) -// { -// if (!pCellII) -// { -// pCellII = new CCell(); -// pCellII->SetParameters(pPeak, CCell::cII); -// m_arCells.push_back(pCellII); -// } -// } -// if (bIsIII && bIsIV) -// { -// if (!pCellIII) -// { -// pCellIII = new CCell(); -// pCellIII->SetParameters(pPeak, CCell::cIII); -// m_arCells.push_back(pCellIII); -// } -// } -// if (bIsIV && bIsI) -// { -// if (!pCellIV) -// { -// pCellIV = new CCell(); -// pCellIV->SetParameters(pPeak, CCell::cIV); -// m_arCells.push_back(pCellIV); -// } -// } -// } - -// //удаляем использованные шейпы -// for (size_t i = 0; i < m_arShapes.size(); ++i) -// { -// if (m_arShapes[i]->m_bIsUseInTable) -// { -// m_arShapes[i]->m_bIsNotNecessaryToUse = true; -// } -// } -// } - -// void CPage::BuildRows() -// { -// //когда созданы все ячейки, собираем их в ряды -// for (size_t i = 0; i < m_arCells.size(); ++i) -// { -// auto pCell = m_arCells[i]; - -// if (pCell->m_bIsNotNecessaryToUse) -// { -// continue; -// } - -// SelectCurrentRow(pCell); -// m_pCurrentRow->RecalcWithNewItem(pCell); -// } - -// CBaseItem::SortByBaseline(m_arRows); -// for (size_t i = 0; i < m_arRows.size(); ++i) -// { -// CBaseItem::SortByLeft(m_arRows[i]->m_arCells); -// } -// } - -// void CPage::SelectCurrentRow(const CCell *pCell) -// { -// //логика аналогична AddContToTextLine -// //todo c_dTHE_SAME_STRING_Y_PRECISION_MM - возможно слишком мала -// if (nullptr == m_pCurrentRow) -// { -// auto pRow = new CRow(); -// m_pCurrentRow = pRow; -// m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; -// m_arRows.push_back(pRow); -// return; -// } - -// if (fabs(m_pCurrentRow->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) -// { -// return; -// } - -// for (size_t i = 0; i < m_arRows.size(); ++i) -// { -// if (fabs(m_arRows[i]->m_dBaselinePos - pCell->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) -// { -// m_pCurrentRow = m_arRows[i]; -// return; -// } -// } - -// auto pRow = new CRow(); -// m_pCurrentRow = pRow; -// m_pCurrentRow->m_dBaselinePos = pCell->m_dBaselinePos; -// m_arRows.push_back(pRow); -// return; -// } - void CPage::DetermineLinesType() { for (size_t i = 0; i < m_arShapes.size(); ++i) @@ -1218,7 +849,7 @@ namespace NSDocxRenderer pShape->m_eLineType != eLineType::ltUnknown; //Условие по вертикали - bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.3; + bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.5; //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 1089edc88b9..aaae98e012f 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -1,8 +1,7 @@ #pragma once -#include "../DesktopEditor/graphics/pro/Graphics.h" +#include "../../../DesktopEditor/graphics/pro/Graphics.h" #include "elements/Paragraph.h" #include "elements/Shape.h" -#include "elements/Table.h" #include "managers/FontStyleManager.h" #include "managers/ParagraphStyleManager.h" #include "styles/ParagraphStyle.h" @@ -41,13 +40,7 @@ namespace NSDocxRenderer std::vector> m_arOutputObjects; -// std::vector m_arPeaks; -// std::vector m_arCells; -// std::vector m_arRows; -// std::vector m_arTables; - CTextLine* m_pCurrentLine {nullptr}; -// CRow* m_pCurrentRow {nullptr}; TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; @@ -66,7 +59,6 @@ namespace NSDocxRenderer void BeginCommand(DWORD lType); void Clear(); - void ClearTables(); //удаляем то, что выходит за границы страницы void DeleteTextClipPage(); @@ -116,12 +108,6 @@ namespace NSDocxRenderer void AnalyzeShapes(); void DetermineLinesType(); -// void BuildTables(); -// void CollectPeaks(); -// void CreatCells(); -// void BuildRows(); -// void SelectCurrentRow(const CCell *pCell); - void BuildLines(); void DetermineDominantGraphics(); diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 6d00dbbf530..ba303ac6c2e 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,5 +1,5 @@ #pragma once -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" #include "src/resources/Constants.h" #include #include diff --git a/DocxRenderer/src/logic/elements/Cell.cpp b/DocxRenderer/src/logic/elements/Cell.cpp deleted file mode 100644 index 4c2beeb2578..00000000000 --- a/DocxRenderer/src/logic/elements/Cell.cpp +++ /dev/null @@ -1,186 +0,0 @@ -//#include "Cell.h" -//#include "Shape.h" - -//namespace NSDocxRenderer -//{ -// CCell::~CCell() -// { -// Clear(); -// } - -// void CCell::Clear() -// { -// m_arTextLines.clear(); -// for(size_t i = 0; i < m_arOutputObjects.size(); ++i) - -// m_arOutputObjects[i]->Clear(); -// m_arOutputObjects.clear(); -// } - -// void CCell::AddContent(CBaseItem* pItem) -// { -// CBaseItem::AddContent(pItem); -// m_arTextLines.push_back(dynamic_cast(pItem)); -// } - -// void CCell::ToXml(NSStringUtils::CStringBuilder &oWriter) const -// { -// oWriter.WriteString(L""); -// oWriter.WriteString(L""); -// oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); -// oWriter.WriteString(L"\" w:type=\"dxa\"/>"); - -// if (m_bIsvMergeStart) -// { -// oWriter.WriteString(L""); -// } -// else if (m_bIsvMerge) -// { -// oWriter.WriteString(L""); -// } - -// if (m_uGridSpan > 1) -// { -// oWriter.WriteString(L""); -// } -// if (!m_bIsTopBorder || !m_bIsLeftBorder || !m_bIsBottomBorder || -// !m_bIsRightBorder || m_bIsDiagonalDownBorder || m_bIsDiagonalUpBorder) -// { -// oWriter.WriteString(L""); -// if (!m_bIsTopBorder) -// { -// oWriter.WriteString(L""); -// } -// if (!m_bIsLeftBorder) -// { -// oWriter.WriteString(L""); -// } -// if (!m_bIsBottomBorder) -// { -// oWriter.WriteString(L""); -// } -// if (!m_bIsRightBorder) -// { -// oWriter.WriteString(L""); -// } -// if (m_bIsDiagonalDownBorder) -// { -// oWriter.WriteString(L""); -// } -// if (m_bIsDiagonalUpBorder) -// { -// oWriter.WriteString(L""); -// } - -// oWriter.WriteString(L""); -// } - -// oWriter.WriteString(L""); - -// if (m_arOutputObjects.empty()) -// { -// oWriter.WriteString(L""); -// } -// else -// { -// for (size_t i = 0; i < m_arOutputObjects.size(); ++i) -// { -// auto pObj = m_arOutputObjects[i]; - -// CParagraph* pParagraph = nullptr; -// if((pParagraph = dynamic_cast(pObj)) != nullptr) -// pParagraph->ToXml(oWriter); -// } -// } - -// oWriter.WriteString(L""); -// } - -// void CCell::SetParameters(CPeak* pPeak, eCorners eCorner) -// { -// m_pPeaks[eCorner] = pPeak; - -// switch (eCorner) -// { -// case cI: -// if (pPeak->m_pLines[CPeak::dI]) -// { -// m_bIsLeftBorder = true; - -// m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dBaselinePos = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// if (pPeak->m_pLines[CPeak::dII]) -// { -// m_bIsBottomBorder = true; - -// m_dLeft = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// break; -// case cII: -// if (pPeak->m_pLines[CPeak::dII]) -// { -// m_bIsRightBorder = true; - -// m_dRight = pPeak->m_pLines[CPeak::dII]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dBaselinePos = pPeak->m_pLines[CPeak::dII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// if (pPeak->m_pLines[CPeak::dIII]) -// { -// m_bIsBottomBorder = true; - -// m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; -// m_dBaselinePos = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// break; -// case cIII: -// if (pPeak->m_pLines[CPeak::dIV]) -// { -// m_bIsRightBorder = true; - -// m_dRight = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// if (pPeak->m_pLines[CPeak::dIII]) -// { -// m_bIsTopBorder = true; - -// m_dRight = pPeak->m_pLines[CPeak::dIII]->m_dRight - pPeak->m_pPeak->m_dWidth/2; -// m_dTop = pPeak->m_pLines[CPeak::dIII]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// break; -// case cIV: -// if (pPeak->m_pLines[CPeak::dIV]) -// { -// m_bIsLeftBorder = true; - -// m_dLeft = pPeak->m_pLines[CPeak::dIV]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dTop = pPeak->m_pLines[CPeak::dIV]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// if (pPeak->m_pLines[CPeak::dI]) -// { -// m_bIsTopBorder = true; - -// m_dLeft = pPeak->m_pLines[CPeak::dI]->m_dLeft + pPeak->m_pPeak->m_dWidth/2; -// m_dTop = pPeak->m_pLines[CPeak::dI]->m_dTop + pPeak->m_pPeak->m_dHeight/2; -// } -// break; -// default: -// break; -// } - -// if (m_dLeft != 0 && m_dRight != 0) -// { -// m_dWidth = m_dRight - m_dLeft; -// } - -// if (m_dTop != 0 && m_dBaselinePos != 0) -// { -// m_dHeight = m_dBaselinePos - m_dTop; -// } -// } -//} diff --git a/DocxRenderer/src/logic/elements/Cell.h b/DocxRenderer/src/logic/elements/Cell.h deleted file mode 100644 index edfb81436ec..00000000000 --- a/DocxRenderer/src/logic/elements/Cell.h +++ /dev/null @@ -1,87 +0,0 @@ -//#pragma once -//#include "Paragraph.h" - -//namespace NSDocxRenderer -//{ -// class CPeak -// { -// public: -// // -// // VI II V -// // | -// // III <- Peak -> I -// // | -// // VII IV VIII -// //note Направления V-VIII потребуются для реализации перечеркиваний ячек (m_bIsDiagonalDownBorder/m_bIsDiagonalUpBorder) -// enum eDirections -// { -// dI = 0, -// dII = 1, -// dIII = 2, -// dIV = 3, -// dV = 4, -// dVI = 5, -// dVII = 6, -// dVIII = 7, -// dNumDirections = 8 -// }; - -// public: -// CShape* const m_pPeak; //привязка к конкретному шейпу, определенному в качестве peak -// CShape* m_pLines[dNumDirections]; //сюда записываем линии/шейпы, которые подходят к peak с разных сторон - -// public: -// CPeak(CShape* pPeak) : m_pPeak(pPeak) {} -// }; - -// class CCell : public CBaseItem -// { -// public: -// //Corners -// // IV------III -// // | | -// // | Cell | -// // | | -// // I--------II -// //У каждой ячейки может быть только 4 угла ) -// enum eCorners -// { -// cI = 0, -// cII = 1, -// cIII = 2, -// cIV = 3, -// cNumCorners = 4 -// }; -// public: -// bool m_bIsvMergeStart {false}; -// bool m_bIsvMerge {false}; - -// bool m_bIsTopBorder {false}; -// bool m_bIsLeftBorder {false}; -// bool m_bIsBottomBorder {false}; -// bool m_bIsRightBorder {false}; - -// bool m_bIsDiagonalDownBorder {false}; -// bool m_bIsDiagonalUpBorder {false}; - -// UINT m_uGridSpan {1}; - -// CPeak *m_pPeaks[cNumCorners]; //сюда записываем peak, распределяя их по углам ячейки - -// //todo пока логика подразумевает, что в каждой ячейке создается новая линия с новыми символами -// //- дополнительное выделение памяти. Возможно нужно просто делать move. -// std::vector m_arTextLines; -// //todo Подразумевается, что здесь хранятся параграфы. Добавить реализацию вывода картинок в ToXml. -// //Возможно подойдет вывод из CShape::BuildPictureProperties -// std::vector m_arOutputObjects; - -// public: -// CCell() = default; -// virtual ~CCell(); -// virtual void Clear() override final; -// virtual void AddContent(CBaseItem* pItem) override final; -// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - -// void SetParameters(CPeak *pPeak, eCorners eCorner); -// }; -//} diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 4eca0859e87..8786ddb6900 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -71,7 +71,7 @@ namespace NSDocxRenderer return *this; } - void CContText::CalcSelected() noexcept + void CContText::CalcSelected() { if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { @@ -265,7 +265,7 @@ namespace NSDocxRenderer (std::shared_ptr& pFirstCont, std::shared_ptr& pSecondCont, eVerticalCrossingType eVType, - eHorizontalCrossingType eHType) noexcept + eHorizontalCrossingType eHType) { //Условие пересечения по вертикали bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext; //текущий cont выше @@ -345,10 +345,10 @@ namespace NSDocxRenderer } bool CContText::CheckVertAlignTypeBetweenConts - (std::shared_ptr& pFirstCont, - std::shared_ptr& pSecondCont, + (std::shared_ptr pFirstCont, + std::shared_ptr pSecondCont, eVerticalCrossingType eVType, - eHorizontalCrossingType eHType) noexcept + eHorizontalCrossingType eHType) { bool bIf1 = eVType == eVerticalCrossingType::vctCurrentAboveNext || diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index a97e774a5c0..752f05a76b1 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -1,6 +1,6 @@ #pragma once #include "BaseItem.h" -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" #include "../managers/FontManager.h" #include "../managers/FontStyleManager.h" #include "../../resources/Constants.h" @@ -46,17 +46,17 @@ namespace NSDocxRenderer eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; // highlights - bool m_bIsStrikeoutPresent {false}; - bool m_bIsDoubleStrikeout {false}; - bool m_bIsHighlightPresent {false}; - LONG m_lHighlightColor {c_iBlackColor}; - bool m_bIsUnderlinePresent {false}; - eLineType m_eUnderlineType {eLineType::ltUnknown}; - LONG m_lUnderlineColor {c_iBlackColor}; - bool m_bIsShadowPresent {false}; - bool m_bIsOutlinePresent {false}; - bool m_bIsEmbossPresent {false}; - bool m_bIsEngravePresent {false}; + bool m_bIsStrikeoutPresent{false}; + bool m_bIsDoubleStrikeout {false}; + bool m_bIsHighlightPresent{false}; + LONG m_lHighlightColor {c_iBlackColor}; + bool m_bIsUnderlinePresent{false}; + eLineType m_eUnderlineType{eLineType::ltUnknown}; + LONG m_lUnderlineColor {c_iBlackColor}; + bool m_bIsShadowPresent {false}; + bool m_bIsOutlinePresent {false}; + bool m_bIsEmbossPresent {false}; + bool m_bIsEngravePresent {false}; // sizes @@ -76,7 +76,7 @@ namespace NSDocxRenderer virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override final; // calc sizes in selected font (uses m_pFontStyle & m_pManager) - void CalcSelected() noexcept; + void CalcSelected(); CContText& operator=(const CContText& rCont); bool IsEqual(const CContText* pCont) const noexcept; @@ -90,13 +90,13 @@ namespace NSDocxRenderer (std::shared_ptr& pFirstCont, std::shared_ptr& pSecondCont, eVerticalCrossingType eVType, - eHorizontalCrossingType eHType) noexcept; + eHorizontalCrossingType eHType); static bool CheckVertAlignTypeBetweenConts - (std::shared_ptr& pFirstCont, - std::shared_ptr& pSecondCont, + (std::shared_ptr pFirstCont, + std::shared_ptr pSecondCont, eVerticalCrossingType eVType, - eHorizontalCrossingType eHType) noexcept; + eHorizontalCrossingType eHType); double CalculateWideSpace() const noexcept; double CalculateThinSpace() const noexcept; diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp index 6a9edf606c0..d523bf7a1bf 100644 --- a/DocxRenderer/src/logic/elements/DropCap.cpp +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -12,14 +12,6 @@ namespace NSDocxRenderer oWriter.AddInt(static_cast((m_dBaselinePos - m_dTop) * c_dMMToDx)); oWriter.WriteString(L"\" "); oWriter.WriteString(L"w:lineRule=\"exact\" />"); -// oWriter.WriteString(L""); -// oWriter.WriteString(L" w:x=\""); -// oWriter.AddInt(static_cast(m_dLeft * c_dMMToDx)); -// oWriter.WriteString(L"\" w:y=\""); -// oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); -// oWriter.WriteString(L"\" />"); oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); @@ -28,9 +20,6 @@ namespace NSDocxRenderer L"\" w:eastAsia=\"" + wsFont + L"\" w:cs=\"" + wsFont + L"\" />"); -// oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index aefd8469625..02f76e25293 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -11,11 +11,11 @@ namespace NSDocxRenderer std::wstring m_strPath {L""}; - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; + bool m_bIsNoFill{true}; + bool m_bIsNoStroke{true}; + bool m_bIsBehindDoc{true}; - double m_dRotate {0.0}; + double m_dRotate{0.0}; public: CImage() = default; diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 44d98ad1914..29e46d7d4e5 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -140,13 +140,16 @@ namespace NSDocxRenderer } } - CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(std::shared_ptr pCurrentLine, std::shared_ptr pNextLine, std::shared_ptr pNextNextLine, double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph) + CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(std::shared_ptr pCurrentLine, + std::shared_ptr pNextLine, + std::shared_ptr pNextNextLine, + double dPageWidth, + bool &bIsUseNextNextLine, + bool &bIsSingleLineParagraph) noexcept { // поменять логику if (!pCurrentLine || !pNextLine) - { return tatUnknown; - } double dCurrLeft = pCurrentLine->m_dLeft; double dNextLeft = pNextLine->m_dLeft; diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 298dfaf166f..95aaed48a7c 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -18,25 +18,24 @@ namespace NSDocxRenderer }; // text frame properties - bool m_bIsNeedFirstLineIndent {false}; - bool m_bIsShadingPresent {false}; - LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR - TextAlignmentType m_eTextAlignmentType {tatUnknown}; + bool m_bIsNeedFirstLineIndent{false}; + bool m_bIsShadingPresent {false}; + LONG m_lColorOfShadingFill {c_iWhiteColor}; //BGR + TextAlignmentType m_eTextAlignmentType {tatUnknown}; // geometry paragraph - double m_dLeftBorder {0.0}; //сдвиг относительно левого края страницы/шейпа/таблицы - double m_dRightBorder {0.0}; //сдвиг относительно правого края страницы/шейпа/таблицы - double m_dFirstLine {0.0}; //сдвиг относительно m_dLeftBorder + double m_dLeftBorder {0.0}; // сдвиг относительно левого края страницы/шейпа/таблицы + double m_dRightBorder{0.0}; // сдвиг относительно правого края страницы/шейпа/таблицы + double m_dFirstLine {0.0}; // сдвиг относительно m_dLeftBorder - double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before - double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after - double m_dLineHeight {0.0}; + double m_dSpaceBefore{0.0}; // по умолчанию выставляется 0, если отсутсвует w:before + double m_dSpaceAfter {0.0}; // в shape по умолчанию выставляется 8pt, если отсутсвует w:after + double m_dLineHeight {0.0}; std::vector> m_arLines; - size_t m_nNumLines {0}; - - std::wstring m_wsStyleId; + size_t m_nNumLines {0}; + std::wstring m_wsStyleId; public: CParagraph() : COutputObject(COutputObject::eOutputType::etParagraph) {} @@ -47,7 +46,11 @@ namespace NSDocxRenderer void RemoveHighlightColor(); void MergeLines(); - static TextAlignmentType DetermineTextAlignmentType(std::shared_ptr pCurrentLine, std::shared_ptr pNextLine, std::shared_ptr pNextNextLine, - double dPageWidth, bool &bIsUseNextNextLine, bool &bIsSingleLineParagraph); + static TextAlignmentType DetermineTextAlignmentType(std::shared_ptr pCurrentLine, + std::shared_ptr pNextLine, + std::shared_ptr pNextNextLine, + double dPageWidth, + bool &bIsUseNextNextLine, + bool &bIsSingleLineParagraph) noexcept; }; } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index aa8b3f632e3..4f0526c3273 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -1,5 +1,4 @@ #include "Shape.h" -#include "Table.h" #include "../../resources/Constants.h" #include "../../resources/utils.h" #include @@ -33,7 +32,7 @@ namespace NSDocxRenderer m_oVector.Clear(); } - UINT CShape::GenerateShapeId() const + UINT CShape::GenerateShapeId() { static UINT iId = 0; iId++; @@ -89,7 +88,7 @@ namespace NSDocxRenderer m_dRight = m_dLeft + m_dWidth; } - bool CShape::TryMergeShape(std::shared_ptr pShape) + bool CShape::TryMergeShape(std::shared_ptr& pShape) { // можно попробовать подбирать динамически, например в зависимости от размера double dHorNearby = 30; @@ -119,7 +118,7 @@ namespace NSDocxRenderer fabs(pShape->m_dLeft - this->m_dRight) < dHorNearby || // друг в друге тоже учитываем - fabs(pShape->m_dRight - this->m_dRight) <= dHorNearby || + fabs(pShape->m_dRight - this->m_dRight) < dHorNearby || fabs(pShape->m_dLeft - this->m_dLeft) < dHorNearby) && // недалеко друг от друга по вертикали @@ -130,7 +129,7 @@ namespace NSDocxRenderer fabs(pShape->m_dBaselinePos - this->m_dBaselinePos) < dVerNearby || fabs(pShape->m_dTop - this->m_dTop) < dVerNearby)) { - CBaseItem::RecalcWithNewItem(pShape.get()); + RecalcWithNewItem(pShape.get()); m_oVector.Join(std::move(pShape->m_oVector)); pShape = nullptr; @@ -216,7 +215,7 @@ namespace NSDocxRenderer return strPath; } - void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) + void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) noexcept { //note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста. if ((m_bIsNoStroke && m_bIsNoFill) || @@ -288,51 +287,6 @@ namespace NSDocxRenderer return m_eGraphicsType == pShape->m_eGraphicsType; } - void CShape::RecalcWithNewItem(const CBaseItem* pObj) - { - if(!pObj) - return; - - const CShape* shape = dynamic_cast(pObj); - if(!shape) - { - CBaseItem::RecalcWithNewItem(pObj); - return; - } - - if(m_dTop == shape->m_dTop || - (m_dTop < shape->m_dTop && m_dHeight > shape->m_dHeight) || - (m_dTop > shape->m_dTop && m_dHeight < shape->m_dHeight)) - { - m_dHeight = std::max(m_dHeight, shape->m_dHeight); - } - else if(m_dTop < shape->m_dTop) - m_dHeight += shape->m_dHeight + shape->m_dTop - m_dBaselinePos; - else - m_dHeight += shape->m_dHeight + shape->m_dBaselinePos - m_dTop; - - if(m_dLeft == shape->m_dLeft || - (m_dLeft < shape->m_dLeft && m_dRight > shape->m_dRight) || - (m_dLeft > shape->m_dLeft && m_dRight < shape->m_dRight)) - { - m_dWidth = std::max(m_dWidth, shape->m_dWidth); - } - else if(m_dLeft < shape->m_dLeft) - m_dWidth += shape->m_dWidth + shape->m_dLeft - m_dRight; - else - m_dWidth += shape->m_dWidth + shape->m_dRight - m_dLeft; - - // m_dWidth иногда меняет знак на "-" - m_dHeight = fabs(m_dHeight); - m_dWidth = fabs(m_dWidth); - - m_dLeft = std::min(m_dLeft, shape->m_dLeft); - m_dTop = std::min(m_dTop, shape->m_dTop); - - m_dBaselinePos = m_dTop + m_dHeight; - m_dRight = m_dLeft + m_dWidth; - } - bool CShape::IsPeak() const noexcept { return m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltVDot; @@ -343,7 +297,7 @@ namespace NSDocxRenderer return m_eSimpleLineType == eSimpleLineType::sltHLongDash || m_eSimpleLineType == eSimpleLineType::sltVLongDash; } - void CShape::CheckLineType(std::shared_ptr& pFirstShape) noexcept + void CShape::CheckLineType(std::shared_ptr& pFirstShape) { if(!pFirstShape) return; @@ -354,7 +308,7 @@ namespace NSDocxRenderer else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave) pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave; } - void CShape::CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast) noexcept + void CShape::CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast) { if(!pFirstShape || !pSecondShape) return; diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 6cc68a568f7..edaaf0c16e4 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -31,31 +31,30 @@ namespace NSDocxRenderer }; public: - eShapeType m_eType {eShapeType::stUnknown}; - CVectorGraphics m_oVector; - std::wstring m_strDstMedia; - NSStructures::CBrush m_oBrush; - NSStructures::CPen m_oPen; - double m_dRotate {0.0}; - - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; + eShapeType m_eType {eShapeType::stUnknown}; + + NSStructures::CBrush m_oBrush{}; + NSStructures::CPen m_oPen {}; + + CVectorGraphics m_oVector {}; + std::wstring m_strDstMedia {}; - bool m_bIsUseInTable {false}; + double m_dRotate {0.0}; + + bool m_bIsNoFill {true}; + bool m_bIsNoStroke {true}; + bool m_bIsBehindDoc {true}; + bool m_bIsUseInTable{false}; - eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; - eSimpleLineType m_eSimpleLineType {eSimpleLineType::sltUnknown}; - eLineType m_eLineType {eLineType::ltUnknown}; + eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; + eSimpleLineType m_eSimpleLineType{eSimpleLineType::sltUnknown}; + eLineType m_eLineType {eLineType::ltUnknown}; std::vector> m_arOutputObjects; - std::shared_ptr m_pImageInfo {nullptr}; + std::shared_ptr m_pImageInfo{nullptr}; private: - UINT m_nShapeId {0}; - UINT m_nRelativeHeight {0}; - static UINT m_gRelativeHeight; public: CShape(); @@ -63,14 +62,14 @@ namespace NSDocxRenderer virtual ~CShape(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - virtual void RecalcWithNewItem(const CBaseItem* pObj) override final; void SetVector(CVectorGraphics&& oVector); // tries merge shape, return true if ok and pShape was deleted - bool TryMergeShape(std::shared_ptr pShape); + bool TryMergeShape(std::shared_ptr& pShape); + std::wstring PathToWString() const; - void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves); + void DetermineGraphicsType(double dWidth, double dHeight, size_t nPeacks, size_t nCurves) noexcept; bool IsItFitLine() const noexcept; bool IsCorrelated(std::shared_ptr pShape) const noexcept; @@ -91,12 +90,16 @@ namespace NSDocxRenderer // check type of line and delete not needed shape // one shape in line - static void CheckLineType(std::shared_ptr& pShape) noexcept; + static void CheckLineType(std::shared_ptr& pShape); // many shapes in line - static void CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast = false) noexcept; + static void CheckLineType(std::shared_ptr& pFirstShape, std::shared_ptr& pSecondShape, bool bIsLast = false); private: - UINT GenerateShapeId() const; + UINT m_nShapeId{0}; + UINT m_nRelativeHeight{0}; + + static UINT m_gRelativeHeight; + static UINT GenerateShapeId(); }; } diff --git a/DocxRenderer/src/logic/elements/Table.cpp b/DocxRenderer/src/logic/elements/Table.cpp deleted file mode 100644 index 27065c05716..00000000000 --- a/DocxRenderer/src/logic/elements/Table.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//#include "Table.h" - -//namespace NSDocxRenderer -//{ -// CRow::~CRow() -// { -// Clear(); -// } - -// void CRow::Clear() -// { -// m_arCells.clear(); -// } - -// void CRow::AddContent(CBaseItem* pItem) -// { -// CBaseItem::AddContent(pItem); -// m_arCells.push_back(dynamic_cast(pItem)); -// } - -// CTable::~CTable() -// { -// Clear(); -// } - -// void CTable::Clear() -// { -// m_arRows.clear(); -// } - -// void CTable::AddContent(CBaseItem* pItem) -// { -// CBaseItem::AddContent(pItem); -// m_arRows.push_back(dynamic_cast(pItem)); -// } - -// void CTable::ToXml(NSStringUtils::CStringBuilder &oWriter) const -// { -// if (m_bIsNotNecessaryToUse) -// { -// return; -// } - -// oWriter.WriteString(L""); - -// oWriter.WriteString(L""); -// oWriter.WriteString(L""); - -// if (m_bIsNeedSpacing) -// { -// oWriter.WriteString(L" 0) -// { -// oWriter.WriteString(L" w:before=\""); -// oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); -// oWriter.WriteString(L"\""); -// } - -// if (m_dSpaceAfter > 0) -// { -// oWriter.WriteString(L" w:after=\""); -// oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); -// oWriter.WriteString(L"\""); -// } - -// if (m_dLineHeight > 0) -// { -// oWriter.WriteString(L" w:line=\""); -// oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); -// oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки -// } -// oWriter.WriteString(L"/>"); //конец w:spacing - -// oWriter.WriteString(L""); -// oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); -// oWriter.WriteString(L"\" w:type=\"dxa\"/>"); -// } -// else -// { -// oWriter.WriteString(L"(m_dLeft * c_dMMToDx)); -// oWriter.WriteString(L"\" w:tblpY=\""); -// oWriter.AddInt(static_cast(m_dTop * c_dMMToDx)); -// oWriter.WriteString(L"\"/>"); -// } - -// oWriter.WriteString(L"(m_dWidth * c_dMMToDx)); -// oWriter.WriteString(L"\" w:type=\"auto\"/>"); - -// oWriter.WriteString(L""); -// oWriter.WriteString(L""); - -// oWriter.WriteString(L""); -// for (size_t i = 0; i < m_arColumnWidths.size(); ++i) -// { -// oWriter.WriteString(L""); -// } -// oWriter.WriteString(L""); - -// for (size_t nRow = 0; nRow < m_arRows.size(); ++nRow) -// { -// auto pRow = m_arRows[nRow]; - -// oWriter.WriteString(L""); - -// oWriter.WriteString(L""); -// oWriter.WriteString(L"m_dHeight * c_dMMToDx); -// oWriter.WriteString(L"\"/>"); -// oWriter.WriteString(L""); - -// for (size_t j = 0; j < pRow->m_arCells.size(); ++j) -// { -// pRow->m_arCells[j]->ToXml(oWriter); -// } - -// oWriter.WriteString(L""); -// } - -// oWriter.WriteString(L""); -// } - -// //note: для полной таблицы, составляющей в сумме ячеек прямоугольник -// void CTable::CalculateColumnWidth() -// { -// m_arColumnWidths.clear(); - -// if (m_arRows.empty()) -// { -// return; -// } - -// //todo пока работает с простыми таблицами, где ширины ячеек по всем рядам совпадают -// //if (m_arRows.size() == 1) -// { -// for (size_t i = 0; i < m_arRows.front()->m_arCells.size(); ++i) -// { -// m_arColumnWidths.push_back(m_arRows.front()->m_arCells[i]->m_dWidth); -// } -// return; -// } - -// double dMinWidth = 0; -// double dCurrLeftBorder = m_dLeft; //начальное состояние равно левому краю таблицы -// CCell* pCurrCellWithMinWidth = nullptr; - -// //todo Доработать логику для сложных таблиц, где ширины ячеек по всем рядам могут не совпадать -// //заполняем m_arColumnWidths пока dCurrLeftBorder не сравняется с правым краем таблицы -// while(dCurrLeftBorder < m_dRight/* && fabs(dCurrLeftBorder - m_dRight) > c_dGRAPHICS_ERROR_MM*/) //где-то тут ошибка! -// { -// //находим минимальный width после текущей dCurrLeftBorder -// for (size_t i = 0; i < m_arRows.size(); ++i) -// { -// for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) -// { -// auto pCell = m_arRows[i]->m_arCells[j]; - -// if (dCurrLeftBorder < pCell->m_dRight && fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM) -// { -// if (pCell->m_dRight - dCurrLeftBorder < dMinWidth || dMinWidth == 0) -// { -// dMinWidth = pCell->m_dRight - dCurrLeftBorder; -// pCurrCellWithMinWidth = pCell; -// } -// break; -// } -// } -// } - -// m_arColumnWidths.push_back(pCurrCellWithMinWidth->m_dWidth); - -// //увеличиваем GridSpan для ячеек между dCurrLeftBorder и правым краем текущей минимальной ячейки -// for (size_t i = 0; i < m_arRows.size(); ++i) -// { -// for (size_t j = 0; m_arRows[i]->m_arCells.size(); ++j) -// { -// auto pCell = m_arRows[i]->m_arCells[j]; - -// if (dCurrLeftBorder < pCell->m_dRight && -// fabs(dCurrLeftBorder - pCell->m_dRight) > c_dGRAPHICS_ERROR_MM && -// pCell->m_dRight > pCurrCellWithMinWidth->m_dRight && -// fabs(pCell->m_dRight - pCurrCellWithMinWidth->m_dRight) > c_dGRAPHICS_ERROR_MM) -// { -// ++pCell->m_uGridSpan; -// break; -// } -// } -// } - -// //сдвигаем dCurrLeftBorder -// dCurrLeftBorder = pCurrCellWithMinWidth->m_dRight; -// } -// } -//} diff --git a/DocxRenderer/src/logic/elements/Table.h b/DocxRenderer/src/logic/elements/Table.h deleted file mode 100644 index 13b05c150df..00000000000 --- a/DocxRenderer/src/logic/elements/Table.h +++ /dev/null @@ -1,43 +0,0 @@ -//#pragma once -//#include "Cell.h" - -//namespace NSDocxRenderer -//{ -// class CRow : public CBaseItem -// { -// public: -// std::vector m_arCells; - -// public: -// CRow() = default; -// virtual ~CRow(); -// virtual void Clear() override final; -// virtual void AddContent(CBaseItem* pObj) override final; -// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final {} -// }; - -// class CTable : public COutputObject -// { -// public: -// std::vector m_arColumnWidths; //общее количество колонок в таблице -// std::vector m_arRows; - -// double m_dSpaceBefore {0.0}; //по умолчанию выставляется 0, если отсутсвует w:before -// double m_dSpaceAfter {0.0}; //в shape по умолчанию выставляется 8pt, если отсутсвует w:after -// double m_dLineHeight {0.0}; -// bool m_bIsNeedSpacing {false}; - -// public: -// CTable() = default; -// virtual ~CTable(); -// virtual void Clear() override final; -// virtual void AddContent(CBaseItem* pItem) override final; -// virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - -// double CalculateBeforeSpacing(double dPreviousStringBaseline) -// { -// return m_dTop - dPreviousStringBaseline; -// } -// void CalculateColumnWidth(); -// }; -//} diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 3a6d04c9893..ba552a7add0 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -160,11 +160,12 @@ namespace NSDocxRenderer m_eVertAlignType = oType; for (size_t i = 0; i < m_arConts.size(); ++i) { - m_arConts[i]->m_eVertAlignType = oType; + if(m_arConts[i]) + m_arConts[i]->m_eVertAlignType = oType; } } - bool CTextLine::IsShadingPresent(const CTextLine *pLine) + bool CTextLine::IsShadingPresent(const CTextLine *pLine) const noexcept { return (m_pDominantShape && pLine->m_pDominantShape && m_pDominantShape->m_oBrush.Color1 == pLine->m_pDominantShape->m_oBrush.Color1 && diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 63ad38ff692..02f28b08832 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -19,11 +19,11 @@ namespace NSDocxRenderer std::vector> m_arConts; - AssumedTextAlignmentType m_eAlignmentType {atatUnknown}; - eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + AssumedTextAlignmentType m_eAlignmentType{atatUnknown}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - std::shared_ptr m_pLine {nullptr}; //Если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - std::shared_ptr m_pDominantShape {nullptr}; + std::shared_ptr m_pLine {nullptr}; // если не nullptr, то есть привязка к vatSubscript или vatSuperscript; + std::shared_ptr m_pDominantShape {nullptr}; UINT m_iNumDuplicates {0}; @@ -34,11 +34,10 @@ namespace NSDocxRenderer virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void AddCont(std::shared_ptr pCont); - void MergeConts(); void RecalcSizes(); void SetVertAlignType(const eVertAlignType& oType); - bool IsShadingPresent(const CTextLine* pLine); + bool IsShadingPresent(const CTextLine* pLine) const noexcept; bool IsCanBeDeleted() const; }; } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 08ad8ae4ede..42f49770eb3 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -1,7 +1,7 @@ #include "FontManager.h" #include "../../resources/Constants.h" -#include "../DesktopEditor/xml/include/xmlutils.h" -#include "../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/xml/include/xmlutils.h" +#include "../../../../DesktopEditor/common/Directory.h" namespace NSDocxRenderer { diff --git a/DocxRenderer/src/logic/managers/FontManager.h b/DocxRenderer/src/logic/managers/FontManager.h index 62ba79d8812..04f440aeca0 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -2,9 +2,9 @@ #include #include -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" -#include "../DesktopEditor/common/StringUTF32.h" +#include "../../../../DesktopEditor/graphics/structures.h" +#include "../../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../../DesktopEditor/common/StringUTF32.h" namespace NSDocxRenderer { @@ -44,14 +44,14 @@ namespace NSDocxRenderer struct CFontSelectParams { // изначальные параметры, которые могут быть нам известны - std::wstring wsDefaultName {L""}; - bool bDefaultBold {false}; - bool bDefaultItalic {false}; + std::wstring wsDefaultName{L""}; + bool bDefaultBold{false}; + bool bDefaultItalic{false}; - SHORT lAvgWidth {-1}; - bool bIsFixedWidth {false}; + SHORT lAvgWidth{-1}; + bool bIsFixedWidth{false}; - BYTE arPANOSE[10] {}; + BYTE arPANOSE[10]{}; std::vector arSignature; CFontSelectParams() = default; diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index fbdfc0a012d..5cc7bc7c899 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -1,5 +1,5 @@ #include "ImageManager.h" -#include "../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/common/Directory.h" namespace NSDocxRenderer { diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index 8e63e12344c..9809542d876 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -1,6 +1,6 @@ #pragma once -#include "../DesktopEditor/common/CalculatorCRC32.h" -#include "../DesktopEditor/raster/BgraFrame.h" +#include "../../../../DesktopEditor/common/CalculatorCRC32.h" +#include "../../../../DesktopEditor/raster/BgraFrame.h" #include "../../resources/ImageInfo.h" #include #include diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index ec388534d3f..f0df1ab9d38 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -1,8 +1,8 @@ #pragma once #include -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/graphics/structures.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/styles/ParagraphStyle.h b/DocxRenderer/src/logic/styles/ParagraphStyle.h index 8c4b6071dce..9cbe775da96 100644 --- a/DocxRenderer/src/logic/styles/ParagraphStyle.h +++ b/DocxRenderer/src/logic/styles/ParagraphStyle.h @@ -1,7 +1,7 @@ #pragma once -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/graphics/structures.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" namespace NSDocxRenderer { diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index 9d23e91c68c..ba529bdf3ce 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -1,5 +1,5 @@ #pragma once -#include "../DesktopEditor/common/Types.h" +#include "../../../DesktopEditor/common/Types.h" #define USING_DELETE_DUPLICATING_CONTS 0 // 0 - все сточки-дубликаты превращаются в shape, 1 - строчки дубликаты удаляются diff --git a/DocxRenderer/src/resources/ImageInfo.h b/DocxRenderer/src/resources/ImageInfo.h index 4425ebe2c22..48e4f195529 100644 --- a/DocxRenderer/src/resources/ImageInfo.h +++ b/DocxRenderer/src/resources/ImageInfo.h @@ -1,6 +1,6 @@ #pragma once #include -#include "../DesktopEditor/common/Types.h" +#include "../../../DesktopEditor/common/Types.h" namespace NSDocxRenderer { diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index f933971a161..d1055e19d41 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,6 +1,6 @@ #pragma once -#include "../DesktopEditor/common/Types.h" -#include "../DesktopEditor/common/StringUTF32.h" +#include "../../../DesktopEditor/common/Types.h" +#include "../../../DesktopEditor/common/StringUTF32.h" inline LONG ConvertColorBGRToRGB(LONG lBGR) { From 21d8353cdca97078677b31bc1216ade5c8cabd35 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 3 Nov 2023 13:00:11 +0300 Subject: [PATCH 176/794] Fix bug with highlighting --- DocxRenderer/src/logic/Page.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index ab2a04e72f2..6bc6c607c52 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -725,14 +725,14 @@ namespace NSDocxRenderer if (!shape || shape->m_eGraphicsType == eGraphicsType::gtNoGraphics) continue; + bool shape_used = false; + for (size_t j = 0; j < m_arTextLines.size(); ++j) { if(!shape) break; auto& pCurrLine = m_arTextLines[j]; - bool shape_used = false; - if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(shape.get()) && (pCurrLine->m_dTop > shape->m_dBaselinePos || pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < shape->m_dTop))) @@ -811,9 +811,9 @@ namespace NSDocxRenderer } } } - if(shape_used) - shape = nullptr; } + if(shape_used) + shape = nullptr; } } From 07b33be69a9c8dbf4e636b92168080a7bbfbbdae Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 6 Nov 2023 15:49:29 +0300 Subject: [PATCH 177/794] Fix bug - shared -> wear ptrs - fix bug with sort --- DocxRenderer/src/logic/Page.cpp | 44 +++++++++++++------- DocxRenderer/src/logic/Page.h | 2 +- DocxRenderer/src/logic/elements/ContText.cpp | 2 - DocxRenderer/src/logic/elements/ContText.h | 2 +- DocxRenderer/src/logic/elements/TextLine.cpp | 3 +- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 6bc6c607c52..3a1f43cdda1 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -351,11 +351,7 @@ namespace NSDocxRenderer pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); - // собираем отдельно, т.к. такие символы не имеют размера m_dWidth - if (nCount == 1 && IsDiacriticalMark(*pUnicodes)) - m_arDiacriticalSymbols.push_back(pCont); - else - m_arConts.push_back(pCont); + m_arConts.push_back(pCont); } void CPage::AddContToTextLine(std::shared_ptr pCont) @@ -393,6 +389,9 @@ namespace NSDocxRenderer void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) { + // build m_arDiacriticalSymbols + BuildDiacriticalSymbols(); + // build text lines from m_arConts BuildTextLines(); @@ -413,21 +412,34 @@ namespace NSDocxRenderer // calc sizes on selected fonts for m_arConts CalcSelected(); + ToXml(oWriter); WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } + void CPage::BuildDiacriticalSymbols() + { + for(size_t i = 0; i < m_arConts.size(); i++) + if(m_arConts[i] && m_arConts[i]->m_oText.length() == 1 && IsDiacriticalMark(m_arConts[i]->m_oText[0])) + m_arDiacriticalSymbols.push_back(std::move(m_arConts[i])); + + } void CPage::BuildTextLines() { using cont_ptr = std::shared_ptr; std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + if(!a) return false; + if(!b) return true; + if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) return a->m_dLeft < b->m_dLeft; + return a->m_dBaselinePos < b->m_dBaselinePos; }); - for(auto&& cont : m_arConts) - AddContToTextLine(cont); + for(auto& cont : m_arConts) + if(cont) + AddContToTextLine(std::move(cont)); } void CPage::MergeShapes() @@ -450,8 +462,11 @@ namespace NSDocxRenderer void CPage::CalcSelected() { - for(auto& cont : m_arConts) - cont->CalcSelected(); + for(auto& line : m_arTextLines) + if(line) + for(auto& cont : line->m_arConts) + if(cont) + cont->CalcSelected(); } void CPage::AnalyzeShapes() @@ -525,7 +540,6 @@ namespace NSDocxRenderer void CPage::AnalyzeTextLines() { // вся логика основана на отсортированных списках объектов - using line_ptr = std::shared_ptr; std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr& a, const line_ptr& b) { return a->m_dBaselinePos < b->m_dBaselinePos; @@ -977,8 +991,8 @@ namespace NSDocxRenderer using cont_ptr = std::shared_ptr; std::sort(pBaseLine->m_arConts.begin(), pBaseLine->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { - if(!a || !b) - return false; + if(!a) return false; + if(!b) return true; return a->m_dLeft < b->m_dLeft; }); @@ -1007,8 +1021,8 @@ namespace NSDocxRenderer using cont_ptr = std::shared_ptr; std::sort(line->m_arConts.begin(), line->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { - if(!a || !b) - return false; + if(!a) return false; + if(!b) return true; return a->m_dLeft < b->m_dLeft; }); pSubLine = nullptr; @@ -1090,7 +1104,7 @@ namespace NSDocxRenderer if (pCurrCont->m_iNumDuplicates > 0) pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); } - pCurrLine->MergeConts(); + pCurrLine->MergeConts(); } DetermineDominantGraphics(); } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index aaae98e012f..942b71b6bc9 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -88,9 +88,9 @@ namespace NSDocxRenderer private: // methods to build text lines + void BuildDiacriticalSymbols(); void BuildTextLines(); void AddContToTextLine(std::shared_ptr pCont); - void AddContToTextLine(std::shared_ptr&& pCont); void AnalyzeTextLines(); void AnalyzeConts(); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 8786ddb6900..672e149ee9c 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -35,9 +35,7 @@ namespace NSDocxRenderer CContText& CContText::operator= (const CContText& rCont) { if (this == &rCont) - { return *this; - } CBaseItem::operator=(rCont); diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 752f05a76b1..141490fef5f 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -42,7 +42,7 @@ namespace NSDocxRenderer std::shared_ptr m_pShape {nullptr}; // super/sub script - std::shared_ptr m_pCont {nullptr}; + std::weak_ptr m_pCont {}; eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; // highlights diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index ba552a7add0..384ea96451f 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -67,7 +67,6 @@ namespace NSDocxRenderer wide_space->m_oText = L" "; wide_space->m_pFontStyle = pFirst->m_pFontStyle; wide_space->m_pShape = nullptr; - wide_space->m_pCont = nullptr; wide_space->m_iNumDuplicates = 0; wide_space->CalcSelected(); }; @@ -104,7 +103,7 @@ namespace NSDocxRenderer pFirst->m_dWidth = pCurrent->m_dRight - pFirst->m_dLeft; pFirst->m_dRight = pCurrent->m_dRight; - if (!pFirst->m_pCont) + if (pFirst->m_pCont.expired()) { pFirst->m_pCont = pCurrent->m_pCont; pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; From e5a4ea21b0aae030f867cc5242831cee928617ed Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 6 Nov 2023 17:19:48 +0300 Subject: [PATCH 178/794] Fix move --- DocxRenderer/src/logic/Page.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 3a1f43cdda1..b40b4389609 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -439,7 +439,7 @@ namespace NSDocxRenderer for(auto& cont : m_arConts) if(cont) - AddContToTextLine(std::move(cont)); + AddContToTextLine(cont); } void CPage::MergeShapes() From 3a17ce21efd69140d4fa1281e4c38680caafc139 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Wed, 8 Nov 2023 17:24:09 +0300 Subject: [PATCH 179/794] Reworking of the CElementOperator class, reworking of some part of the conversion, tests --- .../StarMath2OOXML/TestSMConverter/main.cpp | 98 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 270 ++--- .../StarMath2OOXML/cconversionsmtoooxml.h | 37 +- .../StarMath2OOXML/cstarmathpars.cpp | 998 +++++++++++------- .../Converter/StarMath2OOXML/cstarmathpars.h | 137 ++- .../Converter/StarMath2OOXML/typeselements.h | 27 + 6 files changed, 874 insertions(+), 693 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index ff0774672ee..7369496324f 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -6,154 +6,140 @@ TEST(SMConvectorTest, BinOperatorPlus) { - std::wstring wsBinOperatorPlus = L"2 + 3"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"2 + 3"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"2+3"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorOver) { - std::wstring wsBinOperatorPlus = L"2 over 3"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"2 over 3"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"23"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorCdot) { - std::wstring wsBinOperatorPlus = L"5 cdot 8"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"5 cdot 8"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"5\u00B78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorTimes) { - std::wstring wsBinOperatorPlus = L"5 times 8"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"5 times 8"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"5\u00D78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorMultipl) { - std::wstring wsBinOperatorPlus = L"4 * 2"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"4 * 2"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"4*2"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorDiv) { - std::wstring wsBinOperatorPlus = L"4div2"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"4div2"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"4\u00F72"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorDivision) { - std::wstring wsBinOperatorPlus = L"4/2"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"4/2"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"42"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorOplus) { - std::wstring wsBinOperatorPlus = L"226oplus179"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"226oplus179"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"226\u2295179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorOdot) { - std::wstring wsBinOperatorPlus = L"226 odot 179"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"226 odot 179"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"226\u2299179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,BinOperatorOtimes) { - std::wstring wsBinOperatorPlus = L"226 otimes 179"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsBinOperator = L"226 otimes 179"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); std::wstring XmlString = L"226\u2297179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,OperatorSum) { - std::wstring wsBinOperatorPlus = L"sum 5"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsOperator = L"sum 5"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); std::wstring XmlString = L"5"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,OperatorSumFrom) { - std::wstring wsBinOperatorPlus = L"sum from 10 5"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsOperator = L"sum from 10 5"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,OperatorSumTo) { - std::wstring wsBinOperatorPlus = L"sum to 10 5"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsOperator = L"sum to 10 5"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } TEST(SMConvectorTest,OperatorSumFromTo) { - std::wstring wsBinOperatorPlus = L"sum from 666 to 777 567"; - StarMath::CStarMathPars m_oTempO; - m_oTempO.Pars(wsBinOperatorPlus); + std::wstring wsOperator = L"sum from 666 to 777 567"; + StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; - m_oTest.StartConversion(m_oTempO.GetVector()); + m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); std::wstring XmlString = L"666777567"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index fcb9c297fbe..b71ecf436db 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -1,228 +1,114 @@ #include "cconversionsmtoooxml.h" #include "../../../../DesktopEditor/common/File.h" #include -/*namespace StarMath { +namespace StarMath { CConversionSMtoOOXML::CConversionSMtoOOXML() { } void CConversionSMtoOOXML::StartConversion(std::vector arPars) { - m_oXmlWrite.WriteNodeBegin(L"m:oMathPara",false); - m_oXmlWrite.WriteNodeBegin(L"m:oMath",false); - for(CElement* m_oTempElement:arPars) + m_oXmlWrite = new XmlUtils::CXmlWriter; + m_oXmlWrite->WriteNodeBegin(L"m:oMathPara",false); + m_oXmlWrite->WriteNodeBegin(L"m:oMath",false); + for(CElement* oTempElement:arPars) { - ConversionOneElement(m_oTempElement); + oTempElement->ConversionToOOXML(m_oXmlWrite); } EndConversion(); - NSFile::CFileBinary oFile; - oFile.CreateFileW(L"Test.txt"); - oFile.WriteStringUTF8(m_oXmlWrite.GetXmlString()); - oFile.CloseFile(); +// NSFile::CFileBinary oFile; +// oFile.CreateFileW(L"Test.txt"); +// oFile.WriteStringUTF8(m_oXmlWrite->GetXmlString()); +// oFile.CloseFile(); } - void CConversionSMtoOOXML::ConversionOneElement(CElement *m_oElement) + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* oXmlWrite) { - switch (m_oElement->GetType()) - { - case Text: - ConversText(dynamic_cast(m_oElement)); - break; - case BinOperator: - ConversBinOperator(dynamic_cast (m_oElement)); - break; - case Operator: - ConversOperator(dynamic_cast (m_oElement)); - break; - default: - break; - } - } - void CConversionSMtoOOXML::ConversBinOperator(CBinaryOperator *m_oElement) - { - if(m_oElement->GetTypeBin() == plus || m_oElement->GetTypeBin() == minus || m_oElement->GetTypeBin() == multipl || m_oElement->GetTypeBin() == cdot || m_oElement->GetTypeBin() == times || m_oElement->GetTypeBin() == div || m_oElement->GetTypeBin() == odivide || m_oElement->GetTypeBin() == oplus || m_oElement->GetTypeBin() == ominus || m_oElement->GetTypeBin() == odot || m_oElement->GetTypeBin() == otimes) - { - ConversionOneElement(m_oElement->GetFirstElement()); - m_oXmlWrite.WriteNodeBegin(L"m:r",false); - StandartProperties(); - m_oXmlWrite.WriteNodeBegin(L"m:t",false); - switch (m_oElement->GetTypeBin()) - { - case plus: m_oXmlWrite.WriteString(L"+");break; - case minus: - m_oXmlWrite.WriteString(L"-"); - break; - case multipl: - m_oXmlWrite.WriteString(L"*"); - break; - case cdot: - m_oXmlWrite.WriteString(L"\u00B7"); - break; - case times: - m_oXmlWrite.WriteString(L"\u00D7"); - break; - case div: - m_oXmlWrite.WriteString(L"\u00F7"); - break; - case odivide: - m_oXmlWrite.WriteString(L"\u2298"); - break; - case oplus: - m_oXmlWrite.WriteString(L"\u2295"); - break; - case ominus: - m_oXmlWrite.WriteString(L"\u2296"); - break; - case odot: - m_oXmlWrite.WriteString(L"\u2299"); - break; - case otimes: - m_oXmlWrite.WriteString(L"\u2297"); - break; - default: - break; - } - if(m_oElement->GetTypeSecondElement() == Text) - { - CText* m_oNumber = dynamic_cast (m_oElement->GetSecondElement()); - m_oXmlWrite.WriteString(m_oNumber->GetValue()); - m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); - } - else - { - m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); - ConversionOneElement(m_oElement->GetSecondElement()); - } - - } - else if(m_oElement->GetTypeBin() == over || m_oElement->GetTypeBin() == division) - { - m_oXmlWrite.WriteNodeBegin(L"m:f",false); - if(m_oElement->GetTypeBin() == division) PropertiesMFPR(true,L"lin"); - else PropertiesMFPR(false,L""); - BlockRecording(L"m:num",m_oElement->GetFirstElement()); - BlockRecording(L"m:den",m_oElement->GetSecondElement()); - m_oXmlWrite.WriteNodeEnd(L"m:f",false,false); - } + oXmlWrite->WriteNodeBegin(L"w:rPr",false); + oXmlWrite->WriteNodeBegin(L"w:rFonts",true); + oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"w:sz",true); + oXmlWrite->WriteAttribute(L"w:val",L"40"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"w:szCs",true); + oXmlWrite->WriteAttribute(L"w:val",L"40"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); } - void CConversionSMtoOOXML::ConversText(CText *m_oElement) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* oXmlWrite) { - m_oXmlWrite.WriteNodeBegin(L"m:r",false); - StandartProperties(); - m_oXmlWrite.WriteNodeBegin(L"m:t",false); - m_oXmlWrite.WriteString(m_oElement->GetValue()); - m_oXmlWrite.WriteNodeEnd(L"m:t",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); - } - void CConversionSMtoOOXML::ConversOperator(COperator *m_oElement) - { - if(m_oElement->GetTypeOp() == sum) - { - m_oXmlWrite.WriteNodeBegin(L"m:nary",false); - PropertiesNaryPr(L"\u2211",nullptr == m_oElement->GetFrom(),nullptr == m_oElement->GetTo()); - if(m_oElement->GetFrom() == nullptr) m_oXmlWrite.WriteNode(L"m:sub",L""); - else - { - BlockRecording(L"m:sub",m_oElement->GetFrom()); - } - if(m_oElement->GetTo() == nullptr) m_oXmlWrite.WriteNode(L"m:sup",L""); - else - { - BlockRecording(L"m:sup",m_oElement->GetTo()); - } - BlockRecording(L"m:e",m_oElement->GetValueOp()); - m_oXmlWrite.WriteNodeEnd(L"m:nary",false,false); - } - } - void CConversionSMtoOOXML::StandartProperties() - { - m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); - m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); - m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); - m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeBegin(L"w:sz",true); - m_oXmlWrite.WriteAttribute(L"w:val",L"40"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeBegin(L"w:szCs",true); - m_oXmlWrite.WriteAttribute(L"w:val",L"40"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); - } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType) - { - m_oXmlWrite.WriteNodeBegin(L"m:fPr",false); + oXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) { - m_oXmlWrite.WriteNodeBegin(L"m:type",true); - m_oXmlWrite.WriteAttribute(L"m:val",wsType); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"m:type",true); + oXmlWrite->WriteAttribute(L"m:val",wsType); + oXmlWrite->WriteNodeEnd(L"w",true,true); } - m_oXmlWrite.WriteNodeBegin(L"m:ctrlPr",false); - m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); - m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); - m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); - m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNode(L"w:i",L""); - //m_oXmlWrite.WriteNode(L"w:iCs",L""); - m_oXmlWrite.WriteNodeBegin(L"w:sz",true); - m_oXmlWrite.WriteAttribute(L"w:val",L"40"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeBegin(L"w:szCs",true); - m_oXmlWrite.WriteAttribute(L"w:val",L"40"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:ctrlPr",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:fPr",false,false); + oXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + oXmlWrite->WriteNodeBegin(L"w:rPr",false); + oXmlWrite->WriteNodeBegin(L"w:rFonts",true); + oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNode(L"w:i",L""); + //m_oXmlWrite->WriteNode(L"w:iCs",L""); + oXmlWrite->WriteNodeBegin(L"w:sz",true); + oXmlWrite->WriteAttribute(L"w:val",L"40"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"w:szCs",true); + oXmlWrite->WriteAttribute(L"w:val",L"40"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + oXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + oXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } - void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup) + void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* oXmlWrite) { - m_oXmlWrite.WriteNodeBegin(L"m:naryPr",false); - m_oXmlWrite.WriteNodeBegin(L"m:chr",true); - m_oXmlWrite.WriteAttribute(L"m:val",wsTypeOperator); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNodeBegin(L"m:limLoc",true); - m_oXmlWrite.WriteAttribute(L"m:val",L"undOvr"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"m:naryPr",false); + oXmlWrite->WriteNodeBegin(L"m:chr",true); + oXmlWrite->WriteAttribute(L"m:val",wsTypeOperator); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"m:limLoc",true); + oXmlWrite->WriteAttribute(L"m:val",L"undOvr"); + oXmlWrite->WriteNodeEnd(L"w",true,true); if(bEmptySub) { - m_oXmlWrite.WriteNodeBegin(L"m:subHide",true); - m_oXmlWrite.WriteAttribute(L"m:val",L"1"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"m:subHide",true); + oXmlWrite->WriteAttribute(L"m:val",L"1"); + oXmlWrite->WriteNodeEnd(L"w",true,true); } if(bEmptySup) { - m_oXmlWrite.WriteNodeBegin(L"m:supHide",true); - m_oXmlWrite.WriteAttribute(L"m:val",L"1"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNodeBegin(L"m:supHide",true); + oXmlWrite->WriteAttribute(L"m:val",L"1"); + oXmlWrite->WriteNodeEnd(L"w",true,true); } - m_oXmlWrite.WriteNodeBegin(L"m:ctrlPr",false); - m_oXmlWrite.WriteNodeBegin(L"w:rPr",false); - m_oXmlWrite.WriteNodeBegin(L"w:rFonts",true); - m_oXmlWrite.WriteAttribute(L"w:hAnsi",L"Cambria Math"); - m_oXmlWrite.WriteAttribute(L"w:ascii",L"Cambria Math"); - m_oXmlWrite.WriteNodeEnd(L"w",true,true); - m_oXmlWrite.WriteNode(L"w:i",L""); - m_oXmlWrite.WriteNodeEnd(L"w:rPr",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:ctrlPr",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:naryPr",false,false); + oXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + oXmlWrite->WriteNodeBegin(L"w:rPr",false); + oXmlWrite->WriteNodeBegin(L"w:rFonts",true); + oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + oXmlWrite->WriteNodeEnd(L"w",true,true); + oXmlWrite->WriteNode(L"w:i",L""); + oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + oXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + oXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } - void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock) + void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock,XmlUtils::CXmlWriter* oXmlWrite) { - m_oXmlWrite.WriteNodeBegin(wsNameBlock,false); - ConversionOneElement(CValueBlock); - m_oXmlWrite.WriteNodeEnd(wsNameBlock,false,false); + oXmlWrite->WriteNodeBegin(wsNameBlock,false); + CValueBlock->ConversionToOOXML(oXmlWrite); + oXmlWrite->WriteNodeEnd(wsNameBlock,false,false); } std::wstring CConversionSMtoOOXML::GetOOXML() { - return m_oXmlWrite.GetXmlString(); + return m_oXmlWrite->GetXmlString(); } void CConversionSMtoOOXML::EndConversion() { - //m_oXmlWrite.WriteNodeEnd(L"m:r",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:oMath",false,false); - m_oXmlWrite.WriteNodeEnd(L"m:oMathPara",false,false); + //m_oXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_oXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_oXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } } -*/ + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 1aa8b5f4118..975c7f630fc 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -5,25 +5,20 @@ -//namespace StarMath { -// class CConversionSMtoOOXML -// { -// public: -// CConversionSMtoOOXML(); -// //friend class StarMath::CStarMathPars; -// void StartConversion(std::vector arPars); -// void StandartProperties(); -// void PropertiesMFPR(bool bType,const std::wstring& wsType); -// void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup); -// void ConversionOneElement(CElement* m_oElement); -// void ConversBinOperator(CBinaryOperator* m_oElement); -// void ConversText(CText* m_oElement); -// void ConversOperator(COperator* m_oElement); -// void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock); -// void EndConversion(); -// std::wstring GetOOXML() ; -// private: -// XmlUtils::CXmlWriter m_oXmlWrite; -// }; -//} +namespace StarMath { + class CConversionSMtoOOXML + { + public: + CConversionSMtoOOXML(); + void StartConversion(std::vector arPars); + static void StandartProperties(XmlUtils::CXmlWriter* oXmlWrite); + static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* oXmlWrite); + static void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* m_oXmlWrite); + static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* oXmlWrite); + void EndConversion(); + std::wstring GetOOXML() ; + private: + XmlUtils::CXmlWriter* m_oXmlWrite; + }; +} #endif // CCONVERSIONSMTOOOXML_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 83507abcc4e..8f31a51c1da 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1,118 +1,71 @@ #include "cstarmathpars.h" +#include "cconversionsmtoooxml.h" namespace StarMath { //class methods CParsStarMath - std::vector CParseStarMathString::Parse(std::wstring& wsParseString) + std::vector CParserStarMathString::Parse(std::wstring& wsParseString) { std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); - - while(itStart != itEnd) + CStarMathReader* pReader = new CStarMathReader(itStart,itEnd); + while(!pReader->CheckIteratorPosition()) { - CElement* pTempElement = ParsElement(itStart,itEnd); + CElement* pTempElement = ParseElement(pReader); if(nullptr == pTempElement) break; - if(!arEquation.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations || pTempElement->GetBaseType() == TypeElement::Connection) ) + if(!m_arEquation.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations || pTempElement->GetBaseType() == TypeElement::Connection) ) { - AddLeftArgument(arEquation.back(),pTempElement); - arEquation.pop_back(); + AddLeftArgument(m_arEquation.back(),pTempElement); + m_arEquation.pop_back(); } - arEquation.push_back(pTempElement); + m_arEquation.push_back(pTempElement); } - return arEquation; + return m_arEquation; } - CElement* CParseStarMathString::ParsElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) + CElement* CParserStarMathString::ParseElement(CStarMathReader* pReader) { CElement* pElement; - std::wstring wsToken = GetElement(itStart,itEnd); std::vector arAttributes; - TypeElement enTypeToken = CAttribute::IsAttribute(wsToken); - while(enTypeToken != TypeElement::undefine && itStart != itEnd) + + if(pReader->EmptyString()) + { + pReader->GetToken(); + pReader->SetTypesToken(); + } + + while(pReader->GetGlobalType() == TypeElement::Attribute) { - if(enTypeToken != TypeElement::color) arAttributes.push_back(new CAttribute(enTypeToken)); - wsToken = GetElement(itStart,itEnd); - enTypeToken = CAttribute::IsAttribute(wsToken); + if(pReader->GetLocalType() != TypeElement::color) arAttributes.push_back(new CAttribute(pReader->GetLocalType())); + pReader->GetToken(); + pReader->SetTypesToken(); } - if(L"left" == wsToken) pElement = CElement::CreateElement(GetElement(itStart,itEnd)); - else pElement = CElement::CreateElement(wsToken); + pElement = CElement::CreateElement(pReader); if(pElement != nullptr) { pElement->SetAttribute(arAttributes); - pElement->Pars(itStart,itEnd); - if(CheckingTheNextElement(itStart,itEnd,CIndex::IsIndex)) - { - CIndex* pIndex = CIndex::CreateIndex(GetElement(itStart,itEnd)); - pIndex->SetValueIndex(ParsElement(itStart,itEnd)); - pElement->SetIndex(pIndex); - } + pReader->ClearWString(); + pElement->Parse(pReader); +// if(CheckingTheNextElement(itStart,itEnd,CIndex::IsIndex)) +// { +// CIndex* pIndex = CIndex::CreateIndex(GetElement(itStart,itEnd)); +// pIndex->SetValueIndex(ParseElement(itStart,itEnd)); +// pElement->SetIndex(pIndex); +// } return pElement; } else return pElement; } - std::wstring CParseStarMathString::GetElement(std::wstring::iterator& itFirst,std::wstring::iterator& itEnd) - { - std::wstring m_wsElement{}; - for(; itFirst != itEnd;itFirst++) - { - if(iswspace(*itFirst) && m_wsElement.empty()) continue; - else if(iswspace(*itFirst) && !m_wsElement.empty()) - { - itFirst++; - break; - } - else if(!m_wsElement.empty() && (*itFirst == L'(' || L')' == *itFirst || *itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || (iswdigit(*itFirst) && !iswdigit(m_wsElement.back())) || (iswalpha(*itFirst) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *itFirst || L'>' == *itFirst || L'=' == *itFirst)))) - { - return m_wsElement; - } - else if(((*itFirst == L'{' || *itFirst == L'}' || *itFirst == L'+' || *itFirst == L'-' || *itFirst == L'/' || *itFirst == L'*' || L'^' == *itFirst || L'_' == *itFirst || L'=' == *itFirst ) && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *itFirst || L'<' == *itFirst || L'>' == *itFirst)) || (m_wsElement.back() == L'>' && (L'>' == *itFirst || L'=' == *itFirst)) ) ) ) - { - m_wsElement.push_back(*itFirst); - itFirst++; - return m_wsElement; - } - else - { - m_wsElement.push_back(*itFirst); - } - } - if(!m_wsElement.empty()) return m_wsElement; - else return {}; - } - bool CParseStarMathString::CheckingTheNextElement(std::wstring::iterator& itFirst, std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)) - { - std::wstring::iterator itTempVal = itFirst; - std::wstring wsToken = GetElement(itFirst,itEnd); - TypeElement enTypeAttr = CAttribute::IsAttribute(wsToken); - while(enTypeAttr != TypeElement::undefine && (itFirst != itEnd)) - { - wsToken = GetElement(itFirst,itEnd); - enTypeAttr = CAttribute::IsAttribute(wsToken); - } - itFirst = itTempVal; - if(func(wsToken)) return true; - else return false; - } - bool CParseStarMathString::MoveToNextElement(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) - { - if(itStart !=itEnd) - { - std::wstring wsNextElement = CParseStarMathString::GetElement(itStart,itEnd); - if(L"right" == wsNextElement && (itStart!=itEnd)) wsNextElement = CParseStarMathString::GetElement(itStart,itEnd); - return true; - } - return false; - } template - void CParseStarMathString::SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) + void SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) { T* pBinOpElement = dynamic_cast(pElementWhichAdd); pBinOpElement->SetLeftArg(pLeftArg); pElementWhichAdd = pBinOpElement; } - void CParseStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) + void CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) { switch(pElementWhichAdd->GetBaseType()) { @@ -135,19 +88,40 @@ namespace StarMath break; } } + CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) + { + CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + while(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::SetOperations || pReader->GetGlobalType() == TypeElement::Connection) + { + CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); + if(pFirstTempElement != nullptr) + { + CParserStarMathString::AddLeftArgument(pFirstTempElement,pSecondTempElement); + } + pFirstTempElement = pSecondTempElement; + if(pReader->GetGlobalType() == TypeElement::Empty) + { + pReader->GetToken(); + pReader->SetTypesToken(); + } + } + return pFirstTempElement; + } //class methods CAttribute CAttribute::~CAttribute() {} CAttribute::CAttribute(const TypeElement &enType) { - enTypeAttr = enType; + m_enTypeAttr = enType; } TypeElement CAttribute::GetType() { - return enTypeAttr; + return m_enTypeAttr; } //нет phantom, rgb, 16 , гарнитуры и кегля - TypeElement CAttribute::IsAttribute(const std::wstring &wsToken) + TypeElement CAttribute::GetTypeAttribute(const std::wstring &wsToken) { if(L"acute" == wsToken) return TypeElement::acute; else if(L"color" == wsToken) return TypeElement::color; @@ -201,8 +175,14 @@ namespace StarMath } //class methods CElement CElement::~CElement() - {} - CElement::CElement(): pElementIndex(nullptr) + { + for(CAttribute* pTemp:m_arElementAttributes) + { + delete pTemp; + } + delete m_pElementIndex; + } + CElement::CElement(): m_pElementIndex(nullptr) {} // TypeElement CElement::GetTypeElement(const std::wstring& wsToken) // { @@ -286,263 +266,220 @@ namespace StarMath // else if(L"ldline" == wsToken) return TypeElement::ldline; // else return TypeElement::undefine; // } - CElement* CElement::CreateElement(const std::wstring& wsToken) + CElement* CElement::CreateElement(CStarMathReader* pReader) { - //binop - if (wsToken == L"+") - { - return new CElementBinOperator(TypeElement::plus); - } - else if(CElementString::IsDigit(wsToken)) return new CElementString(wsToken); - else if (wsToken == L"-") - { - return new CElementBinOperator(TypeElement::minus); - } - else if (wsToken == L"*") - { - return new CElementBinOperator(TypeElement::multipl); - } - else if (wsToken == L"/") - { - return new CElementBinOperator(TypeElement::division); - } - else if (wsToken == L"over") - { - return new CElementBinOperator(TypeElement::over); - } - else if (wsToken == L"cdot") - { - return new CElementBinOperator(TypeElement::cdot); - } - else if (wsToken == L"times") - { - return new CElementBinOperator(TypeElement::times); - } - else if (wsToken == L"frac") - { - return new CElementBinOperator(TypeElement::frac); - } - else if (wsToken == L"div") - { - return new CElementBinOperator(TypeElement::div); - } - else if (wsToken == L"oplus") - { - return new CElementBinOperator(TypeElement::oplus); - } - else if (wsToken == L"ominus") - { - return new CElementBinOperator(TypeElement::ominus); - } - else if (wsToken == L"odot") - { - return new CElementBinOperator(TypeElement::odot); - } - else if (wsToken == L"otimes") - { - return new CElementBinOperator(TypeElement::otimes); - } - else if (wsToken == L"odivide") - { - return new CElementBinOperator(TypeElement::odivide); - } - else if (wsToken == L"circ") - { - return new CElementBinOperator(TypeElement::circ); - } - else if (wsToken == L"wideslash") - { - return new CElementBinOperator(TypeElement::wideslash); + switch (pReader->GetGlobalType()) { + case TypeElement::String: + return new CElementString(pReader->GetString()); + case TypeElement::BinOperator: + return new CElementBinOperator(pReader->GetLocalType()); + case TypeElement::SetOperations: + return new CElementSetOperations(pReader->GetLocalType()); + case TypeElement::Connection: + return new CElementConnection(pReader->GetLocalType()); + case TypeElement::Function: + return new CElementFunction(pReader->GetLocalType()); + case TypeElement::Bracket: + return new CElementBracket(pReader->GetLocalType()); + case TypeElement::Operation: + return new CElementOperator(pReader->GetLocalType()); + default: + return nullptr; } - else if (wsToken == L"widebslash") - { - return new CElementBinOperator(TypeElement::widebslash); - } - //brace - else if(L"{" == wsToken) return new CElementBracket(TypeElement::brace); - else if(L"(" == wsToken) return new CElementBracket(TypeElement::round); - else if(L"[" == wsToken) return new CElementBracket(TypeElement::square); - else if(L"ldbracket" == wsToken) return new CElementBracket(TypeElement::ldbracket); - else if(L"lbrace" == wsToken) return new CElementBracket(TypeElement::lbrace); - else if(L"langle" == wsToken) return new CElementBracket(TypeElement::langle); - else if(L"lceil" == wsToken) return new CElementBracket(TypeElement::lceil); - else if(L"lfloor" == wsToken) return new CElementBracket(TypeElement::lfloor); - else if(L"lline" == wsToken) return new CElementBracket(TypeElement::lline); - else if(L"ldline" == wsToken) return new CElementBracket(TypeElement::ldline); - else if(L"intersection" == wsToken) return new CElementSetOperations(TypeElement::intersection); - else if(L"union" == wsToken) return new CElementSetOperations(TypeElement::Union); - else if(L"setminus" == wsToken) return new CElementSetOperations(TypeElement::setminus); - else if(L"setquoyient" == wsToken) return new CElementSetOperations(TypeElement::setquoyient); - else if(L"subseteq" == wsToken) return new CElementSetOperations(TypeElement::subseteq); - else if(L"subset" == wsToken) return new CElementSetOperations(TypeElement::subset); - else if(L"supset" == wsToken) return new CElementSetOperations(TypeElement::supset); - else if(L"supseteq" == wsToken) return new CElementSetOperations(TypeElement::supseteq); - else if(L"nsubset" == wsToken) return new CElementSetOperations(TypeElement::nsubset); - else if(L"nsubseteq" == wsToken) return new CElementSetOperations(TypeElement::nsubseteq); - else if(L"nsupset" == wsToken) return new CElementSetOperations(TypeElement::nsupset); - else if(L"nsubseteq" == wsToken) return new CElementSetOperations(TypeElement::nsubseteq); - else if(L"in" == wsToken) return new CElementSetOperations(TypeElement::in); - else if(L"notin" == wsToken) return new CElementSetOperations(TypeElement::notin); - else if(L"owns" == wsToken) return new CElementSetOperations(TypeElement::owns); - else if(L"approx" == wsToken) return new CElementConnection(TypeElement::approx); - else if(L"sim" == wsToken) return new CElementConnection(TypeElement::sim); - else if(L"simeq" == wsToken) return new CElementConnection(TypeElement::simeq); - else if(L"equiv" == wsToken) return new CElementConnection(TypeElement::equiv); - else if(L"prop" == wsToken) return new CElementConnection(TypeElement::prop); - else if(L"parallel" == wsToken) return new CElementConnection(TypeElement::parallel);\ - else if(L"ortho" == wsToken) return new CElementConnection(TypeElement::ortho); - else if(L"divides" == wsToken) return new CElementConnection(TypeElement::divides); - else if(L"ndivides" == wsToken) return new CElementConnection(TypeElement::ndivides); - else if(L"toward" == wsToken) return new CElementConnection(TypeElement::toward); - else if(L"transl" == wsToken) return new CElementConnection(TypeElement::transl); - else if(L"transr" == wsToken) return new CElementConnection(TypeElement::transr); - else if(L"def" == wsToken) return new CElementConnection(TypeElement::def); - else if(L"=" == wsToken) return new CElementConnection(TypeElement::equals); - else if(L"<>" == wsToken) return new CElementConnection(TypeElement::notequals); - else if(L"<" == wsToken) return new CElementConnection(TypeElement::learrow); - else if(L"<=" == wsToken) return new CElementConnection(TypeElement::learrowequals); - else if(L"leslant" == wsToken) return new CElementConnection(TypeElement::leslant); - else if(L">" == wsToken) return new CElementConnection(TypeElement::riarrow); - else if(L">=" == wsToken) return new CElementConnection(TypeElement::riarrowequals); - else if(L"geslant" == wsToken) return new CElementConnection(TypeElement::geslant); - else if(L"<<" == wsToken) return new CElementConnection(TypeElement::dllearrow); - else if(L">>" == wsToken) return new CElementConnection(TypeElement::dlriarrow); - else if(L"prec" == wsToken) return new CElementConnection(TypeElement::prec); - else if(L"succ" == wsToken) return new CElementConnection(TypeElement::succ); - else if(L"preccurlyeq" == wsToken) return new CElementConnection(TypeElement::preccurlyeq); - else if(L"succcurlyeq" == wsToken) return new CElementConnection(TypeElement::succcurlyeq); - else if(L"precsim" == wsToken) return new CElementConnection(TypeElement::precsim); - else if(L"succsim" == wsToken) return new CElementConnection(TypeElement::succsim); - else if(L"nprec" == wsToken) return new CElementConnection(TypeElement::nprec); - else if(L"nsucc" == wsToken) return new CElementConnection(TypeElement::nsucc); - else if(L"dlarrow" == wsToken) return new CElementConnection(TypeElement::dlarrow); - else if(L"dlrarrow" == wsToken) return new CElementConnection(TypeElement::dlrarrow); - else if(L"drarrow" == wsToken) return new CElementConnection(TypeElement::drarrow); - else if(L"abs" == wsToken) return new CElementFunction(TypeElement::abs); - else if(L"fact" == wsToken) return new CElementFunction(TypeElement::fact); - else if(L"sqrt" == wsToken) return new CElementFunction(TypeElement::sqrt); - else if(L"sin" == wsToken) return new CElementFunction(TypeElement::sin); - else if(L"cos" == wsToken) return new CElementFunction(TypeElement::cos); - else if(L"tan" == wsToken) return new CElementFunction(TypeElement::tan); - else if(L"cot" == wsToken) return new CElementFunction(TypeElement::cot); - else if(L"sinh" == wsToken) return new CElementFunction(TypeElement::sinh); - else if(L"cosh" == wsToken) return new CElementFunction(TypeElement::cosh); - else if(L"tanh" == wsToken) return new CElementFunction(TypeElement::tanh); - else if(L"coth" == wsToken) return new CElementFunction(TypeElement::coth); - else if(L"arcsin" == wsToken) return new CElementFunction(TypeElement::arcsin); - else if(L"arccos" == wsToken) return new CElementFunction(TypeElement::arccos); - else if(L"arctan" == wsToken) return new CElementFunction(TypeElement::arctan); - else if(L"arccot" == wsToken) return new CElementFunction(TypeElement::arccot); - else if(L"arsinh" == wsToken) return new CElementFunction(TypeElement::arsinh); - else if(L"arcosh" == wsToken) return new CElementFunction(TypeElement::arcosh); - else if(L"artanh" == wsToken) return new CElementFunction(TypeElement::artanh); - else if(L"arcoth" == wsToken) return new CElementFunction(TypeElement::arcoth); - else if(L"ln" == wsToken) return new CElementFunction(TypeElement::ln); - else if(L"exp" == wsToken) return new CElementFunction(TypeElement::exp); - else if(L"log" == wsToken) return new CElementFunction(TypeElement::log); - else return nullptr; } void CElement::SetAttribute(const std::vector arAttr) { - arElementAttributes = arAttr; + m_arElementAttributes = arAttr; } void CElement::SetIndex(CIndex *pIndex) { - pElementIndex = pIndex; + m_pElementIndex = pIndex; } TypeElement CElement::GetBaseType() { - return enBaseType; + return m_enBaseType; } void CElement::SetBaseType(const TypeElement &enType) { - enBaseType = enType; + m_enBaseType = enType; } //class methods CElementString CElementString::CElementString(const std::wstring& wsTokenString) { - wsString = wsTokenString; + m_wsString = wsTokenString; + SetBaseType(TypeElement::String); } CElementString::~CElementString() {} void CElementString::SetString(const std::wstring& wsTokenString) { - wsString = wsTokenString; + m_wsString = wsTokenString; } - void CElementString::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementString::Parse(CStarMathReader* pReader) { + pReader->ClearWString(); + } + void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) + { + oXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(oXmlWrite); + oXmlWrite->WriteNodeBegin(L"m:t",false); + oXmlWrite->WriteString(m_wsString); + oXmlWrite->WriteNodeEnd(L"m:t",false,false); + oXmlWrite->WriteNodeEnd(L"m:r",false,false); } std::wstring CElementString::GetString() { - return wsString; + return m_wsString; } - bool CElementString::IsDigit(const std::wstring &wsToken) + TypeElement CElementString::GetDigit(const std::wstring &wsToken) { - for(char cOneElement: wsToken) + for(wchar_t cOneElement: wsToken) { - if(!isdigit(cOneElement)) return false; + if(!isdigit(cOneElement)) return TypeElement::undefine; } - return true; + return TypeElement::String; } //class methods CElementBinOperator - CElementBinOperator::CElementBinOperator(const TypeElement& enType) + CElementBinOperator::CElementBinOperator(const TypeElement& enType): m_pLeftArgument(nullptr) , m_pRightArgument(nullptr) { - enTypeBinOp = enType; + m_enTypeBinOp = enType; SetBaseType(TypeElement::BinOperator); } CElementBinOperator::~CElementBinOperator() { - delete pLeftArgument; - delete pRightArgument; + delete m_pLeftArgument; + delete m_pRightArgument; } void CElementBinOperator::SetLeftArg(CElement *pElement) { - pLeftArgument = pElement; + m_pLeftArgument = pElement; } void CElementBinOperator::SetRightArg(CElement *pElement) { - pRightArgument = pElement; + m_pRightArgument = pElement; } - void CElementBinOperator::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementBinOperator::Parse(CStarMathReader* pReader) { -// нужно сделать функцию для чтения без скобок -// if(enTypeBinOp == TypeElement::frac) -// { - -// } - CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); - if(IsBinOperatorLowPrior() && CParseStarMathString::CheckingTheNextElement(itStart,itEnd,IsBinOperatorHightPrior)) + if(pReader->GetLocalType() == TypeElement::frac) { - CElement* pBinOp = CParseStarMathString::ParsElement(itStart,itEnd); - CParseStarMathString::AddLeftArgument(pTempElement,pBinOp); - SetRightArg(pBinOp); + SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); } else - SetRightArg(pTempElement); + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) + { + CElement* pBinOp = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); + SetRightArg(pBinOp); + } + else + SetRightArg(pTempElement); + } } - void CElementBinOperator::SetTypeBinOP(const TypeElement &enType) + void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) { - enTypeBinOp = enType; + if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division) + { + oXmlWrite->WriteNodeBegin(L"m:f",false); + if(m_enTypeBinOp == TypeElement::division) CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite); + else CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite); + CConversionSMtoOOXML::BlockRecording(L"m:num",m_pLeftArgument,oXmlWrite); + CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); + oXmlWrite->WriteNodeEnd(L"m:f",false,false); + } + else if(m_enTypeBinOp == TypeElement::plus ||m_enTypeBinOp == TypeElement::minus || m_enTypeBinOp == TypeElement::multipl || m_enTypeBinOp == TypeElement::cdot || m_enTypeBinOp == TypeElement::times || m_enTypeBinOp == TypeElement::div || m_enTypeBinOp == TypeElement::odivide || m_enTypeBinOp == TypeElement::oplus || m_enTypeBinOp == TypeElement::ominus || m_enTypeBinOp == TypeElement::odot || m_enTypeBinOp == TypeElement::otimes) + { + m_pLeftArgument->ConversionToOOXML(oXmlWrite); + oXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(oXmlWrite); + oXmlWrite->WriteNodeBegin(L"m:t",false); + switch (m_enTypeBinOp) + { + case TypeElement::plus: + oXmlWrite->WriteString(L"+"); + break; + case TypeElement::minus: + oXmlWrite->WriteString(L"-"); + break; + case TypeElement::multipl: + oXmlWrite->WriteString(L"*"); + break; + case TypeElement::cdot: + oXmlWrite->WriteString(L"\u00B7"); + break; + case TypeElement::times: + oXmlWrite->WriteString(L"\u00D7"); + break; + case TypeElement::div: + oXmlWrite->WriteString(L"\u00F7"); + break; + case TypeElement::odivide: + oXmlWrite->WriteString(L"\u2298"); + break; + case TypeElement::oplus: + oXmlWrite->WriteString(L"\u2295"); + break; + case TypeElement::ominus: + oXmlWrite->WriteString(L"\u2296"); + break; + case TypeElement::odot: + oXmlWrite->WriteString(L"\u2299"); + break; + case TypeElement::otimes: + oXmlWrite->WriteString(L"\u2297"); + break; + default: + break; + } + if(m_pRightArgument->GetBaseType() == TypeElement::String) + { + CElementString* oNumber = dynamic_cast (m_pRightArgument); + oXmlWrite->WriteString(oNumber->GetString()); + oXmlWrite->WriteNodeEnd(L"m:t",false,false); + oXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + else + { + oXmlWrite->WriteNodeEnd(L"m:t",false,false); + oXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_pRightArgument->ConversionToOOXML(oXmlWrite); + } + + } } - bool CElementBinOperator::IsBinOperatorHightPrior(const std::wstring& wsToken) + void CElementBinOperator::SetTypeBinOP(const TypeElement &enType) { - if(L"cdot" == wsToken) return true; - else if(L"times" == wsToken) return true; - else if(L"over" == wsToken) return true; -// else if(L"frac" == wsToken) return true; - else if(L"div" == wsToken) return true; - else if(L"multipl" == wsToken) return true; - else if(L"division" == wsToken) return true; - else if(L"odot" == wsToken) return true; - else if(L"otimes" == wsToken) return true; - else if(L"odivide" == wsToken) return true; - else if(L"circ" == wsToken) return true; - else if(L"wideslash" == wsToken) return true; - else if(L"widebslash" == wsToken) return true; + m_enTypeBinOp = enType; + } + TypeElement CElementBinOperator::GetBinOperator(const std::wstring& wsToken) + { + if(L"cdot" == wsToken) return TypeElement::cdot; + else if(L"+" == wsToken) return TypeElement::plus; + else if(L"-" == wsToken) return TypeElement::minus; + else if(L"oplus" == wsToken) return TypeElement::oplus; + else if(L"ominus" == wsToken) return TypeElement::ominus; + else if(L"circ" == wsToken) return TypeElement::circ; + else if(L"times" == wsToken) return TypeElement::times; + else if(L"over" == wsToken) return TypeElement::over; + else if(L"frac" == wsToken) return TypeElement::frac; + else if(L"div" == wsToken) return TypeElement::div; + else if(L"*" == wsToken) return TypeElement::multipl; + else if(L"/" == wsToken) return TypeElement::division; + else if(L"odot" == wsToken) return TypeElement::odot; + else if(L"otimes" == wsToken) return TypeElement::otimes; + else if(L"odivide" == wsToken) return TypeElement::odivide; + else if(L"wideslash" == wsToken) return TypeElement::wideslash; + else if(L"widebslash" == wsToken) return TypeElement::widebslash; + else return TypeElement::undefine; } bool CElementBinOperator::IsBinOperatorLowPrior() { - switch (enTypeBinOp) { + switch (m_enTypeBinOp) { case TypeElement::plus: return true; case TypeElement::minus: @@ -560,159 +497,252 @@ namespace StarMath //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) { - enTypeBracket = enType; + m_enTypeBracket = enType; } CElementBracket::~CElementBracket() { - for(CElement* pTemp:arBrecketValue) delete pTemp; + for(CElement* pTemp:m_arBrecketValue) delete pTemp; } void CElementBracket::SetBracketValue(const std::vector &arValue) { - arBrecketValue = arValue; - } - bool CElementBracket::IsBracketClose(const std::wstring &wsToken) - { - if(L"}" == wsToken) return true; - else if(L")" == wsToken) return true; - else if(L"]" == wsToken) return true; - else if(L"rdbracket" == wsToken) return true; - else if(L"rbrace" == wsToken) return true; - else if(L"rangle" == wsToken) return true; - else if(L"rceil" == wsToken) return true; - else if(L"rfloor" == wsToken) return true; - else if(L"rline" == wsToken) return true; - else if(L"rdline" == wsToken) return true; - else if(L"right" == wsToken) return true; - else return false; + m_arBrecketValue = arValue; + } + TypeElement CElementBracket::GetBracketOpen(const std::wstring &wsToken) + { + if(L"{" == wsToken) return TypeElement::brace; + else if(L"(" == wsToken) return TypeElement::round; + else if(L"[" == wsToken) return TypeElement::square; + else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; + else if(L"lbrace" == wsToken) return TypeElement::lbrace; + else if(L"langle" == wsToken) return TypeElement::langle; + else if(L"lceil" == wsToken) return TypeElement::lceil; + else if(L"lfloor" == wsToken) return TypeElement::lfloor; + else if(L"lline" == wsToken) return TypeElement::lline; + else if(L"ldline" == wsToken) return TypeElement::ldline; + else return TypeElement::undefine; + } + TypeElement CElementBracket::GetBracketClose(const std::wstring &wsToken) + { + if(L"}" == wsToken) return TypeElement::rwbrace; + else if(L")" == wsToken) return TypeElement::rround; + else if(L"]" == wsToken) return TypeElement::rsquare; + else if(L"rdbracket" == wsToken) return TypeElement::rdbracket; + else if(L"rbrace" == wsToken) return TypeElement::rbrace; + else if(L"rangle" == wsToken) return TypeElement::rangle; + else if(L"rceil" == wsToken) return TypeElement::rceil; + else if(L"rfloor" == wsToken) return TypeElement::rfloor; + else if(L"rline" == wsToken) return TypeElement::rline; + else if(L"rdline" == wsToken) return TypeElement::rdline; + else if(L"right" == wsToken) return TypeElement::right; + else return TypeElement::undefine; } - // правка if - void CElementBracket::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + //сделать не через SetTypesToken,а локальную переменную и через нее определять конец скобок + void CElementBracket::Parse(CStarMathReader* pReader) { - while(!CParseStarMathString::CheckingTheNextElement(itStart,itEnd,IsBracketClose)) + pReader->GetToken(); + TypeElement enBracketClose = GetBracketClose(pReader->GetString()); + if(enBracketClose == TypeElement::undefine) + { + pReader->SetTypesToken(); + } + while(enBracketClose == TypeElement::undefine) { - CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); - if(!arBrecketValue.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations) ) + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + if(!m_arBrecketValue.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations) ) + { + CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement); + m_arBrecketValue.pop_back(); + } + m_arBrecketValue.push_back(pTempElement); + if(pReader->EmptyString()) { - CParseStarMathString::AddLeftArgument(arBrecketValue.back(),pTempElement); - arBrecketValue.pop_back(); + pReader->GetToken(); + enBracketClose = GetBracketClose(pReader->GetString()); + if(enBracketClose == TypeElement::undefine) + { + pReader->SetTypesToken(); + } } - arBrecketValue.push_back(pTempElement); + else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() - if(!CParseStarMathString::MoveToNextElement(itStart,itEnd)); + pReader->ClearWString(); + } + void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + } //class methods CElementSpecialSymbol CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) { - enTypeSpecial = enType; + m_enTypeSpecial = enType; } CElementSpecialSymbol::~CElementSpecialSymbol() {} - void CElementSpecialSymbol::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementSpecialSymbol::Parse(CStarMathReader* pReader) { } //class methods CElementSetOperations - CElementSetOperations::CElementSetOperations(const TypeElement &enType) + CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) { - enTypeSet = enType; + m_enTypeSet = enType; SetBaseType(TypeElement::SetOperations); } CElementSetOperations::~CElementSetOperations() { - delete pLeftArgument; - delete pRightArgument; + delete m_pLeftArgument; + delete m_pRightArgument; } void CElementSetOperations::SetLeftArg(CElement *pElement) { - pLeftArgument = pElement; + m_pLeftArgument = pElement; } CElement* CElementSetOperations::GetLeftArg() { - return pLeftArgument; + return m_pLeftArgument; } void CElementSetOperations::SetRightArg(CElement *pElement) { - pRightArgument = pElement; + m_pRightArgument = pElement; } CElement* CElementSetOperations::GetRightArg() { - return pRightArgument; + return m_pRightArgument; } - void CElementSetOperations::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementSetOperations::Parse(CStarMathReader* pReader) { - CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); - if(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior)) + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + if(pReader->GetGlobalType() == TypeElement::BinOperator) { - CElement* pBinOpElement = CParseStarMathString::ParsElement(itStart,itEnd); - CParseStarMathString::AddLeftArgument(pTempElement,pBinOpElement); + CElement* pBinOpElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pBinOpElement); SetRightArg(pBinOpElement); } else SetRightArg(pTempElement); } - bool CElementSetOperations::IsSetOperation(const std::wstring &wsToken) + void CElementSetOperations::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - if(L"union" == wsToken) return true; - else return false; + + } + TypeElement CElementSetOperations::GetSetOperation(const std::wstring &wsToken) + { + if(L"intersection" == wsToken) return TypeElement::intersection; + else if(L"union" == wsToken) return TypeElement::Union; + else if(L"setminus" == wsToken) return TypeElement::setminus; + else if(L"setquoyient" == wsToken) return TypeElement::setquoyient; + else if(L"subseteq" == wsToken) return TypeElement::subseteq; + else if(L"subset" == wsToken) return TypeElement::subset; + else if(L"supset" == wsToken) return TypeElement::supset; + else if(L"supseteq" == wsToken) return TypeElement::supseteq; + else if(L"nsubset" == wsToken) return TypeElement::nsubset; + else if(L"nsubseteq" == wsToken) return TypeElement::nsubseteq; + else if(L"nsupset" == wsToken) return TypeElement::nsupset; + else if(L"nsubseteq" == wsToken) return TypeElement::nsubseteq; + else if(L"in" == wsToken) return TypeElement::in; + else if(L"notin" == wsToken) return TypeElement::notin; + else if(L"owns" == wsToken) return TypeElement::owns; + else return TypeElement::undefine; } //class methods CElementConnection - CElementConnection::CElementConnection(const TypeElement& enType) + CElementConnection::CElementConnection(const TypeElement& enType): m_pLeftArgument(nullptr), m_pRightArgument(nullptr) { - enTypeCon = enType; + m_enTypeCon = enType; SetBaseType(TypeElement::Connection); } CElementConnection::~CElementConnection() { - delete pLeftArgument; - delete pRightArgument; + delete m_pLeftArgument; + delete m_pRightArgument; } void CElementConnection::SetRightArg(CElement *pElement) { - pRightArgument = pElement; + m_pRightArgument = pElement; } CElement* CElementConnection::GetRightArg() { - return pRightArgument; + return m_pRightArgument; } void CElementConnection::SetLeftArg(CElement *pElement) { - pLeftArgument = pElement; + m_pLeftArgument = pElement; } CElement* CElementConnection::GetLeftArg() { - return pLeftArgument; + return m_pLeftArgument; } - void CElementConnection::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementConnection::Parse(CStarMathReader *pReader) { - CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); - if(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior)) + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + if(pReader->GetGlobalType() == TypeElement::BinOperator) { - CElement* pBinOp = CParseStarMathString::ParsElement(itStart,itEnd); - CParseStarMathString::AddLeftArgument(pTempElement,pBinOp); + CElement* pBinOp = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); SetRightArg(pBinOp); } else SetRightArg(pTempElement); } - bool CElementConnection::IsConnection(const std::wstring& wsToken) + void CElementConnection::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - if(L"def" == wsToken) return true; - else return false; + } + TypeElement CElementConnection::GetConnection(const std::wstring& wsToken) + { + if(L"approx" == wsToken) return TypeElement::approx; + else if(L"sim" == wsToken) return TypeElement::sim; + else if(L"simeq" == wsToken) return TypeElement::simeq; + else if(L"equiv" == wsToken) return TypeElement::equiv; + else if(L"prop" == wsToken) return TypeElement::prop; + else if(L"parallel" == wsToken) return TypeElement::parallel; + else if(L"ortho" == wsToken) return TypeElement::ortho; + else if(L"divides" == wsToken) return TypeElement::divides; + else if(L"ndivides" == wsToken) return TypeElement::ndivides; + else if(L"toward" == wsToken) return TypeElement::toward; + else if(L"transl" == wsToken) return TypeElement::transl; + else if(L"transr" == wsToken) return TypeElement::transr; + else if(L"def" == wsToken) return TypeElement::def; + else if(L"=" == wsToken) return TypeElement::equals; + else if(L"<>" == wsToken) return TypeElement::notequals; + else if(L"<" == wsToken) return TypeElement::learrow; + else if(L"<=" == wsToken) return TypeElement::learrowequals; + else if(L"leslant" == wsToken) return TypeElement::leslant; + else if(L">" == wsToken) return TypeElement::riarrow; + else if(L">=" == wsToken) return TypeElement::riarrowequals; + else if(L"geslant" == wsToken) return TypeElement::geslant; + else if(L"<<" == wsToken) return TypeElement::dllearrow; + else if(L">>" == wsToken) return TypeElement::dlriarrow; + else if(L"prec" == wsToken) return TypeElement::prec; + else if(L"succ" == wsToken) return TypeElement::succ; + else if(L"preccurlyeq" == wsToken) return TypeElement::preccurlyeq; + else if(L"succcurlyeq" == wsToken) return TypeElement::succcurlyeq; + else if(L"precsim" == wsToken) return TypeElement::precsim; + else if(L"succsim" == wsToken) return TypeElement::succsim; + else if(L"nprec" == wsToken) return TypeElement::nprec; + else if(L"nsucc" == wsToken) return TypeElement::nsucc; + else if(L"dlarrow" == wsToken) return TypeElement::dlarrow; + else if(L"dlrarrow" == wsToken) return TypeElement::dlrarrow; + else if(L"drarrow" == wsToken) return TypeElement::drarrow; + else return TypeElement::undefine; +} //class methods CIndex - CIndex::CIndex(const TypeElement& enType) + CIndex::CIndex(const TypeElement& enType): m_pValueIndex(nullptr) { - enTypeIndex = enType; + m_enTypeIndex = enType; } CIndex::~CIndex() { - delete pValueIndex; + delete m_pValueIndex; } void CIndex::SetValueIndex(CElement *pElement) { - pValueIndex = pElement; + m_pValueIndex = pElement; } CElement* CIndex::GetValueIndex() { - return pValueIndex; + return m_pValueIndex; } bool CIndex::IsIndex(const std::wstring &wsCheckToken) { @@ -735,71 +765,293 @@ namespace StarMath else return nullptr; } //class methods CElementFunction - CElementFunction::CElementFunction(const TypeElement &enType) + CElementFunction::CElementFunction(const TypeElement &enType): m_pValue(nullptr) { - enTypeFunction = enType; + m_enTypeFunction = enType; SetBaseType(TypeElement::Function); } CElementFunction::~CElementFunction() { - delete pValue; + delete m_pValue; } void CElementFunction::SetValueFunction(CElement *pElement) { - pValue = pElement; + m_pValue = pElement; } CElement* CElementFunction::GetValueFunction() { - return pValue; + return m_pValue; } - void CElementFunction::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + void CElementFunction::Parse(CStarMathReader* pReader) + { + SetValueFunction(CParserStarMathString::ParseElement(pReader)); + pReader->ClearWString(); + } + void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - SetValueFunction(CParseStarMathString::ParsElement(itStart,itEnd)); + + } + TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) + { + if(L"abs" == wsToken) return TypeElement::abs; + else if(L"fact" == wsToken) return TypeElement::fact; + else if(L"sqrt" == wsToken) return TypeElement::sqrt; + else if(L"sin" == wsToken) return TypeElement::sin; + else if(L"cos" == wsToken) return TypeElement::cos; + else if(L"tan" == wsToken) return TypeElement::tan; + else if(L"cot" == wsToken) return TypeElement::cot; + else if(L"sinh" == wsToken) return TypeElement::sinh; + else if(L"cosh" == wsToken) return TypeElement::cosh; + else if(L"tanh" == wsToken) return TypeElement::tanh; + else if(L"coth" == wsToken) return TypeElement::coth; + else if(L"arcsin" == wsToken) return TypeElement::arcsin; + else if(L"arccos" == wsToken) return TypeElement::arccos; + else if(L"arctan" == wsToken) return TypeElement::arctan; + else if(L"arccot" == wsToken) return TypeElement::arccot; + else if(L"arsinh" == wsToken) return TypeElement::arsinh; + else if(L"arcosh" == wsToken) return TypeElement::arcosh; + else if(L"artanh" == wsToken) return TypeElement::artanh; + else if(L"arcoth" == wsToken) return TypeElement::arcoth; + else if(L"ln" == wsToken) return TypeElement::ln; + else if(L"exp" == wsToken) return TypeElement::exp; + else if(L"log" == wsToken) return TypeElement::log; + else return TypeElement::undefine; } //class methods CElementOperation - CElementOperator::CElementOperator(const TypeElement &enType) + CElementOperator::CElementOperator(const TypeElement &enType): m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr) { - enTypeOperator = enType; + m_enTypeOperator = enType; SetBaseType(TypeElement::Operation); } CElementOperator::~CElementOperator() { - delete pValueOperator; - delete pValueFrom; - delete pValueTo; + delete m_pValueOperator; + delete m_pValueFrom; + delete m_pValueTo; } void CElementOperator::SetValueOperator(CElement *pElement) { - pValueOperator = pElement; + m_pValueOperator = pElement; } CElement* CElementOperator::GetValueOperator() { - return pValueOperator; + return m_pValueOperator; } void CElementOperator::SetFromValue(CElement *pElement) { - pValueFrom = pElement; + m_pValueFrom = pElement; } CElement* CElementOperator::GetFromValue() { - return pValueFrom; + return m_pValueFrom; } void CElementOperator::SetToValue(CElement *pElement) { - pValueTo = pElement; + m_pValueTo = pElement; } CElement* CElementOperator::GetToValue() { - return pValueTo; + return m_pValueTo; } - void CElementOperator::Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) + TypeElement CElementOperator::GetFromOrTo(const std::wstring &wsToken) { - do + if(L"from" == wsToken) return TypeElement::from; + else if(L"to" == wsToken) return TypeElement::to; + else return TypeElement::undefine; + } + TypeElement CElementOperator::GetOperator(const std::wstring &wsToken) + { + if(L"lim" == wsToken) return TypeElement::lim; + if(L"sum" == wsToken) return TypeElement::sum; + if(L"liminf" == wsToken) return TypeElement::liminf; + if(L"limsup" == wsToken) return TypeElement::limsup; + if(L"prod" == wsToken) return TypeElement::prod; + if(L"coprod" == wsToken) return TypeElement::coprod; + if(L"Int" == wsToken) return TypeElement::Int; + if(L"iint" == wsToken) return TypeElement::iint; + if(L"iiint" == wsToken) return TypeElement::iiint; + if(L"lint" == wsToken) return TypeElement::lint; + if(L"llint" == wsToken) return TypeElement::llint; + if(L"lllint" == wsToken) return TypeElement::lllint; + else return TypeElement::undefine; + } + void CElementOperator::Parse(CStarMathReader* pReader) + { + pReader->GetToken(); + pReader->SetTypesToken(); + if(pReader->GetLocalType() == TypeElement::from) { - CElement* pTempElement = CParseStarMathString::ParsElement(itStart,itEnd); + pReader->ClearWString(); + SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + if(pReader->GetLocalType() == TypeElement::to) + { + pReader->ClearWString(); + SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + } - }while(CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementBinOperator::IsBinOperatorHightPrior) || CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementSetOperations::IsSetOperation) || CParseStarMathString::CheckingTheNextElement(itStart,itEnd,CElementConnection::IsConnection)); + SetValueOperator(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) + { + if(m_enTypeOperator == TypeElement::sum) + { + oXmlWrite->WriteNodeBegin(L"m:nary",false); + CConversionSMtoOOXML::PropertiesNaryPr(L"\u2211",nullptr == m_pValueFrom,nullptr == m_pValueTo,oXmlWrite); + if(m_pValueFrom == nullptr) oXmlWrite->WriteNode(L"m:sub",L""); + else + { + CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueFrom,oXmlWrite); + } + if(m_pValueTo == nullptr) oXmlWrite->WriteNode(L"m:sup",L""); + else + { + CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueTo,oXmlWrite); + } + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueOperator,oXmlWrite); + oXmlWrite->WriteNodeEnd(L"m:nary",false,false); + } + } +// class methods CStarMathReader + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty) + { + m_itStart = itStart; + m_itEnd = itEnd; + } + CStarMathReader::~CStarMathReader() + {} + void CStarMathReader::GetToken() + { + if(m_itStart != m_itEnd) + { + m_wsToken = GetElement(); + if(m_wsToken == L"left") m_wsToken = GetElement(); + else if(L"right" == m_wsToken ) m_wsToken = GetElement(); + } + } + void CStarMathReader::SetTypesToken() + { + m_enUnderType = CAttribute::GetTypeAttribute(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Attribute; + return; + } + m_enUnderType = CElementOperator::GetFromOrTo(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Operation; + return; + } + m_enUnderType = CElementBracket::GetBracketOpen(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Bracket; + return; + } + m_enUnderType = CElementString::GetDigit(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::String; + return; + } + m_enUnderType = CElementBinOperator::GetBinOperator(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::BinOperator; + return; + } + m_enUnderType = CElementSetOperations::GetSetOperation(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::SetOperations; + return; + } + m_enUnderType = CElementConnection::GetConnection(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Connection; + return; + } + m_enUnderType = CElementFunction::GetFunction(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Function; + return; + } + m_enUnderType = CElementOperator::GetOperator(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Operation; + return; + } + if(m_enUnderType == TypeElement::undefine) + { + m_enGlobalType = TypeElement::Empty; + return; + } + } + TypeElement CStarMathReader::GetLocalType() + { + return m_enUnderType; + } + TypeElement CStarMathReader::GetGlobalType() + { + return m_enGlobalType; + } + std::wstring CStarMathReader::GetString() + { + return m_wsToken; + } +// void CStarMathReader::SkipNextElement() +// { +// if(m_itStart !=m_itEnd) +// { +// std::wstring wsNextElement = CParserStarMathString::GetElement(m_itStart,m_itEnd); +// } +// } + void CStarMathReader::ClearWString() + { + m_wsToken.clear(); + } + bool CStarMathReader::EmptyString() + { + return m_wsToken.empty(); + } + bool CStarMathReader::CheckIteratorPosition() + { + if(m_itStart !=m_itEnd) return false; + else return true; + } + std::wstring CStarMathReader::GetElement() + { + std::wstring m_wsElement{}; + for(; m_itStart != m_itEnd;m_itStart++) + { + if(iswspace(*m_itStart) && m_wsElement.empty()) continue; + else if(iswspace(*m_itStart) && !m_wsElement.empty()) + { + m_itStart++; + break; + } + else if(!m_wsElement.empty() && (*m_itStart == L'(' || L')' == *m_itStart || *m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + { + return m_wsElement; + } + else if(((*m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || L'=' == *m_itStart ) && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) + { + m_wsElement.push_back(*m_itStart); + m_itStart++; + return m_wsElement; + } + else + { + m_wsElement.push_back(*m_itStart); + } + } + if(!m_wsElement.empty()) return m_wsElement; + else return {}; } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f60e0ae9e63..f10bd3d1b80 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -5,18 +5,45 @@ #include #include #include +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" namespace StarMath { + //Сlass for working with tokens (reading, defining types, passing) + class CStarMathReader + { + public: + CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd); + ~CStarMathReader(); + void GetToken(); + //getting a subtype and setting the global type of a token to variables m_enUnderType and m_enGlobalType + void SetTypesToken(); + //void SkipNextElement(); + TypeElement GetGlobalType(); + TypeElement GetLocalType(); + std::wstring GetString(); + //clearing a variable m_wsToken + void ClearWString(); + bool CheckIteratorPosition(); + bool EmptyString(); + private: + //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) + std::wstring GetElement(); + std::wstring::iterator m_itStart,m_itEnd; + TypeElement m_enGlobalType; + TypeElement m_enUnderType; + std::wstring m_wsToken; + }; + class CAttribute { public: CAttribute(const TypeElement& enType); ~CAttribute(); - static TypeElement IsAttribute(const std::wstring& wsToken); + static TypeElement GetTypeAttribute(const std::wstring& wsToken); TypeElement GetType(); private: - TypeElement enTypeAttr; + TypeElement m_enTypeAttr; }; class CIndex; @@ -26,18 +53,18 @@ namespace StarMath public: CElement(); virtual ~CElement(); - virtual void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) = 0; - //принимает подтип (over, frac и т.д) и создает нужный нам класс(внутри уже идет проверка по классам) - static CElement* CreateElement(const std::wstring& wsToken); - //static TypeElement GetTypeElement(const std::wstring& wsToken); + virtual void Parse(CStarMathReader* pReader) = 0; + //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) + static CElement* CreateElement(CStarMathReader* pReader); + virtual void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) = 0; void SetAttribute(const std::vector arAttr); void SetIndex(CIndex* pIndex); void SetBaseType(const TypeElement& enType); TypeElement GetBaseType(); private: - CIndex* pElementIndex; - std::vector arElementAttributes; - TypeElement enBaseType; + CIndex* m_pElementIndex; + std::vector m_arElementAttributes; + TypeElement m_enBaseType; }; class CIndex @@ -50,8 +77,8 @@ namespace StarMath static bool IsIndex(const std::wstring& wsCheckToken); static CIndex* CreateIndex(const std::wstring& wsToken); private: - CElement* pValueIndex; - TypeElement enTypeIndex; + CElement* m_pValueIndex; + TypeElement m_enTypeIndex; }; class CElementString: public CElement @@ -61,10 +88,11 @@ namespace StarMath virtual ~CElementString(); void SetString(const std::wstring& wsTokenString); std::wstring GetString(); - static bool IsDigit(const std::wstring& wsCheckToken); + static TypeElement GetDigit(const std::wstring& wsCheckToken); private: - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - std::wstring wsString; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + std::wstring m_wsString; }; class CElementBinOperator: public CElement @@ -77,13 +105,14 @@ namespace StarMath void SetTypeBinOP(const TypeElement& enType); CElement* GetRightArg(); CElement* GetLeftArg(); - static bool IsBinOperatorHightPrior(const std::wstring& wsToken); + static TypeElement GetBinOperator(const std::wstring& wsToken); private: bool IsBinOperatorLowPrior(); - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - CElement* pLeftArgument; - CElement* pRightArgument; - TypeElement enTypeBinOp; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeBinOp; }; class CElementOperator: public CElement @@ -97,12 +126,15 @@ namespace StarMath CElement* GetFromValue(); void SetToValue(CElement* pElement); CElement* GetToValue(); + static TypeElement GetOperator(const std::wstring& wsToken); + static TypeElement GetFromOrTo(const std::wstring& wsToken); private: - void Pars(std::wstring::iterator &itStart, std::wstring::iterator &itEnd) override; - CElement* pValueOperator; - CElement* pValueFrom; - CElement* pValueTo; - TypeElement enTypeOperator; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + CElement* m_pValueOperator; + CElement* m_pValueFrom; + CElement* m_pValueTo; + TypeElement m_enTypeOperator; }; class CElementBracket: public CElement @@ -111,11 +143,13 @@ namespace StarMath CElementBracket(const TypeElement& enType); virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); + static TypeElement GetBracketOpen(const std::wstring& wsToken); private: - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - static bool IsBracketClose(const std::wstring& wsToken); - TypeElement enTypeBracket; - std::vector arBrecketValue; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite); + TypeElement GetBracketClose(const std::wstring& wsToken); + TypeElement m_enTypeBracket; + std::vector m_arBrecketValue; }; class CElementSetOperations: public CElement @@ -127,12 +161,13 @@ namespace StarMath CElement* GetLeftArg(); void SetRightArg(CElement* pElement); CElement* GetRightArg(); - static bool IsSetOperation(const std::wstring& wsToken); + static TypeElement GetSetOperation(const std::wstring& wsToken); private: - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - CElement* pLeftArgument; - CElement* pRightArgument; - TypeElement enTypeSet; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeSet; }; class CElementConnection: public CElement @@ -144,12 +179,13 @@ namespace StarMath CElement* GetRightArg(); void SetLeftArg(CElement* pElement); CElement* GetLeftArg(); - static bool IsConnection(const std::wstring& wsToken); + static TypeElement GetConnection(const std::wstring& wsToken); private: - void Pars(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) override; - CElement* pLeftArgument; - CElement* pRightArgument; - TypeElement enTypeCon; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pLeftArgument; + CElement* m_pRightArgument; + TypeElement m_enTypeCon; }; class CElementFunction: public CElement @@ -159,10 +195,12 @@ namespace StarMath virtual ~CElementFunction(); void SetValueFunction(CElement* pElement); CElement* GetValueFunction(); + static TypeElement GetFunction(const std::wstring& wsToken); private: - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - CElement* pValue; - TypeElement enTypeFunction; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pValue; + TypeElement m_enTypeFunction; }; class CElementSpecialSymbol: public CElement @@ -171,23 +209,20 @@ namespace StarMath CElementSpecialSymbol(const TypeElement& enType); virtual ~CElementSpecialSymbol(); private: - void Pars(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) override; - TypeElement enTypeSpecial; + void Parse(CStarMathReader* pReader) override; + TypeElement m_enTypeSpecial; }; - class CParseStarMathString + class CParserStarMathString { public: std::vector Parse(std::wstring& wsParseString); - static CElement* ParsElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd); - static std::wstring GetElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); - static bool CheckingTheNextElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd, bool (&func)(const std::wstring&)); - static bool MoveToNextElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); + static CElement* ParseElement(CStarMathReader* pReader); + //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static void AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); - template - static void SetLeft(CElement* pLeftArg, CElement* pElementWhichaAdd); + static CElement* ReadingWithoutBracket(CStarMathReader* pReader); private: - std::vector arEquation; + std::vector m_arEquation; }; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index c46f56ffd8d..038e89d5a43 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -10,6 +10,7 @@ enum class TypeElement{ SetOperations, Operator, Bracket, + //BracketEnd, UnarSign, Attribute, SpecialSymbol, @@ -18,6 +19,7 @@ enum class TypeElement{ Index, Matrix, Connection, + Empty, //binoop cdot, times, @@ -39,6 +41,16 @@ enum class TypeElement{ //op lim, sum, + liminf, + limsup, + prod, + coprod, + Int, + iint, + iiint, + lint, + llint, + lllint, //brace brace, round, @@ -212,6 +224,21 @@ enum class TypeElement{ binom, stack, matrix, + //bracket close + rwbrace, + rbrace, + rround, + rsquare, + rdbracket, + rangle, + rceil, + rfloor, + rline, + rdline, + right, + //op + from, + to, }; } #endif // TYPESELEMENTS_H From c4085ed69844f07bbfbbafd6d8b863ec89e23ecd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 10 Nov 2023 17:21:44 +0600 Subject: [PATCH 180/794] Fix xlsx 2 xlsb conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 2 +- OOXML/XlsxFormat/Pivot/Pivots.cpp | 13 +++++- OOXML/XlsxFormat/Styles/CellStyles.cpp | 10 +++++ OOXML/XlsxFormat/Styles/Fills.cpp | 45 ++++++++++++++++++- OOXML/XlsxFormat/Styles/Fonts.cpp | 5 ++- OOXML/XlsxFormat/Styles/TableStyles.cpp | 4 +- OOXML/XlsxFormat/Styles/Xfs.cpp | 21 ++++++++- OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 8 ++-- .../Worksheets/WorksheetChildOther.cpp | 16 +++++++ 9 files changed, 112 insertions(+), 12 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 6e0be8609df..d05920bf8f2 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -714,7 +714,7 @@ namespace OOX for(auto i:m_arrExt) { - if(i->m_sUri == L"{EB79DEF2-80B8-43E5-95BD-54CBDDF9020C}") + if(i->m_sUri == L"{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}") { ptr->m_STYLESHEET14 = i->m_oSlicerStyles->toBin(); } diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 38a901fc90c..441bda33b0a 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -534,6 +534,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else ptr->fDisplayPageFieldStyle = false; if (m_oPageWrap.IsInit()) ptr->cWrapPage = m_oPageWrap->GetValue(); + else + ptr->cWrapPage = 0; if (m_oPivotTableStyle.IsInit()) ptr->irstTableStyle = m_oPivotTableStyle.get(); else ptr->fDisplayTableStyle = false; @@ -577,6 +579,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oVacatedStyle.IsInit()) ptr->irstVacateStyle = m_oVacatedStyle.get(); else ptr->fDisplayVacateStyle = false; + ptr->sxaxis4Data = 2; + ptr->fReenterOnLoadOnce = false; return objectPtr; } @@ -2204,7 +2208,12 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oAvgSubtotal.IsInit()) ptr->fAverage = m_oAvgSubtotal.get(); - + + ptr->sxaxis.bCol = false; + ptr->sxaxis.bPage = false; + ptr->sxaxis.bRw = false; + ptr->sxaxis.bData = false; + if(m_oAxis.IsInit()) { if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) @@ -2213,7 +2222,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->sxaxis.bPage = true; else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) ptr->sxaxis.bRw = true; - else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) ptr->sxaxis.bData = true; } if(m_oCompact.IsInit()) diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index 6c9afccd316..6c7fe7e4097 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -34,6 +34,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/Style.h" +#include "../../XlsbFormat/Biff12_records/BeginStyles.h" #include "../../XlsbFormat/Biff12_unions/STYLES.h" @@ -81,14 +82,19 @@ namespace OOX ptr->fBuiltIn = m_oBuiltinId->GetValue(); if (m_oCustomBuiltin.IsInit()) ptr->fCustom = m_oCustomBuiltin->GetValue(); + else + ptr->fCustom = false; if (m_oHidden.IsInit()) ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; if (m_oILevel.IsInit()) ptr->iLevel = m_oILevel->GetValue(); if (m_oName.IsInit()) ptr->stName = m_oName.get(); if (m_oXfId.IsInit()) ptr->ixf = m_oXfId->GetValue(); + ptr->iStyBuiltIn = 0; return objectPtr; } @@ -183,9 +189,13 @@ namespace OOX XLS::BaseObjectPtr CCellStyles::toBin() { auto ptr(new XLSB::STYLES); + auto ptr1(new XLSB::BeginStyles); + ptr->m_BrtBeginStyles = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) ptr->m_arBrtStyle.push_back(i->toBin()); + ptr1->cstyles = ptr->m_arBrtStyle.size(); return objectPtr; } EElementType CCellStyles::getType () const diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index a78fa208ef2..c62f0bdca5a 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -36,6 +36,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/Fill.h" +#include "../../XlsbFormat/Biff12_records/BeginFills.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" #include "../../../XlsbFormat/Biff12_unions/FILLS.h" @@ -159,9 +160,28 @@ namespace OOX if(m_oBgColor.IsInit()) ptr->brtColorBack = m_oBgColor->toColor(); - + else + { + ptr->brtColorBack.bAlpha = 255; + ptr->brtColorBack.bBlue = 0; + ptr->brtColorBack.bGreen = 0; + ptr->brtColorBack.bRed = 0; + ptr->brtColorBack.index = 64; + ptr->brtColorBack.nTintAndShade = 0; + ptr->brtColorBack.xColorType = 0; + } if(m_oFgColor.IsInit()) ptr->brtColorFore = m_oFgColor->toColor(); + else + { + ptr->brtColorFore.bAlpha = 255; + ptr->brtColorFore.bBlue = 255; + ptr->brtColorFore.bGreen = 255; + ptr->brtColorFore.bRed = 255; + ptr->brtColorFore.index = 64; + ptr->brtColorFore.nTintAndShade = 0; + ptr->brtColorFore.xColorType = 0; + } } EElementType CPatternFill::getType () const { @@ -289,6 +309,8 @@ namespace OOX XLSB::GradientStop stop; if(m_oPosition.IsInit()) stop.xnumPosition.data.value = m_oPosition->GetValue(); + else + stop.xnumPosition.data.value = 0; if(m_oColor.IsInit()) { stop.brtColor = m_oColor->toColor(); @@ -383,16 +405,28 @@ namespace OOX if(m_oType.IsInit()) ptr->iGradientType = m_oType->GetValue(); + else + ptr->iGradientType = 0; if(m_oDegree.IsInit()) ptr->xnumDegree.data.value = m_oDegree->GetValue(); + else + ptr->xnumDegree.data.value = 0; if(m_oLeft.IsInit()) ptr->xnumFillToLeft.data.value = m_oLeft->GetValue(); + else + ptr->xnumFillToLeft.data.value = 0; if(m_oRight.IsInit()) ptr->xnumFillToRight.data.value = m_oRight->GetValue(); + else + ptr->xnumFillToRight.data.value = 0; if(m_oTop .IsInit()) ptr->xnumFillToTop.data.value = m_oTop->GetValue(); + else + ptr->xnumFillToTop.data.value = 0; if(m_oBottom.IsInit()) ptr->xnumFillToBottom.data.value = m_oBottom->GetValue(); + else + ptr->xnumFillToBottom.data.value = 0; for(auto i:m_arrItems) { @@ -499,6 +533,11 @@ namespace OOX { m_oGradientFill->toBin(objectPtr); } + else + { + ptr->iGradientType = 0; + } + ptr->cNumStop = 0; return objectPtr; } EElementType CFill::getType () const @@ -607,9 +646,13 @@ namespace OOX XLS::BaseObjectPtr CFills::toBin() { auto ptr(new XLSB::FILLS); + auto ptr1(new XLSB::BeginFills); + ptr->m_BrtBeginFills = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); for(auto i : m_arrItems) ptr->m_arBrtFill.push_back(i->toBin()); + ptr1->cfills = ptr->m_arBrtFill.size(); return objectPtr; } diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 8028fc89577..f634cc49ff5 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -34,6 +34,7 @@ #include "../ComplexTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginFonts.h" #include "../../../XlsbFormat/Biff12_unions/FONTS.h" @@ -517,13 +518,15 @@ namespace OOX XLS::BaseObjectPtr CFonts::toBin() { auto ptr(new XLSB::FONTS); + auto ptr1(new XLSB::BeginFonts); + ptr->m_BrtBeginFonts = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) { ptr->m_arBrtFont.push_back(i->toBin()); } - + ptr1->cfonts = ptr->m_arBrtFont.size(); return objectPtr; } EElementType CFonts::getType () const diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index 9952bfd0172..930021a7b9f 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -84,7 +84,6 @@ namespace OOX { auto ptr(new XLSB::TableStyleElement); XLS::BaseObjectPtr objectPtr(ptr); - ptr->index = m_oDxfId->GetValue(); ptr->size = m_oSize->GetValue(); @@ -426,8 +425,11 @@ namespace OOX { auto ptr(new XLSB::TABLESTYLES); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginTableStyles); + ptr->m_BrtBeginTableStyles = XLS::BaseObjectPtr{ptr1}; for(auto i:m_arrItems) ptr->m_arTABLESTYLE.push_back(i->toBin()); + ptr1->cts = ptr->m_arTABLESTYLE.size(); return objectPtr; } EElementType CTableStyles::getType () const diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 98a218804ed..caf663bf663 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -36,6 +36,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginCellStyleXFs.h" #include "../../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" #include "../../../XlsbFormat/Biff12_unions/CELLXFS.h" @@ -121,6 +122,8 @@ namespace OOX ptr->alc = 6; else if (m_oHorizontal == SimpleTypes::Spreadsheet::EHorizontalAlignment::horizontalalignmentDistributed) ptr->alc = 7; + else + ptr->alc = 0; if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentTop) ptr->alcV = 0; @@ -132,6 +135,8 @@ namespace OOX ptr->alcV = 3; else if (m_oVertical == SimpleTypes::Spreadsheet::EVerticalAlignment::verticalalignmentDistributed) ptr->alcV = 4; + else + ptr->alcV = 2; } EElementType CAligment::getType () const @@ -370,7 +375,7 @@ namespace OOX } XLS::BaseObjectPtr CXfs::toBin() { - size_t id = 1; + size_t id = 0; auto ptr(new XLSB::XF(id, id)); XLS::BaseObjectPtr objectPtr(ptr); if(m_oBorderId.IsInit()) @@ -385,9 +390,12 @@ namespace OOX ptr->fsxButton = m_oPivotButton->GetValue(); if(m_oQuotePrefix.IsInit()) ptr->f123Prefix = m_oQuotePrefix->GetValue(); + ptr->ind_xf = 0; if (m_oXfId.IsInit()) ptr->ixfParent = m_oXfId->GetValue(); + else + ptr->ixfParent = 65535; if(m_oApplyAlignment.IsInit()) ptr->fAtrAlc = m_oApplyAlignment->GetValue(); if(m_oApplyBorder.IsInit()) @@ -403,6 +411,11 @@ namespace OOX if(m_oAligment.IsInit()) m_oAligment->toBin(objectPtr); + else + { + ptr->alc = 0; + ptr->alcV = 2; + } if(m_oProtection.IsInit()) m_oProtection->toBin(objectPtr); @@ -599,10 +612,14 @@ namespace OOX } XLS::BaseObjectPtr CCellStyleXfs::toBin() { - auto ptr(new XLSB::CELLSTYLEXFS); + auto ptr(new XLSB::CELLSTYLEXFS); + auto ptr1(new XLSB::BeginCellStyleXFs); + ptr->m_BrtBeginCellStyleXFs = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) ptr->m_arBrtXF.push_back(i->toBin()); + ptr1->cxfs = ptr->m_arBrtXF.size(); return objectPtr; } void CCellStyleXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index cbc1478bb3d..2e945d49f94 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -225,11 +225,11 @@ namespace OOX if (m_oFills.IsInit()) stylesStream->m_FILLS = m_oFills->toBin(); - if (m_oBorders.IsInit()) - stylesStream->m_BORDERS = m_oBorders->toBin(); + if (m_oBorders.IsInit()) + stylesStream->m_BORDERS = m_oBorders->toBin(); - if (m_oCellStyleXfs.IsInit()) - stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin(); + if (m_oCellStyleXfs.IsInit()) + stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin();// if (m_oCellXfs.IsInit()) stylesStream->m_CELLXFS = m_oCellXfs->toBin(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index ad8273138d9..fad3bdd11df 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1182,10 +1182,16 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); if(m_oActiveCell.IsInit()) ptr->activeCell = m_oActiveCell.get(); + else + ptr->activeCell = L"A1"; if(m_oActiveCellId.IsInit()) ptr->irefAct = m_oActiveCellId->GetValue(); + else + ptr->irefAct = 0; if(m_oSqref.IsInit()) ptr->sqref = m_oSqref.get(); + else + ptr->sqref = L"A1"; if(m_oPane.IsInit()) { if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) @@ -1197,6 +1203,10 @@ namespace OOX else if(m_oPane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) ptr->pnn_xlsb = 3; } + else + ptr->pnn_xlsb = 3; + ptr->rwAct = 0; + ptr->colAct = 0; return objectPtr; } @@ -1387,8 +1397,12 @@ namespace OOX pWsView->fSelected = false; if(m_oTopLeftCell.IsInit()) pWsView->topLeftCell = m_oTopLeftCell.get(); + else + pWsView->topLeftCell = L"A1"; if (m_oView.IsInit()) pWsView->xlView = m_oView->m_eValue; + else + pWsView->xlView = 0; if (m_oWindowProtection.IsInit()) pWsView->fWnProt = m_oWindowProtection->m_eValue; else @@ -1411,6 +1425,8 @@ namespace OOX pWsView->wScaleSLV = m_oZoomScaleSheetLayoutView->m_eValue; else pWsView->wScaleSLV = 0; + pWsView->rwTop = 0; + pWsView->colLeft = 0; if(m_oPane.IsInit()) ptr->m_BrtPane = m_oPane->toBin(); From 2d53f96522787ff712fe18f6f8bec03307eddee5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 14 Nov 2023 15:15:43 +0600 Subject: [PATCH 181/794] Add query table conversion --- OOXML/XlsxFormat/Table/QueryTable.h | 12 +- OOXML/XlsxFormat/Table/Tables.cpp | 185 +++++++++++++++++++++++++++- 2 files changed, 187 insertions(+), 10 deletions(-) diff --git a/OOXML/XlsxFormat/Table/QueryTable.h b/OOXML/XlsxFormat/Table/QueryTable.h index 9967417ab1c..23ce2196540 100644 --- a/OOXML/XlsxFormat/Table/QueryTable.h +++ b/OOXML/XlsxFormat/Table/QueryTable.h @@ -61,6 +61,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableField; @@ -99,6 +100,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableFields; @@ -126,6 +128,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableDeletedField; @@ -154,6 +157,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableFields; @@ -181,6 +185,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTableRefresh; @@ -224,6 +229,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_QueryTable; @@ -280,6 +286,7 @@ namespace OOX { } void readBin(const CPath& oPath); + XLS::BaseObjectPtr WriteBin() const; virtual void read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -288,10 +295,7 @@ namespace OOX } virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::QueryTable; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index a0b49257cad..64c4c6df970 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -47,12 +47,14 @@ #include "../../XlsbFormat/Biff12_records/ListTrFmla.h" #include "../../XlsbFormat/Biff12_records/List14.h" #include "../../XlsbFormat/Biff12_records/BeginDeletedName.h" +#include "../../XlsbFormat/Biff12_records/BeginDeletedNames.h" #include "../../XlsbFormat/QueryTableStream.h" #include "../../XlsbFormat/Biff12_unions/QSI.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" #include "../../XlsbFormat/Biff12_unions/QSIR.h" #include "../../XlsbFormat/Biff12_unions/QSIFS.h" +#include "../../XlsbFormat/Biff12_records/BeginQSIFs.h" #include "../../XlsbFormat/Biff12_unions/QSIF.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAMES.h" #include "../../XlsbFormat/Biff12_unions/DELETEDNAME.h" @@ -1109,6 +1111,29 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTableField::toBin() + { + auto ptr1(new XLSB::QSIF); + auto ptr(new XLSB::BeginQSIF); + ptr1->m_BrtBeginQSIF = XLS::BaseObjectPtr{ptr}; + + if(m_oId.IsInit()) + ptr->idField = m_oId->GetValue(); + if(m_oTableColumnId.IsInit()) + ptr->idList = m_oTableColumnId->GetValue(); + if(m_oName.IsInit()) + ptr->name = m_oName.get(); + if(m_oRowNumbers.IsInit()) + ptr->fRowNums = m_oRowNumbers.get(); + if(m_oFillFormulas.IsInit()) + ptr->fFillDown = m_oFillFormulas.get(); + if(m_oDataBound.IsInit()) + ptr->fUserIns = m_oDataBound.get(); + if(m_oClipped.IsInit()) + ptr->fClipped = m_oClipped.get(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1187,6 +1212,16 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CQueryTableFields::toBin() + { + auto ptr(new XLSB::QSIFS); + auto ptr1(new XLSB::BeginQSIFs); + ptr->m_BrtBeginQSIFs = XLS::BaseObjectPtr{ptr1}; + for(auto i:m_arrItems) + ptr->m_arQSIF.push_back(i->toBin()); + ptr1->nCols = m_arrItems.size(); + return XLS::BaseObjectPtr{ptr}; + } void CQueryTableFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1218,6 +1253,16 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CQueryTableDeletedField::toBin() + { + auto ptr1(new XLSB::DELETEDNAME); + auto ptr(new XLSB::BeginDeletedName); + ptr1->m_BrtBeginDeletedName = XLS::BaseObjectPtr{ptr}; + if(m_oName.IsInit()) + ptr->rgb = m_oName.get(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableDeletedField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1280,6 +1325,18 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") } } } + XLS::BaseObjectPtr CQueryTableDeletedFields::toBin() + { + auto ptr(new XLSB::DELETEDNAMES); + auto ptr1(new XLSB::BeginDeletedNames); + ptr->m_BrtBeginDeletedNames = XLS::BaseObjectPtr{ptr1}; + + for(auto i:m_arrItems) + ptr->m_arDELETEDNAME.push_back(i->toBin()); + + ptr1->nCols = ptr->m_arDELETEDNAME.size(); + return XLS::BaseObjectPtr{ptr}; + } void CQueryTableDeletedFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1345,6 +1402,36 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTableRefresh::toBin() + { + auto ptr1(new XLSB::QSIR); + auto ptr(new XLSB::BeginQSIR); + ptr1->m_BrtBeginQSIR = XLS::BaseObjectPtr{ptr}; + + if(m_oNextId.IsInit()) + ptr->idFieldNext = m_oNextId->GetValue(); + if(m_oMinimumVersion.IsInit()) + ptr->wVerBeforeRefreshAlert = m_oMinimumVersion->GetValue(); + if(m_FieldIdWrapped.IsInit()) + ptr->fidWrapped = m_FieldIdWrapped.get(); + if(m_HeadersInLastRefresh.IsInit()) + ptr->fTitlesOld = m_HeadersInLastRefresh.get(); + if(m_PreserveSortFilterLayout.IsInit()) + ptr->fPersist = m_PreserveSortFilterLayout.get(); + if(m_UnboundColumnsLeft.IsInit()) + ptr->ccolExtraLeft = m_UnboundColumnsLeft->GetValue(); + if(m_UnboundColumnsRight.IsInit()) + ptr->ccolExtraRight = m_UnboundColumnsRight->GetValue(); + + if(m_oQueryTableFields.IsInit()) + ptr1->m_QSIFS = m_oQueryTableFields->toBin(); + if(m_oQueryTableDeletedFields.IsInit()) + ptr1->m_DELETEDNAMES = m_oQueryTableDeletedFields->toBin(); + if(m_oSortState.IsInit()) + ptr1->m_SORTSTATE = m_oSortState->toBin(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTableRefresh::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1455,6 +1542,69 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CQueryTable::toBin() + { + auto ptr1(new XLSB::QSI); + auto ptr(new XLSB::BeginQSI); + ptr1->m_BrtBeginQSI = XLS::BaseObjectPtr{ptr}; + + if(m_oAdjustColumnWidth.IsInit()) + ptr->fAutoFit = m_oAdjustColumnWidth.get(); + if(m_oApplyAlignmentFormats.IsInit()) + ptr->fibitAtrAlc = m_oApplyAlignmentFormats.get(); + if(m_oApplyBorderFormats.IsInit()) + ptr->fibitAtrBdr = m_oApplyBorderFormats.get(); + if(m_oApplyFontFormats.IsInit()) + ptr->fibitAtrFnt = m_oApplyFontFormats.get(); + if(m_oApplyNumberFormats.IsInit()) + ptr->fibitAtrNum = m_oApplyNumberFormats.get(); + if(m_oApplyPatternFormats.IsInit()) + ptr->fibitAtrPat = m_oApplyPatternFormats.get(); + if(m_oApplyWidthHeightFormats.IsInit()) + ptr->fibitAtrProt = m_oApplyWidthHeightFormats.get(); + if(m_oBackgroundRefresh.IsInit()) + ptr->fAsync = m_oBackgroundRefresh.get(); + + if(m_oAutoFormatId.IsInit()) + ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + if(m_oConnectionId.IsInit()) + ptr->dwConnID = m_oConnectionId->GetValue(); + if(m_oDisableEdit.IsInit()) + ptr->fDisableEdit = m_oDisableEdit.get(); + if(m_oDisableRefresh.IsInit()) + ptr->fDisableRefresh = m_oDisableRefresh.get(); + if(m_oFillFormulas.IsInit()) + ptr->fFill = m_oFillFormulas.get(); + if(m_oFirstBackgroundRefresh.IsInit()) + ptr->fNewAsync = m_oFirstBackgroundRefresh.get(); + ptr->fOverwrite = false; + ptr->fShrink = false; + + if(m_oGrowShrinkType == L"overwriteClear" ) + ptr->fOverwrite = true; + else if(m_oGrowShrinkType == L"insertDelete") + ptr->fShrink = true; + if(m_oHeaders.IsInit()) + ptr->fTitles = m_oHeaders.get(); + if(m_oIntermediate.IsInit()) + ptr->fDummyList = m_oIntermediate.get(); + + if(!ptr->name.empty()) + m_oName = ptr->name; + if(m_oPreserveFormatting.IsInit()) + ptr->fPreserveFmt = m_oPreserveFormatting.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr->fAutoRefresh = m_oRefreshOnLoad.get(); + if(m_oRemoveDataOnSave.IsInit()) + ptr->fSaveData = !m_oRemoveDataOnSave.get(); + if(m_oRowNumbers.IsInit()) + ptr->fRowNums = m_oRowNumbers.get(); + + if(m_oQueryTableRefresh.IsInit()) + ptr1->m_QSIR = m_oQueryTableRefresh->toBin(); + + return XLS::BaseObjectPtr{ptr1}; + } void CQueryTable::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); @@ -1560,6 +1710,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } + XLS::BaseObjectPtr CQueryTableFile::WriteBin() const + { + XLSB::QueryTableStreamPtr querytableStream(new XLSB::QueryTableStream); + if(m_oQueryTable.IsInit()) + querytableStream->m_QSI = m_oQueryTable->toBin(); + return XLS::BaseObjectPtr{querytableStream}; + } void CQueryTableFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -1585,17 +1742,33 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if(false == m_oQueryTable.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L""); - m_oQueryTable->toXML(sXml); + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L""); + m_oQueryTable->toXML(sXml); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } + const OOX::FileType CQueryTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::QueryTableBin; + } + return OOX::Spreadsheet::FileTypes::QueryTable; + } } //Spreadsheet } // namespace OOX From fb608d3dd5d0c38047f171dc50e0b896c7b9c114 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 14 Nov 2023 16:33:26 +0600 Subject: [PATCH 182/794] Fix connection conversion --- OOXML/XlsxFormat/Table/Connections.cpp | 12 ++++++++++++ OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index ec86aeb199d..e5fd67ad72c 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -974,10 +974,14 @@ namespace OOX ptr1->iCredMethod = m_oCredentials->GetValue(); if(m_oBackground.IsInit()) ptr1->fBackgroundQuery = m_oBackground.get(); + else + ptr1->fBackgroundQuery = false; if(m_oDeleted.IsInit()) ptr1->fDeleted = m_oDeleted.get(); if(m_oDescription.IsInit()) ptr1->stConnDesc = m_oDescription.get(); + else + ptr1->fLoadConnectionDesc = false; if(m_oInterval.IsInit()) ptr1->wInterval = m_oInterval.get(); if(m_oKeepAlive.IsInit()) @@ -988,8 +992,12 @@ namespace OOX ptr1->fNewQuery = m_oNew.get(); if(m_oOdcFile.IsInit()) ptr1->stConnectionFile = m_oOdcFile.get(); + else + ptr1->fLoadSourceConnectionFile = false; if(m_oOnlyUseConnectionFile.IsInit()) ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); + else + ptr1->fAlwaysUseConnectionFile = false; if(m_oReconnectionMethod.IsInit()) ptr1->irecontype = m_oReconnectionMethod.get(); if(m_oRefreshedVersion.IsInit()) @@ -1004,8 +1012,12 @@ namespace OOX } if(m_oSingleSignOnId.IsInit()) ptr1->stSso = m_oSingleSignOnId.get(); + else + ptr1->fLoadSSOApplicationID = false; if(m_oSourceFile.IsInit()) ptr1->stDataFile = m_oSourceFile.get(); + else + ptr1->fLoadSourceDataFile = false; } return objectPtr; diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 84755a911f3..eab563e4a75 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -133,7 +133,15 @@ namespace OOX if (m_oXlm.IsInit()) ptr->fFutureFunction = m_oXlm->GetValue(); if (m_oRef.IsInit()) - ptr->rgce = m_oRef.get(); + { + auto ref = m_oRef.get(); + auto separatorPos = ref.find(L"!"); + if(separatorPos != std::string::npos && separatorPos != ref.size() -1) + ref = ref.substr(separatorPos + 1, ref.size() - separatorPos -1); + else if(separatorPos == ref.size() -1) + ref = L""; + ptr->rgce = ref; + } return objectPtr; } From e3a0b16578c780021d3361b368ac495a38237f46 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 16 Nov 2023 00:45:21 +0600 Subject: [PATCH 183/794] Fix styles conversion --- OOXML/XlsxFormat/Styles/Borders.cpp | 9 +++++++++ OOXML/XlsxFormat/Styles/CellStyles.cpp | 4 ++++ OOXML/XlsxFormat/Styles/TableStyles.cpp | 2 ++ OOXML/XlsxFormat/Styles/Xfs.cpp | 4 ++++ OOXML/XlsxFormat/Styles/dxf.cpp | 4 ++++ OOXML/XlsxFormat/Workbook/Sheets.cpp | 2 ++ OOXML/XlsxFormat/Workbook/Workbook.cpp | 6 ++++-- 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 23a60068942..d835092476f 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -36,6 +36,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../XlsbFormat/Biff12_records/Border.h" +#include "../../XlsbFormat/Biff12_records/BeginBorders.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" #include "../../../XlsbFormat/Biff12_unions/BORDERS.h" @@ -149,7 +150,10 @@ namespace OOX } if(!m_oStyle.IsInit()) + { + ptr->dg = 0x00; return; + } if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleNone) ptr->dg = 0x00; @@ -179,6 +183,8 @@ namespace OOX ptr->dg = 0x0C; else if (m_oStyle == SimpleTypes::Spreadsheet::EBorderStyle::borderstyleSlantDashDot) ptr->dg = 0x0D; + else + ptr->dg = 0x00; } bool CBorderProp::IsEmpty() { @@ -467,9 +473,12 @@ namespace OOX XLS::BaseObjectPtr CBorders::toBin() { auto ptr(new XLSB::BORDERS); + auto ptr1(new XLSB::BeginBorders); + ptr->m_BrtBeginBorders = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arBrtBorder.push_back(i->toBin()); + ptr1->cborders = ptr->m_arBrtBorder.size(); return objectPtr; } EElementType CBorders::getType () const diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index 6c7fe7e4097..1becfb48b46 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -80,6 +80,8 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); if(m_oBuiltinId.IsInit()) ptr->fBuiltIn = m_oBuiltinId->GetValue(); + else + ptr->fBuiltIn = false; if (m_oCustomBuiltin.IsInit()) ptr->fCustom = m_oCustomBuiltin->GetValue(); else @@ -90,6 +92,8 @@ namespace OOX ptr->fHidden = false; if (m_oILevel.IsInit()) ptr->iLevel = m_oILevel->GetValue(); + else + ptr->iLevel = 0; if (m_oName.IsInit()) ptr->stName = m_oName.get(); if (m_oXfId.IsInit()) diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index 930021a7b9f..f0a6174117b 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -430,6 +430,8 @@ namespace OOX for(auto i:m_arrItems) ptr->m_arTABLESTYLE.push_back(i->toBin()); ptr1->cts = ptr->m_arTABLESTYLE.size(); + ptr1->rgchDefTableStyle = m_oDefaultTableStyle.get(); + ptr1->rgchDefPivotStyle = m_oDefaultPivotStyle.get(); return objectPtr; } EElementType CTableStyles::getType () const diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index caf663bf663..65bb8bb1b25 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -37,6 +37,7 @@ #include "../../XlsbFormat/Biff12_records/CommonRecords.h" #include "../../XlsbFormat/Biff12_records/BeginCellStyleXFs.h" +#include "../../XlsbFormat/Biff12_records/BeginCellXFs.h" #include "../../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" #include "../../../XlsbFormat/Biff12_unions/CELLXFS.h" @@ -524,9 +525,12 @@ namespace OOX XLS::BaseObjectPtr CCellXfs::toBin() { auto ptr(new XLSB::CELLXFS); + auto ptr1(new XLSB::BeginCellXFs); + ptr->m_BrtBeginCellXFs = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrItems) ptr->m_arBrtXF.push_back(i->toBin()); + ptr1->cxfs = ptr->m_arBrtXF.size(); return objectPtr; } EElementType CCellXfs::getType () const diff --git a/OOXML/XlsxFormat/Styles/dxf.cpp b/OOXML/XlsxFormat/Styles/dxf.cpp index 1956658d240..a1a55855956 100644 --- a/OOXML/XlsxFormat/Styles/dxf.cpp +++ b/OOXML/XlsxFormat/Styles/dxf.cpp @@ -41,6 +41,7 @@ #include "../../XlsbFormat/Biff12_unions/DXF.h" #include "../../XlsbFormat/Biff12_unions/FRTDXF.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BeginDXFs.h" #include "../../Common/SimpleTypes_Shared.h" #include @@ -321,10 +322,13 @@ namespace OOX { auto ptr(new XLSB::DXFS); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginDXFs); + ptr->m_BrtBeginDXFs = XLS::BaseObjectPtr{ptr1}; for(auto i:m_arrItems) { ptr->m_aruDXF.push_back(i->toBin()); } + ptr1->cdxfs = ptr->m_aruDXF.size(); return objectPtr; } void CDxfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index 7b64bb9a31d..6fc2a4616d3 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -84,6 +84,8 @@ namespace OOX ptr->hsState = XLSB::BundleSh::ST_SheetState::HIDDEN; else if(m_oState == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) ptr->hsState = XLSB::BundleSh::ST_SheetState::VERYHIDDEN; + else + ptr->hsState = XLSB::BundleSh::ST_SheetState::VISIBLE; return objectPtr; } diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 5354977701e..9da4d3f8699 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -311,7 +311,9 @@ namespace OOX ptr->m_arSUP = m_oExternalReferences->toBin(); workBookStream->m_EXTERNALS = XLS::BaseObjectPtr{ptr}; } - if (m_oAppName.IsInit()) + + /* + if (m_oAppName.IsInit()) { auto ptr(new XLSB::FileVersion); ptr->stAppName = m_oAppName.get(); @@ -319,7 +321,7 @@ namespace OOX ptr->stLowestEdited = L""; ptr->stRupBuild = L""; workBookStream->m_BrtFileVersion = XLS::BaseObjectPtr{ptr}; - } + }*/ if (m_oExtLst.IsInit()) workBookStream->m_FRTWORKBOOK = m_oExtLst->toBinWorkBook(); From f9b4f8402b4dcbb6767de50d1ca9f3d1018ddb7e Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 17 Nov 2023 12:04:13 +0300 Subject: [PATCH 184/794] added conversion of operations on sets and connections. tests added --- .../StarMath2OOXML/TestSMConverter/main.cpp | 470 +++++++++++++++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 136 ++--- .../StarMath2OOXML/cconversionsmtoooxml.h | 9 +- .../StarMath2OOXML/cstarmathpars.cpp | 475 +++++++++++++++++- .../Converter/StarMath2OOXML/cstarmathpars.h | 56 ++- .../Converter/StarMath2OOXML/typeselements.h | 12 +- 6 files changed, 1062 insertions(+), 96 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 7369496324f..3e38e5b8ee4 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -143,3 +143,473 @@ TEST(SMConvectorTest,OperatorSumFromTo) std::wstring XmlString = L"666777567"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } + +TEST(SMConvectorTest,SetOperationUnion) +{ + std::wstring wsString = L"23 union 45"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23\u22C345"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationIntersection) +{ + std::wstring wsString = L"15 intersection 1234"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"15\u22C21234"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSetminus) +{ + std::wstring wsString = L"7 setminus 15745"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"7\u221615745"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSetquotient) +{ + std::wstring wsString = L"91 setquotient 45"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"91\u221545"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSubset) +{ + std::wstring wsString = L"1 subset 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22822"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSubseteq) +{ + std::wstring wsString = L"77subseteq66"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"77\u228666"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSupset) +{ + std::wstring wsString = L"11supset22"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"11\u228322"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationSupseteq) +{ + std::wstring wsString = L"1 supseteq 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22872"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsubset) +{ + std::wstring wsString = L"21nsubset2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"21\u22842"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsubseteq) +{ + std::wstring wsString = L"782nsubseteq250"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"782\u2288250"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsupset) +{ + std::wstring wsString = L"1nsupset2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22852"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNsupseteq) +{ + std::wstring wsString = L"1nsupseteq2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22892"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationIn) +{ + std::wstring wsString = L"1 in 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1\u22082"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationNotin) +{ + std::wstring wsString = L"3 notin 4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3\u22094"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SetOperationOwns) +{ + std::wstring wsString = L"5owns6"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"5\u220B6"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlarrow) +{ + std::wstring wsString = L"7 dlarrow 8"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"7\u21D08"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlrarrow) +{ + std::wstring wsString = L"9 dlrarrow 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"9\u21D410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDrarrow) +{ + std::wstring wsString = L"11drarrow12"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"11\u21D212"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionEquals) +{ + std::wstring wsString = L"13=14"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"13=14"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNotequals) +{ + std::wstring wsString = L"15 <> 16"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"15\u226016"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionLearrow) +{ + std::wstring wsString = L"17<18"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"17<18"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionLearrowequals) +{ + std::wstring wsString = L"19<= 20"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"19\u226420"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionRiarrow) +{ + std::wstring wsString = L"21 >22"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"21>22"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionRiarrowequals) +{ + std::wstring wsString = L"23 >=24"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23\u226524"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDllearrow) +{ + std::wstring wsString = L"25 <<26"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"25\u226A26"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDlriarrow) +{ + std::wstring wsString = L"27 >> 28"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"27\u226B28"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionApprox) +{ + std::wstring wsString = L"29 approx30"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"29\u224830"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSim) +{ + std::wstring wsString = L"31sim 32"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"31\u223C32"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSimeq) +{ + std::wstring wsString = L"33 simeq 34"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"33\u224334"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionEquiv) +{ + std::wstring wsString = L"35 equiv 36"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"35\u226136"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionProp) +{ + std::wstring wsString = L"37 prop 38"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"37\u221D38"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionParallel) +{ + std::wstring wsString = L"39 parallel 40"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"39\u222540"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionOrtho) +{ + std::wstring wsString = L"41ortho42"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"41\u22A542"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDivides) +{ + std::wstring wsString = L"43 divides 44"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"43\u222344"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNdivides) +{ + std::wstring wsString = L"45 ndivides 46"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"45\u222446"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionToward) +{ + std::wstring wsString = L"47 toward 48"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"47\u219248"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionTransl) +{ + std::wstring wsString = L"49 transl 50"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"49\u22B750"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionTransr) +{ + std::wstring wsString = L"51 transr 52"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"51\u22B652"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionDef) +{ + std::wstring wsString = L"53def54"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"53\u225D54"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPrec) +{ + std::wstring wsString = L"55prec56"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"55\u227A56"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSucc) +{ + std::wstring wsString = L"57 succ 58"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"57\u227B58"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPreccurlyeq) +{ + std::wstring wsString = L"59 preccurlyeq 60"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"59\u227C60"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSucccurlyeq) +{ + std::wstring wsString = L"61 succcurlyeq 62"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"61\u227D62"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionPrecsim) +{ + std::wstring wsString = L"63 precsim 64"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"63\u227E64"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionSuccsim) +{ + std::wstring wsString = L"65 succsim 66"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"65\u227F66"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNprec) +{ + std::wstring wsString = L"67nprec68"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"67\u228068"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,ConnectionNsucc) +{ + std::wstring wsString = L"69nsucc70"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"69\u228170"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index b71ecf436db..1410f92e47c 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -20,85 +20,85 @@ namespace StarMath { // oFile.WriteStringUTF8(m_oXmlWrite->GetXmlString()); // oFile.CloseFile(); } - void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* oXmlWrite) + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite) { - oXmlWrite->WriteNodeBegin(L"w:rPr",false); - oXmlWrite->WriteNodeBegin(L"w:rFonts",true); - oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeBegin(L"w:sz",true); - oXmlWrite->WriteAttribute(L"w:val",L"40"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeBegin(L"w:szCs",true); - oXmlWrite->WriteAttribute(L"w:val",L"40"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* oXmlWrite) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite) { - oXmlWrite->WriteNodeBegin(L"m:fPr",false); + pXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) { - oXmlWrite->WriteNodeBegin(L"m:type",true); - oXmlWrite->WriteAttribute(L"m:val",wsType); - oXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:type",true); + pXmlWrite->WriteAttribute(L"m:val",wsType); + pXmlWrite->WriteNodeEnd(L"w",true,true); } - oXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - oXmlWrite->WriteNodeBegin(L"w:rPr",false); - oXmlWrite->WriteNodeBegin(L"w:rFonts",true); - oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNode(L"w:i",L""); - //m_oXmlWrite->WriteNode(L"w:iCs",L""); - oXmlWrite->WriteNodeBegin(L"w:sz",true); - oXmlWrite->WriteAttribute(L"w:val",L"40"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeBegin(L"w:szCs",true); - oXmlWrite->WriteAttribute(L"w:val",L"40"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - oXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); - oXmlWrite->WriteNodeEnd(L"m:fPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNode(L"w:i",L""); + //m_pXmlWrite->WriteNode(L"w:iCs",L""); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } - void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* oXmlWrite) + void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite) { - oXmlWrite->WriteNodeBegin(L"m:naryPr",false); - oXmlWrite->WriteNodeBegin(L"m:chr",true); - oXmlWrite->WriteAttribute(L"m:val",wsTypeOperator); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNodeBegin(L"m:limLoc",true); - oXmlWrite->WriteAttribute(L"m:val",L"undOvr"); - oXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:naryPr",false); + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeOperator); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:limLoc",true); + pXmlWrite->WriteAttribute(L"m:val",L"undOvr"); + pXmlWrite->WriteNodeEnd(L"w",true,true); if(bEmptySub) { - oXmlWrite->WriteNodeBegin(L"m:subHide",true); - oXmlWrite->WriteAttribute(L"m:val",L"1"); - oXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:subHide",true); + pXmlWrite->WriteAttribute(L"m:val",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,true); } if(bEmptySup) { - oXmlWrite->WriteNodeBegin(L"m:supHide",true); - oXmlWrite->WriteAttribute(L"m:val",L"1"); - oXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:supHide",true); + pXmlWrite->WriteAttribute(L"m:val",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,true); } - oXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - oXmlWrite->WriteNodeBegin(L"w:rPr",false); - oXmlWrite->WriteNodeBegin(L"w:rFonts",true); - oXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - oXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - oXmlWrite->WriteNodeEnd(L"w",true,true); - oXmlWrite->WriteNode(L"w:i",L""); - oXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - oXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); - oXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNode(L"w:i",L""); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } - void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock,XmlUtils::CXmlWriter* oXmlWrite) + void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock,XmlUtils::CXmlWriter* pXmlWrite) { - oXmlWrite->WriteNodeBegin(wsNameBlock,false); - CValueBlock->ConversionToOOXML(oXmlWrite); - oXmlWrite->WriteNodeEnd(wsNameBlock,false,false); + pXmlWrite->WriteNodeBegin(wsNameBlock,false); + CValueBlock->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameBlock,false,false); } std::wstring CConversionSMtoOOXML::GetOOXML() { @@ -106,9 +106,17 @@ namespace StarMath { } void CConversionSMtoOOXML::EndConversion() { - //m_oXmlWrite->WriteNodeEnd(L"m:r",false,false); + //m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); m_oXmlWrite->WriteNodeEnd(L"m:oMath",false,false); m_oXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } + void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:funcPr", false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr", false); + StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); + pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 975c7f630fc..09e23d500f3 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -11,10 +11,11 @@ namespace StarMath { public: CConversionSMtoOOXML(); void StartConversion(std::vector arPars); - static void StandartProperties(XmlUtils::CXmlWriter* oXmlWrite); - static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* oXmlWrite); - static void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* m_oXmlWrite); - static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* oXmlWrite); + static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite); + static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite); + static void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite); + static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite); + static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* pXmlWrite); void EndConversion(); std::wstring GetOOXML() ; private: diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 8f31a51c1da..d9f2bdcd644 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -12,7 +12,7 @@ namespace StarMath CElement* pTempElement = ParseElement(pReader); if(nullptr == pTempElement) break; - if(!m_arEquation.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations || pTempElement->GetBaseType() == TypeElement::Connection) ) + if(!m_arEquation.empty() && CheckForLeftArgument(pTempElement->GetBaseType()) ) { AddLeftArgument(m_arEquation.back(),pTempElement); m_arEquation.pop_back(); @@ -45,7 +45,7 @@ namespace StarMath if(pElement != nullptr) { pElement->SetAttribute(arAttributes); - pReader->ClearWString(); + pReader->ClearReader(); pElement->Parse(pReader); // if(CheckingTheNextElement(itStart,itEnd,CIndex::IsIndex)) // { @@ -60,9 +60,9 @@ namespace StarMath template void SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) { - T* pBinOpElement = dynamic_cast(pElementWhichAdd); - pBinOpElement->SetLeftArg(pLeftArg); - pElementWhichAdd = pBinOpElement; + T* pTempElement = dynamic_cast(pElementWhichAdd); + pTempElement->SetLeftArg(pLeftArg); + pElementWhichAdd = pTempElement; } void CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) @@ -84,6 +84,11 @@ namespace StarMath SetLeft(pLeftArg,pElementWhichAdd); break; } + case TypeElement::BracketWithIndex: + { + SetLeft(pLeftArg,pElementWhichAdd); + break; + } default: break; } @@ -93,7 +98,7 @@ namespace StarMath CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - while(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::SetOperations || pReader->GetGlobalType() == TypeElement::Connection) + while(CheckForLeftArgument(pReader->GetGlobalType())) { CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); if(pFirstTempElement != nullptr) @@ -109,6 +114,22 @@ namespace StarMath } return pFirstTempElement; } + bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType) + { + switch(enType) + { + case TypeElement::BinOperator: + return true; + case TypeElement::Connection: + return true; + case TypeElement::SetOperations: + return true; + case TypeElement::BracketWithIndex: + return true; + default: + return false; + } + } //class methods CAttribute CAttribute::~CAttribute() {} @@ -283,6 +304,14 @@ namespace StarMath return new CElementBracket(pReader->GetLocalType()); case TypeElement::Operation: return new CElementOperator(pReader->GetLocalType()); + case TypeElement::BracketWithIndex: + return new CElementBracketWithIndex(pReader->GetLocalType()); + case TypeElement::Grade: + return new CElementGrade(); + case TypeElement::Matrix: + return new CElementMatrix(pReader->GetLocalType()); + case TypeElement::SpecialSymbol: + return new CElementSpecialSymbol(pReader->GetLocalType()); default: return nullptr; } @@ -317,7 +346,7 @@ namespace StarMath } void CElementString::Parse(CStarMathReader* pReader) { - pReader->ClearWString(); + pReader->ClearReader(); } void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) { @@ -336,7 +365,7 @@ namespace StarMath { for(wchar_t cOneElement: wsToken) { - if(!isdigit(cOneElement)) return TypeElement::undefine; + if(!isdigit(cOneElement) || L'\0' == cOneElement) return TypeElement::undefine; } return TypeElement::String; } @@ -361,7 +390,7 @@ namespace StarMath } void CElementBinOperator::Parse(CStarMathReader* pReader) { - if(pReader->GetLocalType() == TypeElement::frac) + if(m_enTypeBinOp == TypeElement::frac) { SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader)); SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); @@ -371,7 +400,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) + if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); @@ -498,6 +527,7 @@ namespace StarMath CElementBracket::CElementBracket(const TypeElement& enType) { m_enTypeBracket = enType; + SetBaseType(TypeElement::Bracket); } CElementBracket::~CElementBracket() { @@ -536,7 +566,6 @@ namespace StarMath else if(L"right" == wsToken) return TypeElement::right; else return TypeElement::undefine; } - //сделать не через SetTypesToken,а локальную переменную и через нее определять конец скобок void CElementBracket::Parse(CStarMathReader* pReader) { pReader->GetToken(); @@ -548,7 +577,7 @@ namespace StarMath while(enBracketClose == TypeElement::undefine) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(!m_arBrecketValue.empty() && (pTempElement->GetBaseType() == TypeElement::BinOperator || pTempElement->GetBaseType() == TypeElement::SetOperations) ) + if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) { CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement); m_arBrecketValue.pop_back(); @@ -566,7 +595,7 @@ namespace StarMath else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() - pReader->ClearWString(); + pReader->ClearReader(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -576,12 +605,26 @@ namespace StarMath CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) { m_enTypeSpecial = enType; + SetBaseType(TypeElement::SpecialSymbol); } CElementSpecialSymbol::~CElementSpecialSymbol() {} void CElementSpecialSymbol::Parse(CStarMathReader* pReader) { } + TypeElement CElementSpecialSymbol::GetSpecialSymbol(const std::wstring &wsToken) + { + if(L"emptyset" == wsToken) return TypeElement::emptyset; + else if(L"aleph" == wsToken) return TypeElement::aleph; + else if(L"setN" == wsToken) return TypeElement::setN; + else if(L"setZ" == wsToken) return TypeElement::setZ; + else if(L"setQ" == wsToken) return TypeElement::setQ; + else if(L"setR" == wsToken) return TypeElement::setR; + else if(L"setc" == wsToken) return TypeElement::setC; + else return TypeElement::undefine; + } + void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + {} //class methods CElementSetOperations CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) { @@ -614,7 +657,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator) + if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) { CElement* pBinOpElement = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOpElement); @@ -624,14 +667,70 @@ namespace StarMath } void CElementSetOperations::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + m_pLeftArgument->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:r", false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(m_enTypeSet) + { + case TypeElement::Union: + pXmlWrite->WriteString(L"\u22C3"); + break; + case TypeElement::intersection: + pXmlWrite->WriteString(L"\u22C2"); + break; + case TypeElement::setminus: + pXmlWrite->WriteString(L"\u2216"); + break; + case TypeElement::setquotient: + pXmlWrite->WriteString(L"\u2215"); + break; + case TypeElement::subset: + pXmlWrite->WriteString(L"\u2282"); + break; + case TypeElement::subseteq: + pXmlWrite->WriteString(L"\u2286"); + break; + case TypeElement::supset: + pXmlWrite->WriteString(L"\u2283"); + break; + case TypeElement::supseteq: + pXmlWrite->WriteString(L"\u2287"); + break; + case TypeElement::nsubset: + pXmlWrite->WriteString(L"\u2284"); + break; + case TypeElement::nsubseteq: + pXmlWrite->WriteString(L"\u2288"); + break; + case TypeElement::nsupset: + pXmlWrite->WriteString(L"\u2285"); + break; + case TypeElement::nsupseteq: + pXmlWrite->WriteString(L"\u2289"); + break; + case TypeElement::in: + pXmlWrite->WriteString(L"\u2208"); + break; + case TypeElement::owns: + pXmlWrite->WriteString(L"\u220B"); + break; + case TypeElement::notin: + pXmlWrite->WriteString(L"\u2209"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_pRightArgument->ConversionToOOXML(pXmlWrite); } TypeElement CElementSetOperations::GetSetOperation(const std::wstring &wsToken) { if(L"intersection" == wsToken) return TypeElement::intersection; else if(L"union" == wsToken) return TypeElement::Union; else if(L"setminus" == wsToken) return TypeElement::setminus; - else if(L"setquoyient" == wsToken) return TypeElement::setquoyient; + else if(L"setquotient" == wsToken) return TypeElement::setquotient; else if(L"subseteq" == wsToken) return TypeElement::subseteq; else if(L"subset" == wsToken) return TypeElement::subset; else if(L"supset" == wsToken) return TypeElement::supset; @@ -639,7 +738,7 @@ namespace StarMath else if(L"nsubset" == wsToken) return TypeElement::nsubset; else if(L"nsubseteq" == wsToken) return TypeElement::nsubseteq; else if(L"nsupset" == wsToken) return TypeElement::nsupset; - else if(L"nsubseteq" == wsToken) return TypeElement::nsubseteq; + else if(L"nsupseteq" == wsToken) return TypeElement::nsupseteq; else if(L"in" == wsToken) return TypeElement::in; else if(L"notin" == wsToken) return TypeElement::notin; else if(L"owns" == wsToken) return TypeElement::owns; @@ -677,7 +776,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator) + if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); @@ -685,9 +784,117 @@ namespace StarMath } else SetRightArg(pTempElement); } + //absent leslant,geslant and toward void CElementConnection::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + m_pLeftArgument->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(m_enTypeCon) + { + case TypeElement::equals: + pXmlWrite->WriteString(L"="); + break; + case TypeElement::notequals: + pXmlWrite->WriteString(L"\u2260"); + break; + case TypeElement::learrow: + pXmlWrite->WriteString(L"<"); + break; + case TypeElement::learrowequals: + pXmlWrite->WriteString(L"\u2264"); + break; + case TypeElement::riarrow: + pXmlWrite->WriteString(L">"); + break; + case TypeElement::riarrowequals: + pXmlWrite->WriteString(L"\u2265"); + break; + case TypeElement::dllearrow: + pXmlWrite->WriteString(L"\u226A"); + break; + case TypeElement::dlriarrow: + pXmlWrite->WriteString(L"\u226B"); + break; + case TypeElement::dlrarrow: + pXmlWrite->WriteString(L"\u21D4"); + break; + case TypeElement::drarrow: + pXmlWrite->WriteString(L"\u21D2"); + break; + case TypeElement::dlarrow: + pXmlWrite->WriteString(L"\u21D0"); + break; + case TypeElement::prec: + pXmlWrite->WriteString(L"\u227A"); + break; + case TypeElement::succ: + pXmlWrite->WriteString(L"\u227B"); + break; + case TypeElement::preccurlyeq: + pXmlWrite->WriteString(L"\u227C"); + break; + case TypeElement::succcurlyeq: + pXmlWrite->WriteString(L"\u227D"); + break; + case TypeElement::precsim: + pXmlWrite->WriteString(L"\u227E"); + break; + case TypeElement::succsim: + pXmlWrite->WriteString(L"\u227F"); + break; + case TypeElement::nprec: + pXmlWrite->WriteString(L"\u2280"); + break; + case TypeElement::nsucc: + pXmlWrite->WriteString(L"\u2281"); + break; + case TypeElement::approx: + pXmlWrite->WriteString(L"\u2248"); + break; + case TypeElement::sim: + pXmlWrite->WriteString(L"\u223C"); + break; + case TypeElement::simeq: + pXmlWrite->WriteString(L"\u2243"); + break; + case TypeElement::equiv: + pXmlWrite->WriteString(L"\u2261"); + break; + case TypeElement::prop: + pXmlWrite->WriteString(L"\u221D"); + break; + case TypeElement::parallel: + pXmlWrite->WriteString(L"\u2225"); + break; + case TypeElement::ortho: + pXmlWrite->WriteString(L"\u22A5"); + break; + case TypeElement::divides: + pXmlWrite->WriteString(L"\u2223"); + break; + case TypeElement::ndivides: + pXmlWrite->WriteString(L"\u2224"); + break; + case TypeElement::toward: + pXmlWrite->WriteString(L"\u2192"); + break; + case TypeElement::transl: + pXmlWrite->WriteString(L"\u22B7"); + break; + case TypeElement::transr: + pXmlWrite->WriteString(L"\u22B6"); + break; + case TypeElement::def: + pXmlWrite->WriteString(L"\u225D"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t", false, false); + pXmlWrite->WriteNodeEnd(L"m:r",false ,false); + m_pRightArgument->ConversionToOOXML(pXmlWrite); } TypeElement CElementConnection::GetConnection(const std::wstring& wsToken) { @@ -786,11 +993,80 @@ namespace StarMath void CElementFunction::Parse(CStarMathReader* pReader) { SetValueFunction(CParserStarMathString::ParseElement(pReader)); - pReader->ClearWString(); + pReader->ClearReader(); } void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + pXmlWrite->WriteNodeBegin(L"m:func",false); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:fName",false); + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"m:rPr",false); + pXmlWrite->WriteNodeBegin(L"m:sty",true); + pXmlWrite->WriteAttribute(L"m:val",L"p"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch (m_enTypeFunction) { + case TypeElement::cos: + pXmlWrite->WriteString(L"cos"); + break; + case TypeElement::sin: + pXmlWrite->WriteString(L"sin"); + break; + case TypeElement::tan: + pXmlWrite->WriteString(L"tan"); + break; + case TypeElement::cot: + pXmlWrite->WriteString(L"cot"); + break; + case TypeElement::sinh: + pXmlWrite->WriteString(L"sinh"); + break; + case TypeElement::cosh: + pXmlWrite->WriteString(L"cosh"); + break; + case TypeElement::tanh: + pXmlWrite->WriteString(L"tanh"); + break; + case TypeElement::coth: + pXmlWrite->WriteString(L"coth"); + break; + case TypeElement::arcsin: + pXmlWrite->WriteString(L"arcsin"); + break; + case TypeElement::arccos: + pXmlWrite->WriteString(L"arccos"); + break; + case TypeElement::arctan: + pXmlWrite->WriteString(L"arctan"); + break; + case TypeElement::arccot: + pXmlWrite->WriteString(L"arccot"); + break; + case TypeElement::arsinh: + pXmlWrite->WriteString(L"arsinh"); + break; + case TypeElement::arcosh: + pXmlWrite->WriteString(L"arcosh"); + break; + case TypeElement::artanh: + pXmlWrite->WriteString(L"artanh"); + break; + case TypeElement::arcoth: + pXmlWrite->WriteString(L"arcoth"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + m_pValue->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:func",false,false); } TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) { @@ -882,12 +1158,12 @@ namespace StarMath pReader->SetTypesToken(); if(pReader->GetLocalType() == TypeElement::from) { - pReader->ClearWString(); + pReader->ClearReader(); SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } if(pReader->GetLocalType() == TypeElement::to) { - pReader->ClearWString(); + pReader->ClearReader(); SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } @@ -944,6 +1220,24 @@ namespace StarMath m_enGlobalType = TypeElement::Operation; return; } + m_enUnderType = CElementBracketWithIndex::GetBracketWithIndex(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::BracketWithIndex; + return; + } + m_enUnderType = CElementGrade::GetGrade(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Grade; + return; + } + m_enUnderType=CElementMatrix::GetMatrix(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Matrix; + return; + } m_enUnderType = CElementBracket::GetBracketOpen(m_wsToken); if(m_enUnderType != TypeElement::undefine) { @@ -956,6 +1250,12 @@ namespace StarMath m_enGlobalType = TypeElement::String; return; } + m_enUnderType = CElementSpecialSymbol::GetSpecialSymbol(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::SpecialSymbol; + return; + } m_enUnderType = CElementBinOperator::GetBinOperator(m_wsToken); if(m_enUnderType != TypeElement::undefine) { @@ -1011,9 +1311,11 @@ namespace StarMath // std::wstring wsNextElement = CParserStarMathString::GetElement(m_itStart,m_itEnd); // } // } - void CStarMathReader::ClearWString() + void CStarMathReader::ClearReader() { m_wsToken.clear(); + m_enGlobalType = TypeElement::Empty; + m_enUnderType = TypeElement::Empty; } bool CStarMathReader::EmptyString() { @@ -1053,6 +1355,131 @@ namespace StarMath if(!m_wsElement.empty()) return m_wsElement; else return {}; } +//class methods CElementBracketWithIndex + CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType): m_pLeftArg(nullptr), m_pValue(nullptr) + { + m_enTypeBracketWithIndex = enType; + SetBaseType(TypeElement::BracketWithIndex); + } + CElementBracketWithIndex::~CElementBracketWithIndex() + { + delete m_pLeftArg; + delete m_pValue; + } + void CElementBracketWithIndex::SetLeftArg(CElement *pElement) + { + m_pLeftArg = pElement; + } + void CElementBracketWithIndex::SetBracketValue(CElement *pElement) + { + m_pValue = pElement; + } + void CElementBracketWithIndex::Parse(CStarMathReader *pReader) + { + SetBracketValue(CParserStarMathString::ParseElement(pReader)); + } + void CElementBracketWithIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + + } + TypeElement CElementBracketWithIndex::GetBracketWithIndex(const std::wstring &wsToken) + { + if(L"overbrace" == wsToken) return TypeElement::overbrace; + else if(L"underbrace" == wsToken) return TypeElement::underbrace; + else return TypeElement::undefine; + } +//class methods CElementGrade + CElementGrade::CElementGrade(): m_pValueFrom(nullptr), m_pValueGrade(nullptr), m_pValueTo(nullptr) + { + SetBaseType(TypeElement::Grade); + } + CElementGrade::~CElementGrade() + { + delete m_pValueFrom; + delete m_pValueTo; + delete m_pValueGrade; + } + void CElementGrade::SetValueFrom(CElement* pElement) + { + m_pValueFrom = pElement; + } + void CElementGrade::SetValueTo(CElement *pElement) + { + m_pValueTo = pElement; + } + void CElementGrade::SetValueGrade(CElement *pElement) + { + m_pValueGrade = pElement; + } + void CElementGrade::Parse(CStarMathReader *pReader) + { + SetValueGrade(CParserStarMathString::ParseElement(pReader)); + pReader->GetToken(); + pReader->SetTypesToken(); + if(pReader->GetLocalType() == TypeElement::from) + { + pReader->ClearReader(); + SetValueFrom(CParserStarMathString::ParseElement(pReader)); + pReader->GetToken(); + pReader->SetTypesToken(); + } + if(pReader->GetLocalType() == TypeElement::to) + { + pReader->ClearReader(); + SetValueTo(CParserStarMathString::ParseElement(pReader)); + } + } + void CElementGrade::ConversionToOOXML(XmlUtils::CXmlWriter *oXmlWrite) + { + + } + TypeElement CElementGrade::GetGrade(const std::wstring &wsToken) + { + if(L"evaluate" == wsToken) return TypeElement::evaluate; + else return TypeElement::undefine; + } +//class methods CElementMatrix + CElementMatrix::CElementMatrix(const TypeElement &enType): m_pFirstArgument(nullptr), m_pSecondArgument(nullptr) + { + m_enTypeMatrix = enType; + SetBaseType(TypeElement::Matrix); + } + CElementMatrix::~CElementMatrix() + { + delete m_pFirstArgument; + delete m_pSecondArgument; + } + void CElementMatrix::SetFirstArgument(CElement *pElement) + { + m_pFirstArgument = pElement; + } + void CElementMatrix::SetSecondArgument(CElement *pElement) + { + m_pSecondArgument = pElement; + } + TypeElement CElementMatrix::GetMatrix(const std::wstring &wsToken) + { + if(L"binom" == wsToken) return TypeElement::binom; + else if(L"stack" == wsToken) return TypeElement::stack; + else if(L"matrix" == wsToken) return TypeElement::matrix; + else return TypeElement::undefine; + } + void CElementMatrix::Parse(CStarMathReader *pReader) + { + if(m_enTypeMatrix == TypeElement::binom) + { + SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + else + { + SetFirstArgument(CParserStarMathString::ParseElement(pReader)); + } + } + void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f10bd3d1b80..a2d01986a0c 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -23,7 +23,7 @@ namespace StarMath TypeElement GetLocalType(); std::wstring GetString(); //clearing a variable m_wsToken - void ClearWString(); + void ClearReader(); bool CheckIteratorPosition(); bool EmptyString(); private: @@ -137,6 +137,23 @@ namespace StarMath TypeElement m_enTypeOperator; }; + class CElementGrade: public CElement + { + public: + CElementGrade(); + virtual ~CElementGrade(); + void SetValueGrade(CElement* pElement); + void SetValueFrom(CElement* pElement); + void SetValueTo(CElement* pElement); + static TypeElement GetGrade(const std::wstring& wsToken); + private: + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + CElement* m_pValueGrade; + CElement* m_pValueFrom; + CElement* m_pValueTo; + }; + class CElementBracket: public CElement { public: @@ -146,12 +163,28 @@ namespace StarMath static TypeElement GetBracketOpen(const std::wstring& wsToken); private: void Parse(CStarMathReader* pReader) override; - void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite); + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; TypeElement GetBracketClose(const std::wstring& wsToken); TypeElement m_enTypeBracket; std::vector m_arBrecketValue; }; + class CElementBracketWithIndex: public CElement + { + public: + CElementBracketWithIndex(const TypeElement& enType); + virtual ~CElementBracketWithIndex(); + void SetLeftArg(CElement* pElement); + void SetBracketValue(CElement* pElement); + static TypeElement GetBracketWithIndex(const std::wstring& wsToken); + private: + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pLeftArg; + CElement* m_pValue; + TypeElement m_enTypeBracketWithIndex; + }; + class CElementSetOperations: public CElement { public: @@ -208,11 +241,29 @@ namespace StarMath public: CElementSpecialSymbol(const TypeElement& enType); virtual ~CElementSpecialSymbol(); + static TypeElement GetSpecialSymbol(const std::wstring& wsToken); private: void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; TypeElement m_enTypeSpecial; }; + class CElementMatrix: public CElement + { + public: + CElementMatrix(const TypeElement& enType); + virtual ~CElementMatrix(); + void SetFirstArgument(CElement* pElement); + void SetSecondArgument(CElement* pElement); + static TypeElement GetMatrix(const std::wstring& wsToken); + private: + void Parse(CStarMathReader *pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pFirstArgument; + CElement* m_pSecondArgument; + TypeElement m_enTypeMatrix; + }; + class CParserStarMathString { public: @@ -220,6 +271,7 @@ namespace StarMath static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static void AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); + static bool CheckForLeftArgument(const TypeElement& enType); static CElement* ReadingWithoutBracket(CStarMathReader* pReader); private: std::vector m_arEquation; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 038e89d5a43..c12a5fbad08 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -10,6 +10,8 @@ enum class TypeElement{ SetOperations, Operator, Bracket, + BracketWithIndex, + Grade, //BracketEnd, UnarSign, Attribute, @@ -120,7 +122,7 @@ enum class TypeElement{ intersection, Union, setminus, - setquoyient, + setquotient, subseteq, subset, supset, @@ -167,7 +169,7 @@ enum class TypeElement{ dlarrow, dlrarrow, drarrow, - // + //SpecialSymbol emptyset, aleph, setN, @@ -175,6 +177,7 @@ enum class TypeElement{ setQ, setR, setC, + // infinity, partial, nabla, @@ -239,6 +242,11 @@ enum class TypeElement{ //op from, to, + //bracketWithIndex + overbrace, + underbrace, + //grade + evaluate, }; } #endif // TYPESELEMENTS_H From fd95d72a08d65a26a899af03a9f4a57567553497 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 26 Nov 2023 01:17:33 +0300 Subject: [PATCH 185/794] Update ascent/descent values in objects crossing using ascent/descent --- DocxRenderer/src/logic/Page.cpp | 18 ++++-- DocxRenderer/src/logic/elements/ContText.cpp | 54 +++++++++++++---- DocxRenderer/src/logic/elements/ContText.h | 5 +- DocxRenderer/src/logic/elements/TextLine.cpp | 62 ++++++++++++++++++-- DocxRenderer/src/logic/elements/TextLine.h | 5 ++ 5 files changed, 121 insertions(+), 23 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index b40b4389609..58f894aae3e 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -341,13 +341,21 @@ namespace NSDocxRenderer pCont->m_oText = oText; + double font_size = m_pFont->Size; + double em_height = oMetrics.dEmHeight; + double ratio = font_size / em_height * c_dPixToMM; + + pCont->m_dTopWithAscent = pCont->m_dBaselinePos - (oMetrics.dAscent * ratio) - oMetrics.dBaselineOffset; + pCont->m_dBotWithDescent = pCont->m_dBaselinePos + (oMetrics.dDescent * ratio) - oMetrics.dBaselineOffset; + // первичное получение стиля для текущего символа // при дальнейшем анализе может измениться pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(*m_pBrush, - m_pFontSelector->GetSelectedName(), - m_pFont->Size, - m_pFontSelector->IsSelectedItalic(), - m_pFontSelector->IsSelectedBold()); + m_pFontSelector->GetSelectedName(), + m_pFont->Size, + m_pFontSelector->IsSelectedItalic(), + m_pFontSelector->IsSelectedBold()); + pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); @@ -763,7 +771,7 @@ namespace NSDocxRenderer if (!curr_cont) continue; - eVerticalCrossingType eVType = curr_cont->GetVerticalCrossingType(shape.get()); + eVerticalCrossingType eVType = curr_cont->CBaseItem::GetVerticalCrossingType(shape.get()); eHorizontalCrossingType eHType = curr_cont->GetHorizontalCrossingType(shape.get()); bool bIsNotComplicatedFigure = shape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 672e149ee9c..2dcd62c418b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -66,6 +66,9 @@ namespace NSDocxRenderer m_iNumDuplicates = rCont.m_iNumDuplicates; + m_dTopWithAscent = rCont.m_dTopWithAscent; + m_dBotWithDescent = rCont.m_dBotWithDescent; + return *this; } @@ -96,23 +99,50 @@ namespace NSDocxRenderer } } - eVerticalCrossingType CContText::GetVerticalCrossingType(const CBaseItem* pItem) const noexcept + eVerticalCrossingType CContText::GetVerticalCrossingType(const CContText* pCont) const noexcept { - const CContText* pCont = nullptr; - if((pCont = dynamic_cast(pItem)) == nullptr) - return CBaseItem::GetVerticalCrossingType(pItem); + const double& this_top = m_dTopWithAscent; + const double& this_bot = m_dBotWithDescent; + + const double& other_top = pCont->m_dTopWithAscent; + const double& other_bot = pCont->m_dBotWithDescent; + + if (this_top > other_top && this_bot < other_bot) + return eVerticalCrossingType::vctCurrentInsideNext; + + else if (this_top < other_top && this_bot > other_bot) + return eVerticalCrossingType::vctCurrentOutsideNext; + + else if (this_top < other_top && this_bot < other_bot && + (this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentAboveNext; - auto vert_cross = CBaseItem::GetVerticalCrossingType(pCont); + else if (this_top > other_top && this_bot > other_bot && + (this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentBelowNext; - if(vert_cross == eVerticalCrossingType::vctCurrentAboveNext && - (m_dBaselinePos - pCont->m_dTop < m_dHeight * 0.3)) - vert_cross = eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + else if (this_top == other_top && this_bot == other_bot && + m_dLeft == pCont->m_dLeft && m_dRight == pCont->m_dRight) + return eVerticalCrossingType::vctDublicate; - if(vert_cross == eVerticalCrossingType::vctCurrentBelowNext && - (pCont->m_dBaselinePos - m_dTop < pCont->m_dHeight * 0.3)) - vert_cross = eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopAndBottomBordersMatch; - return vert_cross; + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopBorderMatch; + + else if (fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctBottomBorderMatch; + + else if (this_bot < other_top) + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + + else if (this_top > other_bot) + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + + else + return eVerticalCrossingType::vctUnknown; } void CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) const diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 141490fef5f..23531b73036 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -63,6 +63,9 @@ namespace NSDocxRenderer double m_dSpaceWidthMM{0}; CSelectedSizes m_oSelectedSizes{}; + double m_dTopWithAscent{0}; + double m_dBotWithDescent{0}; + NSStringUtils::CStringUTF32 m_oText{}; UINT m_iNumDuplicates{0}; @@ -73,7 +76,7 @@ namespace NSDocxRenderer virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; - virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* pItem) const noexcept override final; + virtual eVerticalCrossingType GetVerticalCrossingType(const CContText* pItem) const noexcept; // calc sizes in selected font (uses m_pFontStyle & m_pManager) void CalcSelected(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 384ea96451f..86cf7b4c4a2 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -17,7 +17,7 @@ namespace NSDocxRenderer } void CTextLine::AddCont(std::shared_ptr oCont) { - CBaseItem::RecalcWithNewItem(oCont.get()); + RecalcWithNewItem(oCont.get()); m_arConts.push_back(oCont); } @@ -148,10 +148,62 @@ namespace NSDocxRenderer for(const auto& cont : m_arConts) if(cont) - { - m_dHeight = std::max(m_dHeight, dynamic_cast(cont.get())->m_dHeight); - CBaseItem::RecalcWithNewItem(cont.get()); - } + RecalcWithNewItem(cont.get()); + } + + eVerticalCrossingType CTextLine::GetVerticalCrossingType(const CTextLine* pLine) const noexcept + { + const double& this_top = m_dTopWithMaxAscent; + const double& this_bot = m_dBotWithMaxDescent; + + const double& other_top = pLine->m_dTopWithMaxAscent; + const double& other_bot = pLine->m_dBotWithMaxDescent; + + if (this_top > other_top && this_bot < other_bot) + return eVerticalCrossingType::vctCurrentInsideNext; + + else if (this_top < other_top && this_bot > other_bot) + return eVerticalCrossingType::vctCurrentOutsideNext; + + else if (this_top < other_top && this_bot < other_bot && + (this_bot >= other_top || fabs(this_bot - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentAboveNext; + + else if (this_top > other_top && this_bot > other_bot && + (this_top <= other_bot || fabs(this_top - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM)) + return eVerticalCrossingType::vctCurrentBelowNext; + + else if (this_top == other_top && this_bot == other_bot && + m_dLeft == pLine->m_dLeft && m_dRight == pLine->m_dRight) + return eVerticalCrossingType::vctDublicate; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM && + fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopAndBottomBordersMatch; + + else if (fabs(this_top - other_top) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctTopBorderMatch; + + else if (fabs(this_bot - other_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + return eVerticalCrossingType::vctBottomBorderMatch; + + else if (this_bot < other_top) + return eVerticalCrossingType::vctNoCrossingCurrentAboveNext; + + else if (this_top > other_bot) + return eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + + else + return eVerticalCrossingType::vctUnknown; + } + + void CTextLine::RecalcWithNewItem(const CContText* pCont) + { + CBaseItem::RecalcWithNewItem(pCont); + if (m_dTopWithMaxAscent == 0.0) m_dTopWithMaxAscent = pCont->m_dTopWithAscent; + else m_dTopWithMaxAscent = std::min(m_dTopWithMaxAscent, pCont->m_dTopWithAscent); + + m_dBotWithMaxDescent = std::max(m_dBotWithMaxDescent, pCont->m_dBotWithDescent); } void CTextLine::SetVertAlignType(const eVertAlignType& oType) diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 02f28b08832..b983d8b5ce7 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -27,11 +27,16 @@ namespace NSDocxRenderer UINT m_iNumDuplicates {0}; + double m_dTopWithMaxAscent{0}; + double m_dBotWithMaxDescent{0}; + public: CTextLine() = default; virtual ~CTextLine(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void RecalcWithNewItem(const CContText* pCont); + virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept; void AddCont(std::shared_ptr pCont); void MergeConts(); From be08b9c6c6e423ddd06e3a797f224217a4c78cc0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 28 Nov 2023 13:33:33 +0600 Subject: [PATCH 186/794] Fix pivot conversion --- OOXML/XlsxFormat/Pivot/Pivots.cpp | 186 ++++++++++++++++++++++++++---- 1 file changed, 161 insertions(+), 25 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 441bda33b0a..7eb31e565da 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -1200,19 +1200,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr1->itmtype = XLSB::PivotItemType::PITDATA; } - auto ptr2(new XLSB::ISXVIS(size)); - ptr2->_cisxvis = size; + if(ptr1->cisxvis > 0) + { - ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; - auto ptr3(new XLSB::BeginISXVIs(size)); - ptr3->_cisxvis = size; - ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; + auto ptr2(new XLSB::ISXVIS(size)); + ptr2->_cisxvis = size; - for(auto i:m_arrItems) - if(i->m_oV.IsInit()) - ptr3->rgisxvis.push_back(i->m_oV->GetValue()); - else - ptr3->rgisxvis.push_back(0); + ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; + auto ptr3(new XLSB::BeginISXVIs(size)); + ptr3->_cisxvis = size; + ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; + + for(auto i:m_arrItems) + if(i->m_oV.IsInit()) + ptr3->rgisxvis.push_back(i->m_oV->GetValue()); + else + ptr3->rgisxvis.push_back(0); + } return objectPtr; } void CColumnRowItem::fromBin(XLS::BaseObjectPtr& obj) @@ -2202,12 +2206,18 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oAllDrilled.IsInit()) ptr->fDrilledLevel = m_oAllDrilled.get(); + else + ptr->fDrilledLevel = false; if(m_oAutoShow.IsInit()) ptr->fAutoShow = m_oAutoShow.get(); + else + ptr->fAutoShow = false; if(m_oAvgSubtotal.IsInit()) ptr->fAverage = m_oAvgSubtotal.get(); + else + ptr->fAverage = false; ptr->sxaxis.bCol = false; ptr->sxaxis.bPage = false; @@ -2225,34 +2235,79 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) ptr->sxaxis.bData = true; } + else + ptr->sxaxis.bData = true; if(m_oCompact.IsInit()) ptr->fCompact = m_oCompact.get(); + else + ptr->fCompact = false; if(m_oCountASubtotal.IsInit()) ptr->fCounta = m_oCountASubtotal.get(); + else + ptr->fCounta = false; if(m_oCountSubtotal.IsInit()) ptr->fCount = m_oCountSubtotal.get(); + else + ptr->fCount = false; if(m_oDataField.IsInit()) ptr->fDrilledLevel = m_oDataField.get(); + else + ptr->fDrilledLevel = false; if(m_oDataSourceSort.IsInit()) ptr->fTensorSort = m_oDataSourceSort.get(); + else + ptr->fTensorSort = false; if(m_oDefaultAttributeDrillState.IsInit()) ptr->fItemsDrilledByDefault = m_oDefaultAttributeDrillState.get(); + else + ptr->fItemsDrilledByDefault = false; if(m_oDefaultSubtotal.IsInit()) ptr->fDefault = m_oDefaultSubtotal.get(); + else + ptr->fDefault = false; if(m_oDragOff.IsInit()) ptr->fDragToHide = m_oDragOff.get(); + else + ptr->fDragToHide = false; - if (m_oDragToCol.IsInit()) ptr->fDragToColumn = m_oDragToCol.get(); - if (m_oDragToData.IsInit()) ptr->fDragToData = m_oDragToData.get(); - if (m_oDragToPage.IsInit()) ptr->fDragToPage = m_oDragToPage.get(); - if (m_oDragToRow.IsInit()) ptr->fDragToRow = m_oDragToRow.get(); - if (m_oHiddenLevel.IsInit()) ptr->fHiddenLvl = m_oHiddenLevel.get(); - if (m_oHideNewItems.IsInit()) ptr->fHideNewItems = m_oHideNewItems.get(); - if (m_oIncludeNewItemsInFilter.IsInit()) ptr->fFilterInclusive = m_oIncludeNewItemsInFilter.get(); - if (m_oInsertBlankRow.IsInit()) ptr->fInsertBlankRow = m_oInsertBlankRow.get(); - if (m_oInsertPageBreak.IsInit()) ptr->fPageBreaksBetweenItems = m_oInsertPageBreak.get(); + if (m_oDragToCol.IsInit()) + ptr->fDragToColumn = m_oDragToCol.get(); + else + ptr->fDragToColumn = false; + if (m_oDragToData.IsInit()) + ptr->fDragToData = m_oDragToData.get(); + else + ptr->fDragToData = false; + if (m_oDragToPage.IsInit()) + ptr->fDragToPage = m_oDragToPage.get(); + else + ptr->fDragToPage = false; + if (m_oDragToRow.IsInit()) + ptr->fDragToRow = m_oDragToRow.get(); + else + ptr->fDragToRow = false; + if (m_oHiddenLevel.IsInit()) + ptr->fHiddenLvl = m_oHiddenLevel.get(); + else + ptr->fHiddenLvl = false; + if (m_oHideNewItems.IsInit()) + ptr->fHideNewItems = m_oHideNewItems.get(); + else + ptr->fHideNewItems = false; + if (m_oIncludeNewItemsInFilter.IsInit()) + ptr->fFilterInclusive = m_oIncludeNewItemsInFilter.get(); + else + ptr->fFilterInclusive = false; + if (m_oInsertBlankRow.IsInit()) + ptr->fInsertBlankRow = m_oInsertBlankRow.get(); + else + ptr->fInsertBlankRow = false; + if (m_oInsertPageBreak.IsInit()) + ptr->fPageBreaksBetweenItems = m_oInsertPageBreak.get(); + else + ptr->fPageBreaksBetweenItems = false; if(m_oItemPageCount.IsInit()) ptr->citmAutoShow = m_oItemPageCount->GetValue(); @@ -2261,15 +2316,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oMaxSubtotal.IsInit()) ptr->fMax = m_oMaxSubtotal.get(); + else + ptr->fMax = false; if(m_oMeasureFilter.IsInit()) ptr->fHasAdvFilter = m_oMeasureFilter.get(); + else + ptr->fHasAdvFilter = false; if(m_oMinSubtotal.IsInit()) ptr->fMin = m_oMinSubtotal.get(); + else + ptr->fMin = false; if(m_oMultipleItemSelectionAllowed.IsInit()) ptr->fEnableMultiplePageItems = m_oMultipleItemSelectionAllowed.get(); + else + ptr->fEnableMultiplePageItems = false; if(m_oName.IsInit()) ptr->irstName = m_oName.get(); @@ -2279,17 +2342,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oNonAutoSortDefault.IsInit()) ptr->fNotAutoSortDft = m_oNonAutoSortDefault.get(); + else + ptr->fNotAutoSortDft = false; if (m_oNumFmtId.IsInit()) ptr->ifmt = m_oNumFmtId->GetValue(); else - ptr->ifmt = 0; + ptr->ifmt = 0; if (m_oOutline.IsInit()) ptr->fOutline = m_oOutline.get(); + else + ptr->fOutline = false; if (m_oProductSubtotal.IsInit()) ptr->fProduct = m_oProductSubtotal.get(); + else + ptr->fProduct = false; if (m_oRankBy.IsInit()) ptr->isxdiAutoShow = m_oRankBy->GetValue(); @@ -2298,21 +2367,33 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oServerField.IsInit()) ptr->fServerBased = m_oServerField.get(); + else + ptr->fServerBased = false; if (m_oShowAll.IsInit()) ptr->fShowAllItems = m_oShowAll.get(); + else + ptr->fShowAllItems = false; if (m_oShowDropDowns.IsInit()) ptr->fHideDD = !m_oShowDropDowns.get(); + else + ptr->fHideDD = false; if (m_oShowPropAsCaption.IsInit()) ptr->fMemPropDisplayInCaption = m_oShowPropAsCaption.get(); + else + ptr->fMemPropDisplayInCaption = false; if (m_oShowPropCell.IsInit()) ptr->fMemPropDisplayInReport = m_oShowPropCell.get(); + else + ptr->fMemPropDisplayInReport = false; if (m_oShowPropTip.IsInit()) ptr->fMemPropDisplayInTip = m_oShowPropTip.get(); + else + ptr->fMemPropDisplayInTip = false; if(m_oSortType.IsInit()) { if(m_oSortType->GetValue() != SimpleTypes::Spreadsheet::EFieldSortType::sortManual) @@ -2325,9 +2406,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oStdDevPSubtotal.IsInit()) ptr->fStdevp = m_oStdDevPSubtotal.get(); + else + ptr->fStdevp = false; if (m_oStdDevSubtotal.IsInit()) ptr->fStdev = m_oStdDevSubtotal.get(); + else + ptr->fStdev = false; if (m_oSubtotalCaption.IsInit()) ptr->irstSub.value() = m_oSubtotalCaption.get(); @@ -2336,12 +2421,18 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oSubtotalTop.IsInit()) ptr->fSubtotalAtTop = !m_oSubtotalTop.get(); + else + ptr->fSubtotalAtTop = false; if (m_oSumSubtotal.IsInit()) ptr->fSum = m_oSumSubtotal.get(); + else + ptr->fSum = false; if (m_oTopAutoShow.IsInit()) ptr->fTopAutoShow = !m_oTopAutoShow.get(); + else + ptr->fTopAutoShow = false; if (m_oUniqueMemberProperty.IsInit()) ptr->irstMemberPropertyCaption = m_oUniqueMemberProperty.get(); @@ -2350,9 +2441,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oVarPSubtotal.IsInit()) ptr->fVarp = m_oVarPSubtotal.get(); + else + ptr->fVarp = false; if (m_oVarSubtotal.IsInit()) ptr->fVar = m_oVarSubtotal.get(); + else + ptr->fVar = false; return objectPtr; } @@ -3530,7 +3625,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oMinRefreshableVersion.IsInit()) ptr->bVerCacheRefreshableMin = m_oMinRefreshableVersion->GetValue(); - + else + ptr->bVerCacheRefreshableMin = 0; if (m_oMissingItemsLimit.IsInit()) ptr->citmGhostMax = m_oMissingItemsLimit->GetValue(); else @@ -3836,18 +3932,25 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oDatabaseField.IsInit()) ptr->fSrcField = m_oDatabaseField.get(); else - ptr->fSrcField = false; + ptr->fSrcField = true; if (m_oServerField.IsInit()) ptr->fServerBased = m_oServerField.get(); + else + ptr->fServerBased = false; if (m_oFormula.IsInit()) ptr->fldFmla = m_oFormula.get(); else + { ptr->fLoadFmla = false; + ptr->fldFmla.cSxName = 0; + } if (m_oHierarchy.IsInit()) ptr->ihdb = m_oHierarchy.get(); + else + ptr->ihdb = 0; if (m_oMemberPropertyField.IsInit()) ptr->fOlapMemPropField = m_oMemberPropertyField.get(); @@ -3861,16 +3964,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oSqlType.IsInit()) ptr->wTypeSql = m_oSqlType.get(); + else + ptr->wTypeSql = 0; if (m_oUniqueList.IsInit()) ptr->fCantGetUniqueItems = !m_oUniqueList.get(); + else + ptr->fCantGetUniqueItems = false; if (m_oLevel.IsInit()) ptr->isxtl = m_oLevel->GetValue(); + else + ptr->isxtl = 0; if(m_oMappingCount.IsInit()) ptr->cIsxtmps = m_oMappingCount->GetValue(); + else + ptr->cIsxtmps = 0; if(m_oNumFmtId.IsInit()) ptr->ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt = 0xFFFFFFFF; + + ptr->cbRgisxtmp = 0; return objectPtr; } @@ -4104,25 +4219,44 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oContainsBlank.IsInit()) ptr->fHasBlankItem = m_oContainsBlank.get(); + else + ptr->fHasBlankItem = false; if(m_oContainsDate.IsInit()) ptr->fDateInField = m_oContainsDate.get(); + else + ptr->fDateInField = false; if(m_oContainsInteger.IsInit()) ptr->fIntField = m_oContainsInteger.get(); + else + ptr->fIntField = false; if(m_oContainsMixedTypes.IsInit()) ptr->fMixedTypesIgnoringBlanks = m_oContainsMixedTypes.get(); + else + ptr->fMixedTypesIgnoringBlanks = false; if(m_oContainsNonDate.IsInit()) ptr->fNonDates = m_oContainsNonDate.get(); + else + ptr->fNonDates = false; if(m_oContainsNumber.IsInit()) ptr->fNumField = m_oContainsNumber.get(); + else + ptr->fNumField = false; if(m_oContainsSemiMixedTypes.IsInit()) ptr->fTextEtcField = m_oContainsSemiMixedTypes.get(); - + else + ptr->fTextEtcField = false; if(m_oContainsString.IsInit()) ptr->fHasTextItem = m_oContainsString.get(); + else + ptr->fHasTextItem = false; if(m_oLongText.IsInit()) ptr->fHasLongTextItem = m_oLongText.get(); + else + ptr->fHasLongTextItem = false; if(m_oCount.IsInit()) ptr->citems = m_oCount->GetValue(); + else + ptr->citems = 0; if(m_oMinDate.IsInit() && m_oMaxDate.IsInit()) { ptr->xnumMin.data.value = std::stod(m_oMinDate->GetValue()); @@ -5717,7 +5851,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr1->iSrcType = 0x00000003; } if(m_oConnectionId.IsInit()) - ptr1->dwConnID = m_oConnectionId->GetValue(); + ptr1->dwConnID = m_oConnectionId->GetValue(); + else + ptr1->dwConnID = 0; if(m_oWorksheetSource.IsInit()) ptr->m_PCDSRANGE = m_oWorksheetSource->toBin(); From 3426704f80efbcbaae9632d315a9cffa969222f1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 30 Nov 2023 14:00:19 +0600 Subject: [PATCH 187/794] mend --- X2tConverter/src/lib/xlsx.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index d638c7d0954..e18e81d577b 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -300,6 +300,34 @@ namespace NExtractTools return nRes; } + _UINT32 xlsx_dir2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); + if(!SUCCEEDED_X2T(nRes)) + return nRes; + + + const OOX::CPath oox_path(sTempUnpackedXLSX); + + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + oXlsb.Read(oox_path); + + + + OOX::CContentTypes oContentTypes; + nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } + _UINT32 xlsx2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsb", xlsx_dir2xlsb); + } _UINT32 xml2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xml2xlsx_dir); From d404457744958816fb8819141098c5f6533b52b4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Dec 2023 18:17:12 +0600 Subject: [PATCH 188/794] FIx tables and cols conversion --- OOXML/XlsxFormat/Table/Tables.cpp | 2 +- OOXML/XlsxFormat/Worksheets/Cols.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 64c4c6df970..9aeba06f02c 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -319,7 +319,7 @@ namespace Spreadsheet if(m_oQueryTableFieldId.IsInit()) ptr1->idqsif = m_oQueryTableFieldId->GetValue(); else - ptr1->idqsif = 0xFFFFFFFF; + ptr1->idqsif = 0; if(m_oTotalsRowLabel.IsInit()) ptr1->stTotal = m_oTotalsRowLabel.get(); diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index c10922071fe..2d686f81d07 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -103,6 +103,8 @@ namespace OOX castedPtr->fPhonetic = m_oPhonetic->ToBool(); if(m_oStyle.IsInit()) castedPtr->ixfeXLSB = m_oStyle->m_eValue; + else + castedPtr->ixfeXLSB = 0; if (m_oWidth.IsInit()) { From 5533ac8a591536ceaec8529fefc55f56ca5a6875 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 1 Dec 2023 16:27:26 +0300 Subject: [PATCH 189/794] Adding conversion of brackets, matrices, scores and indexes. Tests. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 322 +++++++++++++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 92 +++++ .../StarMath2OOXML/cconversionsmtoooxml.h | 4 + .../StarMath2OOXML/cstarmathpars.cpp | 376 +++++++++++------- .../Converter/StarMath2OOXML/cstarmathpars.h | 24 +- .../Converter/StarMath2OOXML/typeselements.h | 3 +- 6 files changed, 673 insertions(+), 148 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 3e38e5b8ee4..41495fe80ed 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -613,3 +613,325 @@ TEST(SMConvectorTest,ConnectionNsucc) std::wstring wsXmlString = L"69\u228170"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } + +TEST(SMConvectorTest,BracketRound) +{ + std::wstring wsString = L"(2+3)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketSquare) +{ + std::wstring wsString = L"[4-5]"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"4-5"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdbracket) +{ + std::wstring wsString = L"ldbracket 6+7 rdbracket"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"6+7"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLbrace) +{ + std::wstring wsString = L"lbrace 8 - 9 rbrace"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"8-9"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLangle) +{ + std::wstring wsString = L"langle 10 over 11 rangle"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1011"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLceil) +{ + std::wstring wsString = L"lceil 12 ominus 13 rceil"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"12\u229613"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLfloor) +{ + std::wstring wsString = L"lfloor 14 union 15 rfloor"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"14\u22C315"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLline) +{ + std::wstring wsString = L"lline 16 / 17 rline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"1617"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdline) +{ + std::wstring wsString = L"ldline 18 oplus 19 rdline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"18\u229519"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCos) +{ + std::wstring wsString = L"cos{2+3}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cos2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionSin) +{ + std::wstring wsString = L"sin 4 over 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"sin45"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionTan) +{ + std::wstring wsString = L"tan{6 / 7}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"tan67"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCot) +{ + std::wstring wsString = L"cot(8 over 9)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cot89"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionSinh) +{ + std::wstring wsString = L"sinh 2 supset 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"sinh2\u22833"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCosh) +{ + std::wstring wsString = L"cosh 2 + 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cosh2+3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionTanh) +{ + std::wstring wsString = L"tanh(11otimes12)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"tanh11\u229712"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionCoth222) +{ + std::wstring wsString = L"coth222"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"coth222"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArcsin) +{ + std::wstring wsString = L"arcsin{13 ominus 14}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arcsin13\u229614"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArccos) +{ + std::wstring wsString = L"arccos{15 - 16}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arccos15-16"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArctan) +{ + std::wstring wsString = L"arctan 17 over 18"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arctan1718"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArccot) +{ + std::wstring wsString = L"arccot 20 + 30"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arccot20+30"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArsinh) +{ + std::wstring wsString = L"{arsinh{2/3}} over sum from 1 to 5 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arsinh231510"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArcosh) +{ + std::wstring wsString = L"35 + 27 over {arcosh binom 23 78}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"35+27arcosh2378"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionArtanhArcoth) +{ + std::wstring wsString = L"arcoth 30 subset {artanh 27}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"arcoth30\u2282artanh27"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixBinom) +{ + std::wstring wsString = L"binom{2 over 7 supset 277}{arcoth 89}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"27\u2283277arcoth89"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixMatrix) +{ + std::wstring wsString = L"matrix{2 / 8 -5 # sum from 2 over 10 union 3 to 10*10 100 ## cosh(10) # 2 oplus 10over100 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,MatrixStack) +{ + std::wstring wsString = L"stack{2 over 10 # binom 2 3 # matrix{1 # 2 ## 3 # 4}}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"210231234"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLower) +{ + std::wstring wsString = L"25 over 1 _ 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2512"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexUpper) +{ + std::wstring wsString = L"{binom {cos 5} 2 over 4 }^ 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"cos52410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLsup) +{ + std::wstring wsString = L"{2 over 7} lsup binom 2+3 {cos 15}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+3cos1527"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexLsub) +{ + std::wstring wsString = L"2222^10 lsub 2 over 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"22222103"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 1410f92e47c..8a378998660 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -118,5 +118,97 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } + + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket) + { + pXmlWrite->WriteNodeBegin(L"m:dPr",false); + switch(enTypeBracket) + { + case TypeElement::langle: + BracketTypeNotation(L"\u2329",L"\u232A",pXmlWrite); + break; + case TypeElement::square: + BracketTypeNotation(L"\u005B",L"\u005D",pXmlWrite); + break; + case TypeElement::ldbracket: + BracketTypeNotation(L"\u27E6",L"\u27E7",pXmlWrite); + break; + case TypeElement::lbrace: + BracketTypeNotation(L"\u007B",L"\u007D",pXmlWrite); + break; + case TypeElement::lceil: + BracketTypeNotation(L"\u23A1",L"\u23A4",pXmlWrite); + break; + case TypeElement::lfloor: + BracketTypeNotation(L"\u23A3",L"\u23A6",pXmlWrite); + break; + case TypeElement::lline: + BracketTypeNotation(L"\u23AA",L"\u23AA",pXmlWrite); + break; + case TypeElement::ldline: + BracketTypeNotation(L"\u2016",L"\u2016",pXmlWrite); + break; + } + pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); + StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); + } + void CConversionSMtoOOXML::BracketTypeNotation(const std::wstring &wsOpenBracket, const std::wstring &wsCloseBracket, XmlUtils::CXmlWriter *pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:begChr", true); + pXmlWrite->WriteAttribute(L"m:val",wsOpenBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:endChr", true); + pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix) + { + pXmlWrite->WriteNodeBegin(L"m:mPr",false); + pXmlWrite->WriteNodeBegin(L"m:mcs",false); + pXmlWrite->WriteNodeBegin(L"m:mc",false); + pXmlWrite->WriteNodeBegin(L"m:mcPr",false); + pXmlWrite->WriteNodeBegin(L"m:count",true); + switch(enTypeMatrix) + { + case TypeElement::matrix: + pXmlWrite->WriteAttribute(L"m:val",L"2"); + break; + default: + pXmlWrite->WriteAttribute(L"m:val",L"1"); + break; + } + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:mcJc",true); + pXmlWrite->WriteAttribute(L"m:val",L"center"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:mcPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:mc",false,false); + pXmlWrite->WriteNodeEnd(L"m:mcs",false,false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:mPr",false,false); + } + void CConversionSMtoOOXML::BlocGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade) + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + pXmlWrite->WriteNodeBegin(L"m:dPr",false); + pXmlWrite->WriteNodeBegin(L"m:begChr",true); + pXmlWrite->WriteAttribute(L"m:val",L""); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:endChr",true); + pXmlWrite->WriteAttribute(L"m:val",L"\u23AA"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); + pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + pValueGrade->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 09e23d500f3..e1932e7a39a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -16,9 +16,13 @@ namespace StarMath { static void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite); static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* pXmlWrite); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket); + static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix); + static void BlocGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade); void EndConversion(); std::wstring GetOOXML() ; private: + static void BracketTypeNotation(const std::wstring& wsOpenBracket,const std::wstring& wsCloseBracket, XmlUtils::CXmlWriter* pXmlWrite); XmlUtils::CXmlWriter* m_oXmlWrite; }; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index d9f2bdcd644..95511ad53ba 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -19,6 +19,12 @@ namespace StarMath } m_arEquation.push_back(pTempElement); } + if(!pReader->EmptyString()) + { + CElement* pTempElement = ParseElement(pReader); + if(nullptr != pTempElement) + m_arEquation.push_back(pTempElement); + } return m_arEquation; } @@ -47,12 +53,6 @@ namespace StarMath pElement->SetAttribute(arAttributes); pReader->ClearReader(); pElement->Parse(pReader); -// if(CheckingTheNextElement(itStart,itEnd,CIndex::IsIndex)) -// { -// CIndex* pIndex = CIndex::CreateIndex(GetElement(itStart,itEnd)); -// pIndex->SetValueIndex(ParseElement(itStart,itEnd)); -// pElement->SetIndex(pIndex); -// } return pElement; } else return pElement; @@ -89,6 +89,11 @@ namespace StarMath SetLeft(pLeftArg,pElementWhichAdd); break; } + case TypeElement::Index: + { + SetLeft(pLeftArg,pElementWhichAdd); + break; + } default: break; } @@ -106,7 +111,7 @@ namespace StarMath CParserStarMathString::AddLeftArgument(pFirstTempElement,pSecondTempElement); } pFirstTempElement = pSecondTempElement; - if(pReader->GetGlobalType() == TypeElement::Empty) + if(pReader->EmptyString()) { pReader->GetToken(); pReader->SetTypesToken(); @@ -126,6 +131,8 @@ namespace StarMath return true; case TypeElement::BracketWithIndex: return true; + case TypeElement::Index: + return true; default: return false; } @@ -201,92 +208,9 @@ namespace StarMath { delete pTemp; } - delete m_pElementIndex; } - CElement::CElement(): m_pElementIndex(nullptr) + CElement::CElement() {} -// TypeElement CElement::GetTypeElement(const std::wstring& wsToken) -// { -// if (wsToken == L"+") -// { -// return TypeElement::plus; -// } -// else if (wsToken == L"-") -// { -// return TypeElement::minus; -// } -// else if (wsToken == L"*") -// { -// return TypeElement::multipl; -// } -// else if (wsToken == L"/") -// { -// return TypeElement::division; -// } -// else if (wsToken == L"over") -// { -// return TypeElement::over; -// } -// else if (wsToken == L"cdot") -// { -// return TypeElement::cdot; -// } -// else if (wsToken == L"times") -// { -// return TypeElement::times; -// } -// else if (wsToken == L"frac") -// { -// return TypeElement::frac; -// } -// else if (wsToken == L"div") -// { -// return TypeElement::div; -// } -// else if (wsToken == L"oplus") -// { -// return TypeElement::oplus; -// } -// else if (wsToken == L"ominus") -// { -// return TypeElement::ominus; -// } -// else if (wsToken == L"odot") -// { -// return TypeElement::odot; -// } -// else if (wsToken == L"otimes") -// { -// return TypeElement::otimes; -// } -// else if (wsToken == L"odivide") -// { -// return TypeElement::odivide; -// } -// else if (wsToken == L"circ") -// { -// return TypeElement::circ; -// } -// else if (wsToken == L"wideslash") -// { -// return TypeElement::wideslash; -// } -// else if (wsToken == L"widebslash") -// { -// return TypeElement::widebslash; -// } -// else if(L"{" == wsToken) return TypeElement::brace; -// else if(L"(" == wsToken) return TypeElement::round; -// else if(L"[" == wsToken) return TypeElement::square; -// else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; -// else if(L"lbrace" == wsToken) return TypeElement::lbrace; -// else if(L"langle" == wsToken) return TypeElement::langle; -// else if(L"lceil" == wsToken) return TypeElement::lceil; -// else if(L"lfloor" == wsToken) return TypeElement::lfloor; -// else if(L"lline" == wsToken) return TypeElement::lline; -// else if(L"ldline" == wsToken) return TypeElement::ldline; -// else return TypeElement::undefine; -// } CElement* CElement::CreateElement(CStarMathReader* pReader) { switch (pReader->GetGlobalType()) { @@ -312,6 +236,8 @@ namespace StarMath return new CElementMatrix(pReader->GetLocalType()); case TypeElement::SpecialSymbol: return new CElementSpecialSymbol(pReader->GetLocalType()); + case TypeElement::Index: + return new CElementIndex(pReader->GetLocalType()); default: return nullptr; } @@ -320,11 +246,7 @@ namespace StarMath { m_arElementAttributes = arAttr; } - void CElement::SetIndex(CIndex *pIndex) - { - m_pElementIndex = pIndex; - } - TypeElement CElement::GetBaseType() + const TypeElement& CElement::GetBaseType() { return m_enBaseType; } @@ -363,6 +285,8 @@ namespace StarMath } TypeElement CElementString::GetDigit(const std::wstring &wsToken) { + if(wsToken.empty()) return TypeElement::undefine; + for(wchar_t cOneElement: wsToken) { if(!isdigit(cOneElement) || L'\0' == cOneElement) return TypeElement::undefine; @@ -400,7 +324,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) + if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); @@ -566,6 +490,10 @@ namespace StarMath else if(L"right" == wsToken) return TypeElement::right; else return TypeElement::undefine; } + std::vector CElementBracket::GetBracketValue() + { + return m_arBrecketValue; + } void CElementBracket::Parse(CStarMathReader* pReader) { pReader->GetToken(); @@ -599,6 +527,25 @@ namespace StarMath } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { + if(m_enTypeBracket != TypeElement::brace) + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket); + pXmlWrite->WriteNodeBegin(L"m:e",false); + for(CElement* oTemp:m_arBrecketValue) + { + oTemp->ConversionToOOXML(pXmlWrite); + } + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + } + else + { + for(CElement* oTemp:m_arBrecketValue) + { + oTemp->ConversionToOOXML(pXmlWrite); + } + } } //class methods CElementSpecialSymbol @@ -614,7 +561,9 @@ namespace StarMath } TypeElement CElementSpecialSymbol::GetSpecialSymbol(const std::wstring &wsToken) { - if(L"emptyset" == wsToken) return TypeElement::emptyset; + if(L"#" == wsToken) return TypeElement::grid; + else if(L"##" == wsToken) return TypeElement::transition; + else if(L"emptyset" == wsToken) return TypeElement::emptyset; else if(L"aleph" == wsToken) return TypeElement::aleph; else if(L"setN" == wsToken) return TypeElement::setN; else if(L"setZ" == wsToken) return TypeElement::setZ; @@ -624,7 +573,13 @@ namespace StarMath else return TypeElement::undefine; } void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) - {} + { + if(m_enTypeSpecial == TypeElement::transition) + { + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + } //class methods CElementSetOperations CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) { @@ -657,7 +612,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) + if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) { CElement* pBinOpElement = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOpElement); @@ -776,7 +731,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex) + if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); @@ -935,41 +890,93 @@ namespace StarMath else return TypeElement::undefine; } //class methods CIndex - CIndex::CIndex(const TypeElement& enType): m_pValueIndex(nullptr) + CElementIndex::CElementIndex(const TypeElement& enType): m_pValueIndex(nullptr),m_pValue(nullptr) { m_enTypeIndex = enType; + SetBaseType(TypeElement::Index); } - CIndex::~CIndex() + CElementIndex::~CElementIndex() { delete m_pValueIndex; + delete m_pValue; } - void CIndex::SetValueIndex(CElement *pElement) + void CElementIndex::SetValueIndex(CElement *pElement) { m_pValueIndex = pElement; } - CElement* CIndex::GetValueIndex() + void CElementIndex::SetLeftArg(CElement *pElement) + { + m_pValue = pElement; + } + CElement* CElementIndex::GetValueIndex() { return m_pValueIndex; } - bool CIndex::IsIndex(const std::wstring &wsCheckToken) + TypeElement CElementIndex::GetIndex(const std::wstring &wsCheckToken) { - if(L"^" == wsCheckToken) return true; - else if(L"_" == wsCheckToken) return true; - else if(L"lsup" == wsCheckToken) return true; - else if(L"lsub" == wsCheckToken) return true; - else if(L"csup" == wsCheckToken) return true; - else if(L"csub" == wsCheckToken) return true; - else return false; + if(L"^" == wsCheckToken) return TypeElement::upper; + else if(L"_" == wsCheckToken) return TypeElement::lower; + else if(L"lsup" == wsCheckToken) return TypeElement::lsup; + else if(L"lsub" == wsCheckToken) return TypeElement::lsub; + else if(L"csup" == wsCheckToken) return TypeElement::csup; + else if(L"csub" == wsCheckToken) return TypeElement::csub; + else return TypeElement::undefine; } - CIndex* CIndex::CreateIndex(const std::wstring &wsToken) + void CElementIndex::Parse(CStarMathReader *pReader) { - if(L"^" == wsToken) return new CIndex(TypeElement::upper); - else if(L"_" == wsToken) return new CIndex(TypeElement::lower); - else if(L"lsup" == wsToken) return new CIndex(TypeElement::lsup); - else if(L"lsub" == wsToken) return new CIndex(TypeElement::lsub); - else if(L"csup" == wsToken) return new CIndex(TypeElement::csup); - else if(L"csub" == wsToken) return new CIndex(TypeElement::csub); - else return nullptr; + SetValueIndex(CParserStarMathString::ParseElement(pReader)); + } + void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_enTypeIndex == TypeElement::upper || m_enTypeIndex == TypeElement::lower) + { + std::wstring wsNameNodeIndex; + switch(m_enTypeIndex) + { + case TypeElement::upper: + wsNameNodeIndex = L"m:sSup"; + break; + case TypeElement::lower: + wsNameNodeIndex = L"m:sSub"; + break; + } + pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); + pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); + switch(m_enTypeIndex) + { + case TypeElement::upper: + CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueIndex,pXmlWrite); + break; + case TypeElement::lower: + CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueIndex,pXmlWrite); + break; + } + pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); + } + else if(m_enTypeIndex == TypeElement::lsub || TypeElement::lsup == m_enTypeIndex) + { + pXmlWrite->WriteNodeBegin(L"m:sPre",false); + pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); + if(m_enTypeIndex==TypeElement::lsup) + { + CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueIndex,pXmlWrite); + } + else if(m_enTypeIndex == TypeElement::lsub) + { + CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueIndex,pXmlWrite); + } + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); + } } //class methods CElementFunction CElementFunction::CElementFunction(const TypeElement &enType): m_pValue(nullptr) @@ -992,8 +999,17 @@ namespace StarMath void CElementFunction::Parse(CStarMathReader* pReader) { - SetValueFunction(CParserStarMathString::ParseElement(pReader)); - pReader->ClearReader(); + CElement* pTemp = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::Index) + { + CElement* pBinOp = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTemp,pBinOp); + pTemp = pBinOp; + } + SetValueFunction(pTemp); + //pReader->ClearReader(); } void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1205,6 +1221,7 @@ namespace StarMath if(m_wsToken == L"left") m_wsToken = GetElement(); else if(L"right" == m_wsToken ) m_wsToken = GetElement(); } + //std::wcout<') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (*m_itStart == L'[' || *m_itStart == L']' || *m_itStart == L'(' || L')' == *m_itStart || *m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) { return m_wsElement; } - else if(((*m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || L'=' == *m_itStart ) && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) + else if(((*m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || L'=' == *m_itStart || *m_itStart == L'[' || *m_itStart == L']') && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) { m_wsElement.push_back(*m_itStart); m_itStart++; @@ -1429,9 +1445,50 @@ namespace StarMath SetValueTo(CParserStarMathString::ParseElement(pReader)); } } - void CElementGrade::ConversionToOOXML(XmlUtils::CXmlWriter *oXmlWrite) + void CElementGrade::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + if(m_pValueFrom == nullptr && m_pValueTo == nullptr) + { + CConversionSMtoOOXML::BlocGrade(pXmlWrite,m_pValueGrade); + } + else + { + std::wstring wsNodeGrade; + if(m_pValueFrom != nullptr && m_pValueTo == nullptr) + { + wsNodeGrade = L"m:sSub"; + } + else if(m_pValueFrom == nullptr && m_pValueTo != nullptr) + { + wsNodeGrade = L"m:sSup"; + } + else if(m_pValueFrom != nullptr && m_pValueTo != nullptr) + { + wsNodeGrade = L"m:sSubSup"; + } + pXmlWrite->WriteNodeBegin(wsNodeGrade,false); + pXmlWrite->WriteNodeBegin(wsNodeGrade + L"Pr",false); + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + pXmlWrite->WriteNodeEnd(wsNodeGrade + L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::BlocGrade(pXmlWrite,m_pValueGrade); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + if(m_pValueFrom != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sub",false); + m_pValueFrom->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sub",false,false); + } + if(m_pValueTo != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sup",false); + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sup",false,false); + } + pXmlWrite->WriteNodeEnd(wsNodeGrade,false,false); + } } TypeElement CElementGrade::GetGrade(const std::wstring &wsToken) { @@ -1478,7 +1535,56 @@ namespace StarMath } void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + pXmlWrite->WriteNodeBegin(L"m:m",false); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + switch(m_enTypeMatrix) + { + case TypeElement::matrix: + { + CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); + std::vector pTempValue = pTempBracket->GetBracketValue(); + for(CElement* pOneElement:pTempValue) + { + if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol && pOneElement->GetBaseType()!= TypeElement::undefine) + { + pXmlWrite->WriteNodeBegin(L"m:e",false); + pOneElement->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + } + else if(pOneElement->GetBaseType() != TypeElement::undefine) + pOneElement->ConversionToOOXML(pXmlWrite); + } + break; + } + case TypeElement::stack: + { + CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); + std::vector pTempValue = pTempBracket->GetBracketValue(); + for(CElement* pOneElement:pTempValue) + { + if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol) + { + pXmlWrite->WriteNodeBegin(L"m:e",false); + pOneElement->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + } + break; + } + case TypeElement::binom: + { + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pFirstArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pSecondArgument,pXmlWrite); + break; + } + } + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeEnd(L"m:m",false,false); } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index a2d01986a0c..fd08ad4af82 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -46,8 +46,6 @@ namespace StarMath TypeElement m_enTypeAttr; }; - class CIndex; - class CElement { public: @@ -58,26 +56,27 @@ namespace StarMath static CElement* CreateElement(CStarMathReader* pReader); virtual void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) = 0; void SetAttribute(const std::vector arAttr); - void SetIndex(CIndex* pIndex); void SetBaseType(const TypeElement& enType); - TypeElement GetBaseType(); + const TypeElement& GetBaseType(); private: - CIndex* m_pElementIndex; std::vector m_arElementAttributes; TypeElement m_enBaseType; }; - class CIndex + class CElementIndex: public CElement { public: - CIndex(const TypeElement& enType); - ~CIndex(); + CElementIndex(const TypeElement& enType); + virtual ~CElementIndex(); void SetValueIndex(CElement* pElement); + void SetLeftArg(CElement* pElement); CElement* GetValueIndex(); - static bool IsIndex(const std::wstring& wsCheckToken); - static CIndex* CreateIndex(const std::wstring& wsToken); + static TypeElement GetIndex(const std::wstring& wsCheckToken); private: + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueIndex; + CElement* m_pValue; TypeElement m_enTypeIndex; }; @@ -148,7 +147,7 @@ namespace StarMath static TypeElement GetGrade(const std::wstring& wsToken); private: void Parse(CStarMathReader* pReader) override; - void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueGrade; CElement* m_pValueFrom; CElement* m_pValueTo; @@ -161,9 +160,10 @@ namespace StarMath virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); static TypeElement GetBracketOpen(const std::wstring& wsToken); + std::vector GetBracketValue(); private: void Parse(CStarMathReader* pReader) override; - void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override;// TypeElement GetBracketClose(const std::wstring& wsToken); TypeElement m_enTypeBracket; std::vector m_arBrecketValue; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index c12a5fbad08..e997664bd49 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -116,7 +116,6 @@ enum class TypeElement{ lavender, //color(without rgb and hex) mline, - grid, dlgrid, //setopetions intersection, @@ -177,6 +176,8 @@ enum class TypeElement{ setQ, setR, setC, + grid, + transition, // infinity, partial, From 1bf45a3c2307417e44dd35e57e0c2e2dfd668463 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 4 Dec 2023 13:07:30 +0600 Subject: [PATCH 190/794] Add xlsx 2 xlsb tests --- .../test/ExampleFiles/xlsx2xlsb/simple1.xlsb | Bin 0 -> 6973 bytes .../test/ExampleFiles/xlsx2xlsb/simple1.xlsx | Bin 0 -> 7310 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 0 -> 14044 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsx | Bin 0 -> 18500 bytes OOXML/test/common.cpp | 4 +- OOXML/test/test.pro | 3 +- OOXML/test/xlsx2xlsb/conversion.cpp | 247 ++++++++++++++++++ 7 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsx create mode 100644 OOXML/test/xlsx2xlsb/conversion.cpp diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb new file mode 100644 index 0000000000000000000000000000000000000000..c71a49e25f38717f7bf71cf02a1e2946ccfcfd05 GIT binary patch literal 6973 zcmeHM2Uio@8V$WeXwo}Kla2wT3n-lcQIR4f5I|aJQkCANH&IZ50D{t_dTAP(hzbJI zrT1P0qXP2AavzGm^?ty;lQnZ@tux;xB}TAT;TbCkAE-&sj!#&E#lw?o-L}R zG6AobI9zY5hy-XD3e~CY2FIlh*+#eP_zwIbOKQ;SBKPRDA*o8K@z?f7mrf3=JnJ2f zrT7%YXO-5MZ(+OY_~njL1wOjUl-Z8U+Drw)G%+4KZ$^~?9znFnFdn3U3rP!k-4`&u z`s-);cp4+}H;qbWX<84gHaSx(shxDKTQKcthK{+BRvXj41q;5Ly%n>*-la*M89U>t z+UJB|PQ~-|1yEseR+{2lt{lTWR8N_=@JEx%FUym=yV7Tbt91QX{zs z8nJ;ud>$U+fuO%cu3E@U8y0X!T_7;YfXKCUM>=_kiGIEQ8?pc3F#T!ivB}*)#FDpf zXf~+L?k&4$66aLcbLNeKg{UU^Tv)2((7YtUT(lu-c8}GaCH;ldRD{PWg7cLFC zW*CBa&}K4tVY8>9^qxwade<9)cwt%hFpC?3wKo=$jM!rucMXyB48n`X+uc!ySOvpV zt(7m+E;g$RM&_s)_+`ht8K);OesNG~d;{}0RvpSDg1+uqcs*F1?_4s^&~u-*-qV&~ zJ8OsuBFrIarU|h`Gn2ACAdOwD&5G9?XJBI4ROp%a$~`P=i>77L4l~8IoR_<1j%zwW z={c5*d|oF1K5Bv{BD4d_S}cD%^d?7PAh7h`;{?}rypIuxpmgA*0-o@367xp6J0egh zM^VI87xP3#9XwTV#Qo?8X&jdbHHbq7+3pl-kw?9|ihCj?UxPFIF}0!ADO_%I*c<)F z)LUrmhRGiPD!~nJT5uM8{I0K^ot;-{>?`g4l&op?^BG;8;PZ30@`Ni$4Io!GqgChj zGbAK6J}{m*+2&+~){4Z_m&*}8)D5^a#M^9fl6Pf6%mPo0teIP_ART1kOnUag~`$oF=9$0P<>AjYCq2H-bql%@tCw6IWK%}{P^`y;)Z z+t?k(i49ARQGfZB()C0;snR&hKa#k-`~KEPV5Sa8Hq0Pm9Du~{`Q~RT|IR%)fLZ{^ z{%0S>MwqX$*Z8$sZb+}G5a;CA>uT1Y{S=h=M6ViBgsAL!$}bdhtv5(VEd8FyQ|$Ki z?mT*<6^Ex9BP>wCitk73w8BDA*5CIUj~KC5vL14tfQQDZbLG*ll-Hd;n!mg_lS~u@ zU0=1JQ*Bs3+^G=HHb^gXDz*5%VQL*FY_9MPIxwa7gU6RhC6PG)eWT@Jb+2gs^ zUvO=|cy4fWR$A~2>8y*E)U2oaUbDpA(S5V|HI&r$>U5_8@Vb8wzPyhS!BfD@W56F6 zf$>N1dDtV7o*rV~28pjx=n0i4ZC0Vns$~fT+sIc_Q|pQN1mPP@;k0(DsjI5W2ii}G zD1?WnrDc1?;2J^4aLHjJ(+GF(tTu_+2!Zvsns9hD>sV=9adPCZqAE)?Sw2 zv1{XO})DHmqci@l3=-3%8S zc{%JBP*9`yf=?n0r%CQ95qWdDeKA(}K_t!;!JlZkG`kkGhX(>Z1rieNcUnB{kU_;LMnzAv>@GximAWEx42@=i{+An(dAunB z(rz`8xS8g~Ju)pQ_ADlgr-2WdKI?}UGvAwhQ7>^W^?}~SEpE)=yRyT&W=)}Hsb*$< z+I?NVfWY?)9D_DF+NQ?%pUp)zLv->-+U$9a!L*-BuL?$b`|>#CP8!mobrac!N`~#v zu%AcYfwA)FJBaV`bw5hY^>?P3*lFKjRB-33=0qaUdVTscQe#|?kekCT>gd@@bIIT) z+H@;fVMj0QjuyN%3bx6Ov3?(UUS^P|Vlg%240>g;f6J4}=j;6VNYQ>3bdch7pIlSYr6YZhs<(_3O#ef*{V#j41C-JQ4^oJ94txf$0) zwTM)W^IJ{sL<9{i&<|TA}wr+?)$8QPQ7}bo}`)t3pErwmtdykXpV?K zoh1of$PyPLG7Uyjvr9%*eurXALwb2aJ1sN0N*r2GxG1WAvhkw6i5ZOy z7UhY3IoWs0(@@w{1=ZqZw1iY!t6I^fPPZ@#d4lX+TC4CC< zQg+W=ld&%q{+Q}xqdk%k$NN0h)cUR6JYcG2iLw2sm>YN}|jIOVWUYxQO*f{TGYV8V#4|8D4 z^KJ>0Qp|1sn5g!V1xP3ncl~JX}({ z5KJVG8+JE}N~HG*jd@fUFLHat&X%r6x)T3R!WYo(>*^l@FF1s(%)-#LsbnK~`(5?a z@A%iO*WXiT;j!b_mYABQ#}BOI@8->K2%KfbiXZg%GH&$8#^>G|<-dG6(f9UAeJ!<3 zC-oIE!m@(wE3K&8!UAq2D*^}xqH!}sReSg>*H~^Y~aB?qu!^+b# zYe&32%6JH#=(xnLQkm8&ogRnO-u|%byf(CT>!Whcm#Xj!V*)o5oU$EFp{ji}GSRI?(hx$n2QNksVT~pC?@4U%$d5b> z_bot7E_e@}J{`pFcd*mvO7tfNDs>uP@d7KC08aMb7y!H%?(VDQVuSSgCINbrt!%BV zpo9oP&U1v!XJb{?uNQ)OLPZl#r$qx4{()f&_viEaz?26N8PtF%wLw`!-BGR{V%8{k zO>0th$^|7k z4!y$S1G$FRu2mk)e^tjf1%20pqHSoKO~96?>`l{?qBulXr0q?XcB~VbZ1jxW#mNk- z_$f+82oLq$q>zM;`Ij(76<2b4fj3@Z_ z>w9bC5e+x$t4b#C(!;ZV z;xaqU^6H9mtFM;rPW&4i?FLZH_|~qBU=!eKzboAQs%eE3V1^FJ0^pyW5bo;wuMYyw z_v6S)#^}$8gCjPCwooADKk8vk1 zgI7q;Th1->_Tk`0xAo1N*PJT}5t8HdP70lu3HA4SpCB>o41>=XPU#ey7ZrO$%PDxh zxDuM8FYn-RGix$wJb{(dBQjj??T|X8o#T}^65?dnH7_-*HU9Od}d?g+(;>>JAQjoxv9<9hE1AQ#vz0?Rp4f5%OaE14rx zJnHYJ$92tdgyW*+2*LC_!vB*n#{rLPfFnS2n&YG%R|Lngey#UMNFY!Hfc0DTKW_eO hrvBMnmHsF5A9)+9LjbrQ2t*G2*Z}V({o1|&{RijqN0$Hq literal 0 HcmV?d00001 diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6f10ff38a5c0f1f5178ac2415bc6c29d267998b1 GIT binary patch literal 7310 zcmb_h2{=@H*dJMn?6Om`WgpqH@05Mbnq`bJGlrRA>||deOGMdAwq%z*ODLj56ta!1 z$-ZYv->7?UxzGKM=Qw7L-@E+&@BcmT`yPEQe1bE8@5gyS{Vt#}g%AKZI%#lU zTB@LsZV;rKjj=Zxg0T|va&}sI(k!chyRvyeTrqGIQjYzikT5$N1PMmj!;w%q_N&I~ zf|BfP7&j2o9^`~VLgd)JAsBWAc@o)gQrK`{Bu0)M=H`Z$1_Ci)7{nQb5kjFMNZcI< zl&dqy4foL%3Pgjz2oMwk6cHAd0D`|;BItHx3A?a$`F7)PKse`)=>eh9PH-^D4aXwz z={z>QGsdmGKH3azW z_r?Egz&A1fsPQj;aY6N;)j^K7ls&}$Uoh>7az%V22m}0f`R_jeO8Q^&|B;2GC5M4r zA@)XYuDE3M|Gx4+%l^L%IkMOeg+l!2)%cZ&Z|n*=gW$+N4FG;itMdAPWb#wEynPuR2vfcvWwcOK>U-!UT|qeR{+OiIv9y{l^_$rhS`R-7bU4SXo>oYM{m(|=qcJ{kMC z@XgT63p%rEYIY7M_wxuc5mxhIR!P~yLX2N62s!x$;1;{_Yx$fIP`zH2&QLHOA9no0d(9npiDPj@fTjtM-f z`D|I{@rC|ZAEw@1=TyfB0JMn#0J1-P_-jKinRFYD2vhpg#w@pJr0Ta0IWVz_z7iHR z`lwwRB{;&j=fcIvA}zP`RA!UaXEAF9fO?x`Pi;gF+QT5o%eP-H*YIC2be{|{LA$9{ zfi$_jDn*~&=+d6izC-NqSiIQ2MatB;08+s(&NO@MfT5DuL<1z`lWf zMHGphhp`UVfgz9J4ML;4@de^sbuLQ5m#03UFHwhTurO?^ZL?4-Z9G&-TNZ$U3qn#e@S>FgH+#T-6HtrAeUOpEm|CTs_4ccyFhN5BvT zuY3a?1)voxc6vNw(mu2dqE)! zrH1O=)m!N5x37W-siI5w-kGX0e{8mfEN|9dX;D--ss4fOpbbDa<#$~d%n~RT?oeU; zl91t{rA?9J@DfQwmx>K{2n_^&U};*lR}K zBu+oX(~#^qGT$XSG#lg0!6;P&@N9;rCEFm|g*pV+v~H0%KV$5!wykI!!w^dK2 z^@!eIQ7SJ`C~?v9X?6K*CK|k7$PQDO(B{_?W#$%9KgTTGBPM9JKr^_g`Q979gFPdo zeLCpGRn5oDSC)~A8eH!}!C2wgv&sr$?G<+Jn$dC)WIFzAIEnWDr7QsoG()lJracXm zuX}nX%%aTJGMNUI#FeEE7|n&IG_P0#qf5jKfKQ8`q;2`=J+zae+!rpX&>HMgs;dqx zZBkY$Rk-^|@DQ5X=mD8BHEH$Z(xyG z{;Q+3_<({zwt27uYmd$A*jW0hmT`2`rQ`<5Omc_*-8Z(2{@dzlTZRknp{4w3@vU`^)E#$d^$lfuX?bKjt9T3Aip`%_izwC!06crXr4^}$>Nltq|I9dbNoN&0q&A!vv7($5%;@aCOmxFvcklX_j39$C&_yHdjKGp8&qe40Zdv1(cwZFVEZLliH;hGZeQPUMB#Q&eS9+Ze2P z%aFwK6>DN~OQn0Jmee~+Q zj!S@c*lPJjL|9nKcB)I+ObDwvSz{XG?ZTL!O8b#B2>DY1Z)E$b^Jy=v^-N*&ZSRc*nyAc6z765lm9})^M5^m{4#7>$aSO90O z3bk~+FQp8uu}l#!THHup95k}xw=wNY6H=6pk`Lk3u$*lL&{U_zQY`0k<3a26<}Ai~ z$tuY$%7+;az+0US7p)Ag8oduwYmy*!=!x`PT6FN(qxdz>DRM<*PT&CmBe;_i7w5-| zrwoIaj%~t}2ejF~0=Z%Otrq7c1?4LB%le<(8mN9KK&(N$jWx}BrZHb!lW|h?iNIps zn=?>S0~yPB_s%OpCepdiHu2#73Lkbg?N&Ze`tzt)44tuUm(gcc`WSAq*n-u<6A$k6 z@tkB)6L{?OxUWt)DiQRtU_n}NZDJa(n)VSN%p7H;T&Q1sKz+rZx@K+@t3NXhY5x5F zwfvmRkT0t83@`Qtwu)4!UWm5mwyMftT7sMi(dIZo6?0>m=*fERx@;wH66tQ)k(Kie zvkz=5zeH`ZImJbJwyF~BnFiLJmfjm+Rc$R?xkMauhG@aB?P@bsFDd)|uC1HZl!~Z; z57=M%;@c~ilE!i6g3Aq5KlAlxF&~p)g=%Fx6aH1R?Yb5`|6)#YXSJ93ZLS6R3Yim^ zx#%?3DOO5?D zI{9Wn&|vRyUyzeJhcqwYxun?+i4a9JDH%`iI4FVA4EZJLvCXgeX~gN)rA z@1$C+7n)zkBikiDv}kG|%WgN^Nt+COq>Szo6vhsJQbC^fySnoPk-YJ;Y&wZx%}bI! zAkMe1Rd*X@6d%O!a#HM*!D)69s(F|Dm^sk^pA!0qU3~&^#F3pjx==B_dHcPw3-xsY zRF8}TzcS>Dr}UmwevFth*C&faHEV30{*`E1Pge&O&NVPVd-?qgdh&uA>@FbSk~JFk)>h6X=?IDONsq2~2jkC;F!P zrLT2oQ^Ou`c)lk#+B59C04>`E{7T0Hs}*4pt^mxV{yvVt6|u+LswFcW%m^Fh7yjtw z;-+Frnwr}~Yn!*KMRla*z{DDyr{I8&?q(p-du8>gv35DPyv~-g#gXez1j@GGb=;%H z>$%}_tv_X|d50wsW&us66P?>{TOSLdoT=+tk{HeN zsak_G1!q(an~;=A2=8t_p6NtdWc!4=Mez-0ukmNaY&ftyBJq4P1jA%swDJzGfmx?yGaqUK#GLy$Zs*SZVoVclPUu)ZA2HJ!p>v=* z@0Z0+tp6&#`~^~36%ma6XY)pHMTIc@Q`5>quUPcHXxw;WWYR{b`|L*26rBZZ`wY+N zBC{nORRb2C63b9)SO(E>0a=|6@{u_W&`K{G$mM)PM9uX+dD@ZxUTQ|*EE z+Ym6N(y67d3}TD-;|Z;V=Bz{nVQ-bDf{M6XWSK(RS>5cEXjXivxWM|kHq_ep1n$%8 zweBh=Y!7?u$dj?>yHskQV1AExExWynm(Pb5W$a6M4pE&*^2mR>;DKU;7*9mO+ccG6 zQ_>KbYl+If#(b7m1Z2+<;pg9woO&eM9${)!BJX3(uN`M7S-A1~9)kOF?jxpd<5=Q4 zdLY4=%k#uR0;m?RF%9AHih)rV=!x1BS~*cA!jQ4#8i&*5si`kdxLB9-8NcK75>77?f8TU2ig@u}5Ks`*EB3{YoWVoV1zbYo}+r4>; zNli{2UACx|eBM$ivd3DYf4=+?argsaNpAWJ27chN+U+ehSOAg4I@2jITrjMH>g9|T zf5cUeZdVIQK!WmiN&(FCQ}M3(4-qmq+gO+8ZK4S%uPP^cq5&r6I4n3iIZ?! zCp$~d0-;)*Q!cZ+XGkBHPh4^8(}kOf+@zp6fE>QyyCBv>*^)ghg`UEkGdyKb2w9-wC@E}Etuz-FuSoK~4+Fr3Ag zxP0)+ieBUz`MkK%N-$$g|V?Dwa$~vTx`R-u-r9~DfEN6|Z za%KZwdmSY*!sj2NE}QMD{o0i&0OfOHia?JDnq1KuH)LbUohIxAWbI0k7;-bZqV$nV z&?vJw)XlcZj<|)m3+lqU*PwVcyvC!26J>u==AN{Pfc}F{v#H)G(pe*?^fM$pki06V zyCq4s;3gfN{yu-A$S0Iyj7>M)XC7p=j#>FNJ1v~Z)w!Qq3?g1Oz;>AJxE*TSBb~a& zF;X>VymmP0=m_Jz*N{h(Zc!S?EHg+xvUG_G*L*BU{ z)x5;-9%q>HQk#%spRC^l`qAbu$}T#$ z!}WaVURcjdr=Z$3qI11^5o8dW#uNwZcq1S0_80YG$+KJVuPpZ*wiWOTCl*rYgZ8mI zU!p}d!SOsC_5L^du0B3^kR5N~fe(Mtei=-`lzUrB;vUl|L{<1=qENcw@@N_zc&|Dm zE-yqdY_`)!?b7@MvL?_RGv#afmQ(5BXa)Oc!Bx+U1m5VaxtrCarz;0GRpL{DEqJtj zZ~1iXD)kxH7`6sCwnpl9*evQ#Dx3F39)`i{;NlFajXKz&#@0!jE?M#%I!iYS>oa{w zbiyf)zE>T(Saz&pO5dlVIL)R?Uu$*}rn@F4%vqxu`!MBb_4EBfUxy7s``Y0wy~4VJD@1sh4P{g$ZoKA$G# zN1d`_)EQalb0tV6N(9QCUY3vHmTlEFS-X6xnp+5t$XBa5PcL@J@ODZriqoEd&~wTC zO5-ex5l6O!%-H?(q?s7)IZ_7EFf&U+xbqxawaT-vPgSgHh*myZ4hvgn-BK- zxaud`aUf?C>p!-RudjuNW90AO{NSki>G;iipdSK$KX5!k<5~vX(S>`N^tK)>Q55!GieyabE1CQ6nKY($#mKNvo@k;r)faA~K9|D|kVetoN|7)aw mT*~qN^+QS@?xBv8@;AFpUyBg8r~m*7?k5lziJuvdKK%~^qzBai literal 0 HcmV?d00001 diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb new file mode 100644 index 0000000000000000000000000000000000000000..b6e5e04031d0669c92005dfc13117e648a3853c1 GIT binary patch literal 14044 zcmeHtgTaZS&k?xXiC6zpMgM@TRHzF-9-6P7#^ae9(v#782LDNa}xN;Ui9OEfmE`HNb!ElU*KS0i9S+AddE zE&TkWf_^W?<_N*h1iU3wrQt8x79rQ2Db!FtiL4)d#C}@x_!yI?7oXP0uPh zYCc6g+YPDKY23#tn?3lBg(b;1Y`x0=NHBS!Bc^47$!%)*^I(ig&Y|T(@u3QMaJJ@& zFCSZ6aW%s|qBcq4r+P3;h>*4ojQ5y|T!$~}VYS+W15#IOl~!PU44EaH;9$u7Ff{UU zZF&aS5iQQJPL@)=HJM(4%sMT^+GyduY)%QSItd_{J)Wg=?eOguKgO(}ww~u&P$Heq zHMZ$$_OByD>geodZg;}ozduFjq?taO_=r(ImQt(^bQV6j3H`|WDw0B)O`T`7pxVxX ziB9jF7U$*Yhqvx3s|pz626eigq?b_s<(OA0wT~W&M~4tt+9ufBUd2$lc!x^y@V@d6 z_?#W29zJyFq6wRnu`@&|^v((;Atv}f`7+d#Ip2#-hEzDS{=n8C@14PWMwhFL6d$pk z2E96b^ss`3a@RvxoM_A5u&0=E3-#V7+}r~bN3G|`>F_prof3G_m;Alo1a?wTpC?dT zXk~L+k~I;(6x_z6NjKYfL`gA89N}6Mio~I7|~k z&u#Dj)WfUR<8!nMaY)m#G8hMsena)^P>}KozcNE-W#6kO?c%h78Dfer(j)9t<0J8Z zmf19^(DCh+!MG zDG^c&cm#y|{3Gj5nOCLngRux?{Iwu;*Lj}nKx!?bI?iW;yG!{FgBCGg`t>Lg74aqd zg_7jm{hka+D&EtD0DF<$FY?6uu7J2CrhAAt^ zC|@7A`e}$D(!E4!xo?A7;X@SziE7){(KnU7RtAGcz}?AKAs(3Uh*nQRQa#TusE~$j zlH#yOZS%liwhLXu7&$)v@AmGk4tEeR6iRxxC{-Z%w#w)l?lL?{MZ2 zUa%FS?nY;PEDxs}9Tt>N^rcOTkq#su_<>RHCC;=56B;2et<-@(DZttCl7h2%uw;CS zTR{H>&p5xVX#TBsL#*aDfRLaNVKq@>w9b&^-`51fYvwZtG8t{L6(w03j3b z-T&L4#<)cVKNjq+FY@kiqi(cv^I-(D0inIt&jp1U;Y?wz##G)cC`h$St!?6Mln@m| z%am}TR7MiY+TG6kc|JhW`DB!*n^CftV5Z5ucA#HP3dMx9gfF8huONi#(36-uO$1f5B zjcF;2gxtRmLUxxcLY9-03P9=XA@pV*$YIK-Q?MT#y!_()IWnR(KfzT66E^X3RWh_B zs0Ze#e0{o{*_LMgjDxX%YTBtBl1bcw(psz?;qXXmNmws~oU~BNO$#>Y;8Vc3w97X52!Nb4K2PL47i6(Zv>jGd&36(1HY74y=j}#ruceHH0mK=G|U*ed~h#}Y=8Pj zEG3ibYg+dhs*q%L`p>7QPTi|^hM-*^B#?5V$|+io^$=LfEROcV`@yln4AYw3SPFbf z;jxIvJL2Zd#;o$a(w7r9X<@@B@yu^#xk~xoAh=QSsY9u zmh_v|LmSp^Qpu>ud}^t2fLJmQMtZ6n-T0X=^Kr^)g8Bl7ZJ}Lh;S8Ocf<}j5SE?k| zQ6@T>yhU_)B$05KfY04};(2;Niv#HCDd5fjgPz!a>d9TXK?Yg`y(mp{9tW2|?g$fO zBpgOnAFgE?vr-I8$Ut#lJls8_?J_`DU(bj#FL7DdbaL)EEiLlpW>WrM$>!!J5|hyZ zlS7cyH&#w!CMxa#1{jbsKQ>X{*Wt)~Xl0KtNOlw!i_7;6Hmg$MVSSG^eUcwJJgy_c zdFIgzi&&H!B5bel;nYh}Rv&xT#6l*(le@%V}X%_57Q! z*B1BdMvj5RMKw!DAvGO0zU60*#fZb@HTHMa- zuAUGYmyoEpyIIvG?qqPfAK*|AFz;@CuPZ_k^KR+PAWJuk_g$}%o>S*WcL#*^Pm{+G zFwzGDrfvo_(qAU;U}Cg1HrGMz^X{GEL9wsHTEpwfz%!V6! z;u-Pv^r^?puy(jUeIOAv6qFc?7^>I`cqwPWdVLa9sNJ2sJ^=EeGa^lEx^W&^=pcbreG^D^Yw4mpSks_ zx~$DCH+nO3*_F?d$M$RDa*Q0QU3>vY?esx|p(=5Kdm)%oxe7l#0<$S&Jvr=Z0wI%i zibl9PY=~0`p0;=u5S%Fl6x~Z(>TO_^jC(8pDo?M& z&m@yZ88TX`&}TYKQogb|Gw)3)Rnf6dOU!5kon0x+GnbUHv*e=gPZdv_@)AGFN>U@D zP%vjXry44Z%XG8CTs-Rfg3oVHRZR*u$dVsZSYe+hD+KRPcZg@LR_d_%G-JieLG2Ogr@3{OH*Yj&FMle%^Yruh$b=-pT3 zTXDly>rm1^3u^rIp^)qCg!$KE3=5DcDMi7ult3*9HLcp$m@;#Ex}$tLnVd*6B$U7TBqBZ{N`!kk4PCP>F$tp6DM zBv?gtv6H#`2~h+#Rn#dSF?dF@o$j+<>umH=k^^zSM556h%>JZ08XR`X2@Q=O!lQ$assf%_p$xTxXZw@erolCfa%qu$4Cxt#ovXrjJKdI1_R)AutT?B03 zO)`A&D>a0gVG^v1!d9p`eCskco_$ev{2MSMCj- zRA__6M)9)a?1{pD*J=P?q*$gd398i8h!c0r`eiYF-ZX?AS?jTV2uW1W8451O*cN;G%iVMzSY%Al4{}5Ii>E zb%j8C-MsDh8co39sLyh)6SZcudN;JxLYr;9?Tg4IsW2j!FFgi$5Ib&S6=#IA5<02x z2Pje0cm4`&25&9F&lWC^$pOFXJd(P^N<>nd`bLj&pRz8}9Ha0>u>gFM{=j7x^wzQG zGp}0g2e3zy>dN`BRP;z}%(wk zUsBj(8EHPj`wrK&RwUe_#{iK8R!sDG7Uf7xRoQq$k~en>-zlKlN&TnLfrkBC_@?^yU?WvWdoyd3YaJvF z^|W=hwu0K*Q;_9^>0&dWyBJ_tT?sV2GpUgCk>8V+&_KaO(GME*8MH1B8X#sfYFuch zx3?kZAlD-!BI7cwGaw?rWcira{s0*Xp8$Bu9Xp2bs8h!#uw$G642<>Y5aLN&u7zJ1AhhW62ebfkQU&vWaaS@8-^)WLSENj^#^Ldm! zb3TJpUnJ`j;=muHl4Uz*uinP17KdrgkZC+HuV0Nj7WQ?GrW&ukyju4znETJ|)>!o8XoBId{S73tZMLFY9K2=xhCC9H;p8U;v&1VS;KM zmq8jL-QywW;IP&q=2cOFyOThvq#vTOpE55Yit*vdK>CN$+(UPj`OoSrx`Vugc-Z)Q zKJL0(Kh`P_Y{Xb(E@sb#y>bt@ysz>JM^{(~bqC%$Ykuo%GFi_0a&^gw`N+a+Qy3v3 ztwS_K6}yG*9owKf2mj=^Z5zV|?X8JVu*_R72<}kta+p|1UcWV<%+Nh9d69+hHx@ny zXCU2r#ei}ZDzq6b)cT4%idGPo;o_Si(Z&5>%vM2!aX-&GzZT6nelGoUVersa2z)uI zBThTyXxI0e(oDCk4a-+0e8n{E>)GF+yZpC4Hh0VSG{Q+tG8%c(=qXJl3C26)wAQAW zK5$1&cT#~EoW(c0NZB= z(yyE}k~PFlgkGq$FJ_vO3m?TQ5S}OIiXEKH*5*gAe zsdGGJ*^DIyI+s8U$9NJG3qjX_@<=D<1U%l);^z=^@XKd(v3_47ht<7=#|b#@m73bT zxn~_^CeJ_3 zAu}^GF*h^lW4WJ-)pVxgYF);_v6Ev^XxXlpZa2fDc9BH+a-xTkr9MH*dD1gYSb@;> z0~z|M$Ff@18?;Xxi)rXoU(rHwk&96Z153_CXT336eK2gl?rcY&_}UdJA)Fndjk;n* zPMa;0EH>qz4X)HkD(NMyuB|_)Vm`4_?9Y@IRpfg8MhXkU3+vbaaVsOj5N9(fB zFVy17E;BJ1KeFApVee_4x-XGqv1w9GtF^DRT;#3gSiSZ}C|v409_EKpY^}~U&)lm> z_IJ!xYufLqp+3=1o6w_Idu+gZ-;;+T;-xhze$4xO!H);G^TSU$4Xkut2!v!M zmjz@Qm+GZ-hf+<O%}}Li!D+)M7u~c2#dJPSU0- zv@hx|ja_5w+%&*DZlUL-R2QR){;}ESPxE}#o6EEnq5ecqF^{X-60K{Xh)FpLNB0Se zweS5EK~akM-ZD2%MEV0OX>XZiu>gbm^zT;2DWgqNoT&%KHbrfrd0{Fu@{r1AMU1VY z$%k)ah*P0AjncaAVV{yJ!gD!8CGkq`A4QNP5f@Q$;iM4MwGBl-w*lKx4mL3>6zA?m zmMpwDXmf^BSZoO3@O0alHdWfy&y_Ppspp8rm5Aa(Q0>;pm2-x9=@7>SNA2qzYsL9? z$GdMm72j;->KQ+91S4b`G+la0Uw%a(xkSCht--MU-dSC3xT|o={sZOGfW3vweQf8Z_wvRz|d*Yv(zN38Jos2?gdw!T`obF`j6(&a4x)%b)8^;mG z_DcFq-0t1EYc>bb$j?nu4`{f*jPF;D^{-s(I?Z}F@MoGu>ZWGXCGd?33#^Xk{x!Vt zO>S3Naz{!c1U$Y7G`gH-cYiB%Hamd~KDUn}katC;_D6kC>O@Dw4d~tbq*vF`20Z7E zZ4zDO;~ohREFA!i_}5fy&75o;)$|R3h>7{;{(4I8%6&3WKr&ry#vzV|0WAO<))l%G z5`rh9SRaIVz=U`J5rT))NR^)MwM4b`{$yoq+wcOWMYwq3xiY23@L0c^y1b&Imo_xE zQt1gUX%)R=lpd%%rFxULaq{bXE=d0XMKb#R0@U~X6Xl_dmWB|r8eOpFLD5)ahOwNM zIE1QcWjt>B(t<1j9pS#@v*(E`iQGA^;Mn!FyRfKaTrs&RTwQd=Fy-`h&H59>p-!qR{D(MHr;h0EtusJUv?;$1s_`yP`QBXgIK5;>W4oa1U5UVU{FJ?gFZDr zMy>H1>pT7NDJ(OewMN8$SB|;lyqYUl%$dcarA{hV!jxR$*u>Xr+`_7EmMP4C0K@P( zvN1LnEBi}~)8zivv^}l0NPKSItF}=5A&jsDq^yN9mjH)d-gj0#mEYWyFKIJ9V-b8x zu^pv;kaK4>bo%%`PYc{+zSH*K^DJVl0X>y~lK!iLu8E{;1^Gt}$#k-y2Y&JWg1&A& z`i+!4nJEa~?bR7*+HnRpIWej;$HNV(Vk#h{_O!#jC6b2-Pbd_rYc+vmyaLk4sNR{w z{QJfNahhZ1qJs8V2d+oK1s zIV0%s&&?#&g3lQ`0?f^mx1xloc7CPvVG4k@pls$4nrxhCb5p|E89Qk9gOIoU{3^ficM*N(^&QrF!GQAHL_^%!v z`cdSIDHA=`U{7CQk(jlBx6<|9AQt4i8glB;LwPu;gSUJX81VJm`Y83f3kpj7ZlUnH zAwI2Hls%P3c*~56r#9?kb#v7g&pYX|M}<*coPZ!61MRoV{Nud_a!h@DS7~b_u*^=J(;XTbfbP6c=ElAgV;l_JGZ`oMyeoWlD z6ki_Dg$rn!8o2&T)7LcMFQs4Kii3^Ktj!$FY^;B63JN@^?ZW7Xmay>HG#v0E9XMxF z*l|8gXiIQGaQnWEa58(UL6JVx(1?f()7#|}m4vu3@KL$pAn^cq%yl>o*}Sv~L7#v@ z&SE{^^~ovxAm?E|Ljo zl>cS1Dquq!dn1SImGbuVw0E|)rqh5Zy@lH#E#=cP0ea0iIM4eq6>OcUeWK)XQ&1W7t7UW%3SS8vdqmkx#}V9k}*Swu~w|9o^D7VO@m=8@84IMU`{(ltFraCPSz-Id-2N&p&l z09*tHaDZuKW2j_rW9tB{)E@l1)a!remVoF|V%mO|9=!Zndhp6EIrk%a$czGH6;^B% zK8sx_rcLNXwle0#?ymG~v7;~6quCarD<_ry$btw|y;MubV5yi)cn%x?@mb8KV%!6P zkQ5WGvUej&nONK$z_BHwHH{5J<5ZXTF{Tc-)QqyVOx59nQrP`P9|I-?#QP!1U3BYW zrnOTn%_iEdnn?@#Flh+u1bg1)1i>3&*zV#<%-ScQHrDZUVYfhO(f!B?zsGw+FPqtv z={6M~>^Ro&fsq8UA03bMDo@o|jjlI^FTGhh{(4%i`!N1p0}h-Tj<2e<&uQ0_FZQ}i z(sT1A#)HfqiCmbS9cED%3eGY}aMMi+uW(%My+pVa?Z8J@E|UrjV0smKabQ+0{5am& zRZc2pjXp+|Evs_c+$`1E8;FrM&7zUChfK62e@dx!!8qltj+u>tfJ`k%I^ zZ)^KM(*s2I`;!tYVmu_Uz8J+!{?NR)Q~xoWyGkP;WiV<_h$j`$$ai7-aKw z@{636$`~n~Xob8m4>zF1IilD?Z1eRjI$75EHy@7Eg-bbQs|ijZZsM!YslOVrT{|{J zK|Q4$8sf1;*Fjj*KpTO^7dO2N|^oy3G}Q`;GDNs>yVG*c_Ac!4}< zMuoO}IN|nE8pXvzj@2j#S?(ULmkn+UmkXB|Daam`^nnZdR?Q!zP12Xgr(lmrDO1Rq zP_(3KKk7)hN7fl`xGEBKi*-Wnc={5Xa|_pEiJpF5Vb_IQtDz(+c++($Buu7&d!I$yfd6eHBYQz))o$1hMObKf8a%}94h~ydK*e|1T7@!bP9Xd z28n%9l-drcjQyuc1J}R9j$e7wb$oeO@bN3s9Qqk)BEv47r+?9N)J-{J=?WU_kja=F z74SBu57s0n=wsZT9qNupal#fl^UPoLC=IPwnV{K8x6oqgd?vcu+tz)$e}O28WZx>0 zKr|<%&t;i*hQ+9{6*I`1pO0ARS08s|Tzr=JWLy%{PF}K?KAv~I_rZ}acl3PCZs@=X zEHYXy4=mg%J}=8>?Sg@;S+D3N*4f#n zGHTIEQH6l@{xde2SWo@B2lOZa62bW`5iqa=S_29B_4Vgl4vrf58D9JAO6<(X?@Upl z)Icd1(!`~WE;X|6q67z&A@=r*`3)Y1|MUkQg6t&Te_Y z>yD^mALY0wz3(+GKlwt>mK@}N+KJ8W(ID3_*N+&n;eKl;NkPl?0y$z1`*4I{FIPIU zrxz|R#JJNG_gRR+z{-VThKxF_6=mI5&d-FIho-8W^?F8fY(zFL%Mpb6j29?IGO@a= zYnn+_mycVZ#tH(445*yY);xPUht;Q>^7<@WW^ks5@jT|$Jp^_Nne|BgKPg}0de~AI zmvlkoXs#0OmwdV^-DrmRyX5hmg7r2lAeW#dy zYSZDGljm}ILV@Q|L1UIv4ITiCCh)-OIi{Iy>EGmG)5T*PfEjscf zCk(B8GNOgG!h^4_e%{1<(sN(HrlZ{nMu)o$b-vQ2cY}$6?QE&bnYdKx0;n{FfMf*1 z*1K!m0m=XMxufF!Ho)J-s(+4l0cesxN>^_Wyj{I_Gc+CU+GqS(Id*&S-{odELqQ-0 zgzLfoq4?}J&h6r$8>B9PWd-{uK|sL<0O0WNGuYchZ=V_7 z421!_-_N19PY`b-+&=8PL5TQ;@NaJa_sz98xQ%lAOyCBk7&v4E=J9WoTPFm!fo}7= zH$ZemzZP^|QS&dY+^LY;#Ow`5^)HMY%H8}K%B zb^};W@?QXNc(mJqw@IcOz)8|;z&}^}M@Vo@Q(w#PIuN)Gdz-4cf!!dxJ%1hjl7=%4(?ZN%Hu#SJ1J zK$!rD{~$7MBiyC}ZV(Wtt`Yts25yi3JITHo3j*x|qyLd|-yZ&Vp7iH%GazXA_we6Y z)9ul>!_u4a+yEE%w>bZ>$p09m-p0Qj@;&vEx17X4VOFw_dKn`~X YMM|20Kr3W3zneYB-!0;`0w4_ zd+z(efq~zgdP=&gySl4-6lK7`(LjED5rJ^Nq=NN^0|EK=g9?18BVuRkY-;Olpz2|7 z>ZC{SZexAi+Q};bd?j=>b#wyQ+42!H(K8Ygn%WxMnE-6f`H0n2#pyVS37wn`ZA}cV z?QBi?h&@c5hz0mzdB39&0*P&%_=qi>o$a|97@UkPOl=IE=`YGP;XVguBY9!M|hXy^u1gP7s3Ik?%FJ>mec z`6i+}-M4rC1Cc!t?^m&Y5Pf_8A4n|iP5+wa`y2m(2xz`XeEzKdw|D;op`)p_)8A13 zh2ef18hRk*cjG!)0PLM;{)UAS!1ll6@Mvi4tW6b+EKQA_zv-X=^gTy_i76qWqM@U+ zyrB(nq#4|;8SDYBcFwAXM%JcIfBKv0o7?_R%$@8VO$|+)EKE(EZLH~ka`|21|0oYI zMC@#VvV4F27h>2r(V4m%n*w=!r}#(wZ~BTD0wd^$y5Ii<1_r%{PxHH zZiU}~{#I*XIQ~9N|2xB9&Hg*?Kk;`0PW`|*V)*g;Z>0Fc(|(Zr69eZTQ_c66e*^#b zL;I_e-$DOLfIl4YHwS0_pZ)7sA^yPsTS5MCaAP}1)Bj$A-`A3F)c=KBJ2`s*=lTDh z-J^x&SA~Co{;jq^$94v$ET%tx|L?>89qgYt{_w}|bMNo|{QaMQ!~T&|f2aFLeinv~ zrY0)Rj=)^#|GAC-jQvl7d|zz8i~Of0PT3UbD<)3=M*06Hn>yr0a&mq)7)aO`X15>5R(RR^L1|LX>)3|VPR$c5;(Rq~MygIB9n5({$ zkw9=@y8tAj#a*;u5j%@vC}!SDeW(`X9ZWdX2lTi$EH$%{DlAN@FRp<&4!<6Del}LT zZ@(+C|7DcmmAaEacz&AGYlnKRcKJ;YZ#lp?76^az75xN1=(u27+(oea@@t#8r&pL& zQqkRAG7}jOVK@hSkPQ>uN?tq?fe4$nPnxI$xtdSIKN==Lhg`GZ6B?WjEgUX z>w+tVfvXu`O zGE+h{G1t9(c(Fi6iJ=gbgOV3QVe+1{hql}XMF&glQ^VYc7%V=9smPhco5X??$TRh` z%t<6(V(H9tkNGO+^8mq%vRF;c0BSURSpB;-S3*t_`WKTMk^K2~#hHwO-rckF*IKKH z;}`9tck5d*zL6cD7Otukhu@{TK_3;1s$E@(&^?%Ueredh#Jqy|)e6VKU47G96r9SJHzE|Apl7F_pdnL2!MQIbO-gFoX$kWI ze&c)X@Q~Wg5K%2j` z*HWNoWKJH4wCfuu~ zOa(xoR;92BH$V_fW;~a44=>?#WSc$+i1rsAjF)B!wXiFrmGIxAHFvBu!d5PKBgutx zg1K84wIILYGjD*mmxp(OUpe=AYqZ1i0H((H z71<{DK|HSI03kV0=nfYvL^RkA-=~U73*R)@SsjneL@P zHr+jefv^AUC+QUXz2iBYO}s?1Om&Q}V7{FL1RA#w#UWh-d&KK;;FuGEkW*^8w* z9BO_j&(Q}W$00_>vNx%QY~NjhnDP(k{AU)en0p7&E4Z|Bn7{y zp#--`9df&?11Nq!y5(p45;K70ja6IqRk~MpbFT;coL!jGI^Sr?CP&O(m@su}>lwUC znO->GbDL*6y`8dm*WD#*j8`w*yu9}>awq-Jk}v{+f477}Xiw0=pSp7*I(Gl$*N9ZW zYk#W_}2d6fu*QN$?s@G=flY@}T<_oKE zG|3@MG@qUOclVM41$PCARKs-%VowVNi2?N7PG+AJ`FU2+h&2P)bqAlmR3Jw2H=*AA z>>$d&V&Eb#^_({88M<`$3+t}fv(p9b-7VcRQ~y^oEW|AhTa54s!+E)%M3V@a>J;DP zV#wWLr7MGt$|638drGb}g9JB3R`xXXnheXbb`5@oQXQSp1|eTaG2)}#n9Ou8`T?0e z#O!eS0i#+XG}CtAQWX@LP*>=*L>X%qoV6!vNtgJh0l~v2G=r210QD+6iJEhIs5FF6 zXa{e1`wpqQYZAO>U_W+)GIG#O3+l0m!h1fKQnLahT^3qO;rhneX}7?ni_`t z-qDe=WU-35IZrGrK?&}ZaPKgR;_Hj_u0Zwf6=R8$GOqO0_O@tXEGV}gE(kl>+& zt#0Od2nt)Dg{4jJ*3as*u3Ybt$c-@&>n`0r6EZD7?(BH^mpf+}IJKOYS-oK+#m#9U z^WLaoKa|gWW{uxGGUF-AUAuID`Civ+Kfs)wAdZwz?y{rPU*HpGJm(<~MIWMuzYiy( zCOvQIcHiU&u-&GMyUycPU+=rqSH}p;)0Ic4Uhhh$k>tVqIX_}eOw+pNK0w9df{=EC zNb**M!VdY%3}iY+SK(b}3EJ#;wvcTK*mg&}J|Q&qHd)_~gblrR<>>D&Lm^nrV|I8# zd5p7l6+v8~h=}zjX+GR6N`9{w?jU;;k?+ppfmbQXStVL~9tSzuXiN&NkL{Bz*k4W5nGtz>;Sw3tFJ)*3{8 zH-o_$Dt;z+32%v;zH`*di_fRMudxRqsM_unpg^ZqJJ%Iljd`LyiJfOgYU z3yP(c_MmtY%^Y5dM<>o@P%=QByU4~M&iJOzlUPi)o7yn5FMI@RFuF&=9$#b%D+2eq zu~=y0ZSoW)6s{QUYwOojEsWubhC5~Z+;pdF9|58nJ7C5*;VQxvidDBLlD;TS+vlr_ zTOUn3zbuULZ#%sAva3g$k3OCtDl(rD&&LdTz5?EW(_X^@^+vX(K*$4@ zdz5$Sn5gYj{`2~~@C!ogm~gjlQSfUG|0X!@>p48p?uug$m?$*JeeWK%&ZiUb#JNKk z5sk=#c7E%tzuF7#{fH(L&{ht>#P#W)?e+WqF)Lors+$ol^g(*iC!@HJNm$1aM_&$W z#HXe;7MJb4cdUu}!`)Q5+GK@Zb|wYVF_#qEavA$V;Mvp;b{wq)jD>CROa-VgDX&P-c*k(mr0;&^=$sia7J~{R|Qv51xCIF3?tHtf2+6~)1|XD`72|L zjJ`Co!VQ?C*M|he#yY=@VyqXnmC*(G^@QI#tCh z$$&Az`vWa|Q{4nZTxZK5@;+nW_DSvNa#AaMQIzM+6^4+*#yfm(>vZq0D0M4ihRSw{ z5!)8e7wU5T=++-BPjPtG5KDew*MITz_Qu>{L zNm3e2^+EwVD_rG@VHh!1$;%xdsH{%m5-39?-BDE38LO9UQ8zzzd9}(PeQ1o3G9DQr z&hgNKpB|D=;o7ySVezfk1nrG#9yAtvdLOPuq_7^5HO52MP=E2NFu|k{(zgp zcG$*omT%t{l-&}?o;$HRj5xycRUhfc@3UaOINAzO<3 zkZoF4KTtDvgao}B^_^+`eS?L?0rS8oGC~|19Ah@9?Pxm;E_1k&t)U)@ zJ|3IR?8#_rD^K>aA+3w-cs;q2>D`acvJpEVItrYgk><13>P8`4Z&XWWZ*~h|`T27E z;_)ku@aY>qr}}kp`AN<3y&g{DT7SbKxgspN?k4id`EADmD{}&JR`BUA>V&?1MV9Ry zv=B;COUDb=YFG+~Vdc+w_c}0e)x}`S`CBW@(=fg^T1bWF(CX7B%KHpZ@9bW(+>c*p zkmU>E^UIb4TrLfTUkZn%!^Xt*tpJYw;Ct}1uGP+pZaVk+ocsc=V@Dle`_3>wG&Uk} z5vK^@ZV^T>XZw3~C7Q;8$3-@0__K&g@2p*fdx)#6-#Xw8>-I-D(XR5+<0qbawn;R2 z`SX*qlKM2uH}MwYG+lb)6?%;p>N0jjQXR2vjp&>7k{BwNZUwB_j;N$1arJ#jv=3INk2-l@(e=vxqb6=aE82r>RfGXX3l`@9(L3%32xow}ct5FEq9b ztX!Wl&nmOd3lHIXQPF9!Xidve@RFWL=qty`HIE(l9Mk!GV(SNgadv9zY+Ai9%FuhO zxyFDJc{cnI5u?t46p2g0`H()-~VyJ~A>?3jbCH6E%$SUBeNuUP_6KTgb=nxgn8k!39{R z*V64*`lgMb9E(>x>p3Z2 zJ`;pT z<~hsLs65NVTq|;G-=@?i=-%0}&$(U@Rvs5Pzp`+8U^4h-k=Zi~b2~Ffo5EXZSNmGa zCLDt|k&`ADV|(#)3;`tREgXy~0G5yTD*Z^n(pke|xJfl3;3UbqK1qX{Oqu1 z9-=?fxVZ*o+c`kUd`u_&oi9Fivy0Qdi5lYF7neHSP)@yr{QEF75yx3KlwAS7G~^=Q@?PNFOP1DK2A*)jO=d#KZ|*=Rsh)Y4IbuTy0Mz@b7sJF~OmsI`NK9 zM_xK4pDA0y>sFFsVTQ;b1=sXn!ufnZ}NO%ff;U#158|58jg@ zG=j++Qzm9lt*BYyMQ96H%*HBSAE`;nAaRY2jP=)yURq7_GwwK2ZAqEpO&p3Boq&55^Gu-Mo-#tmN3iPY@s=6u%khU(^n_633%~(fH1Q>@y#!p^7B3 zVZ&`g>>?l98@El_x5SMkOL>*$_>1#95$8;wu^i*#*KJ_Fd?NH(x!Or@R3h=^jI4;)%(p0wAY4mC1{M9SDYv<6WE zQ0f{QvD~w}#DwG|&hn zvr|lWy!^Ih{V*Qar{`y1m(H%l{e;QeyI6@=EOr{c^!I$i{XDZ~n1a1mLsIq@^(l#k z(wdCBYPhxu)u(Rt?hhbW&jHv|ArKDYYLHZbQ#t0%%%NqmLdP@Wnph0>-2EQ;TBKW$ zUDybA%(5$K_9dONt0K*ZS}&NuPGL=LJvX$_nizH(PFBy;e0&RiV(xNjeq0J6fo_y` z^(YDotCVU^jC;T6KAZmh`&9%hIeQqxpTTdSqvr*IZF*kaMZxGEUAAwchI)Dw{P2#bljKR8Wj>E)(u#F z+@-~|wC>kaU~NI{;i(9?BR=-Ai-(JhRhEU7%a5&mdt5P)CnK!IEx&CnRR%a^Wg& zP*5pRu|PqicVB8!H% z?6!TCZb7TbqNc%y_NmC4P?hqOjla$T*u;}=Q0$>Z_%Tn7WBW>Vs7MDV#_lP240!jH zgPuILZpw+T7WtWDhWXCMB_k~~YxwFUtaFhjHp-G5a1Gce+H`s>y7_+m%10-<;*eCu z8L)I{s`&`-i{;@%sxp}O`^TB@Wu&|U2CsK)OB>Iax|}g;6(z$c0`)6P48JVN4O}f!~;d`gAb^>o|R@kAw0C;n$FG8Vbj90!}BX zz_1|v5fXn}GtE+#v)W`tzM~O#lW>SHmV1F3-y9&gz*i^}BbL-(TT1q9w0Xboz;Cry zL`&L>vRyJg=IYa^g?h%=>;?q!;u=d@^gCsLj=Y-t%t3>zu#e)fq=#^NP)KRs5Q!NV zuvS)tM-63!VN;$mk(eV}ObO^puT^2Wc37h`*_fVF0!#u`@@Sux*SySys{|RCwPeO; zm=Wf(X>Y5c&H5^chJAudE8?8~KGIygce_z4wRzGc$J%DM!8}7|edM$ICDC3ng?lK2}NZIwsETX!B<)ssvxB{!?gYCl+?yG$ZZ3jNejMc1Tzf{ z8D5>8wdnTN-NQYZI1Vw%6)QJUL(;KnnbaI11H4s)+Eiu+U7BnlCeC03e_>>b}3>O8lN-`DjHYI+WWyh1?@;%fBm}67l@ICqVV%M_|h0YehY{sz8 zDWQ{CU%!i;PA5g-t1)}1iqo4MiACQ>$3H3Xp7R!(3A?*Fd18$;!U59 zyqK2QVf~g;ppFh%!xDHR?Cq?xs{>X389|UyTfTo&2Y?pOiELJUOYlPJh^SGch^-2? zStu$`hBhwEvGGH^i%7ZdfnKBA{P;Ta_+BI3GPsb(XZ7jj)s@ipj_zr<;|`*h-v7aCI;lm zkbfR7($I3F!*QGAE4;5<%&mX0bgOuGMA;zzc@0!%(3QIiyHX^6v3YXfzE^KV4Zcwj z?`;;8=E#=J`WK3$s_0N&^N8NkGWViRe7x}<^tdU?7Q%ZA;v4)fm;Ekn!ksTSrIDR>P$uJy> z3)+DVf?p@PeLOvgO5n&Aqx@*m{fl;#LrpoSB|_lb7I{?FQN@Ycl<@xaJhqWVj+@UI zMv4>~0Mb9&$pE<^EFQl6j?cMxu&d@^$)}aJ=5n?_2mQ(T3kTilw9U>dTz?B~^HdC$ z?VFy@%OPOR{;WZT#TK912#>sP?I9S%UQ&aTrhk^SDS|qSgZ%RaS(d+ z+j`7&7BfPd0hQ!kyx2kS@SKf=P>(&Ik{K%&8KB7K(B@()bbl3$zg+Z?<3}Jaaj2IC z#aVcwTkx)dirN$1PSp#7z^XA3w%qq)S-xN!D`i;OOom9H27C~YZlbW4Dz%OtI6|LQ zDA6P=bUDkrFb$PzeouWG*%)QcinFmCD{_gVa_mvnXqXmE2JmHvzQlQOa~UdCREWi6 zC6yt=R>2Y#>b7h^)hgTD`W5;4H)wEAM&!Mr!_{8mN4rEe^bc9}x>$6Yq z)|SJB<}-4VV^S!28!tCsUWi%vL9&0whBgM!h15MA-qNE9QzIF5)aC?<7rsm@vvAuR zO)=9wlg?%^W=YZvljgbfjdg!uzAL+8Fk9uLB}?35w6HoqN0q5 z%bae7)1uP^pQyw*-uiu5Ua&bl**(EfbSsalQ-zVorSBmcTsvmnKGiv##|b;><kvYCbCxrTuKn)pw&dwcK~IdEmnX-6W(+^geV!?QrdLV$#f~^xR`AX@$gyCSL+3_of-I zZAMNpk+jqzipeVJNInl063S^hOeMD^nyL;pzU*MqcCF$)6`i{k6~*Hqtt?{Yec5BB<(Bo{AG#^RY9>U zS0f6sT^xT7${==OldKPHaSq`Hk0s7F2-_FAN~It+PJaYHRO=7^2%DuN@~=2_DdU-~ z4J35hQd^eYsHfP*tAq0y0&%)OF*SCw@dYrm!a){5&(AczC*bL(p11Btv{gN{u9JQy zc8*J+f?Gw!lH2hTHxspabYp7PgUbEL=pw$R(g@+e$V~DLnr!I{RdLPCBO`L^9!e1x*Wl` z@)Z{DrS^>G11N2i4wY91lmnR6W(&nGELOHLutnes9qfXEBid0jA^e%w8~vGd7idW-cOD4@G&S;_^sffclM!A)1unnIrU57wnHmb*Qhbpt?oC>t?D)RSXt8y z&mxr7rYjspHcm79e0LfzG+QK{f?g}*T0xg6k}uzJ)0%sKH9$?v)-KYkXd z!wRN_eBg?ZGEamr-W+^6oWD!N?UgHs_=!P12jZDKk{>yru zq!#D=oeKZDh#+2Gc}U2b$?|xwq7w{jmd^9D$;&f_eRcmP)+dQpGpCo3b}i*(l(f5z zHrDx~*BoX?5F%4qj7aMBL9V8h>*0`cpBYZYO>_oCw4*NKUK_V=^%X#y1{O+-wX`JJ zB8ozk6ZmeQNZ25vEa+E(ici8A#+Xh0k}nut zXA;xfLPaMe=tFhc)H~|!t8&?(>(&^WUIa?df^z_?;BF|0AS{JtWA0LZV1ea zyx+H2)d2^bdC)%kBLV{>*l2PDE){3E9wA(Sl4YbLcJQGq!@yI+4zXr*g08hCI;oRD z3e)JcIzmvDLPF29IN^@G_CkVg83=CSV!KmTVO>qRsQH%+Cyw#Z^k3DNNqOD!^vt;6 zLytd?B*cIxlhiUqV1Qu8eh5{}r$#j23 z*$zw!C(OpEF!8C;=Q+DfdS%35dXSl^VYRE&#A@qLleuJN*m@EPqEslp$h)T11x6Aa zSKYlC;>eVS($2-xH@;Bi)igk|&lY03ni6}3A0>Meupdy7PP59=C9&{jDF}&ts~@Th zU4D-ku+42epg0#O04}A099_A2GZqtjhR2H1T$+6UGH>}4sWW?wcSzIF9KOw5Y9N6I zAV^7>_MXI;p-)Fuxu`t@bl%O+M0DLH0A;BJ%!K7K?Fbb@qiw==JGGlvwu^YO(crBe z!)3e1*cn?StfuSY;k&OHOdReF)>T#w!syOt3tud#U5dt?)6FXEz^C)vEf21iLL2;^qM)Y`H98RNi+rX#q{ezN>(Hgwa$DK{%o~u* zne1+wY+)^YMU6?+F1BSnPxi&8;Z5=aoglT}><%002O91{ZY= z@c#D5s#w!7b%fbGS-TSa(-i)p@GQaGR;Qk~(w1P|q{x0}fk_|KATR{UZ;ERgH!?a2 z9fuhqxa==VwN~QvKrQeT1g%HXvW12a*Kbs)q zRj#a9eyNgC($F)oN5>HcY7}7OgJe6+7GlfdEoKB&<~iedB-googmleByYI_uAz^r+ z`4y9UjjUkTHMCu*2@iq9Yw(I)mn!=~I4uo5H);LkK;kN*!hlNQrjqt~Xs)r&VgvnU-*vq>&rFP^y>NV$-ut8P(Hge#;UMh-~qUw76La&&R zKgMDdVm2uZ!wa3NjbuR?7n=_%^HR@!LbRn%5y@sZbTI*0Q^vRc!SVi@i!s$ie9P=J z1ew(e;$Ot73Yk0Gl?8PLN`ib}@nj(CI5ctC^ieI=o1HRS%54t|v8K9pk8PX@fFL2& z>qxC@QK*ZSKOA2yi}H(Af2HB1TEVOLLl%U+G)PcXeCRj-%<${n8QAxcNfMZh-vhHl z>>mmFk8YYjcUOMztZ7f|k_Vntg&L3zWfjxa$XP5S%1X9&yZckRELqqnlbO|+Z@wit zg>}yo*LhD(q?Sp%bb35qn>l_J^YwET^#Wq%{2VDStnk=d$_&c{id&B}d$!Gy0@gCx zs(|3*uCpzpd*~uj>C=#EJ`#jYRDHrZH(_@*K{B7`R*Yzal@+A%yN*gS4M|)tIN>R} zUD(_W5^7!2?VIH7IF}BrzL4nywkn&RK@O>Ro298o9n>?>cuPHTW1xykEF6AA^e;JpP;(YM7xob6SpK{Mxr6A^ef+`}{Dk5;o`})tO2TPz0%AH< z96m3HFSBNTOD7i8`6m>3cLsdf@A$te%!(aPYkNN`T;kTST-E{Y&I}v_<{$R|c}s)g z$58xy@aXE}_i>3D7lQ3(M248C2wqsKrxz_OgA=o-@$@H3YwTi2WmY=BG%MTb-a7eu z%yM|iq_8J1#R~-{rxuj|eBmo2R&yp&1RLcb7Op(*z}p1yMm?{57^kvG1i?Im*HT$rh2cOJvr8U%? z&!0^2{mJ)z%5REy0TusNFr#W&vc(rQ$$|>2sn`Jvre6xz(O#rJI;?7f!RHNq7{^q` zGdLs7M$31p%u9rTHrnJK4hmhmXj=$+0n^em$OO=&?5?e*XEhw6aj54Hx3-^QEdGcj zEygkxsl=_2nXnS_Oa;Fump7dUv9M9BR>jcfZ4;H~5&+spBe0o1`@TzWRYxR>B_@sY zt~syG=Z$l>EbEL;V-D#J7Nj(Gp)R_wt4x|gU^&gjh2Pzy3m5dNQxM-AfCZ>N$q)7a zv^D#o{m;9dzblRy_+4==Pd5?7cUX{^#@(}PU^7b39ju4hU$(XL2yb*5FLfGBmwz1z zr9;biRqu|&d^>Q%4Q%|M-DK`<4W-&5l9 zmu8V4JnB4{n;DIVOtC^FF1q7Hwa_S@HbNfAy<5~5wzxsjZ1TK@a_h-O*UR!8H<^yX z>E7=vLd*%R3pXqz4LFnY!r}US5L8N2>(zJ<`sVE3=^@dCJ3C?6J+x0@hlo-x5k%!b)Y z#f)*x*$)69!K3QSnb5xD=kO_j7@*5zz4kmgmTimaIr^$PBOo@e#s6d(SuqmPR z=p2JOq&R1Wufd-bGe4#3#fxyA;zQAOVObe$u*#oyY7D|9oA-+-@u0!Z_Sio-^C}s1w21^d<*L__2U~v-{^i&69Mz{zq(KK7~%2lo1X|2h(8eixQp|c^zk); zpQJ6oMqD8CKQC*Ki66H)|0HGyHr+gKdVWm(xas#NwHdJd^9S|sEx?b-ANREWB!7qb zONZ-Y!pGg8KM7}nn<1def7uKA80B#b+fNjA++R^1HMBhjdfck?6Q~JT$p?z_e;bz` zLp*Ng`3do!;0MINXzh6n`nVHJi2B47~t_?@lODMhTj1G#b+-(Mtyu1`V;kv@jL3DmfxQX?_-q5XAVD6X4(D{ z<@;Lp80B&H{S)OW&v%snkc&UYd7MT5#EIkmj`K5x{8u^UWBkWC+E4rhzMuI2n6W*E zeVqIJgpKEaY{b9JgdPJv&MbZch6wx(;LkimQ3e9oa`bI0gbgAKylS=~`0c;{4?lsS APXGV_ literal 0 HcmV?d00001 diff --git a/OOXML/test/common.cpp b/OOXML/test/common.cpp index cde7cd8c13e..42c17f05a0e 100644 --- a/OOXML/test/common.cpp +++ b/OOXML/test/common.cpp @@ -96,8 +96,8 @@ std::wstring CreateParamsFile(const std::wstring &pathFrom, const std::wstring & oBuilder.WriteString(L""); oBuilder.WriteString(L""); - int nFormat = COfficeFileFormatChecker::GetFormatByExtension(L"." + NSFile::GetFileExtention(pathTo)); - oBuilder.WriteString(std::to_wstring(nFormat)); + int nFormat = COfficeFileFormatChecker::GetFormatByExtension(L"." + NSFile::GetFileExtention(pathTo)); + oBuilder.WriteString(std::to_wstring(nFormat)); oBuilder.WriteString(L""); if (nFormat == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA) diff --git a/OOXML/test/test.pro b/OOXML/test/test.pro index 4763e64c7c6..d9ab1094cd3 100644 --- a/OOXML/test/test.pro +++ b/OOXML/test/test.pro @@ -14,7 +14,8 @@ SOURCES += $$X2T_DIR/src/dylib/x2t.cpp SOURCES += main.cpp\ common.cpp\ - xlsb2xlsx/conversion.cpp + xlsb2xlsx/conversion.cpp\ + xlsx2xlsb/conversion.cpp\ HEADERS += common.h diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp new file mode 100644 index 00000000000..2930c2dc0e2 --- /dev/null +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -0,0 +1,247 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../common.h" +#include +#include +#include +#include "gtest/gtest.h" + +namespace xlsbTests +{ +void processTestFile(const std::wstring &tempDir, const std::wstring &testFile, const std::wstring &resultFile, const std::wstring &exampleFile) +{ + + boost::filesystem::path rootPath = std::wstring{L".."} + FILE_SEPARATOR_STR; + rootPath =boost::filesystem::absolute(rootPath.wstring() + rootPath.wstring() + rootPath.wstring()+ rootPath.wstring()); + boost::filesystem::path filePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsx2xlsb" + FILE_SEPARATOR_STR + testFile; + boost::filesystem::path examplePath = rootPath.wstring() +L"OOXML" + FILE_SEPARATOR_STR + L"test" + FILE_SEPARATOR_STR +L"ExampleFiles" + + FILE_SEPARATOR_STR + L"xlsx2xlsb" + FILE_SEPARATOR_STR + exampleFile; + + std::wstring resultPath = tempDir + FILE_SEPARATOR_STR + resultFile; + + auto paramsPath = CreateParamsFile(filePath.wstring(), resultPath, tempDir); + ConvertFile(paramsPath); + PrepareFiles(resultPath, examplePath.wstring(), tempDir); +} + +class XlsbSimpleTests1 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple1.xlsx", L"result.xlsb", L"simple1.xlsb"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; +class XlsbSimpleTests2 : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"simple2.xlsx", L"result.xlsb", L"simple2.xlsb"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; + +std::wstring XlsbSimpleTests1::tempDir = L""; +std::wstring XlsbSimpleTests2::tempDir = L""; + +_UINT32 readBinaryFiles(const std::wstring &filePath, const std::wstring &examplePath, std::vector &fileContent, std::vector &exampleContent) +{ + boost::filesystem::path path1(filePath); + boost::filesystem::path path2(examplePath); + path1 = boost::filesystem::absolute(path1); + path2 = boost::filesystem::absolute(path2); + std::ifstream file1(path1.string(), std::ios::binary); + std::ifstream file2(path2.string(), std::ios::binary); + + if (!file1.is_open() || !file2.is_open()) + { + return 1; + } + + fileContent = std::vector((std::istreambuf_iterator(file1)), std::istreambuf_iterator()); + exampleContent = std::vector((std::istreambuf_iterator(file2)), std::istreambuf_iterator()); + + return 0; +} + + +TEST_F(XlsbSimpleTests1, ContentTypesTest) +{ + auto tempDir = XlsbSimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} +/* +TEST_F(SimpleTests1, WorkbookTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, StylesTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, SharedStringsTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests1, WorksheetsTest) +{ + auto tempDir = SimpleTests1::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, ContentTypesTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, WorkbookTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, StylesTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, SharedStringsTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(SimpleTests2, WorksheetsTest) +{ + auto tempDir = SimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} +*/ +} From 0a157c4afd92d44d8db6b6aa8b4267a7e26f0765 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 4 Dec 2023 20:19:08 +0600 Subject: [PATCH 191/794] Remove formats from test convert params --- OOXML/test/common.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/OOXML/test/common.cpp b/OOXML/test/common.cpp index 42c17f05a0e..daac3751ae1 100644 --- a/OOXML/test/common.cpp +++ b/OOXML/test/common.cpp @@ -95,14 +95,6 @@ std::wstring CreateParamsFile(const std::wstring &pathFrom, const std::wstring & oBuilder.WriteEncodeXmlString(pathTo); oBuilder.WriteString(L""); - oBuilder.WriteString(L""); - int nFormat = COfficeFileFormatChecker::GetFormatByExtension(L"." + NSFile::GetFileExtention(pathTo)); - oBuilder.WriteString(std::to_wstring(nFormat)); - oBuilder.WriteString(L""); - - if (nFormat == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA) - oBuilder.WriteString(L"true"); - // changes oBuilder.WriteString(L"false"); From bfbae147f0280740e6e6a88f12a4012ce4b6e8d8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 5 Dec 2023 13:10:22 +0600 Subject: [PATCH 192/794] Add tests for simple xlsb --- .../Worksheets/WorksheetChildOther.cpp | 9 +- .../test/ExampleFiles/xlsb2xlsx/simple2.xlsx | Bin 18500 -> 18503 bytes .../test/ExampleFiles/xlsx2xlsb/simple1.xlsb | Bin 6973 -> 4932 bytes .../test/ExampleFiles/xlsx2xlsb/simple1.xlsx | Bin 7310 -> 7602 bytes OOXML/test/xlsx2xlsb/conversion.cpp | 112 +++++++++--------- 5 files changed, 62 insertions(+), 59 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index fad3bdd11df..2d306b2ad51 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1795,7 +1795,10 @@ namespace OOX auto ptr(new XLSB::WsProp); objectPtr = XLS::BaseObjectPtr{ptr}; - ptr->strName.value = m_oCodeName.get(); + if(m_oCodeName.IsInit()) + ptr->strName.value = m_oCodeName.get(); + else + ptr->strName.value = L""; ptr->fCondFmtCalc = m_oEnableFormatConditionsCalculation->GetValue(); ptr->fFilterMode = m_oFilterMode->GetValue(); @@ -1807,8 +1810,8 @@ namespace OOX if (m_oSyncRef.IsInit()) ptr->syncRef = m_oSyncRef.get(); - - ptr->brtcolorTab = m_oTabColor->toColor(); + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); } return objectPtr; diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx index e49f4060d7fd14daf4103c23f822e210051642ad..7cf898ccb1827f299b1e4e46ed552d6f71433dcd 100644 GIT binary patch delta 1140 zcmV-)1dIE`kO9Y#0kFpr3h>ld?^6Q+01OC|(GeAYt(EI;+cp%(UqxU)JG$6%W5afl zxD9F`O}r&-KMpi?9I>WIfuwvv(GS~e>_zq%=^O2kvMf6ph9DbYOXA_t@7(^hNAI?U z2-cttS8`0^vxo#Bnaa3)7?aQUSDkYb7)xbFg_1BPJ22$kWVBIwwNPpm;Oo+iNp5X9 z3`4_zaww=dQzb~;St?yni%b0wnol01sB}zJd^|l8_pi2(sUuP=xv+^TaBMSe&Yx) zNfT)s_nw6+IMd3gr9DIRKI!N655mDo2QbKg>qv1F#_=iYc{g81>R~(A+-adj^9F%KF3S({|R|#W!?DFKlFO@##%-sxe2Gz6VsL ztNfbFm3Q6Hogv|5`6ZPW#SCvBEWA9WDn97aqm);%M%H^wWC$^YO2rzyJKh*M{a<=PhNqoy*Ae0gG%!;`QGbae(0YM($3p%ns$10 z(Cu7C(T7el?WS?Jn_dp4gCGCrulZzzl%ersZqma4n`28`LJ!@;C%fMAln`P?_0`uG zHYaWJH&9Ch1d|~`8naXtnk)+N)K~9Q0{{RF2$T3hO#wNRMnXLSX_JIPJ_^Yf003Wd zWo&aVlh8&Lli@-d0@xUn@faGD7egumS(8FTNCCQ&i$g*I+mp^iR03)ulg~pMlRiW? z1gawd0F%lB9+PTC5R=Fz5DNeR0003100000y_3O2O#yC`4@E-)$SITIDHfAzMJfWO zE0ez~6_cw)DguKqlbkOqlSf7nlLavl3;+NC009610002`Fq82$6_Y|nF9O&#lkqhg zlZ{3y0u(!wEjt{O)kZ1-l#)kZ0hW_sM^*xrK9iw88G@T1yY9ojN@ad=hJ){QV++u;!X=KRR5J& z{XJH{1&gEKMvJ2sE_o$dx<^Y$E9RLFs1R!X0Tvoe{=Nde9T6-?E2}1`67-rGXSTuz zJS-%bQ-%t<;!Y%(haA{)awwEIR>Iz6NARgRnwY(R z;KG8QX}+SYM$UN#Grm&xii60mxv}0|YQ(gV-6>J|vr&7ix!@+BS}1CVuKT zKjt`+IPE(p#ST}1eK-zSE9_U$zwh6EeEspS?+xA4tnL$g#;DT|P6Wp| z9r~R>ZR@|eCF4JC!i%%;AZ2`iWZ~-=U)HvZU1zTcK+<9X{SdA z-Ogncz3n8EZW?#H>E&QD_=2Ak{E!cg-%W#sKN5$Ywr&s8!zWSid5RDsjr!_Ih0XC8 z{{*u+6}T)4PaVC$Py+w}!3UH3K}`WRlSx870cMkjLOub;lg2_g0o9ZLLPY^qlSM;F z0k@NmLqY-AlhH#|1ZN@u0F#{xB$G`kvx;I zJT#LyM=Al6lVe9#0+K$Hu|6e};72L~g+G(AJ{yz2KMEF5O9ci10000Q02%;H2LJ%# IKmY&$0H0j<2><{9 diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb index c71a49e25f38717f7bf71cf02a1e2946ccfcfd05..809f7678c97eb272a319e10ee557715dcc4e686b 100644 GIT binary patch literal 4932 zcmbtY2|QHm-ygw3>CtR_3vV2-)UTwoiQ_vX3UJ4schLpa zFzBcDGGifOfk8}y5LMrj8){@C zZlB*l9EQ&9!#*H0sDW4<6pBJq=?>^1U>xAUUr|&tg$4&Y&CH?yS2!GV$gw!ADg~g# zQR#uWFTMM5a15D>`}ydfO%)e{!4cKIfWJG2Km-~dO~qlI=u}{;(|(5i8{iKk&_jv1pQBz! z{D_m;H9s<$@N*3YbYue1)KIk`G=@qxC!zg_I4tl3m@Pn_!`I81A?j244O>ya$N* z*g+tHPlR72%4=(x%QHcUpTIBdsH?1;wFoz6$YQ ze>9psdAdG2OG6KVSm94I1}!vK;UR<`~KK*?`w#Lg!b)LO)bX8yYBk6kM)f8`td8Mx(!z$R-YffuL7YF=G_=4SjyP&H@1>8YzNmomJ$U{Rl&AtlHqo-kzxVbQ3s zZa&x>&?Xkxw`^$i&mkxHV{tR^pzkGm0Acy*p3pK zkSu7C5NVO{ONtG2hm}0P&^GlDjY5QkMiu+xewD2%CsiC&5+I@y+n;OLG(C_53$2Np z^8ahNwiIdTv$KIfPk>zrXbNlHJL}kWkbw|d5x*3!QgjT}>@KIPimX9Z-M^VOP zbev>ZQg)d3OPrAQ#h52#t(@vt>wt*1KwbUe^3?*$kmmF#3v zj;dS{v5FL_n_L({O^oC2ynEbhI2rs`IJrhlX{3GRcZgcOn)tm;Gt)`9$6+#+-ei;wz_=DrQF|p<_%@XxrRw2^^x*jgE5DyAMS)% zC&T(0#DBeNyWkBU+n$^s;9gby5Ooo(t96x+q)1k67#xUR6!8=@7<44r)XWc~Qe;M= z{nU8l1$$fw;%^IT2tFgimh z0*!Q?cvG;$beRdIQx!2X z_|lZbAK|imlaTYat7<%(V?IO|7L^*_-|VnNc1n+t=o-^{>BtY`6P^mbK%3Nz3cIrH za%aCvD(~@*LWcmYeN)&EL%Zv5L#e?&{8*2_<{3Vr9&~+ zqf>yw_JGp-z}biCE8t9zK&#AX0+JG96xI4-Sof80ieuerjTepo7Tw~Od=n+3S{Jhd4jwXlg0T&Ad9=lx+mpzdxHSP6~7+z}yoBrk7p=?5EkFw%;mN=>HsfBxG zl2piWOC_|};Y2{m(`kddO70J)>P?*S@(^J~1)BF*!fb_hi7P>3tUtwMS;^70L-&p{ z`6*he=z8k%sSA~~+v0`sLnX?*lJlHF(H2UpGaVz5bK4AeLkvtcXxMjdw?d8f9s~1? zo2Ye5?_0G_y6Lo^vDKj^Df`)0cl?r=B7cSJD|<6XY5OZ4@!t5eT!WqMpc zUp8xHht8|IMrhu0YtiZMd&FQ%J%JVefI%?`c;llk9Om$$MiPoMR}sHR};afUT0VDCgj;qf;mPruj{A zq^2=v+)z%PKfmCaGhOV#-q-dxUAtoVDEHKd$Rnxv8?h#T28IM5(arK4O3C57WoW(B zu|90nG^WI|xgqa$H3J}R>TDPCbwolGD zcR2ij5Qj+}?_@q6An_ouFv@g`hE z=o03|w|4U$7WIFiU*5V!rSoqQ9emXEVtx5*Y195Jl&$HZ0nc*U zAgvE+W_eF$^kZT{d;nzUN7>GkH}#!q<$j?{k*~z~Z*8ldR$AZ>ozqcRdNQ{xX%RPo zh95H8QyaK=uA+1iD?^qZ9+r|=fqPHN?s!H%#F@Cl7@3H&8SzEr#OuUiycj+Q`33JC zCq!`fD;ci5FZ4!sUaw8_xjJBm7X-sN|DNOjc5=5=mmE9^lsRtT;UWQ?zh{pLSZq$S zVq-VckJ+KZVDfRwX+w={3J)YCIE?+Eb8I%6hHO7cjUW7PMZaJfUdMnj1T`|RoPnuSr znUTUUb`lp&sJ`E3fLBvLq7iugkxZw#*GPLrZ?uwAQl(2;-I8Pr$?lzO2+@N)XLyDY z9TWA7X~zBSuS6%Q`pUj%^|73p)WtDyJHJj(z7AP^wnOes$9T!Yl>4dY`|?`zbv(o7 zvD6fw)?($V6Cz!1+%1^Y$;@A#&swHs`qX^{6k-F^`2PC}K&F3eo4mdFO0cOBTv!9nPtYB8J$pi!04s3h5|Lr_k(X7sk ziQ7Pv0b#!Q*3UkS70zlWzQP~#eq%0Jfviv6ufS=(^)9onn^_51XEu{yV`~@uqS?Qe p!K^H-bBoEa(ft%)2>}fIcV-&OmJ=8mU_AzWqJd1j!gTqd{{gm(SCRk# literal 6973 zcmeHM2Uio@8V$WeXwo}Kla2wT3n-lcQIR4f5I|aJQkCANH&IZ50D{t_dTAP(hzbJI zrT1P0qXP2AavzGm^?ty;lQnZ@tux;xB}TAT;TbCkAE-&sj!#&E#lw?o-L}R zG6AobI9zY5hy-XD3e~CY2FIlh*+#eP_zwIbOKQ;SBKPRDA*o8K@z?f7mrf3=JnJ2f zrT7%YXO-5MZ(+OY_~njL1wOjUl-Z8U+Drw)G%+4KZ$^~?9znFnFdn3U3rP!k-4`&u z`s-);cp4+}H;qbWX<84gHaSx(shxDKTQKcthK{+BRvXj41q;5Ly%n>*-la*M89U>t z+UJB|PQ~-|1yEseR+{2lt{lTWR8N_=@JEx%FUym=yV7Tbt91QX{zs z8nJ;ud>$U+fuO%cu3E@U8y0X!T_7;YfXKCUM>=_kiGIEQ8?pc3F#T!ivB}*)#FDpf zXf~+L?k&4$66aLcbLNeKg{UU^Tv)2((7YtUT(lu-c8}GaCH;ldRD{PWg7cLFC zW*CBa&}K4tVY8>9^qxwade<9)cwt%hFpC?3wKo=$jM!rucMXyB48n`X+uc!ySOvpV zt(7m+E;g$RM&_s)_+`ht8K);OesNG~d;{}0RvpSDg1+uqcs*F1?_4s^&~u-*-qV&~ zJ8OsuBFrIarU|h`Gn2ACAdOwD&5G9?XJBI4ROp%a$~`P=i>77L4l~8IoR_<1j%zwW z={c5*d|oF1K5Bv{BD4d_S}cD%^d?7PAh7h`;{?}rypIuxpmgA*0-o@367xp6J0egh zM^VI87xP3#9XwTV#Qo?8X&jdbHHbq7+3pl-kw?9|ihCj?UxPFIF}0!ADO_%I*c<)F z)LUrmhRGiPD!~nJT5uM8{I0K^ot;-{>?`g4l&op?^BG;8;PZ30@`Ni$4Io!GqgChj zGbAK6J}{m*+2&+~){4Z_m&*}8)D5^a#M^9fl6Pf6%mPo0teIP_ART1kOnUag~`$oF=9$0P<>AjYCq2H-bql%@tCw6IWK%}{P^`y;)Z z+t?k(i49ARQGfZB()C0;snR&hKa#k-`~KEPV5Sa8Hq0Pm9Du~{`Q~RT|IR%)fLZ{^ z{%0S>MwqX$*Z8$sZb+}G5a;CA>uT1Y{S=h=M6ViBgsAL!$}bdhtv5(VEd8FyQ|$Ki z?mT*<6^Ex9BP>wCitk73w8BDA*5CIUj~KC5vL14tfQQDZbLG*ll-Hd;n!mg_lS~u@ zU0=1JQ*Bs3+^G=HHb^gXDz*5%VQL*FY_9MPIxwa7gU6RhC6PG)eWT@Jb+2gs^ zUvO=|cy4fWR$A~2>8y*E)U2oaUbDpA(S5V|HI&r$>U5_8@Vb8wzPyhS!BfD@W56F6 zf$>N1dDtV7o*rV~28pjx=n0i4ZC0Vns$~fT+sIc_Q|pQN1mPP@;k0(DsjI5W2ii}G zD1?WnrDc1?;2J^4aLHjJ(+GF(tTu_+2!Zvsns9hD>sV=9adPCZqAE)?Sw2 zv1{XO})DHmqci@l3=-3%8S zc{%JBP*9`yf=?n0r%CQ95qWdDeKA(}K_t!;!JlZkG`kkGhX(>Z1rieNcUnB{kU_;LMnzAv>@GximAWEx42@=i{+An(dAunB z(rz`8xS8g~Ju)pQ_ADlgr-2WdKI?}UGvAwhQ7>^W^?}~SEpE)=yRyT&W=)}Hsb*$< z+I?NVfWY?)9D_DF+NQ?%pUp)zLv->-+U$9a!L*-BuL?$b`|>#CP8!mobrac!N`~#v zu%AcYfwA)FJBaV`bw5hY^>?P3*lFKjRB-33=0qaUdVTscQe#|?kekCT>gd@@bIIT) z+H@;fVMj0QjuyN%3bx6Ov3?(UUS^P|Vlg%240>g;f6J4}=j;6VNYQ>3bdch7pIlSYr6YZhs<(_3O#ef*{V#j41C-JQ4^oJ94txf$0) zwTM)W^IJ{sL<9{i&<|TA}wr+?)$8QPQ7}bo}`)t3pErwmtdykXpV?K zoh1of$PyPLG7Uyjvr9%*eurXALwb2aJ1sN0N*r2GxG1WAvhkw6i5ZOy z7UhY3IoWs0(@@w{1=ZqZw1iY!t6I^fPPZ@#d4lX+TC4CC< zQg+W=ld&%q{+Q}xqdk%k$NN0h)cUR6JYcG2iLw2sm>YN}|jIOVWUYxQO*f{TGYV8V#4|8D4 z^KJ>0Qp|1sn5g!V1xP3ncl~JX}({ z5KJVG8+JE}N~HG*jd@fUFLHat&X%r6x)T3R!WYo(>*^l@FF1s(%)-#LsbnK~`(5?a z@A%iO*WXiT;j!b_mYABQ#}BOI@8->K2%KfbiXZg%GH&$8#^>G|<-dG6(f9UAeJ!<3 zC-oIE!m@(wE3K&8!UAq2D*^}xqH!}sReSg>*H~^Y~aB?qu!^+b# zYe&32%6JH#=(xnLQkm8&ogRnO-u|%byf(CT>!Whcm#Xj!V*)o5oU$EFp{ji}GSRI?(hx$n2QNksVT~pC?@4U%$d5b> z_bot7E_e@}J{`pFcd*mvO7tfNDs>uP@d7KC08aMb7y!H%?(VDQVuSSgCINbrt!%BV zpo9oP&U1v!XJb{?uNQ)OLPZl#r$qx4{()f&_viEaz?26N8PtF%wLw`!-BGR{V%8{k zO>0th$^|7k z4!y$S1G$FRu2mk)e^tjf1%20pqHSoKO~96?>`l{?qBulXr0q?XcB~VbZ1jxW#mNk- z_$f+82oLq$q>zM;`Ij(76<2b4fj3@Z_ z>w9bC5e+x$t4b#C(!;ZV z;xaqU^6H9mtFM;rPW&4i?FLZH_|~qBU=!eKzboAQs%eE3V1^FJ0^pyW5bo;wuMYyw z_v6S)#^}$8gCjPCwooADKk8vk1 zgI7q;Th1->_Tk`0xAo1N*PJT}5t8HdP70lu3HA4SpCB>o41>=XPU#ey7ZrO$%PDxh zxDuM8FYn-RGix$wJb{(dBQjj??T|X8o#T}^65?dnH7_-*HU9Od}d?g+(;>>JAQjoxv9<9hE1AQ#vz0?Rp4f5%OaE14rx zJnHYJ$92tdgyW*+2*LC_!vB*n#{rLPfFnS2n&YG%R|Lngey#UMNFY!Hfc0DTKW_eO hrvBMnmHsF5A9)+9LjbrQ2t*G2*Z}V({o1|&{RijqN0$Hq diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsx index 6f10ff38a5c0f1f5178ac2415bc6c29d267998b1..99714a52fd3b336e9590fc969c76ddb14d25a7b1 100644 GIT binary patch literal 7602 zcmeHMg?P3Ks;qr2Hpvgr=X2}L1Bd-5%{EJthEU{msgNH!jMEOE)nNxN8y)>ra zR&X~F+XKn=&V;TKOQS4X+v}|7=LE7jq;|rUM1#}5e0!g5-a9$g21j%?Y2ii%^|b4n zQVMf_?A~N-Bd3UWGc?%ACZUw(r7$y#u}%l1xYl)O3CJ(VsFvNaAtjRxT*{p6)+3zj zYQQZqEE4URg3fE`%@T_A6^{}u4HJK{vt{))Jy_yYL5-sGohI`zEdbFz)MmBNYH&MC z2DXA(>iJ=hERknTLeT@PD{lzV7bb06x5nNM4cpVPHEzR7l9KhUMKaT&ol#Jh)*y$`|21C$O291hPO+8RaHg9sfX;Y5ba)JO;{{HfAaUojcD^lmc4( zFZ!ltBx2TkXpa{K%A$x!#OZ52%fph-T-`C)nB0;SUCS0a2|Zv(u;WxERc{uLmRPpZ z`l1|Q?;O42=$?Ef!629Z9W3GksxY$qsX>Na>ISnG@V7`XS?#Uzu!=h2?Dd4f^nkIX zH*0uO5u$3FBdMf4V2dXcZ~b~4Xpc_s=xW=D+E!R(xrxzvn>}`DKafvvBfj+G)X3=3 zq7xv3^9?F>GiDzJ7*-4H^=Eo_3S)JY_U!fsM^P8eA~Mw9orDE5jXMJ2Aj@a~06t=6 zyd1bao!#s$oSp4|zQ8##tZwbOuvmTvRro$_q_TuHoF z$AYdect*k^qsg=?ZkzGPXofk@;p%Cb3=}lW185-8V9SyoclWfa_;nNmUZkv09Y(=N zB?YDIA8p=%yVMNoTUSDzR2tejW%IM1(URk2y{}Z;h{qZYX3+zo9J&v%&*Z#X1JA3L zaBcLdSQ#L7W{^)C3uoVcWh-ESUA)>HSTV*RZI9-OiNE(~w<)2$##5(Po3X|?1trkK zXvBAqc#!ciGup-_l>~nA4x7hEN4&Z+9k{IC0vWp>fPS`g7*n})SQWL`m)5Z2+xMk~ zM^GG(Syl4kk~4XrQ898}upKzbwd4J5>R?uVhbM9{SW_DL{Ly8*ROhw}`${n~ik%c2 zu6FPp54KRGV#lI3Jw3c*TP~T-RsQn_;E(fjNLVr=JR<_R;QIwkN;Pa25-+SHb+ra@ zQF(mxMH;zxu7{}99ecP!CbVqFH0970+14R~g4j?WzAHe(rR+PJQP7~n0lfyzE2TMS zMHOxe@2gbsjg^5E*aI+`?A>u=W$a#P3XuYD6yAIb+3K9A19P0mXnlQS$=9i7{Gm2RcNW5aQ|T;Bz?4KkTpne zU8`mzlV>gpBNlTjSnreza&qkYatS&`@r{ zNG;(#sjW0oOPNIT2ijFgEA(G6VI%ysHL*MpT~;hGrzc+Z6>cR6C-$l-hHqQeewn^r zaeQmwFy9H6POn7oiX=NxfbXek-DIS0j4O4Xys}%h7yj;ZZa(u1jp7F*c7^P7N_^ty ze$-cq>ZvdFN1k5bo9BiYjF&p0I2S>?jU&VKzs{paNnui&n42^@G-_LETv9C!5Dx#1#OLl7m9vFoLUs zlg1?#ii$jEj2yWXaY6CmYG&ap#Ye3Zm$9O6>>w^24+yY|>vh`ZfMOmiBv#&UWHeLa zWkh8(uGlM$$!Y(1T9r#^4`bwH3INcC$fm@<5e;HvzI@jl=dBwCId)RT;?83m=oiSpp52-?1<{eRTQZfzhaWx%o?WefrcQP!=QDLd z-Y+n&dTFf++vt^7bosR0RPvqiB3VZrN+Kb&#^5xLbVz2w_gdpp1-c&}A5WTnyu;8- zud!XN>H}kKBiwz+R*X+KJZ%SSeg%)Bj);@>^OG87Ib{&er8P^%WSu6}4;Q~GVj)yx zgVX10UkvrazJ-(<(dKCM7`lmHRJ)Z+`$=_+r$gq<8jXE`*NtPbfSebu!qAw2rIRy) z_FT*|L1Tx^*>G5R`IrUg%Tv)@UrGmZehlX|Gb-2C!EJg;HI`FsoE zYt)0!BR@_r>HTVzbqjzg-ggte-}yKXJrYVcT;hY28n1dNj*M4SI?9G;EDM zzC=f()u2JIf?Kx=B@i9^&3=4QVHz_>u-Yt7+)jFiU*D+On*Deh|HkzO(~}PwN^YA} zDI(+~-lvO>?^>RK@ak?c<)K6-95Xi%)UB)RY7&{yu*Y?ai*$}ZiaS06J=v`~s(l8e z{Mw)Y9+s%8rB75sVt>a7E8q?G(<{)0!N)g!PxwuSyO83G7yQ8A3~Ah|N7 zuGdC0864&zC_j`_Xfn)rElpn!=awxs>a6M`FPOoQSGh%dM1GHhkg!xPO&T2XS^=+^ zu0N58No$;s4wiD}uRd2qSzN1T-L){TrM5@ju!u+KO{nGQ{~9m1Gbw1=8eDWemo$yt z*t4T}D|j0{l^H8G@vg@PYT;ev$uQIV(jccQxb*R2&S|&|-6Q-QhJga?;$AbaKv>xh zmwJKZ3R~0Xhj=J8j)BLrAq#>lYF{Y$8!9TQX4@+>kEnKgD-?VlO|f_iY_F(8-}*CY zH%=5VcV17E2&+1pZfUnTU+fd@?|;u7ZBOIt&{(K8Z_$m`d|kCALH69d&_y|AIE=E8 z${Jcyip{b-%zE~LXdeY-G*`&@J7_dIwmUJ)cB>e;6@4D}4eL5&?uObUVqSrgo=m75Q01Dl3KRavfG{+XiB*lr zJSvDL74Nrz0ET!wSb=}m*SbKbDIS6u^3}VT+oY&%S)YZO1wkmKtgQYJUDxcSNx< zxiKfv#RAuX;%(iel3?uehrxAaAIR4>^j)p$f@ioWsxWDEUdkqF{WPdia^L_d~n zFlBLEH3q=MZVyqxphF==Lg5TCCo1=P!FlW^ll<+BjU3(sStEB7cyqkNQF{jEu;~`V znQO+rrz)dZjE9Mzy4*=NoWTC(Q_c~AC2xYmbfOxdl`8HwAjB3^I%p$@=7p>_A~GgR z`B+A5)p+TF&U>N7cx*}G=}^JN?U{JF(#(YV>hl6*FRsow`PKa(`WP9`{^-6(&yJ60 zJkTacaP@FTJ1^;d%vXgl^JX#fRZ_aZj@Y-C-(Eapk3nPSBoOqggp|VA;hFaKGMfTi zA|^Hpq3i`{qIW!utGOKlf9b}xsWuBy0mzx zlUxW79M5|ydzNxf)SI~Zy!Ct!z6*Ce+1N8bAx5{x5B+Y>#i1WSb8B2-rsjjE>O;?^ zG^V>%GD_HbBQ+JC-5sc&$KrasHMp@4c1{(i(CMI=PnSq=!niO>x75)r(b)|tv*x+= zM}?Orbjf_^1H|^xS2*^&h9Tb-p7pOeB*k0~wOvd$op9G5edd4F8RbU--GioN; zYwDC}daC*`-2iR!>GqP#YFiBQT>rpjJ0Fix8FCyIhWS*VwF6F*pO} zq-R%LEK?GYsb0*+9aOY~7We2pnXX3$Yvd9mzwI9z$g~bVpG*X;YY|_P-|1~*?q>B^ z8{%f`^yDYY1!82dKm1U=f;};->a8=YLj%&Cb@loL;T$Ih;Sw z^L~)@vOegk?lanLEo%5g`=!TBW_yIs_GL=Sorfyf?o%YG$fXG!=gj1GO3NoGswghZaXaR)Pu>!r^uL7HB>1`N=t2M+ zkIQl7<4F{`MU87!qnX zCDz##CVmpP?%Z%!a5;KPRsDMg>yHIdIu#}!A_e@FU zm#uPCxM@q}38x-;hqmizG$^`e9Nn?tTVTOm4A zfYl28EIsj`yOo0KMTtZN3rP@#B*C9qXzt?j9|;lc`+a1@L!F3u5#5?{b4TAvS9&lT ziML4($rqFeWffoQ=BnqRW3`)WYzyf6_kze5c+-R}JoMFt+n-N;x@hwcxMyUtW26sB zd5_mhbYQ@WeaQ6Xt24W6op->VB1vld*nDueDiu$Z{pEhBVF3Ye+(%=Vkil2ugdal_ zCpIfWB`hbZMnb+IyQbIj3B(9`5r2}4%38KEFjbi*KD)CK<%LaRxtN=GjaU9`?R5Y0 zI|0SR(mGx-`#^ZoS)L&4@(^gx$$5xXl$3O|d{}}3h+)De>Ij<*>|n&$KsQ!oe2uYA zmSZ-F?a*iFUcEX5QdX!n^L9+mh2v8AW~f45a(G#k%?b(0ZCSj@rw)+367v`Lm%0MQ z<1M+c6wcZ@nr)munqQnA$B3rk$e?%P5dHKzjg;XGW6w`jf+xCpC3>k+yK~{I-#GPN z|B&J?2AKv7W20@ksUAyM8eTnokYl(*WBxhTWfE?i?c|->dqmrR7tZ-rGpjB1>T;)B z^X-a$)xK`8rg$pr=|$#|Gh$DEi>FA)oQPEL&u_>6*ttLEe|T300{+#&Uv>OHfIsGB zgnRr+)xQb6scrs(HX~}W8%pO*@Lx5iUr+$R73(MX|52Q7+PNt_{IZmf^S_(;n+$Q& z%FV9wmleEQKds#CF>e~US%v;GaF6JxfnPQ0P3X-G{|kDFNcf0l1mDc}H!b`%ss6$P u0G~(!fWM{KoAAFz!#~5d5K_+n;J?R45D*Qqy8r+-;uDC-;#8DBe*GUC-~(^~ literal 7310 zcmb_h2{=@H*dJMn?6Om`WgpqH@05Mbnq`bJGlrRA>||deOGMdAwq%z*ODLj56ta!1 z$-ZYv->7?UxzGKM=Qw7L-@E+&@BcmT`yPEQe1bE8@5gyS{Vt#}g%AKZI%#lU zTB@LsZV;rKjj=Zxg0T|va&}sI(k!chyRvyeTrqGIQjYzikT5$N1PMmj!;w%q_N&I~ zf|BfP7&j2o9^`~VLgd)JAsBWAc@o)gQrK`{Bu0)M=H`Z$1_Ci)7{nQb5kjFMNZcI< zl&dqy4foL%3Pgjz2oMwk6cHAd0D`|;BItHx3A?a$`F7)PKse`)=>eh9PH-^D4aXwz z={z>QGsdmGKH3azW z_r?Egz&A1fsPQj;aY6N;)j^K7ls&}$Uoh>7az%V22m}0f`R_jeO8Q^&|B;2GC5M4r zA@)XYuDE3M|Gx4+%l^L%IkMOeg+l!2)%cZ&Z|n*=gW$+N4FG;itMdAPWb#wEynPuR2vfcvWwcOK>U-!UT|qeR{+OiIv9y{l^_$rhS`R-7bU4SXo>oYM{m(|=qcJ{kMC z@XgT63p%rEYIY7M_wxuc5mxhIR!P~yLX2N62s!x$;1;{_Yx$fIP`zH2&QLHOA9no0d(9npiDPj@fTjtM-f z`D|I{@rC|ZAEw@1=TyfB0JMn#0J1-P_-jKinRFYD2vhpg#w@pJr0Ta0IWVz_z7iHR z`lwwRB{;&j=fcIvA}zP`RA!UaXEAF9fO?x`Pi;gF+QT5o%eP-H*YIC2be{|{LA$9{ zfi$_jDn*~&=+d6izC-NqSiIQ2MatB;08+s(&NO@MfT5DuL<1z`lWf zMHGphhp`UVfgz9J4ML;4@de^sbuLQ5m#03UFHwhTurO?^ZL?4-Z9G&-TNZ$U3qn#e@S>FgH+#T-6HtrAeUOpEm|CTs_4ccyFhN5BvT zuY3a?1)voxc6vNw(mu2dqE)! zrH1O=)m!N5x37W-siI5w-kGX0e{8mfEN|9dX;D--ss4fOpbbDa<#$~d%n~RT?oeU; zl91t{rA?9J@DfQwmx>K{2n_^&U};*lR}K zBu+oX(~#^qGT$XSG#lg0!6;P&@N9;rCEFm|g*pV+v~H0%KV$5!wykI!!w^dK2 z^@!eIQ7SJ`C~?v9X?6K*CK|k7$PQDO(B{_?W#$%9KgTTGBPM9JKr^_g`Q979gFPdo zeLCpGRn5oDSC)~A8eH!}!C2wgv&sr$?G<+Jn$dC)WIFzAIEnWDr7QsoG()lJracXm zuX}nX%%aTJGMNUI#FeEE7|n&IG_P0#qf5jKfKQ8`q;2`=J+zae+!rpX&>HMgs;dqx zZBkY$Rk-^|@DQ5X=mD8BHEH$Z(xyG z{;Q+3_<({zwt27uYmd$A*jW0hmT`2`rQ`<5Omc_*-8Z(2{@dzlTZRknp{4w3@vU`^)E#$d^$lfuX?bKjt9T3Aip`%_izwC!06crXr4^}$>Nltq|I9dbNoN&0q&A!vv7($5%;@aCOmxFvcklX_j39$C&_yHdjKGp8&qe40Zdv1(cwZFVEZLliH;hGZeQPUMB#Q&eS9+Ze2P z%aFwK6>DN~OQn0Jmee~+Q zj!S@c*lPJjL|9nKcB)I+ObDwvSz{XG?ZTL!O8b#B2>DY1Z)E$b^Jy=v^-N*&ZSRc*nyAc6z765lm9})^M5^m{4#7>$aSO90O z3bk~+FQp8uu}l#!THHup95k}xw=wNY6H=6pk`Lk3u$*lL&{U_zQY`0k<3a26<}Ai~ z$tuY$%7+;az+0US7p)Ag8oduwYmy*!=!x`PT6FN(qxdz>DRM<*PT&CmBe;_i7w5-| zrwoIaj%~t}2ejF~0=Z%Otrq7c1?4LB%le<(8mN9KK&(N$jWx}BrZHb!lW|h?iNIps zn=?>S0~yPB_s%OpCepdiHu2#73Lkbg?N&Ze`tzt)44tuUm(gcc`WSAq*n-u<6A$k6 z@tkB)6L{?OxUWt)DiQRtU_n}NZDJa(n)VSN%p7H;T&Q1sKz+rZx@K+@t3NXhY5x5F zwfvmRkT0t83@`Qtwu)4!UWm5mwyMftT7sMi(dIZo6?0>m=*fERx@;wH66tQ)k(Kie zvkz=5zeH`ZImJbJwyF~BnFiLJmfjm+Rc$R?xkMauhG@aB?P@bsFDd)|uC1HZl!~Z; z57=M%;@c~ilE!i6g3Aq5KlAlxF&~p)g=%Fx6aH1R?Yb5`|6)#YXSJ93ZLS6R3Yim^ zx#%?3DOO5?D zI{9Wn&|vRyUyzeJhcqwYxun?+i4a9JDH%`iI4FVA4EZJLvCXgeX~gN)rA z@1$C+7n)zkBikiDv}kG|%WgN^Nt+COq>Szo6vhsJQbC^fySnoPk-YJ;Y&wZx%}bI! zAkMe1Rd*X@6d%O!a#HM*!D)69s(F|Dm^sk^pA!0qU3~&^#F3pjx==B_dHcPw3-xsY zRF8}TzcS>Dr}UmwevFth*C&faHEV30{*`E1Pge&O&NVPVd-?qgdh&uA>@FbSk~JFk)>h6X=?IDONsq2~2jkC;F!P zrLT2oQ^Ou`c)lk#+B59C04>`E{7T0Hs}*4pt^mxV{yvVt6|u+LswFcW%m^Fh7yjtw z;-+Frnwr}~Yn!*KMRla*z{DDyr{I8&?q(p-du8>gv35DPyv~-g#gXez1j@GGb=;%H z>$%}_tv_X|d50wsW&us66P?>{TOSLdoT=+tk{HeN zsak_G1!q(an~;=A2=8t_p6NtdWc!4=Mez-0ukmNaY&ftyBJq4P1jA%swDJzGfmx?yGaqUK#GLy$Zs*SZVoVclPUu)ZA2HJ!p>v=* z@0Z0+tp6&#`~^~36%ma6XY)pHMTIc@Q`5>quUPcHXxw;WWYR{b`|L*26rBZZ`wY+N zBC{nORRb2C63b9)SO(E>0a=|6@{u_W&`K{G$mM)PM9uX+dD@ZxUTQ|*EE z+Ym6N(y67d3}TD-;|Z;V=Bz{nVQ-bDf{M6XWSK(RS>5cEXjXivxWM|kHq_ep1n$%8 zweBh=Y!7?u$dj?>yHskQV1AExExWynm(Pb5W$a6M4pE&*^2mR>;DKU;7*9mO+ccG6 zQ_>KbYl+If#(b7m1Z2+<;pg9woO&eM9${)!BJX3(uN`M7S-A1~9)kOF?jxpd<5=Q4 zdLY4=%k#uR0;m?RF%9AHih)rV=!x1BS~*cA!jQ4#8i&*5si`kdxLB9-8NcK75>77?f8TU2ig@u}5Ks`*EB3{YoWVoV1zbYo}+r4>; zNli{2UACx|eBM$ivd3DYf4=+?argsaNpAWJ27chN+U+ehSOAg4I@2jITrjMH>g9|T zf5cUeZdVIQK!WmiN&(FCQ}M3(4-qmq+gO+8ZK4S%uPP^cq5&r6I4n3iIZ?! zCp$~d0-;)*Q!cZ+XGkBHPh4^8(}kOf+@zp6fE>QyyCBv>*^)ghg`UEkGdyKb2w9-wC@E}Etuz-FuSoK~4+Fr3Ag zxP0)+ieBUz`MkK%N-$$g|V?Dwa$~vTx`R-u-r9~DfEN6|Z za%KZwdmSY*!sj2NE}QMD{o0i&0OfOHia?JDnq1KuH)LbUohIxAWbI0k7;-bZqV$nV z&?vJw)XlcZj<|)m3+lqU*PwVcyvC!26J>u==AN{Pfc}F{v#H)G(pe*?^fM$pki06V zyCq4s;3gfN{yu-A$S0Iyj7>M)XC7p=j#>FNJ1v~Z)w!Qq3?g1Oz;>AJxE*TSBb~a& zF;X>VymmP0=m_Jz*N{h(Zc!S?EHg+xvUG_G*L*BU{ z)x5;-9%q>HQk#%spRC^l`qAbu$}T#$ z!}WaVURcjdr=Z$3qI11^5o8dW#uNwZcq1S0_80YG$+KJVuPpZ*wiWOTCl*rYgZ8mI zU!p}d!SOsC_5L^du0B3^kR5N~fe(Mtei=-`lzUrB;vUl|L{<1=qENcw@@N_zc&|Dm zE-yqdY_`)!?b7@MvL?_RGv#afmQ(5BXa)Oc!Bx+U1m5VaxtrCarz;0GRpL{DEqJtj zZ~1iXD)kxH7`6sCwnpl9*evQ#Dx3F39)`i{;NlFajXKz&#@0!jE?M#%I!iYS>oa{w zbiyf)zE>T(Saz&pO5dlVIL)R?Uu$*}rn@F4%vqxu`!MBb_4EBfUxy7s``Y0wy~4VJD@1sh4P{g$ZoKA$G# zN1d`_)EQalb0tV6N(9QCUY3vHmTlEFS-X6xnp+5t$XBa5PcL@J@ODZriqoEd&~wTC zO5-ex5l6O!%-H?(q?s7)IZ_7EFf&U+xbqxawaT-vPgSgHh*myZ4hvgn-BK- zxaud`aUf?C>p!-RudjuNW90AO{NSki>G;iipdSK$KX5!k<5~vX(S>`N^tK)>Q55!GieyabE1CQ6nKY($#mKNvo@k;r)faA~K9|D|kVetoN|7)aw mT*~qN^+QS@?xBv8@;AFpUyBg8r~m*7?k5lziJuvdKK%~^qzBai diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 2930c2dc0e2..2cfc2bc58b3 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -36,7 +36,7 @@ #include #include "gtest/gtest.h" -namespace xlsbTests +namespace xlsb2xlsxTests { void processTestFile(const std::wstring &tempDir, const std::wstring &testFile, const std::wstring &resultFile, const std::wstring &exampleFile) { @@ -128,68 +128,68 @@ TEST_F(XlsbSimpleTests1, ContentTypesTest) ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -/* -TEST_F(SimpleTests1, WorkbookTest) + +TEST_F(XlsbSimpleTests1, WorkbookTest) { - auto tempDir = SimpleTests1::tempDir; + auto tempDir = XlsbSimpleTests1::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"workbook.xml"); + FILE_SEPARATOR_STR + L"workbook.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"workbook.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + FILE_SEPARATOR_STR + L"workbook.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests1, StylesTest) +TEST_F(XlsbSimpleTests1, DISABLED_StylesTest) { - auto tempDir = SimpleTests1::tempDir; + auto tempDir = XlsbSimpleTests1::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"styles.xml"); + FILE_SEPARATOR_STR + L"styles.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"styles.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests1, SharedStringsTest) +TEST_F(XlsbSimpleTests1, SharedStringsTest) { - auto tempDir = SimpleTests1::tempDir; + auto tempDir = XlsbSimpleTests1::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"sharedStrings.xml"); + FILE_SEPARATOR_STR + L"sharedStrings.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"sharedStrings.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests1, WorksheetsTest) +TEST_F(XlsbSimpleTests1, WorksheetsTest) { - auto tempDir = SimpleTests1::tempDir; + auto tempDir = XlsbSimpleTests1::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } - +/* TEST_F(SimpleTests2, ContentTypesTest) { auto tempDir = SimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } TEST_F(SimpleTests2, WorkbookTest) @@ -199,10 +199,10 @@ TEST_F(SimpleTests2, WorkbookTest) FILE_SEPARATOR_STR + L"workbook.xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"workbook.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } TEST_F(SimpleTests2, StylesTest) @@ -212,10 +212,10 @@ TEST_F(SimpleTests2, StylesTest) FILE_SEPARATOR_STR + L"styles.xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"styles.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } TEST_F(SimpleTests2, SharedStringsTest) @@ -225,10 +225,10 @@ TEST_F(SimpleTests2, SharedStringsTest) FILE_SEPARATOR_STR + L"sharedStrings.xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"sharedStrings.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } TEST_F(SimpleTests2, WorksheetsTest) @@ -238,10 +238,10 @@ TEST_F(SimpleTests2, WorksheetsTest) FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); - std::wstring content1; - std::wstring content2; - ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); - ASSERT_TRUE(boost::algorithm::equals(content1, content2)); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); } */ -} +} \ No newline at end of file From 4f32c84e8a1a3b90a6ab01ee00ba56469c2055c0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 5 Dec 2023 13:10:51 +0600 Subject: [PATCH 193/794] Add defaults for style colors --- OOXML/XlsxFormat/Styles/rPr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 4909887134a..9d2b0363932 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -479,6 +479,8 @@ namespace OOX { ptr.nTintAndShade = m_oTint->GetValue() * 32767.0; } + else + ptr.nTintAndShade = 0; return ptr; } XLS::BaseObjectPtr CColor::toBin() @@ -514,6 +516,8 @@ namespace OOX { ptr->nTintAndShade = m_oTint->GetValue() * 32767.0; } + else + ptr->nTintAndShade = 0; return objectPtr; } EElementType CColor::getType () const From 5af35f3b09c0d978de4f6da6bf74fdbde40a81e7 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 5 Dec 2023 21:21:10 +0600 Subject: [PATCH 194/794] Fix styles conversion --- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 8 ++++++++ OOXML/XlsxFormat/Styles/Borders.cpp | 2 ++ OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 4 ++-- OOXML/test/xlsx2xlsb/conversion.cpp | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 9d294356df6..90740eded4e 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -50,6 +50,8 @@ #include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEIDS.h" #include "../../XlsbFormat/Biff12_unions/TABLESLICERCACHEID.h" #include "../../XlsbFormat/Biff12_records/TableSlicerCacheID.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" +#include "../../XlsbFormat/Biff12_structures/FRTProductVersion.h" #include "../../Binary/Presentation/XmlWriter.h" #include "../../Binary/Presentation/BinReaderWriterDefines.h" @@ -1129,6 +1131,12 @@ void CSlicerStyles::fromBin(XLS::BaseObjectPtr &obj) XLS::BaseObjectPtr CSlicerStyles::toBin() { auto ptr(new XLSB::STYLESHEET14); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; XLS::BaseObjectPtr objectPtr(ptr); auto slicerStyle(new XLSB::SLICERSTYLES); ptr->m_SLICERSTYLES = XLS::BaseObjectPtr {slicerStyle}; diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index d835092476f..11548d478e5 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -146,6 +146,8 @@ namespace OOX { XLSB::Color col; col.xColorType = 0; + col.nTintAndShade = 0; + col.index = 0; ptr->brtColor = col; } diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index 2e945d49f94..059707090a1 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -246,8 +246,8 @@ namespace OOX if (m_oColors.IsInit()) stylesStream->m_COLORPALETTE = m_oColors->toBin(); - if (m_oExtLst.IsInit()) - stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); + if (m_oExtLst.IsInit()) + stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); return objectPtr; } void CStyles::read(const CPath& oPath) diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 2cfc2bc58b3..d6625a6cdf6 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -142,7 +142,7 @@ TEST_F(XlsbSimpleTests1, WorkbookTest) ASSERT_EQ(fileContent, exampleContent); } -TEST_F(XlsbSimpleTests1, DISABLED_StylesTest) +TEST_F(XlsbSimpleTests1, StylesTest) { auto tempDir = XlsbSimpleTests1::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + From 986b1114be9cf7f6cd7971470d07c531c396faf9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 5 Dec 2023 21:21:23 +0600 Subject: [PATCH 195/794] Change test file --- .../test/ExampleFiles/xlsx2xlsb/simple1.xlsb | Bin 4932 -> 4924 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb index 809f7678c97eb272a319e10ee557715dcc4e686b..1b80dd46442977eadc04328af495951e0cfd8827 100644 GIT binary patch delta 344 zcmV-e0jK`NCcGxFo&|rS?&an20000A0ssIF0001ZY%gUxvGC9C5|Cbu~sGEkCLly z{X>_bFo_n~KQh{G1^mu?7T%)r125PZ?vZ9Lyu{e%NQ=D+(+JC_;=DcCwiKi$CsI~j zl9{kHVzCdyr}3?4mu~1`n|j(S>fF%}y)%86dggnsISg68Mi1O7W6e6%T#L5G1&Vwb zcEa{kmxa3*x33U~zjmSY-VdekE;E-5j}G6nv<8g|1*7ie q5j_EClM)g>0nw9D5;y_llZp~R0l<^X5=8-olMxdw2Br`I0002hpqujm delta 367 zcmV-#0g(Q@Cd4MNo&|s3ldkOf0000A0ssIF0001ZY%g$-rHGCD9Y{09OM z4FvxgNCdhrf>bc&4hzFmh)48{nSsX1i8DbYh+{otVfX~mt}lP^AIWk71_g%CEDSGU za>!PK98% zu{%HUH3!2t4lNj%@xkC&O9m=0!lCs$2g4f<1{H?sObh_CtOkt=1>cjd?D>;E5l{iN zlaCQR0Y8(>5j_EKlL`_(0ojvD5;y|u3X}f|6_c0}Dgww3liUs(lim_40*nunpbs3A NCKC__t`GnK002StlXd_A From 0c7963f4275c4494799a98f7876081a1a7425d0d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 15:53:17 +0600 Subject: [PATCH 196/794] Fix slicercache ext conversion --- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 6 ++++++ OOXML/test/xlsx2xlsb/conversion.cpp | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 90740eded4e..964b005267a 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -874,6 +874,12 @@ XLS::BaseObjectPtr CSlicerCaches::toBin() XLS::BaseObjectPtr CSlicerCaches::toBinTable() { auto ptr(new XLSB::TABLESLICERCACHEIDS); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_oSlicerCache) { diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index d6625a6cdf6..91abd48c286 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -180,10 +180,10 @@ TEST_F(XlsbSimpleTests1, WorksheetsTest) ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -/* -TEST_F(SimpleTests2, ContentTypesTest) + +TEST_F(XlsbSimpleTests2, ContentTypesTest) { - auto tempDir = SimpleTests2::tempDir; + auto tempDir = XlsbSimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); std::vector fileContent; @@ -192,19 +192,19 @@ TEST_F(SimpleTests2, ContentTypesTest) ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests2, WorkbookTest) +TEST_F(XlsbSimpleTests2, WorkbookTest) { - auto tempDir = SimpleTests2::tempDir; + auto tempDir = XlsbSimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"workbook.xml"); + FILE_SEPARATOR_STR + L"workbook.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"workbook.xml"); + FILE_SEPARATOR_STR + L"workbook.bin"); std::vector fileContent; std::vector exampleContent; ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } - +/* TEST_F(SimpleTests2, StylesTest) { auto tempDir = SimpleTests2::tempDir; From 2fde5de8b02f5edecfae542bb91cd289b678816d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 17:54:11 +0600 Subject: [PATCH 197/794] Fix defined names conversion --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 19 ++++++++++++++++-- .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 14044 -> 12641 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsx | Bin 18500 -> 18819 bytes 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index eab563e4a75..424486d3844 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -91,7 +91,7 @@ namespace OOX if(m_oFunction.IsInit()) ptr->fFunc = m_oFunction->GetValue(); else - ptr->fFunc = 0xFFFFFFFF; + ptr->fFunc = false; if(m_oFunctionGroupId.IsInit()) ptr->fGrp = m_oFunctionGroupId->GetValue(); @@ -113,8 +113,12 @@ namespace OOX ptr->name = 0xFFFFFFFF; if (m_oPublishToServer.IsInit()) ptr->fPublished = m_oPublishToServer->GetValue(); + else + ptr->fPublished = false; if (m_oShortcutKey.IsInit()) ptr->chKey = std::stoi(m_oShortcutKey.get()); + else + ptr->chKey = 0; if (m_oVbProcedure.IsInit()) ptr->fOB = m_oVbProcedure->GetValue(); @@ -130,8 +134,12 @@ namespace OOX if (m_oWorkbookParameter.IsInit()) ptr->fWorkbookParam = m_oWorkbookParameter->GetValue(); + else + ptr->fWorkbookParam = false; if (m_oXlm.IsInit()) ptr->fFutureFunction = m_oXlm->GetValue(); + else + ptr->fFutureFunction = false; if (m_oRef.IsInit()) { auto ref = m_oRef.get(); @@ -141,8 +149,15 @@ namespace OOX else if(separatorPos == ref.size() -1) ref = L""; ptr->rgce = ref; + if(m_oRef.get() == L"#N/A") + { + ptr->rgce.rgce.sequence.at(0)->offset_in_record = 35; + ptr->rgce.rgce.sequence.at(0)->size_of_struct = 2; + ptr->rgce.rgce.cce = 2; + } } - + ptr->fCalcExp = true; + ptr->fBuiltin = false; return objectPtr; } void CDefinedName::fromBin(XLS::BaseObjectPtr& obj) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index b6e5e04031d0669c92005dfc13117e648a3853c1..e7a64a5c9e768a2878e8f260479c95fa399e5f18 100644 GIT binary patch literal 12641 zcmb_@2UJsA({|`B(t7~uy@XIidJ&`xiqcC+0zo1ASw!k-a)~F zAWcE4h@dFtKY(5|SG}+6`{Oz!Ia$v$duH!FGkfM}q(?wV588Wifil*%iMPo>pq+~j zxM`{3?&ghh^R_kd_dsE+#r<4e6jgvfoW3Y8jFY>Y61Su{l$#UfhHytZxj8CvpES`D zljG*Zc*EV0a2IzsloGc;3d60UOs=>~!3lufFiPBLZ*LEI2?-1WjdF!!#N9nmZon@N z?q05NZ{Vw!ql5<>;S6^~Nx+~`Sqa46FvPrfhQY0@cm(AD_i^#&>3z@Sj!+2Jky5FAX^0-T)c< zU;awc54bJLpfu z7;k@I(*MR*dx$@A?o5TfySwvWvF_~P9RS?RU)&Xr@N(C5+gU3};0q9Meitc#cyHw8 z?tuYv3NO_E;9Gu9O~k&(z8$of2S9}K@^(V~6a9YY!T0v^cVF;VbFv5hZ+(Dp|M%+P z1X|QiIt94>UuY(=o4+X=eaja~f$WeAl>BvjEDiY709@3-1%%=6OK4X|>%>~}MiBLp zgZEDALK<|#IfcTRC29J(ZLTG$mtUmkZsGQ|pQ|C;O8kVEXwQdT?CIg?>X(C<>M7cF zCvZS4nxxN}#1u&?hncl$m$a**L+(=DI2bQY#_T-w%=*^(Br&E*2gQ=2CHk!!ied(^ zkk>xWZZ;~s4>J7e^98!h`x=sSQmtya5hCg8x&@=-POr|VEEE5%f^XDaU&EcD1J_O> z{HsjjQg2&BOMN}4vGFokUsX6Ihp80!h?s&A!$?G|L0rNl6pHRUSa>kwf%0|lG&}m11*K`PIk)g| z;>l;$RAF9vx(^0Rc$uWu#V=2mX_zh(Tb`9; zB-j*mV7-m}*!|uyMtEtn?+dF`qWJ{>1l`Y8xpTEmt_ZLO3mynWwP%$deT1_EGPAuc zx4ym&M6i$muC63v1A{ePz~CAJ7UtkvFz69z!y6W1d1jU`EG%!K!eM@#=S5Ymn#S6b z8toeE$&q?hX615~auv*t^pZJ(Fim4*6ErMY&H5-PZ&8KX1OJ^}G+VTOG&0)cdZHg^ zF`>(OuztIhmQdzk8>lIyxv##fuL&%B0G`XGAtj~3BNYMDJ_oM`VcGD6f~7}9jqYlJ zg~4J8V4TUW!g9&31L`~g)Y{oE|2U&>oA*kRu^tvm-TGL!{cE-%szX~UuSyUsP(pVW z+cM&`F5>AHOZ)P@IJ7z+hU6kQ zX*7$xm_XeYS9Qpp{qrp@q)uoKZ%~4pj#H8nn0ty0!CkrYllHq3Y;#LOOQ=WPQzNrJ{5$V>Whl`pmlG zV{7P_z|fPv9{5LlW=xa>k`J+}Xbe)!t1h3)1SQxIR3G*UeD?hAIghJfA(dC?iHq(` zX4&Fb&qa}>iDy5jhX$-GY~$=nXMNBBIbfofz(w<;nZEmM*JSHsSWf!rZCz}TUd}R4 z-h#OFgMp?d*7Iiwd*tnN2t7u&>ga3aGpw&Zq@s$+2)O%9qncoP5Y2idjuvItB$)ON z@^PqiB`|fp{`?dceO-;@J$i7c5hf|`=b1~yME_YdAi=Rw77YnUF$Y!(qeL@LRq}s z+r>Xu)uF#9_{?F=r9mvBMoUc0DJ=yiaEB*yO;ELa>;lX+1i5z z$c0oromp$`BIwzHzG=3rG%4@=ZYWD4$!;d_Jubz}cHshk8I>@w9cm16q{x+;hmT`C+<;I(d#Tx?V*0 z($}=I-gr94%2cxRM;?iJx8HO6`2L!ng~P^77f-Mbn<2M`kJlD=M7-4VARLP<%P)o4 z5`aMWfq=yfSOjqIzdXj}pBnZWmZc8rHMM&`kYSdGesNs7K&p`aW>)*1te5W;2*nK& zR6#`7EgwCKr{FVpgOz<%r+HpQ5_ouQc6PHm19@PGtn{=zM_Ov=#C@9Cih|c1i#-mh za=j+lyi-O`*yX-#eK|e+e7$AFB7Cu<+td6>PoR_pd8@)q7Q~5wytK4hY31IX3z~=* z#Ib?qCMbV%IYgLD8NvISc6F(Pfkc+Qk*piG^yl3y8^%wqoTTaypryFzFB&x$=}BO@ zZ6Pb|OVIw7j~C(!LCBCy8%pWPI8xkv(}5*vR&afCwLj6tIpA<%hq;eods)Ggcivu- z1)BKvLv)GfmP@j`b?2c+wSA1Q91}QM|MBdWT0nW6|GoYW#D>P(4L;*fUE-#16Xr(k zmKoK_AIB#@X$yMdRHEU)2chqpbS?MuA=WRVALjVND8<7*Lk!=NCxHa@MI>K%!A_xO^@li3d=k+e~v+1w{8V&?mA^3Jy# z+e+Ks-xe`f{A6oJ)qgqKXhW{f)j81q?rkC2+O)=v>X5G@52HR;+*2{q0~2=Rte<+rd^h3hQm_h}(X(G@FD z6jxW4+q9IKO3{)b)FfCiHVJ;mq7@BkLNw$Vb=Db|E_Gw9(*u_=4B2 zEQ=3em+)UEG`n2+U|vO9Snqm5w*)~$&Uo#hXN}xF=D7`lJ|!{r)QdHD*G-bK2TzjBm0a|@kN4j+wQ`0-_9x~W1?jib~ zi6Q~hvmJKf)M>@|$-CDHRdQb+TeDZoTlo|$z$LEl*Tia(mn;fCYUKEO(NiwC^;RoN zJoj<%Oe9Ykg7_Q}n+N6Nf<)-V3w3-QFGzAsE`x=b-3cX65yYL%Q{?5nRyr12a<}m)PS-?fv5`jPvoK3l3hJ)>tJ$U@A>ov@h5@lhRRgP;CbZi!U=e_;=0P!S1x`{FFm?$sU$bdo+Ep5P5bt%=)-j5 zYKy5Atr!^@^RBcOzsu3J6wn9D4RSF?}ZjhfUsoQ_~k zPSv#fz$7cf9*8t&SGq(z)K+ot?NrW7!|ppgtmWu)H^^k9d?-$~IXY~lD~b%N+0~|s zoJzV{ca$h0j}*}Z%WrO*E-bvI$6J-48P{acjc@vec!~G%Y{>08wigj$a8`qtHB^UA zzq~e8IThF0Me!`3UZJ^Xpj_K;h`}XSu~m6fnfXHN&Bgl4n8mR>*NS=6+FwB|Sbay9 z`#fW?6*B4%Cn{bBltpxkO}3x%->fJ&|FsNNYetcrA>M0$Dlno-Nn$;lqKtAhy;ZW) z@cpCq0ypJB?88Tvi*)sp3Z;VeJO+}4_~IGNTw(EiCB>=@QACeVHBgG1f>eBZ@Eky$ zgf?TZ!rzb=$#U3L+;|?76*(u%-5VAaxzhV)XuBgSa*Bw`V;Kx5stVN=75MJD#yX*k zR$3PBUX4eg+VmlJORE{-9~15lq3(#7>Gxe~*oI;FrG~DPzkX*ibkwmRf4=4N!^E}u zXmx+y>85KI58yi{QNc->(}VA5d|LNWTT=h^Z8+!Cd> z8>ONfYONgJmlGF!qpu`Kq%7zM+!kCe-^Sl23!#a-=rr#aK2utGRL| z4pb8uA_P;f4ve03W{m#6ynD@s(YI0cCt z+S*A{;~bjMj5cxh-IE)L99>glSKfOcWTzoFR?sJ8YweKwFgAC;i9|@D*v0{*Zi?;H z8}sZtnizVz1MvfbAG6s1F zl$N#N<(p4I-j|JU-=2Ad<3nym9Mg&d46|b-fo}%-RV8e{TC#g04Kh%mY%~H_S+1Cy zGu!378q)zM+;(9Lg@8oPag=U^%yx5LU^MorznJnoF6FYJ(Gp5EO0IH1wxF%Nxn-6d zR)=NNle2ohxj32`YTQ|nQ=lu8qG802kfVbvHKoZJHOP5#K7E{ay??wRxZ&F257*v4 z+tRtbE}`J$(2A-yGkL*NAu#&$R2$TJ+Uzu2Sb>Z851RZ~(^F_`Yiz2ozuv^zLaGk^ zLd`>fbJA#JGyU=gAgcw|562IryY;qzmFzAxOtntT)W7FS(;HW&BOst7pjZjvv{S`@ zrOH;H)Na(0)N9m8-I&yt)Rcrx>ac68$4jO8`MCQa(M1eZ{txGJAV7Y*YD_SOVTpR5Qu!`e0|S zHM^q7IHhm>`Hi;D9zOOca6d1n0Gh zC)4gE=a1H6Jb)lpORc9Qp3wEM`wD6vV1b36)gYFN9?{1=ip^XX=vM>`qX}G`dj|TU z;QGB%vs+i)T{y#C4drPXi78=WT$x-kTq#^xTxmJyxH#H`;dc0O;b;_N?82%!hR84M zEU}g#;}wDW>y72-Bj6MyxKmRjXkrEfBx(Q`mr(K7< z12I46m3E`Xda}F-7O&8G;Ak4n9qm^xsP9Wff@P;9##sOd1ExfR0Cpu{0eq`#{Hv7u zpvR;EMA)U;McSkfrmiP#hQ2>Y0&4dJRnW%c#dF2W#1q9s&PAOBTQ8|=;dvJ`Ny1(s z?eQwyq_Uv)6_6GZp?0KT19XLwPFsKu?@Io2pHX{zG_oHGrzR98gKHzT?c3nmC{kkK zGQz5}VRA%hS0N4Y2pa4Ge%#^Cv0D?B0C{==?Ox{*$kTDV9t&m$m|;%pO_7Af(nqCo zbTui@mp>*|OBu*3A;@%iNu5Bg-H#=RU#M%vjkG9v7qmB&&kqMZ5G`LDY`w;S*L%*> z>Pgn*<4ulF*D5CgjcjpeKjX<;vE3 z_NI_tW9yL{b(*t(x3J(;DuY|gn3hH9If&nAQz>VGVZ7tbu{p(7A&aN)?yH-idB8M+ zycnB_=%o^wn`X|;69WnApM;Ff+T|V#yN|&k`BfJ_rC%?_JYvX;9Jwh>#=1=88mc9< zIp6*|_&t-d09a82hCzNduk%+`i6S7KQWx)HJGQBF?!k#uSVqI9b7_-|7U(s4L5dQy z1%o5TYzAePkv8Zn#4igE)Ec-6)X+f&W*eo`{FlYd&PvspH_3MOJ;UN%h)2?VK^S43 z(Q3CR7q*$D=dULdS&L6w!^F@})h5GA_!|^iBU;$K?bYa(0%-UUM)|h1`qxCSGaYMO zSG~CQ(%(S&0QXJLJNo#L7kE~=Eq8^40~p**0*MYfSErH}1y2>;P<<#Z7*qK4l18{G zI6}cHRXxx|*wUKtK(li+S3fyvkyJ~J>4`Gs02>kg3&-V(S9-2F^B>JGV(m6bB&%hT zARO^*PJKq`s3&AXNAz;Z_(TW%f#w4SB`Gzch>^@12MWsU>`r`7n+lN=6=llLveLf< zpSggp4Oj1X^7A|+mufYVkV#&rth3f>ISyJ5zce*5G+sz};1hxnYf8pHzC`n}Zbj?zgfg$(C;NGHdHFy_c2`?EXl~ zs;Q*qQ9iGi$z`b)+iN5H(IIoI_lpTlo!ber4+G+J_N#QDz-JNZ86vDhAVKaS@W76G+ zC}sou`b~)LYddIWq-+Gj8f$x+g0eT(`7FtRkn+ZQo{dsRRdtf>?V%%RN&;@8ukR^- zj&S!4-R2|#Khz6cf_onCdrwf~PYp&?a;IAalv?xCCV6MzBnk6z!Xx8+KF1D?a53W_ zcj0l-EG*gzG`M7tay~z+RyjLRKwHzo3OSpV!3=oiNG!d5EB!=0{X`S}L?it~3;jd`{X{eU1eSiHm7cbqp0_hBD#eLM!fB{B(Q9X-mh2eXBriW>k3=Jo_pmNTVwF9c zIcYZu5-4ACJ^NzO2Qlo;Cc`iA_`*@eD)6*}l%F&@UsQ|!!6HmbQtFjs`b4X}0->TE zF&{pTRfe`l6{&%RSonLZ>;_=KDrPN>*v9&LqrJLuS2(6Ar7|+f!l3oc*lR~^CLg<7s zl-mo3n&VY)ID}K19fr8Q(G~0%tnYZ?DWcLGS)xdJ%Z`=@d%}T(*pQer9F0aHXOO88 zBKQP9nub`4^>0k$fK+X!_Q=SJ%^Fv(qE}%Y<{HD3!qT5&OiC;)(RS)cg|mu8z~Wnm zzLYGmffWuz_3grhr4i4Y8_FXh)S_}?lksq@NVdM_t_E1~E8$+^3dHNZV&jix`rX1~ zU220NP7Bi>yx92!E{H@DPI)kJ}Ry z5i`qGoA4Ydr6c*D(mC=o%ruJ5y9wLa-Ukc5ZJm7)pE70u5f}F`6!%ECI2_E7#%U6lJddytBN4hoX($wxemgkI-LbeZzFa(ExJrL)f7$`%e!fN!H*alo*iw zjg5kbJl&G>&6_Gujzma5k#uT%yfCi|2^Pq0!0T>_thbWawrN}6##e|RHlVVA9ZZX! z#lO$&dUi%4;M&j!9ADblv!z`PY-$)_{GBWkF#LXN_}d)p-@rNj>`ut}-UhcuD42N6 zH1@3R2|3QlY_I2$O$-$z?`dn!qZb4zNk^};#XN@}oqM*u=~eSsqN>(-NO0b6@Q&TN zy2!TNh^3Wr1cerbSG{>Ao1!-S^%;Teil=dgl7)rD#Sw+6cdAZp9-%nR6MK(8Vv0yl zX$4L9g(4C8%=JOVdJW#~0?F1f&VyL;uJz;@m3v@~k01HA?o(%|$hyQG61rvyGz>rQxYPbklhlcw=g7 zpU8!`iAseA#x5s6OOFlH-*A(Oyl)+WW<0h%RyJ3XlOlB?R&MiN&ciF#^7j0OPtB{B zc)v0S=(6T*2yV=~O?AU=6`9y>n@aqwe!Bi9MC_C5kSjEEY+fF{g5>qJ$l zAeF81SD^WU(@X zzJVol7A=91pzIP!J*Bh_Mb1M7Xc6{~YkE9X+sH_m5w4oWoIhaDl{_2T*q&I3)a0<^8!XP5IU(A|JOw7rV72EHpMF zYaF&f#5ct%R0+&R9%nd=qy|Y#zT=yY`lL7=(L8H;=oZ0rnhbcF7fYH@empB~{L{kR z2%VO)2aiAE0Q4cr1=G%Eh_qspz@t;8NBgmU(R0)<9d+w&sbP+}Q1A=q`((%Xc{8}y zeja1!Qj*8ThG_V zR4kK8eW13O6RO`<>+4y|S%I(bUe9o7tjr{s)5>!B#juSNh=D-8@eG&|d9%wP@vG3` zyh&TnFJvv$3bB)}{+YBlpL7Q#%$Q1OAHrXi<1-n1Ks=y1%M$@rE_tynD}U+Qn>7P^ ztBV`d^13%aO0Va49yHR!1H$0%9{>f`)(@{=JPx`~@arc6_R&!CU1#;v^8vVM+-Cef zdSws&)3bUz4}ah?;I`BE88ARY3~-kFkFVfDaeL1D&{*&;^vBSK3&!p2?tp>S3cT!q zu0C#`7Z;7&@Z7=ep<^h2K!0z4;=*y;e*5rxpn3j76A%}O+a22n4gl?Gz*@iTmEp4B zmh<;n9D$YfBMVM(AD0NX=($f6$FxiI?-D331#Vezhhpzl45Yw62g~1vNnBFg3f*@~ z5Xgt+_oP48>u?!y%X9mT9X~Msx>$$Hguqs4aBENd9G!a{|EfgcGT@ejb{O_HL;&0FC~%8IxCFRI&V2$?&Tj-i zJ<$5=CtPt^aZgk`tb4B>u3gq2qVRtF#bv=gfqdrxfu^{B$?{7h<7VJHEPEyr2CB%w zMExco#~lrBLb=bA%eTw3zfJz9^b(gJH&xr`FXZ3n|Ifq?mlih#+NZq*v;zS3f0&A2 oCPcV|xCzES;U%DE@ms?Ebi+uGhTaZS&k?xXiC6zpMgM@TRHzF-9-6P7#^ae9(v#782LDNa}xN;Ui9OEfmE`HNb!ElU*KS0i9S+AddE zE&TkWf_^W?<_N*h1iU3wrQt8x79rQ2Db!FtiL4)d#C}@x_!yI?7oXP0uPh zYCc6g+YPDKY23#tn?3lBg(b;1Y`x0=NHBS!Bc^47$!%)*^I(ig&Y|T(@u3QMaJJ@& zFCSZ6aW%s|qBcq4r+P3;h>*4ojQ5y|T!$~}VYS+W15#IOl~!PU44EaH;9$u7Ff{UU zZF&aS5iQQJPL@)=HJM(4%sMT^+GyduY)%QSItd_{J)Wg=?eOguKgO(}ww~u&P$Heq zHMZ$$_OByD>geodZg;}ozduFjq?taO_=r(ImQt(^bQV6j3H`|WDw0B)O`T`7pxVxX ziB9jF7U$*Yhqvx3s|pz626eigq?b_s<(OA0wT~W&M~4tt+9ufBUd2$lc!x^y@V@d6 z_?#W29zJyFq6wRnu`@&|^v((;Atv}f`7+d#Ip2#-hEzDS{=n8C@14PWMwhFL6d$pk z2E96b^ss`3a@RvxoM_A5u&0=E3-#V7+}r~bN3G|`>F_prof3G_m;Alo1a?wTpC?dT zXk~L+k~I;(6x_z6NjKYfL`gA89N}6Mio~I7|~k z&u#Dj)WfUR<8!nMaY)m#G8hMsena)^P>}KozcNE-W#6kO?c%h78Dfer(j)9t<0J8Z zmf19^(DCh+!MG zDG^c&cm#y|{3Gj5nOCLngRux?{Iwu;*Lj}nKx!?bI?iW;yG!{FgBCGg`t>Lg74aqd zg_7jm{hka+D&EtD0DF<$FY?6uu7J2CrhAAt^ zC|@7A`e}$D(!E4!xo?A7;X@SziE7){(KnU7RtAGcz}?AKAs(3Uh*nQRQa#TusE~$j zlH#yOZS%liwhLXu7&$)v@AmGk4tEeR6iRxxC{-Z%w#w)l?lL?{MZ2 zUa%FS?nY;PEDxs}9Tt>N^rcOTkq#su_<>RHCC;=56B;2et<-@(DZttCl7h2%uw;CS zTR{H>&p5xVX#TBsL#*aDfRLaNVKq@>w9b&^-`51fYvwZtG8t{L6(w03j3b z-T&L4#<)cVKNjq+FY@kiqi(cv^I-(D0inIt&jp1U;Y?wz##G)cC`h$St!?6Mln@m| z%am}TR7MiY+TG6kc|JhW`DB!*n^CftV5Z5ucA#HP3dMx9gfF8huONi#(36-uO$1f5B zjcF;2gxtRmLUxxcLY9-03P9=XA@pV*$YIK-Q?MT#y!_()IWnR(KfzT66E^X3RWh_B zs0Ze#e0{o{*_LMgjDxX%YTBtBl1bcw(psz?;qXXmNmws~oU~BNO$#>Y;8Vc3w97X52!Nb4K2PL47i6(Zv>jGd&36(1HY74y=j}#ruceHH0mK=G|U*ed~h#}Y=8Pj zEG3ibYg+dhs*q%L`p>7QPTi|^hM-*^B#?5V$|+io^$=LfEROcV`@yln4AYw3SPFbf z;jxIvJL2Zd#;o$a(w7r9X<@@B@yu^#xk~xoAh=QSsY9u zmh_v|LmSp^Qpu>ud}^t2fLJmQMtZ6n-T0X=^Kr^)g8Bl7ZJ}Lh;S8Ocf<}j5SE?k| zQ6@T>yhU_)B$05KfY04};(2;Niv#HCDd5fjgPz!a>d9TXK?Yg`y(mp{9tW2|?g$fO zBpgOnAFgE?vr-I8$Ut#lJls8_?J_`DU(bj#FL7DdbaL)EEiLlpW>WrM$>!!J5|hyZ zlS7cyH&#w!CMxa#1{jbsKQ>X{*Wt)~Xl0KtNOlw!i_7;6Hmg$MVSSG^eUcwJJgy_c zdFIgzi&&H!B5bel;nYh}Rv&xT#6l*(le@%V}X%_57Q! z*B1BdMvj5RMKw!DAvGO0zU60*#fZb@HTHMa- zuAUGYmyoEpyIIvG?qqPfAK*|AFz;@CuPZ_k^KR+PAWJuk_g$}%o>S*WcL#*^Pm{+G zFwzGDrfvo_(qAU;U}Cg1HrGMz^X{GEL9wsHTEpwfz%!V6! z;u-Pv^r^?puy(jUeIOAv6qFc?7^>I`cqwPWdVLa9sNJ2sJ^=EeGa^lEx^W&^=pcbreG^D^Yw4mpSks_ zx~$DCH+nO3*_F?d$M$RDa*Q0QU3>vY?esx|p(=5Kdm)%oxe7l#0<$S&Jvr=Z0wI%i zibl9PY=~0`p0;=u5S%Fl6x~Z(>TO_^jC(8pDo?M& z&m@yZ88TX`&}TYKQogb|Gw)3)Rnf6dOU!5kon0x+GnbUHv*e=gPZdv_@)AGFN>U@D zP%vjXry44Z%XG8CTs-Rfg3oVHRZR*u$dVsZSYe+hD+KRPcZg@LR_d_%G-JieLG2Ogr@3{OH*Yj&FMle%^Yruh$b=-pT3 zTXDly>rm1^3u^rIp^)qCg!$KE3=5DcDMi7ult3*9HLcp$m@;#Ex}$tLnVd*6B$U7TBqBZ{N`!kk4PCP>F$tp6DM zBv?gtv6H#`2~h+#Rn#dSF?dF@o$j+<>umH=k^^zSM556h%>JZ08XR`X2@Q=O!lQ$assf%_p$xTxXZw@erolCfa%qu$4Cxt#ovXrjJKdI1_R)AutT?B03 zO)`A&D>a0gVG^v1!d9p`eCskco_$ev{2MSMCj- zRA__6M)9)a?1{pD*J=P?q*$gd398i8h!c0r`eiYF-ZX?AS?jTV2uW1W8451O*cN;G%iVMzSY%Al4{}5Ii>E zb%j8C-MsDh8co39sLyh)6SZcudN;JxLYr;9?Tg4IsW2j!FFgi$5Ib&S6=#IA5<02x z2Pje0cm4`&25&9F&lWC^$pOFXJd(P^N<>nd`bLj&pRz8}9Ha0>u>gFM{=j7x^wzQG zGp}0g2e3zy>dN`BRP;z}%(wk zUsBj(8EHPj`wrK&RwUe_#{iK8R!sDG7Uf7xRoQq$k~en>-zlKlN&TnLfrkBC_@?^yU?WvWdoyd3YaJvF z^|W=hwu0K*Q;_9^>0&dWyBJ_tT?sV2GpUgCk>8V+&_KaO(GME*8MH1B8X#sfYFuch zx3?kZAlD-!BI7cwGaw?rWcira{s0*Xp8$Bu9Xp2bs8h!#uw$G642<>Y5aLN&u7zJ1AhhW62ebfkQU&vWaaS@8-^)WLSENj^#^Ldm! zb3TJpUnJ`j;=muHl4Uz*uinP17KdrgkZC+HuV0Nj7WQ?GrW&ukyju4znETJ|)>!o8XoBId{S73tZMLFY9K2=xhCC9H;p8U;v&1VS;KM zmq8jL-QywW;IP&q=2cOFyOThvq#vTOpE55Yit*vdK>CN$+(UPj`OoSrx`Vugc-Z)Q zKJL0(Kh`P_Y{Xb(E@sb#y>bt@ysz>JM^{(~bqC%$Ykuo%GFi_0a&^gw`N+a+Qy3v3 ztwS_K6}yG*9owKf2mj=^Z5zV|?X8JVu*_R72<}kta+p|1UcWV<%+Nh9d69+hHx@ny zXCU2r#ei}ZDzq6b)cT4%idGPo;o_Si(Z&5>%vM2!aX-&GzZT6nelGoUVersa2z)uI zBThTyXxI0e(oDCk4a-+0e8n{E>)GF+yZpC4Hh0VSG{Q+tG8%c(=qXJl3C26)wAQAW zK5$1&cT#~EoW(c0NZB= z(yyE}k~PFlgkGq$FJ_vO3m?TQ5S}OIiXEKH*5*gAe zsdGGJ*^DIyI+s8U$9NJG3qjX_@<=D<1U%l);^z=^@XKd(v3_47ht<7=#|b#@m73bT zxn~_^CeJ_3 zAu}^GF*h^lW4WJ-)pVxgYF);_v6Ev^XxXlpZa2fDc9BH+a-xTkr9MH*dD1gYSb@;> z0~z|M$Ff@18?;Xxi)rXoU(rHwk&96Z153_CXT336eK2gl?rcY&_}UdJA)Fndjk;n* zPMa;0EH>qz4X)HkD(NMyuB|_)Vm`4_?9Y@IRpfg8MhXkU3+vbaaVsOj5N9(fB zFVy17E;BJ1KeFApVee_4x-XGqv1w9GtF^DRT;#3gSiSZ}C|v409_EKpY^}~U&)lm> z_IJ!xYufLqp+3=1o6w_Idu+gZ-;;+T;-xhze$4xO!H);G^TSU$4Xkut2!v!M zmjz@Qm+GZ-hf+<O%}}Li!D+)M7u~c2#dJPSU0- zv@hx|ja_5w+%&*DZlUL-R2QR){;}ESPxE}#o6EEnq5ecqF^{X-60K{Xh)FpLNB0Se zweS5EK~akM-ZD2%MEV0OX>XZiu>gbm^zT;2DWgqNoT&%KHbrfrd0{Fu@{r1AMU1VY z$%k)ah*P0AjncaAVV{yJ!gD!8CGkq`A4QNP5f@Q$;iM4MwGBl-w*lKx4mL3>6zA?m zmMpwDXmf^BSZoO3@O0alHdWfy&y_Ppspp8rm5Aa(Q0>;pm2-x9=@7>SNA2qzYsL9? z$GdMm72j;->KQ+91S4b`G+la0Uw%a(xkSCht--MU-dSC3xT|o={sZOGfW3vweQf8Z_wvRz|d*Yv(zN38Jos2?gdw!T`obF`j6(&a4x)%b)8^;mG z_DcFq-0t1EYc>bb$j?nu4`{f*jPF;D^{-s(I?Z}F@MoGu>ZWGXCGd?33#^Xk{x!Vt zO>S3Naz{!c1U$Y7G`gH-cYiB%Hamd~KDUn}katC;_D6kC>O@Dw4d~tbq*vF`20Z7E zZ4zDO;~ohREFA!i_}5fy&75o;)$|R3h>7{;{(4I8%6&3WKr&ry#vzV|0WAO<))l%G z5`rh9SRaIVz=U`J5rT))NR^)MwM4b`{$yoq+wcOWMYwq3xiY23@L0c^y1b&Imo_xE zQt1gUX%)R=lpd%%rFxULaq{bXE=d0XMKb#R0@U~X6Xl_dmWB|r8eOpFLD5)ahOwNM zIE1QcWjt>B(t<1j9pS#@v*(E`iQGA^;Mn!FyRfKaTrs&RTwQd=Fy-`h&H59>p-!qR{D(MHr;h0EtusJUv?;$1s_`yP`QBXgIK5;>W4oa1U5UVU{FJ?gFZDr zMy>H1>pT7NDJ(OewMN8$SB|;lyqYUl%$dcarA{hV!jxR$*u>Xr+`_7EmMP4C0K@P( zvN1LnEBi}~)8zivv^}l0NPKSItF}=5A&jsDq^yN9mjH)d-gj0#mEYWyFKIJ9V-b8x zu^pv;kaK4>bo%%`PYc{+zSH*K^DJVl0X>y~lK!iLu8E{;1^Gt}$#k-y2Y&JWg1&A& z`i+!4nJEa~?bR7*+HnRpIWej;$HNV(Vk#h{_O!#jC6b2-Pbd_rYc+vmyaLk4sNR{w z{QJfNahhZ1qJs8V2d+oK1s zIV0%s&&?#&g3lQ`0?f^mx1xloc7CPvVG4k@pls$4nrxhCb5p|E89Qk9gOIoU{3^ficM*N(^&QrF!GQAHL_^%!v z`cdSIDHA=`U{7CQk(jlBx6<|9AQt4i8glB;LwPu;gSUJX81VJm`Y83f3kpj7ZlUnH zAwI2Hls%P3c*~56r#9?kb#v7g&pYX|M}<*coPZ!61MRoV{Nud_a!h@DS7~b_u*^=J(;XTbfbP6c=ElAgV;l_JGZ`oMyeoWlD z6ki_Dg$rn!8o2&T)7LcMFQs4Kii3^Ktj!$FY^;B63JN@^?ZW7Xmay>HG#v0E9XMxF z*l|8gXiIQGaQnWEa58(UL6JVx(1?f()7#|}m4vu3@KL$pAn^cq%yl>o*}Sv~L7#v@ z&SE{^^~ovxAm?E|Ljo zl>cS1Dquq!dn1SImGbuVw0E|)rqh5Zy@lH#E#=cP0ea0iIM4eq6>OcUeWK)XQ&1W7t7UW%3SS8vdqmkx#}V9k}*Swu~w|9o^D7VO@m=8@84IMU`{(ltFraCPSz-Id-2N&p&l z09*tHaDZuKW2j_rW9tB{)E@l1)a!remVoF|V%mO|9=!Zndhp6EIrk%a$czGH6;^B% zK8sx_rcLNXwle0#?ymG~v7;~6quCarD<_ry$btw|y;MubV5yi)cn%x?@mb8KV%!6P zkQ5WGvUej&nONK$z_BHwHH{5J<5ZXTF{Tc-)QqyVOx59nQrP`P9|I-?#QP!1U3BYW zrnOTn%_iEdnn?@#Flh+u1bg1)1i>3&*zV#<%-ScQHrDZUVYfhO(f!B?zsGw+FPqtv z={6M~>^Ro&fsq8UA03bMDo@o|jjlI^FTGhh{(4%i`!N1p0}h-Tj<2e<&uQ0_FZQ}i z(sT1A#)HfqiCmbS9cED%3eGY}aMMi+uW(%My+pVa?Z8J@E|UrjV0smKabQ+0{5am& zRZc2pjXp+|Evs_c+$`1E8;FrM&7zUChfK62e@dx!!8qltj+u>tfJ`k%I^ zZ)^KM(*s2I`;!tYVmu_Uz8J+!{?NR)Q~xoWyGkP;WiV<_h$j`$$ai7-aKw z@{636$`~n~Xob8m4>zF1IilD?Z1eRjI$75EHy@7Eg-bbQs|ijZZsM!YslOVrT{|{J zK|Q4$8sf1;*Fjj*KpTO^7dO2N|^oy3G}Q`;GDNs>yVG*c_Ac!4}< zMuoO}IN|nE8pXvzj@2j#S?(ULmkn+UmkXB|Daam`^nnZdR?Q!zP12Xgr(lmrDO1Rq zP_(3KKk7)hN7fl`xGEBKi*-Wnc={5Xa|_pEiJpF5Vb_IQtDz(+c++($Buu7&d!I$yfd6eHBYQz))o$1hMObKf8a%}94h~ydK*e|1T7@!bP9Xd z28n%9l-drcjQyuc1J}R9j$e7wb$oeO@bN3s9Qqk)BEv47r+?9N)J-{J=?WU_kja=F z74SBu57s0n=wsZT9qNupal#fl^UPoLC=IPwnV{K8x6oqgd?vcu+tz)$e}O28WZx>0 zKr|<%&t;i*hQ+9{6*I`1pO0ARS08s|Tzr=JWLy%{PF}K?KAv~I_rZ}acl3PCZs@=X zEHYXy4=mg%J}=8>?Sg@;S+D3N*4f#n zGHTIEQH6l@{xde2SWo@B2lOZa62bW`5iqa=S_29B_4Vgl4vrf58D9JAO6<(X?@Upl z)Icd1(!`~WE;X|6q67z&A@=r*`3)Y1|MUkQg6t&Te_Y z>yD^mALY0wz3(+GKlwt>mK@}N+KJ8W(ID3_*N+&n;eKl;NkPl?0y$z1`*4I{FIPIU zrxz|R#JJNG_gRR+z{-VThKxF_6=mI5&d-FIho-8W^?F8fY(zFL%Mpb6j29?IGO@a= zYnn+_mycVZ#tH(445*yY);xPUht;Q>^7<@WW^ks5@jT|$Jp^_Nne|BgKPg}0de~AI zmvlkoXs#0OmwdV^-DrmRyX5hmg7r2lAeW#dy zYSZDGljm}ILV@Q|L1UIv4ITiCCh)-OIi{Iy>EGmG)5T*PfEjscf zCk(B8GNOgG!h^4_e%{1<(sN(HrlZ{nMu)o$b-vQ2cY}$6?QE&bnYdKx0;n{FfMf*1 z*1K!m0m=XMxufF!Ho)J-s(+4l0cesxN>^_Wyj{I_Gc+CU+GqS(Id*&S-{odELqQ-0 zgzLfoq4?}J&h6r$8>B9PWd-{uK|sL<0O0WNGuYchZ=V_7 z421!_-_N19PY`b-+&=8PL5TQ;@NaJa_sz98xQ%lAOyCBk7&v4E=J9WoTPFm!fo}7= zH$ZemzZP^|QS&dY+^LY;#Ow`5^)HMY%H8}K%B zb^};W@?QXNc(mJqw@IcOz)8|;z&}^}M@Vo@Q(w#PIuN)Gdz-4cf!!dxJ%1hjl7=%4(?ZN%Hu#SJ1J zK$!rD{~$7MBiyC}ZV(Wtt`Yts25yi3JITHo3j*x|qyLd|-yZ&Vp7iH%GazXA_we6Y z)9ul>!_u4a+yEE%w>bZ>$p09m-p0Qj@;&vEx17X4VOFw_dKn`~X YMM| ztvzdY@7h(}ySl2ntG>Y$h;R@DyP6^tG&bN*BL}3xcWn6~0RX=*tk+IMNf&2NYiCbW zEk9Rl4`UWzCr2<>0VL?FBpFB=K^TM%j|yUf27`=XLqNiCp`dTDCLl|gJ5V&R;9 z;^g!y(u4iCv_$oB=WRCRM;vjOn>{+WcO(8zcy@CD82MpRhzDb1$GG`@5@f<>LI9$0x$ zKvlZ-HA`}b_dJ@2$|x$9tj!xAH6jnV*b|5%ouIph2}6uZ=7NExd95a-1RSVj9(hb~nIAea=gUp#cK15sgY#uS z|4LyT5~GIW9!xuQu{z(85*W{7V>rI)Wg$c-K2pkrXL_q&$uWWko>wM+QGj*B&^r#v z>OfUF2Oa&$`uuXkJdSgUC5o-vcFvk&UX2nkd`2-yGWv5`nfFOHgi0lz6cZ1}3pr0W zKTdRZHjlIaCs7kQ3N{3=o^oi;=2aWCumAwcAB}i;`Z-#A{8mS;)~fR=8}bv5_<1F( zVh2rw@f&3n?1MN6<@r$9RW|PLw%fe;KMsuQQ8@Hxl=6Sq3_p*bSOyAzs25aVhJ>_p?`&!{mP)Pk z)zNpl*PURQFw`d@+4tm>Pk!%q@@zp`QvB8A&}TLJIw<%YilnlNszdz}FNo z?NxLLI>bpf%g~YGzJdKovB*{P{)_wGY#=&S)zG{SgE9}X0j!KhvB<~8LwO8$=3m>^ za@-scr|Up=>Lxms@GT05^k!J?DiH24AAs!x*+IUmm|5d2Vr zNHTa^qDkU|A>;-#S7Ouz$a+&`E%Q9G@p3+ZG;9-CYaEl9Yxy_`X_3n4z1a5lGkVve zRbgop2)ajXEpd+9Xk|VMO3Nyb2lwuQKRui&8V8tTv%0pJ2^T+6b>j~AX2iZ0Gs_Ty zxiL4jHZ8*RjLemc&;mAUSR1>?q$S;rKGx9{v%%h9 zs6ToMymcu|ykNzAc#^UO-8p{DohU~eU#!X-v3vY+EE-&4 z#x>??&L?$P{8jw%IA-^D5aH(l!2nh^P za2G~WQw_Z&yqo1i9_aFNpOsd0wGCz2-6&zO-qU8&hM>pjFY;wmq_Ks% zkc)4^x6TRu*kSpirbsr&kTQIVg&yba%L}a`U*≷ae=m>qk36@H?t!c356MyTPS3 zPqhQ1$wAE&hI_;+SEK@#}Je3(#yD zQ0x1i`D!J};P!hr@6!2(PCR6=^4|F6on0mnmews77GZ45EcU_=y>^Q$VcRpOw$Ww# z@nqm?2)ZTA-dfArR;xvI;L-wBGNIoUe~7~;J@P^Yxv^k#?4{2wsu4;srxDFYsxBtD z`hEh8o8|r;x!MOYk<$1X@}HV-8X)JndtC#cUbX)_LRh(2s)6)yP=G1wiUVxuBRvXZ z54kGVpXE49o9K{fYp?>5$68Rzvr-1Z!2z6B`Hj5mXU{#`BWvJAH@2@3fit*@9Mec? z5DL{?-qc@tuTMg)$Pu;r^&-*|&`0B%cwIhzZGsI?|=AmwP2L< zksgBXdfV*7o{pix_9a+^Wz5sjuSCpdb}HD1U;2D;z_Lw-nb|G_#6jCk8L{>a97h_w zbgMB_j`aK@`vCRNm9&U~ivU{2dk^F-LLHI%();navy5c*iWZ2yuk3_BS%u)9sfw9~K7r?)9boA7kWrebYP-`zh znvou|)q!yYE?*}-o3csgo7NgA)lr)#;k$pnw_jbp8(uRAJNrE8rawOwz{!d@B6yHP zWCw*B{$r@3a28sEz*bG&jWBnf==@Vvq_E) z{`{4n^}STa>dNO2J>A*Mr6GHlu##dfYH}wPPS|9Da$f5BsZ<8q6YS_Gn)4;a&hc73K`f4^qn&ulb=>xe<snV)D*UkLo!0!(&$S55 z$dFtLpe8u_WcCBq$(Xt+mubffqrT8DQ$4iVyePFtzAh(+0E?D-dY+FN{g17{2gc6G zTX4Imnj$jvB*Zn=SRU;g3U{W>g_6(2UEevTM?c5Cd^>kP_;rob>Q{gZ2h&x+%4>L= zG8lT_4o7~l?KSnYaxku|u4M2$I~{2_i++%<9JsNKd`KV@MKoyHSE@GNrCxhJ>0z81 zAdDNJ+0S087^Zm-F($$TNkqcxcLA-J*ZAo~l#4;JC}ENns;_wSI7y!7%{FfBQYlJ6j)L1`)z zvaFiz`k5PF@JPjoHA_iP@IeG+oh57x46!R}Pk9pC)>jEgd3U1J=n@lyUo7&IwA4y?7bWJ6T|RQCe$Pg9g$g{(Mw-PW4I002Y)0LX)w6lm=7jtx7gu=yoq zS<*BOW)u!ZIfX@ePRGEY%t70W6$c{Pmm5D6OAh#S#$8G_&$Xx#==2(#g;7U90ywbG zjdQE2lg6oj*3H&-dfu9(IF0EoH#Vab4&6I=`gNhpQ4oZ=`O8r`p~tWczCN|25lRGx&?y@x%g0`?pM>$`}*hKHIHDzCJm z@!GEx?lkVijZYwbDZ>^Vnwo2n^IgJmED;(Jc@n`-9{F(A+ZcVe(Og(fDL(d%$bis$ z?PA6)dH~EV(YXa)@vjRXXWkyu@p}T7CqC3!f7C-t&0?9h&e5;X1e0%9^XCoyFA1tRbQ5N&i9$gX8j z(0+ZvIU4qThkhRCDZr*k2UH5`4rWh8!J|l%z&%JrLA3!b&g3YSamb8B2vWB=#oE2C zx*R@jDTueW9#tZ0scpqIze;FXvTkP7Q<{0#_rl>p!?{$1xPEA`Bx_q3X0R8 za&+8uE4?2jugrGH!Q=vRd<4h&F`Y8Fm%-3{BkZlFIBH()l4GwtR3`@mXW9H%_?3|B zvEKr*!DXL+iqc@AEl2&{$d4$e-}Kmd zGHwV?XUsnj+*w4G_K4?TA0xpr_*>jOM-V#Wa* z1FZj54(jVJfgHfQ?JwK=`cD`XOu+<97Po)h=t|d9*c6VAy>|=SWzujDnIjb&-PSXk zgr6KNZL5D1+G+(_dwCoQUng;~<3YlWRYK)ChDFxcAfFrR`?Bx17>04pb(@1g5?Im; zK6f|LQx#FV4GkTCQ|>QEtW9jU~Ql-;YV0cUvdY0k$A7tU!ilhpc!uJsY}-I{3W z+LQUo{O&W{e<%0X+;++-$|YYN@f#RW4OEJ)#ssGVNeL0w zFE{5sDM#r55P^12U#2~195*R>2f22II+gf2nn^GjQXDU8tZ*P%)Rr$duP)sR&5VRF z|8jFPgmWg6UY*tB`OZ1`M=GbRM3w|03cqRi_J?`-aI~ni!LA6T3N^~R(}|MiaX)3? zLPFC74maH;c(8p|jssK7+#;aViiZ$cg@an{QVM_d7n_o{IRsw$Tb#EF z=tvsSv~|P7Zsn0blkmD0$!#Nl3|4dOKNq~W+qu`QKI@yp@}(^#FzhCuPAu2ml0Xk# ztiQ?`EJNKhsSO-TJ5ubm?lQdGQxM+*8gXGOg73h0O?P)!PM6~^FTwXy`m479x*o@P zuZbLqAgBx&-ROsFMp=>Nz8Y%K5A5ngRWZnxhKfT}c?p4*A1%J2(#HO)v-NiJ7Icpd zWTw9F-0BSEm*ui4N8OX=Y{^aB1yajnBF%8C@}`r9ZOQnmX9PN~BH;ooNh!&J3ZZzB zvjwisR$|s`n(?xHI@vt8gcm{ld(24`^NV|KG}atxr~S_k5$-CNgq@~^V|q7D}8 z(3}m2l!hdhtnEVrHj5M`c#(QdS&*J?fN4pBb3dL+*OpI#lFoL_n+m!%J=P_@B>q;u zX$m`J^8O-q^|?SAR%$XYMO-2|lrPd<>2;BmtZfP|9`{SMPWO2KTw{|rL4GB#J`D#7 zG)F@VOf&r*=!bd`e+sgrMo`g}Zq;K~u8_`ECW91}8ls%6Oa-bc*MsohJ5{YjSF(l# z1p!6&UD13%M_sn&`CJ0jjyUM52g63C-Q_#0lBee}`yt0j=ZU!Vei%vLNYLuC5*uJ# z1k~en>=BmF$rV4PdjcdSDhJ+gIhR>kCUOFqYY0m!>3;xpmxn%epM0pV(1F!r)MU%HLp`*cd1YEmD1`=E)Sjt_b)^Gae@T z;}E!fPBrWTJ=HnwXU*QSr9YKAoyMh0_oI{Q-WXCpou;I-bVnEGeA`%$tp{`ZCUE?>Lw=AssxA$L&Rs-h@#0WkOc?!Lu4&{Ho?6JGZOvLiH9CT0;W#|eNu-vTf zf`5m3Mp(QLF$h%xRdQAq&bj0wOxM3C-WYvXaXc}N1;0y5?MV$+&=*ed!~TADtv%82 zTY;j$)d0K5^Z%Y||8uCF*#DHF@~T0FS5JWp0HI6c1M^cSe@CVW)1jZjeDdU67!c}^ z3~dTd(;04ggZ-kZr($Z0KIb$s3OHF+y!E#G^CxE(i;S@<-vrD(lS<@cFuqKrOMKxE z2Cl*+a_)!Nx}J>X5ZP{J=vw2##VrqETRT$g6yeAdptl7Uy)U z-EH;+qU@W445?iF2*CLP&hG+yW6|cr+v~x5)~{+$RTi zGJq)eMoo!-1@%L1n8DngsBhlp z>nDh5JqE1L8H4Z)Tx^BP%t3nxA3x1WrRcwlj>zVd6jwIgr85RGFjsiVb^)nrzQ|#L z$PN0&*x+fT)M$#SBPgDcq|}}?cDnRp^9*h#_?ol_AXNu9?HMyf45ZcU>laEmI~PdW z&A>V`Wv%CCQf2h<;B7v9tVBU?qgNMyPwU`r&d-|Jt{k4l2J$cvR@=-wZo60O`BHd2 z^2H&@wRV^b@@0uE;<=w}0O+WIRGpb%xUiOFG(Nx1gv}bkWm1D^M~UBG|5)?pU0V*! zTy6Az$6NcKSOK{vt8v>3P6-{xyB)N!-P-=2u+Qh7_ zNc|isGF|VRmecSFrCIKsWI935dDpqHD9}>1&LrS~(^D>@ROmpjMNu0mwRh8!5ZF#~ zeCFy3b|SBIWgAX_E47@AX|8iJ8PZLc4GaU2j54-c`YA-}GTEOt%c(P9pf_uxUN`sc}Ikr?tL2 z_+}*Dw!ZuBahj|Eo3a&}G$)4qI##M}3}a`<1ym+ks2S&SRn(8E zwCjkzFh_{}E&+A*ft(4#V5@yUm3Y?}Ryfoc6Fu?@U-V5WzF*;-QI}5zW%~|R5e?pWkF&A>24eAy@V)JAA;*$MXr7Yp?E#_nZvPEi*oY+*X~?nr*##I`%} z>49Lq;X>E~yXRD)kl^9BS=AgoLOpd?+)5azI@bfj3JaBsn=D>kTQqZ&n&v_jN*T%4 zg|IHEK{DdM)^kq6ySwji4&fMX4S$F+>C47*^z?hGe+w{5I0QzQov!*4o?z;c@6QFZ zoWA~0*qIi?f57mR?AhiN>zMokcO2W}J}p|Da9T}3*=AMsg8364ZKJz8DdD{(-PEHmcYa+c6?n152BH}gN=AD!j*l33NDuVd6Qliv@9II(^z8|B>O=~Pw1V~4kvQBXdsCLS=a+dX6&f1!I zlM>^Hms!Q{*0AwiQZ!gw6_LRl&Nk#*0a1__l@u21L}bMn@8X1!33#@o;YLdL#WzSFZ0TPs_CNDVu`FV0KaAPRKN665Q2q*<95Me{rW0d7D6|?%O14^~q zJ|o~y3xeTJA680OFtH;{{K8U?sZN(uIct`M;2${MB3xw75#!BUM*Ag z#*U|YZ%OhzQ0jA-EjbPQ-)s7xP#7kDDH z$U>4F9#*&dU4CMskx=kE5-bzMszFqPYxLFTNVFD%apvZgBAJo6xxz4?AsKZ7u+*_- zLC3hocm^Lrz3nBPL91h@gHg>LY|7Rqfk?RPN-nry6wa$_*WPUk{fKA$g&%|lGsnIU zys#*OZ>_|$#{JqzaJi0(F2r4NxUyCcqDGKXzo-k~Jfm5Ee4&|#~&ZyMWEj(6I4C?t5+iWCW ze8AP&E=a6U=PaWXX;Mh_uv_aI;@hX}?soh`D=g}PJ#4cY8ua5A{QdVk0u@th-_64Q z8E$U_QXN2By%(`vYsiNbV3E>!S2Z?Qe+`ItVd5gQ)^~?jdW+DK>iEQh|EN1;X%SVj^cD%T0jd0u$H zYdR;*#Qf}$9)}^%>-6QQh0EL2hNywU;RfY%2&M4?!Jfq)^d|()qx{7!INaSJ1fu4i zYyUNEpCocSg^IFb0f)Lp{!{(~()T6%Nv8QN zUSr=!3i%RYJ~-V5$fJ~qA2(zP6ydBk`>QT3_%|l;qPm=;AV1^PU!o;nv~`3@K5w4? z6fJXM!&j1c*9WfKWNm?o-XG)+hC0M1dwwW25&qoNnj+fd#hL5C2MHhhIwYZTV8^aPkBnYD2wg= zLT-(^FYk7Y6^6bMn_%J?x8L+{$q{6X7(zwj5`@xxUtC&mt z(Kj8Z3^5eQsN1elWhjs|!MK9Xzf0mIuIUb(MTe0EdsxxZ(I;qX3U(jMs7UI?Gxuv4 zh4qc6?Q(73br;t*z6o2Bf(XzDt8^C&H=hBXf0*KMyfn#HeiPIDKlT?0t4+yjdr@2G9)H z;i{tcObfOV&ICdti6G!!n?cAZcXxhoF-mbl*>#wUnjh4AnLJQOEto~xpA1rIF5Z`* zJz!XOf3C>*GKBbP1+>KV1h)en@1B_CCrRY3-D@!bp!j9q=qt79{h&G;UtOfaf*%9S>7(`| zj$@w|VcCO88|hJ}$-Y>+NV+KQ=Qh$leYzLqQCP4BkXQsi91XU4svZm9jx7l{sVE2~ zQI_irBhj~}1RP+cLzuKZG2*&6Oerz|o*Uv*5sJbx6uI=EVoct*Rhud@6X*jPc&+B} z$1=Rd%XXT>K2&MgifUQNEBY+ZSh60w%+6M0hd}l1@SE5Eg-`@fel(cqHpSFD-b3qy zuPqm+3&s#9uO9Rgd4H+@mk&I#Gd%wkC3=-`4@JTk#S-V;oTjZ?CoM65- z1IKF9T(6@;ny5+3&~zNVJqNPla4AL!vCTj(ufI>I8xqoDuVZ$~5o-U-GOwYByk5VA zD})RT$XL0+4&n}if|WRXL4Tyk>N-E9$l^{d?J`MS5@yaqvxEI(c$hB`7-$?U$3!r} z=w=MPQdTaQCThFip>~{3`rb#14#E7Uc5GG5zmeziGk?wpgdh!GjU3ZvJh7X?4F)5Z z_iP1Hx-d5k`FI zPdH)cEoZI7%Pfs33CsNf( z8Y?E5)u_2EgY=aUvQ*58P@{C0fz+!Z5L3MxYGZ=6vrv?*Q9LRk-05Mr5shYGdS8zfi8uQnIV+=KY9i zLBg2~_kpC5}9fSUk!dNBt0>Uo$)lAcfHG$Z`ZrAU{bL)c)ur*gCOb^Ph z)#Oa|xr^%hfJ)@m7QJqAC(kCtrFH1MlY@7ibc<^qdnh1$!9LwPl}g$AM}u0s6X9Z* zv*SdzK$1S)r`V@;F%r*N8yu9?gr4=*^{A#E&eE`45`$m$0#67Q>wH#e z({uflu8S+cAFAGFYdXFp!?ac}HmaLJm>CXBp8VsVo0VXvD^>50K&T?SHF8ZthR}r- z>vb-$d&@S~3$bRkR@u;JqIK+_Vr<=lzFAct9OVBH|J27vmT;NsCV~&QMrLVz!LG&* z!0BV6-?x3!70Cax3{;thj`tAvW6>)>O7o?Vr%Ce!QjF201yaz{q#Qi5)xJtId}3?m7GG^T{gsKeH&N@N0xD{c8Q z7@39_+HZ8%&ubU5vw|-oYfBB$4-zzL{aJ)8E=jU$0 z7h^T?#o`)wpwAN_lE+{45N1JzmDG`cXiU}N8Rnn4`ByTA^%b+> zW9Mw^!D{Mm?db8J+rRLsEWdkz+7sfakmSgbo7E|2Br}ohu-W-=Z2loO<&dfL5tt=y zS!FDy&z;j#=gif3-13nmC$vy;zVr@T8ymr&PE?9YDeJS5K;dWz6W>kfEy?g=E8_@Z z!(ya4( zzka)2sZU=1y@~awvS3K9XGTFliGP zlW{l-#EJLKUf$`q7S-GeGPJ-IiwR%DTo#XYHBI)oay^t)yZlr4avW?$jjuZAgaGA> z(xW9#_o0TdA;WIy>ihdZp@FtUs3j%Fkj$(yj$25mg*sL@k(p?kg$Zrt`xP*9J32sp z>AG8`K~`TI)ce!Zdf+h@r8s5IguV(97-h5XawPPZ_;1Q>>46kP*{JCKZp0TdmW2(0 zuRsNe*DUw{1B4BF5aT2IH$wV#cz{>Ke{EGD6>(t*aZrLdEz!SGyT70Rp^^nniN7KK z8$SsEp#6UM+WtIWMh79jmN@?nv-_K19TOxgK|%aC%nSg)`0M@uaDc@IMM_Xo{f1ZV zy*^NWoy;qI{IB*$gecA{?&2@g0nNzZ5dRw$^_%h!p$abO0-q3sCy7q{FTBS8;kHcx zl9ZH%ge3tbNYWDjUA}&WEdNFIA7-?qplL~dqW{)XUqw*;gJ1(RB}oJlks>DjyCw+$ zkp6>a>&+`x4FxDu3Z3|$m5cvNBtiXJ$Dkwr zJJbHR(*JN7qycTxcz1-jtI0ZF`S=I;&Jzlr*IUx^4oiLadg8+xDt z0Kz}>``@7<3WAsgi9w4p=zRb7qJN7E5&CQV{~w?#3BceN(>+dtib^QDdN9h F`5)&LQo;ZL delta 12222 zcmZv?WmH_-vM}1XOK^90cXxN!AORZJ;51HxL*o|Q-3e~N-4a|vaMz%ZoPEE$Z_aqt zWBpmPy5?Nvv#LVC5CicLTxyC?&{%+ffE>X0nI6#(2>|%>V7|RHlyq`*|KR9us^#tc z!OfV(%fbGvy}OP*2NFCDdj!r##BSJtM1laf!=Z!OWMRO%urAKHMZ|fIeDR?)q7=k^x0Y17R8<7wKL2ny=Tm}LF-~sm{;e(W& z`q+@48MSFnbY^krO6{WXkP(1G4tMcix$@=9`En@+K&H9Og7y)=-wUsJPm#*wR#kRl z;$azlpdx}9fEx55pBJJ0LP`iy5o%Pzu3SXqaD}Cc652ITP{R?H)lEwnU8c#y@`g#= zlH<)aDw>z!IFe{6`HuG5phd8MRC=O-fE@Ni1Q7F0*_?XpAR zsQOJ!3Bya^0hEoE@z6&^?Jh>3o$rxftrim+0iT!v`#(0Vv~p9a{+Q8O-UPUgHH^9A zPZl3JAIKivPmtE=xQRyQr@J+{H0pP%?0EYr1E=r+BC&TY(;|>lV(AGtp)y`;4GszK z?r^K*WBYm)r!!w82#*h8o2CWSeFbHMQFa_5S{Q=)Ax63f$h`w>Q(1AQef;-)DT-pH z1vyTTL`yT>Ke4^SHi)BOL4eLedk3wd0065uk)phb)XSdL&E4DngWDfrp6E~=V{Ljr- zU~X$gK4ndDZXjESi;f(bIA6;(nJE=gpi(F)aWg8Bzg)l

a$#|T5{}U=Z3B*NqP~hqRWr*ze|^w>xswp>&uLhlc^i6 zFKPf2-Sjxv5s* z59IZ0{~q&w&Q~OL=c0tLFv)6*2ssMa2;I;IBThISDG*y1vFrxAL+-0gLfbJ)O0f7d z5nh;7s1u2Q6}>*mhfsGNVrolC0_tJwpBA{IQSN?Z!0- zWo9M32^CXLPMp8n6IxW4wSHE2n0wgaKmg(G^mFg|;p;K&>NF`F##%((DN1}!YFLJ_ zrkfHi5Wb_%j$)Enb}K^@6L!pu&h~}36BL*Vg3vc?4C>Ye9e)(mSD?;PWM@%Z$_5b> z{qS`@MV>l5I z^BVq<>^v}Kd&5y@gSp0Ov0-G;-Ge>7`>VcEO4P!QC40Alv1v`}+>h%+&n5PYr&(t& zqXY8hM4iH&+n2y1FRIlx@Hh;~^9lwTr88-lNZS6n)Z`1q|MRu*Z)QjiP$ll{QF}AY zUO4bMIyR_Cd&O~u5B(WC=<#^pe2kE=E@Z%=7It>PVfL4cxaQ6$yGSg#QCuwl{g-bq za-s##1*r66^?(iU<6t+>|DA?iL9G?sK~!( zO2)@l==)^f8-I22!{A`osO&>vjUp#SThlHZGRhbzFZY*JG8ucl+SgnhJ?kVdJ?-i1F<Nrgnx|7%M+!(@uhC z-wR%;f}Recgd)mDdDf-sL1S@Xd{uh6#)B6Cdn7qxJR9 zK-Ug~j^elJqIWDx_vZZYHPD9IwpEarwO*6;o`rR~VWJ8)WTFaiSiGqXzRD`fG5$(N zEk(C|hQJ|Edg+4fB!0&v%UD5EigBHRZ{6GnC&WaRrWua-bz6lhErRH~t1Df}aur8w zo^&=?9qEGX@Fa%z_os~BV4c2o3)%BB{*1Iv&}Lt74zMe~QfAT{ma|LaHZo+mx~*>A z*mj^XevMxJcZ0fbMcXFL7Xv!mi0a1d1nO2^ZoeD(9tBzRkS0(GE8li?2a5jUOXNEdq#Z=n4fN+j)ngGV-5Z=) zg*s@tdG0>j2=IHps5wJfo2xv<^!-*kho%BO#P<_#dXDL1?kik85rC>2ASYB2jyM{q zIGp7gTSfekE#`34-A275>ev_6a8CBY4`jJ@6pa}E@R4_@uMC59Bag!cg6@oP_b!T} zLJbw~Yw}X0RgB8v0Mc>J4yy38&8v`lvb$!i!4e^Qiut5G)*$yUC8(X^nMlUdP*y;4 zQ;8en**@YSG_`&acfc>=blPf9Egdbc5ARHYu)2cV?Yk)^o>*~({9LuDCZ3ev(Lh~C zaG+~M`{Sm%7ZRy4_KWiRA5H}&-R1e_Z;`ZUofBI z(PB1~L&8KcB66A?(dPPT)z7>m(J5jc4&}opF7RHV|28?aA`U^ww=84j?LmJtLQ5wL zHCHERH&!!ekn^8-n5{l$+s}sngk9jvR1~JxXF$%!EZnG8JJ%k+*j&nlAdhgnp_?}# ze^Awu4aeEebX+`xWsR&ZXqezJA{V41P~>2mVDVV*Lm{oy$6%H<7&(qN65B89Od>gp z7e(~mLOML@DP@)pj!2rR!MZ>^8MTo(IJ@V_G)OmfLE!Uo@FwV)MMLXk{=Uyx0`4N0IyHAk7B#U6<7&>1;;Ll`r zK&jyO-k^5TrgVlxD1!&PC5aHuX;RNwJXkef)_2q)W|3SkvTn~#ZQMFxx~`2&r4C)O zr4N*Hfno^3a`^D6<&vQ(a|j0f}@YSt4En39Nue*XUmAATqbKNfJFdP@P3i zek4?dM$|vQ;?X)!0QSD+g32a*U}>Z9H`L$!6!OFt2diV}%PFcwSmfJnu6nG`#-7;a z(t)n;lhsGkd@-P|3OD%USjR0i^Kz$#E2~raMaxjB_SMu3CmZG3bgVBtYBoe-Pb^SU zr=p`|c)@}=L`M~bMd^!}}MPJ%C>)!W3%UV%Jq<)MN^3^gNO ziM6Hc)7uA2na@{B+)B1E+-pGvq^y%IG1*S5$<%n&t3;{XCmp<3`OY07Ic*6%xuEG~ z+ZE0@MPE~{6bJOyRB7!L>o86ny&VAn2%DK}t4=rfMyZtOHQ(NS1rb#@qsB)~Bv>zg zoD#bl^V^5UmnIvVV~*ip)MSJXgcjUzd$CS9{MJY%yQBTIgMtn_IWw{Lc0N31qxv^F ziN?w$a|b`&m7?|mhN^r%(bfz0Iw12f{;ygk3y%kdh$6yYK#3%k<|Hglmua9bevtg4 zaKl(K|JGMtxpfJ-Elf-<&>kzDzx2Qs;}4h$xi<8_uqQ~yTK{rs)L;Qpb;@}nTYI8FhKSioI(JomOM^2z`Z_M3C7Lue3pAOk3-#`&6E-L?4l@_5w!j@Yf z;zHkvLL;`WX!=v`-EkAk0T88`M(J+QrsKF~dNTjuYLZQ40Px#&IBj@*!{pxtUSZr-`xKR#&wI!+8*X&>3hX}Ob1Z0ZElG?L`O-7% zbL!72(+W|Y%bI8;D7Q|Y^`9{Z`Vg3e-n+ZCbhm806lEIs=xwrMM1!uzUZdi4Y=xo} z&FFfkcH#;;gU}D2Vm9RQaA<^JQJMSXaKcGS!R>@ZKB8<#F6lPcxGmYv10Lgmy1Lur46zl#TKYFTKaaW7j)=w@YIdQu2%^ zkd!zxnxkt%rzJxkgB_+lr3wbj*(T$5C60E{&%O)5qB%l~a?WjLIIj=RnZvmjulv*k z>RqR!Ax{FxM0w)nv4=ZKTn8LSm@#yR+^B%WXj&p%?{RJ}h!`(PBcs0jZN~~v_3L?rAf|u5RTpU}Dd|l@7$;REw`eH!qr+#4YpzjcgBb3C)n2WQwd>KayOZ9|= z@BxS@%ygG=Dr)PlYctlO1r9n-wr@<<hUCJ!fdyleFtN-$w*b^Rn z`fQPzy@OK|Vy~B*Lk3phA_|aADt+A{O zsSd1U?vYSTRPb@fCG*r`!z<)AyB!g3vL9T0;+4Jm%=&SslFqHv3y$%6@ecU^o< z24VA8E%#%da4H+`IJeit2 z^^;DGE*qb53B$JpQP>~bK$N!|ok^sD{qJF>d3Cj>zcCxC=u0>$jQNb}Xf~@nQp-2| z=H$|1O8lnl>iEb|wIuvr2%o%rv;G-_gB%ad)CSfTcPfI9=e+bDC{d>TFz56NXn-YV zg+MH2>{4V}149QR<;+rd-LZ zEGJoB+K;+s|F}^KhPK(SUnpO4g}?QBy5jx9iN8)Fb$TpLSZyg09IHwcuT*5@h;a$z z_N3g#Q~aRdMoms0_kQ@qM(@0{9&@yrEi78m(WO0v4v10T)Qsl^%ITFBSC+*lbD`EW zP>a&+yim#uDz-v;FMaCa-@S)0N)3dEdd3MK<(Pb5u17Dn44Y40l8n)?8^%8a?Te(M z*2##JO0Q04KH=s_YDeb+O~}Nf0sJ~S6BvT(L+j2R0D+qY{Geqe2roG5r|vQ>Tjy)i zX0ml1Sb{JU#nr23dce^=s)P{)A13cYkm4Yz&Nv)oXL<) zpRJ-r?;!EjlFM>|nnk+|pHE31q0-ek$n{+4QSbf8m*n+@S@vfk5y!G21n-B7>#N@@ zS9dZX37XDcE{b)V{ige&{$E6w^P6U=1c$YhWj&bhC~ed?L5f~lkp`CZzxs6gRsnbK zfdsQ*FfKCMu=KzSWsaS!(KYEp*DH$JcpRSGqkfe-v?ss;ViXT<*_{Ha zFG6s)gr0%1CsufE91kNOm(N8$iH!+`K)Hel5v{mrA4aE63@xo)YBe9u3n+HbVJQD) z1I13+8Nuw#Hm2$|TjMI!@4$0oZQ`pZCok$w4@v=d>&_{kd;br<(}=5)7}7A)DSy(? z*Tvg_R+lVGaE6eHWeGRiv9U(NQ zei+2pF?bTr$w?wAm6!DVJ$whBs}SpU8?Ix;JpuqA_>W1COoDP1$dQ?97nHC!oipbW zKJ|fH;cU?i1B_4av%2kcMEmpyO~EU`dKL^?&J5>gacOgpn~yT)9t1l#xRYp}K4rYE z+!-U9q_dx@>>ODpqgs#cQ)o^3lrh6)j-?IV3@tc#^P`&vn!F7NN4kSL?s4g(MDg2x zXWbIw{mmpDu%zYEn?26Jf*;7JKoi=Ejw@{Fosm8M6l3ypeYIG82+?@(kdzZ0o#xJIQD?|zb;(lZdjLsWfiBx>C+Q`HcC>& zw=tw;mHgas_qq&{`lg|;R!voC2^DT+^&H8ZoIQ&lK}eTwiBlpgN3E=Y16tJS*ED1gu4N)7nH% zuC9{cq*Vwl%v4&m)L7rU06J+osX4hTVO=4;f4w?j{A{CrF%j6%hDCN#YoeWow{Apl z94HbTahSa7OKVm0Gq$WLclX`PXY7wINcLS`#S$m;`r1PQ5CQD1K1hQ*)tr;^1EJ?L z7?6Zu7=@Y$oB=&fV9B^^DFO@_P0f}K=}bk@E!>HyrE;6ivL}js2SnGfSdz6ney2AZ z>oolhy}jIveh440vD{%_S80IQHAywONT}AzzuJ{xnN!zKY0tUJsG!|)Sx%A<*y`Y8s*sl3+9mdD2Js%(+qrF51P7t#1|?2iYt2xId4(k8b+6O@7v-S-!hP z$#@&%CW#Iu*J8A#14u)T7paNh+<@7b(fBw_@QbEZqT5yO^-%J3RE5)?!TQrJHE>f##V38Lge4)ip}C?e@_PlSq5w7G2xfje$GXz1Pm|Oa*(jjOYl2%cGNOu z{}#g{I45F~bkF!6Z7nmf*DRmbI%E08-r=ChI#Y3L{L<@|{IDd$!!tkX;6A3~5%CW0 z^OYy0Z`avP#-w&A?n+!o>dz*Npc1qExD>DTycpO3WXI+u#{GR%V5>Bt1I?=v2o)^t z)44|5(thB3BMQnMF*`zsm z6wlEx14_1Bn~%hsp*Zxdf>G|<_b~m;+r5kPCFa-xqzFVJdgZRlK8kmFTeF7^%g4WH zSoWq9AKbxt{m_dyTyC_n3{T4=)zR`sPDu zFNn6Jj-k1N*gRYO8lWHnSCCql`Jwafg394zi03vkyFPN!IBq%?I-zO2 zwiqb}W`lAzs3$dXk8|IL^!7X4Hk512;Mj`@&E9e^{%WDS&0E4@R__MxrZ6$-XeKSk7$ft2Q>EziIGF)OWmzFfRrkVJy5*5_^2zd z$6p>ypTE4^ZIC`=j$uFORGf~jXv2B1fJ9WR?szE}ncpP^zS??Ld^@FUlDXW3R2=yzP(@HFnYi3KGyF1OJg$x0EJoau4W~E0tGIPfds-D6 zE@T}wP+I0y)J;M>)sLMpOV>vBVngvr((7^5Ye2St$d=bpsQd+ZANP_WQ5KPlAf&xv8r~-T*Bbs9!x6DD zOyygtqZs3#7A0659uvI9!iG4~TYJ3X-_BHf3npYO0iEND&>{;-a=2OE>vwvKiH1SJ z|CC@ECsKWu|J1Ij(~qMv@F{r*$H3+miw>z$??hQjok+RbFx12*8+N%2rA^t9wgr=L z_OOpD+53W7&yTZHe}HFvdZ`~GF3R%VgN0hZosD?S&dDnt*KuwFj4{ieF$c5Fy!cK~ zB~7mo0Vw1fvAelA=9$ksY74a@Qw*gqOu4wKeZR#LZJIl+WhEJ7PDD>P`$WiV+8+FFrb3lnDfOkH!-tX;Yt zTbNTECS)zG#R>^EBV!EG#iWi=v#wfXDLv&Oz%$OKEm&d(=;h+cmt?dSorc&cB7Zw( zxCOWf&iuK(xK##?a%TbEuZuvlb@uMM^NKU8YxKNNG%U~VxKXGQ;AncpH){`}N-mzh z?hDeTw+Yp!bt+BYK{zX+!jqH7J?9eeow$Z4kQSD4u02*vBR3TPJY~W&cTiW35T4J* zM}teN?q{*qdV3>n1A^tbB!IU7GKbZ_8{0KzjL@c>a5dlqBud<-m)Uq8PNbUlx9W+R z*hU-7rmY1B5I~y;ZYt!kT5u-oMJNc~27uzdUOAr2?pUohgqf(5_UN!F6CIbU7wmw? zUE@6Or5BG0lOSZjmU4~{jw5`;w3-*J7(`^OPAL_GCx?1B_F-m|5J@`P9z_nX=xp-z3a z^MjkE7kTU~t5Y7<~foQDBMOXS(XBa>NlW~!}RrVZIclgj>7}dL+Oy_3v zn;Gebf(BSVK{BrK(x&rt2{ccAH0Z0@xIh9n_k3QFggnHb+PUD|u@-oIFsiqKQ_$?) zbLpOoqTEa$rr#Lf8HyNV1@p~@pJ%c4nvpE!?$kv6Fe$BK0VsuD7)|Z;;dw8g999M< z?#IUW%rxMD%Bf&eZRZv=AV!SUM!traIIS`x?AFQhX@BWOKjNO)l(5uBSoK1OiN+f@ z!PPp{ZQOg(^lGE@GN)Ew zQ3w!!|2b8WzM%Lce=`P!Q-a7Bj1hvu7A1eg;xA-3AVFKgJplK;a;16*H(wwM2-AKw z5M`%yT&0HBh%S-C-c;7GBdu-ClVO&7syZ~EHJGsP7khIzw{Q>#7ZPj%{L*~$cT&MV zh9&zUR7b57`+5a@>1!fVO`cLA71*oDK#P#J|y$xBippH*yMzqB`3P#swGd+B~&iq_+WGQqy`N6A|!A%lu{Mm~?_AJJcMhT+wx(bvV*Ua4h3x=}LO zS}9xGNP@rJII?GXc=8Z|*z*w-*AWyA%;YhD`RzGu?E4ST2*y+5PJfAx+wAZc5Ro`+ zKE;*V)`qTCZ2Bg0+h~~F=AOS_5m+A;A|#{&3tKx=p6FY2j$_Z+eSI}^d&PRB69{VI zf=IHPzqo~UYAdIvV>)Pdu+Nuz;I%r1k(|wDL(^#t`S^iuD-u@ulJ!Ey(r{SPAm%2a z!J>V4umJu;aG`>9TU)XtsuWB)X~5pOtOF{>50ffLnHl6NY7BUW#v2yo>SlKMXWo1s zuZ2(E2q#(BKD1ykwDp-h#{mkQJUZwHnjanKBr@?#h)y9@^Wmb8e67)ft!=PP?>O z7>RVB@&Ex*9cH`O(#w5hDSA}WbceR1a?Qd!ZG;$I?AQnvbp4ks(!lN*TS0ktz5(^3 ztxG;e!KY-5kBz%piZZstE7BeDSVQtP+Pxvvn2F)?Wh(S3^9Kr7D1H~1e+O_>i}P1l z7yv*J<;|PngE;>5-Kuo|r}-^@7Hcox1=EaVdZ-N1f^bL$a~qRl6J-}UpO{2k^c}RZ zMO|;+9+mrDh-(XZZ(Q5@`%Fn{mJb{g)t3FSr{i*0gnpl9-$#qr1D78J_c>ahiaxo9 z4+Vr3y#hG|TU&pcx*e&q18%W-fVbP8o1YZMLuH-0r-EuR6?f|AVr^Yul%ng*q@ z4(L#lEgMe(MCRkHqPFE^?qOGX4vq6nqgMkP<;SY(*nNzLYa?mqr~Kn-WOy|IJ*QI7 zbqL0LSBYHU*6gWiA0J5?gH{caUHLU$5nWqBKH3ItK%yL6x?2UE@Ux zzmg(%e-deoChfh-$MpK(XwtK)=dYu@Sqg9lxx^+GH(Ek^rfAMN;_P>`(lsP8N{>ND zK@}N{8=SqeKkipT&}ept;CiuD4k>_p0v5w+i@~DM^1A4;l{=4 zW5#4Ol4~R?S6*KyS~>>L+}`gvyq&2RVsI#hs4NpqDs1@PGY_eb)&Tm2wxGWdGd39N zUM0&5R(GqIYxLH4t)uK{{wpABKBtc{N5T$0+Z%Dpxe|>LrKUhuce+4EZ4WdeB|~5g z7sc9ZRmZ+>%)4()Fz&mQsHX??BQ6HP6gwfqTC?d0bf9v!LUPv5Tu%j6`b~>UA`*bN z^>$;p-&Yoe_O@_V0D(Zgc_PeB;PUM14gv2&BR z&W~m9qAE=3RUa#v-iPN}*j*w%@y#3aU0kKWmvJowFkZzN;#$q{2lxsu&ciB)t=#oV z!92zYTcxc@uH{|@i~U&r#gZ!z`HpNGMS3J)RHH%r_&ws!TOG)g>?}sVu~IPtC~yl@BPCJ6fRJy z7q*RXf!VVbPl2I{fqKhv)#So!JoBVk)v7Z0(p7~V-JKd@MxrGl0X2e|sD>^rybgo( z%Z*kS9Jb1PW8z$Co_&+sSE2wkv_?buEqz)Ysq)ven>8sB>1w9mjC}O##El?yF~nO_ zu$tQIko6_&-ySn~@F%<6+wJuQOfEQ#BW|A(7Wk7gG$*DBkrp(@F>_jv`_T8;;>5RdY0^F@^!G|5y>9b1Li8*d$W%QGW@MNWr zNh%zJz+88^b(Dg*aCL#$y@ec27l{*MtT16<^C~tDN?IYe9WQXhGv}ZQ9rBmIvfn7G zgFBM7SOhgW9w7nj-*p*FdGc+`iD%q@0ft+15_|B3xyOs-6(}FamL8E5wvm8~7X_mx zVk^n!WJoEPwFrfMUG5jGKr81q4Eg7@#LuR}Ip0Knt1d{N%^CPXGzbZ!K|-@=&BB0d z#HjJv|HL5{*AMn?F;l&$!T+g=>-%_0qJmGvs3rRnaC?Rsmh1!-yxd#*@%5B!e7PnQ zLz5}EJUnPa=xYY#ABXGB3PS0rLGLKaKU+nwde?h%w6a-@e!vTpz3EGk(g$mcvyt#$ z9*2}N*7-KSK>jUbxFwY>BCwh$)jt98KL@D-uc<(hqlcM>jd#`>HrXiwS?!g4><*#G z#$N_tcmgZ@eSseI79t$w<0g3*ori(2&@qkW?AQ@|Cp!zo=%k_Q z`Ax9=$J70`ZC-skp27^X&MVdwK9=9DabyhGZ`O=9`x$%aN$|FQ1b+`L( z1T{s7w`%48&+Ia|Oq`GKe+P=+aQ=+?{DC(UdV?zPlejPhIaok~mhiuaWB;uGgGCGW zlOQAdcSa8YK>M@!2LG(Ly#u#OkQ4p)MA5$pJlNnH2@0Zr=Vt(bcmMhS|D#}q1Ll;Z zd`lIu#ecmmD8C)_ZAAA!@Xr?CZ~*|*KMKhTMw7!P`g_LX{~|8ny-j>D5dGbf{=W!1 zL~jjhS;!U=uz(aT;lEu+0D$%%wEy|2@8B6JLhuG88n{>ro#^kD(f_4qP4PbsBqE}J zTP6Si$zQ}uD8VmeWMDiQbfW(*FaN>&=NrG$fSsi|i2k?2`NjmCzo^*JfxD#Xi2g0$ z{VVc+C=AkrH)(MGY(w(jrJ;YfDPRNu{!=JQmtlYmWCd4oFo4hA4)*WO`p?|VKkyIP zJ2tSHEcV+_J2uh33G06&EpWdfF%bT*e}2286Z}Qx9k^JQ8LS|Tj{NUg5`@5Fawd>q zVQ{XT;6MI{O&$j_Q3R|nN)0BGM~C^x7i`L5Lxzch+r+5B4)XA*1aG93-~fPau|K5# EKh~+fj{pDw From 93b8a80fa942f6e678d21eb5f2c2ffe6897ded6a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 20:59:10 +0600 Subject: [PATCH 198/794] Fix parsed formula binary writing --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp | 4 ++++ MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h | 1 + 2 files changed, 5 insertions(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp index ebf02c69898..48691468f28 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.cpp @@ -57,6 +57,10 @@ void PtgErr::loadFields(CFRecord& record) record >> err; } +void PtgErr::writeFields(CFRecord& record) +{ + record << err; +} void PtgErr::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h index b83569a1a65..4abd32527d4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgErr.h @@ -49,6 +49,7 @@ class PtgErr: public OperandPtg virtual void loadFields(CFRecord& record); + void writeFields(CFRecord& record) override; virtual void assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref = false); From af7d46dbf7d3eba354e37068d8c76a1e473d5ff7 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 20:59:59 +0600 Subject: [PATCH 199/794] Remove rgce check --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 424486d3844..3c288b63795 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -149,12 +149,6 @@ namespace OOX else if(separatorPos == ref.size() -1) ref = L""; ptr->rgce = ref; - if(m_oRef.get() == L"#N/A") - { - ptr->rgce.rgce.sequence.at(0)->offset_in_record = 35; - ptr->rgce.rgce.sequence.at(0)->size_of_struct = 2; - ptr->rgce.rgce.cce = 2; - } } ptr->fCalcExp = true; ptr->fBuiltin = false; From f3b23b3b47353e5070a006bac7cd780fabad5646 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 21:05:51 +0600 Subject: [PATCH 200/794] Change example file --- .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 12641 -> 12642 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index e7a64a5c9e768a2878e8f260479c95fa399e5f18..4bb6fc68be94154aaf51e2c8200aaf8049bf9ffe 100644 GIT binary patch delta 366 zcmaEu^eAb=bRN#a&WUqZGcYhnOb=cjJqcoj?^E$aNx{^ zBRpn&iAy&-@b2VgS-c}dVDeunKbC%7p}5Wd(u>(y98xb7ZT_Yt#>nb@M2&O(WATW8m8nUBTO|CTvV_Z4; Yia`L=9F57_HB={i8w#*7Xn~9Z0QppGQ~&?~ delta 356 zcmaEq^e}0|bRNzv^G;Z-Vqjp9oVd9|(LKsUYJL(29osyjVTvB0jhn|2m$SF2JC9XiM096X1UQfQS z>&uurSy#`Q@$}?EJx9i>$(!{Y7{e!j(Fm)l3@e!!7$i`P zcrtl{zAK~FCFwNGOyhB5E NvX7wv+kZ`vBmf@^aQy%P From 6298d21b5ae667467e40d5c53c3030f232b5ca17 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Dec 2023 21:43:18 +0600 Subject: [PATCH 201/794] Fix worksheet conversion --- OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp | 12 +++++ .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 12642 -> 12640 bytes OOXML/test/xlsx2xlsb/conversion.cpp | 41 ++++++++++++------ 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp index 964b005267a..ceb34ce64e8 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCacheExt.cpp @@ -945,6 +945,12 @@ XLS::BaseObjectPtr CSlicerRefs::toBin() { auto ptr(new XLSB::SLICERSEX); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; for(auto i:m_oSlicer) { @@ -956,6 +962,12 @@ XLS::BaseObjectPtr CSlicerRefs::toBinTable() { auto ptr(new XLSB::TABLESLICERSEX); XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::FRTBegin); + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr1->productVersion = version; for(auto i:m_oSlicer) { diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index 4bb6fc68be94154aaf51e2c8200aaf8049bf9ffe..0f0f857c698240aae2a0eaac2ad0efb54b2e77b6 100644 GIT binary patch delta 182 zcmaEq^dM=&FDaH4w$C~y|C92Sn%1%Qb?q~*4@^IKdIEH;{2Lrw6Q$V?i}A5-PL=Ls zXFbxCGna4k4<%7Xg^u$Z<~Ap)v$t{T1hl5{?6#07D==7LU}9**z!2cg%rbeSzSL$< zm1<6~>6=gJu4RO1pIoIM&8Ru~n!Y>JBGt(UR81zYG7y-&Lrs920SFjD1jCBSbp~OK a%O_to2w<9}F?olE>SP~70k(gdAV~mVFXZ zSshX@6bWqpp(M(vl=0NyV?)c^nh diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 91abd48c286..ab3803c8c37 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -204,44 +204,57 @@ TEST_F(XlsbSimpleTests2, WorkbookTest) ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -/* -TEST_F(SimpleTests2, StylesTest) + +TEST_F(XlsbSimpleTests2, StylesTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, SharedStringsTest) { - auto tempDir = SimpleTests2::tempDir; + auto tempDir = XlsbSimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"styles.xml"); + FILE_SEPARATOR_STR + L"sharedStrings.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"styles.xml"); + FILE_SEPARATOR_STR + L"sharedStrings.bin"); std::vector fileContent; std::vector exampleContent; ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests2, SharedStringsTest) +TEST_F(XlsbSimpleTests2, Worksheet1Test) { - auto tempDir = SimpleTests2::tempDir; + auto tempDir = XlsbSimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"sharedStrings.xml"); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"sharedStrings.xml"); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); std::vector fileContent; std::vector exampleContent; ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -TEST_F(SimpleTests2, WorksheetsTest) +TEST_F(XlsbSimpleTests2, Worksheet2Test) { - auto tempDir = SimpleTests2::tempDir; + auto tempDir = XlsbSimpleTests2::tempDir; std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + - FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); std::vector fileContent; std::vector exampleContent; ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } -*/ + } \ No newline at end of file From e4031da0ba0162b74e16e4ef4b3943826f491dbb Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Dec 2023 14:24:13 +0600 Subject: [PATCH 202/794] Add comments and tables test --- OOXML/test/xlsx2xlsb/conversion.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index ab3803c8c37..2f493726dd1 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -257,4 +257,29 @@ TEST_F(XlsbSimpleTests2, Worksheet2Test) ASSERT_EQ(fileContent, exampleContent); } +TEST_F(XlsbSimpleTests2, CommentsTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"comments2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"comments2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, TablesTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"tables" + FILE_SEPARATOR_STR + L"table2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"tables" + FILE_SEPARATOR_STR + L"table2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} } \ No newline at end of file From 92312df5ad12d20f4cedefa73ef09d72b32d8f88 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Dec 2023 20:57:20 +0600 Subject: [PATCH 203/794] Add slicer tests --- OOXML/test/xlsx2xlsb/conversion.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 2f493726dd1..51c32c74743 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -282,4 +282,31 @@ TEST_F(XlsbSimpleTests2, TablesTest) ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); ASSERT_EQ(fileContent, exampleContent); } + +TEST_F(XlsbSimpleTests2, SlicerTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicers" + FILE_SEPARATOR_STR + L"slicer2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicers" + FILE_SEPARATOR_STR + L"slicer2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, SlicerCacheTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicerCaches" + FILE_SEPARATOR_STR + L"slicerCache2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"slicerCaches" + FILE_SEPARATOR_STR + L"slicerCache2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + } \ No newline at end of file From 5c7f07f71d73dcd3cb6c42b438eba61c4d31f918 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Dec 2023 20:57:56 +0600 Subject: [PATCH 204/794] Fix frtslicercache conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 26 +++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/Borders.cpp | 1 + 2 files changed, 27 insertions(+) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 041ce8784f1..f9a1415e407 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -771,6 +771,16 @@ namespace OOX ptr->m_SLICERCACHEBOOKPIVOTTABLES = XLS::BaseObjectPtr{ptr1}; auto ptr2(new XLSB::SlicerCacheBookPivotTables); ptr1->m_BrtSlicerCacheBookPivotTables = XLS::BaseObjectPtr{ptr2}; + + auto ptr3(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr3}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr3->productVersion = version; + + + for(auto j:i->m_oSlicerCachePivotTables) { XLSB::SlicerCachePivotTable table; @@ -781,12 +791,28 @@ namespace OOX if(i->m_sUri == L"{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}") { auto ptr1(new XLSB::TABLESLICERCACHE); + + auto ptr2(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr2}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr2->productVersion = version; + ptr->m_TABLESLICERCACHE = XLS::BaseObjectPtr{ptr1}; ptr1->m_BrtBeginTableSlicerCache = i->m_oTableSlicerCache->toBin(); } if(i->m_sUri == L"{470722E0-AACD-4C17-9CDC-17EF765DBC7E}") { auto ptr1(new XLSB::SLICERCACHECROSSFILTEREXT); + + auto ptr2(new XLSB::FRTBegin); + ptr1->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr2}; + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0; + ptr2->productVersion = version; + ptr->m_SLICERCACHECROSSFILTEREXT = XLS::BaseObjectPtr{ptr1}; ptr1->m_BrtSlicerCacheHideItemsWithNoData = i->m_oSlicerCacheHideItemsWithNoData->toBin(); } diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 11548d478e5..0089e7a5350 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -148,6 +148,7 @@ namespace OOX col.xColorType = 0; col.nTintAndShade = 0; col.index = 0; + col.fValidRGB = true; ptr->brtColor = col; } From daba967cdc4c407946bd8e7622655d57f71248a9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 7 Dec 2023 21:10:08 +0600 Subject: [PATCH 205/794] Add pivot tables tests --- .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 12640 -> 12640 bytes OOXML/test/xlsx2xlsb/conversion.cpp | 39 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index 0f0f857c698240aae2a0eaac2ad0efb54b2e77b6..ba7c4c50e3e30eb82c61d417b4c199c3d80b29eb 100644 GIT binary patch delta 58 zcmaEm^dM=&FDVwK!WC~O|C92S5=*ONYum}R$H9(SS)}`%a6&-hjbjHlv^FztPL+-o M0xR5nOm`MD0QLqL-~a#s delta 58 zcmaEm^dM=&FDaH4w$C~y|C92Sn%1%Qb?q~*4@^IKdIEH;{2Lrw6Q$V?i}A5-PL+-o M0xR5nOm`MD05SU+PXGV_ diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 51c32c74743..9469cc50603 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -309,4 +309,43 @@ TEST_F(XlsbSimpleTests2, SlicerCacheTest) ASSERT_EQ(fileContent, exampleContent); } +TEST_F(XlsbSimpleTests2, PivotTableTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotTables" + FILE_SEPARATOR_STR + L"pivotTable2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotTables" + FILE_SEPARATOR_STR + L"pivotTable2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, PivotCacheDefTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheDefinition2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheDefinition2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbSimpleTests2, PivotCacheRecordsTest) +{ + auto tempDir = XlsbSimpleTests2::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheRecords2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"pivotCache" + FILE_SEPARATOR_STR + L"pivotCacheRecords2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + } \ No newline at end of file From bea162aef90e953b0fcbfff2239056f8b50fe61c Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 11 Dec 2023 00:25:17 +0300 Subject: [PATCH 206/794] BuildParagraphes update (in progress) --- DocxRenderer/src/logic/Page.cpp | 476 +++++++----------- DocxRenderer/src/logic/Page.h | 4 +- DocxRenderer/src/logic/elements/ContText.cpp | 3 +- DocxRenderer/src/logic/elements/ContText.h | 2 + DocxRenderer/src/logic/elements/Paragraph.cpp | 131 +---- DocxRenderer/src/logic/elements/Paragraph.h | 13 +- .../logic/managers/ParagraphStyleManager.cpp | 2 +- 7 files changed, 198 insertions(+), 433 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 58f894aae3e..aeb5e476978 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -332,7 +332,7 @@ namespace NSDocxRenderer _h = m_pFontManager->GetFontHeight(); pCont->m_dBaselinePos = dBaseLinePos; - pCont->m_dTop = pCont->m_dBaselinePos - _h - oMetrics.dBaselineOffset; + pCont->m_dTop = pCont->m_dBaselinePos - _h; pCont->m_dHeight = pCont->m_dBaselinePos - pCont->m_dTop; pCont->m_dLeft = dTextX; @@ -434,8 +434,8 @@ namespace NSDocxRenderer } void CPage::BuildTextLines() { - using cont_ptr = std::shared_ptr; - std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { + using cont_ptr_t = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr_t& a, const cont_ptr_t& b) { if(!a) return false; if(!b) return true; @@ -1154,351 +1154,243 @@ namespace NSDocxRenderer } void CPage::BuildParagraphes() { - std::shared_ptr pCurrLine, pNextLine, pNextNextLine, pPrevLine; - double dCurrBeforeSpacing = 0, dNextBeforeSpacing = 0, dPrevBeforeSpacing = 0; - double dBeforeSpacingWithShapes = 0; - - //note Все параграфы были сдвинуты на данное значение от верхнего края страницы - double dPreviousStringBaseline = c_dCORRECTION_FOR_FIRST_PARAGRAPH; - eVerticalCrossingType eCrossingType; - - bool bIf1, bIf2, bIf3, bIf4, bIf5, bIf6, bIf7; - bool bIsNeedParagraphToShape = m_eTextAssociationType == TextAssociationType::tatParagraphToShape; - - size_t nIndexForCheking = c_nAntiZero; - - double avg_height = 0; - size_t n = 0; - - for (size_t nIndex = 0; nIndex < m_arTextLines.size(); ++nIndex) + auto no_crossing = [] (const eHorizontalCrossingType& h_type, const eVerticalCrossingType& v_type) { + return h_type == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + h_type == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext || + v_type == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + v_type == eVerticalCrossingType::vctNoCrossingCurrentBelowNext; + }; + + // линии из которых сделаем шейпы + for (size_t index = 0; index < m_arTextLines.size(); ++index) { - pCurrLine = m_arTextLines[nIndex]; - if (!pCurrLine) + auto& curr_line = m_arTextLines[index]; + if (!curr_line) continue; - avg_height = (avg_height / (n + 1)) * n + (pCurrLine->m_dHeight / (n + 1)); + // 1 строчка в параграфе if (m_eTextAssociationType == TextAssociationType::tatShapeLine) { - CreateSingleLineShape(pCurrLine); + CreateSingleLineShape(curr_line); continue; } - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight - dPreviousStringBaseline; - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - - //Если у текущей линии есть дубликаты, то создаем из них шейпы - if (pCurrLine->m_iNumDuplicates > 0) + // если у текущей линии есть дубликаты, то создаем из них шейпы + if (curr_line->m_iNumDuplicates > 0) { - dBeforeSpacingWithShapes += dCurrBeforeSpacing + pCurrLine->m_dHeight; - - auto iNumDuplicates = pCurrLine->m_iNumDuplicates; - CreateSingleLineShape(pCurrLine); - while (iNumDuplicates > 0) + size_t duplicates = curr_line->m_iNumDuplicates; + CreateSingleLineShape(curr_line); + while (duplicates > 0) { - CreateSingleLineShape(pCurrLine); - iNumDuplicates--; + CreateSingleLineShape(curr_line); + duplicates--; } continue; } - if (m_eTextAssociationType == TextAssociationType::tatPlainLine) - { - CreateSingleLineParagraph(pCurrLine, m_dWidth, dCurrBeforeSpacing); - continue; - } - - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); - if (bIsNeedParagraphToShape) + // если линия пересекается с другим шейпом + bool next = false; + for (auto& shape : m_arShapes) { - pPrevLine = GetPrevTextLine(nIndex); - } + if (!shape) + continue; - //Если две линии пересекаются, то создаем из них шейпы - if (pNextLine) - { - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); - bool bIsPassed = false; - double dCurrentAdditive = 0.0; + auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); + auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); - switch (eCrossingType) + if (!no_crossing(h_type, v_type)) { - case eVerticalCrossingType::vctCurrentInsideNext: - case eVerticalCrossingType::vctCurrentBelowNext: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight + pNextLine->m_dBaselinePos - pCurrLine->m_dBaselinePos; - dPreviousStringBaseline = pNextLine->m_dBaselinePos; - bIsPassed = true; - break; - case eVerticalCrossingType::vctCurrentOutsideNext: - case eVerticalCrossingType::vctCurrentAboveNext: - case eVerticalCrossingType::vctDublicate: - dCurrentAdditive = dCurrBeforeSpacing + pCurrLine->m_dHeight; - bIsPassed = true; - break; - default: + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + curr_line = nullptr; + next = true; break; } + } + if (next) + continue; - if (bIsPassed) - { - CreateSingleLineShape(pCurrLine); - CreateSingleLineShape(pNextLine); + // если линия пересекается с предыдущей линией + if (index && m_arTextLines[index - 1]) + { + auto& prev_line = m_arTextLines[index - 1]; - dBeforeSpacingWithShapes += dCurrentAdditive; + if (!prev_line) + continue; + + auto h_type = curr_line->GetHorizontalCrossingType(prev_line.get()); + auto v_type = curr_line->GetVerticalCrossingType(prev_line.get()); - nIndex++; + if (!no_crossing(h_type, v_type)) + { + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + prev_line = nullptr; + curr_line = nullptr; continue; } } + } - dCurrBeforeSpacing += dBeforeSpacingWithShapes; - dBeforeSpacingWithShapes = 0; + if(m_arTextLines.empty()) + return; - bool bIsSingleLineParagraph = false; + // переметим nullptr в конец и удалим + auto&& left = m_arTextLines.begin(), right = m_arTextLines.end() - 1; + for (;;) + { + while (!*right && left < right) right--; + while (*left && left < right) left++; + if (left >= right) break; + std::swap(left, right); + } + if (*right) + ++right; + if (right != m_arTextLines.end()) + m_arTextLines.erase(right, m_arTextLines.end()); - //Логика определения параметров для DetermineTextAlignmentType - if (pNextLine) - { - dNextBeforeSpacing = pNextLine->m_dBaselinePos - pNextLine->m_dHeight - dPreviousStringBaseline; - //dNextBeforeSpacing = pNextLine->CalculateBeforeSpacing(dPreviousStringBaseline); - - //Высота строк должна быть примерно одинаковой - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; - //расстрояние между строк тоже одинаково - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - //или - bIf3 = dCurrBeforeSpacing > dNextBeforeSpacing; - //нет отступа - bIf4 = fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - //есть отступ - bIf5 = pCurrLine->m_dLeft > pNextLine->m_dLeft; - //совпадают правые границы - bIf6 = fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - size_t nNextIndex = nIndex+1; - pNextNextLine = GetNextTextLine(nNextIndex); - - bIf7 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH) && - (pNextNextLine ? pCurrLine->m_dWidth > pNextNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH : true); - - if (pNextNextLine) - { - //double dNextNextBeforeSpacing = pNextNextLine->CalculateBeforeSpacing(pNextLine->m_dBaselinePos); - double dNextNextBeforeSpacing = pNextNextLine->m_dBaselinePos - pNextNextLine->m_dHeight - dPreviousStringBaseline; - if (bIf1 && (bIf2 || bIf3)) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM) - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) >= c_dTHE_SAME_STRING_Y_PRECISION_MM) - pNextNextLine = nullptr; - } - else - { - if (fabs(pNextLine->m_dHeight - pNextNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - { - if (fabs(dNextBeforeSpacing - dNextNextBeforeSpacing) < c_dTHE_SAME_STRING_Y_PRECISION_MM) - pNextNextLine = nullptr; - else - bIsSingleLineParagraph = true; - } - else - pNextNextLine = nullptr; - } - } - } - } + // todo обработать все TextAssociationType + // параграф будет набиваться строчками + auto paragraph = std::make_shared(); - bool bIsUseNextNextLine = true; - CParagraph::TextAlignmentType eTextAlignmentType = CParagraph::DetermineTextAlignmentType( - pCurrLine, pNextLine, pNextNextLine, m_dWidth, bIsUseNextNextLine, bIsSingleLineParagraph); + // после переместим все в output objects + std::vector> ar_paragraphs; - auto pParagraph = std::make_shared(); + double avg_spacing{0.0}; + size_t avg_spacing_n{0}; - pParagraph->m_dLineHeight = avg_height; - avg_height = 0; - n = 0; + double min_left{m_dWidth}; + double max_right{0.0}; - pParagraph->m_eTextAlignmentType = eTextAlignmentType; + // ar_spacing[index]- расстояние строки до строки снизу + // если 0.0 - строка последняя + std::vector ar_spacings(m_arTextLines.size(), 0.0); - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3)) - { - pParagraph->m_dLeft = std::min(pCurrLine->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pCurrLine->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - if (pParagraph->m_eTextAlignmentType != CParagraph::tatByCenter) - { - pParagraph->m_bIsNeedFirstLineIndent = pCurrLine->m_dLeft > pNextLine->m_dLeft ? true : false; - pParagraph->m_dFirstLine = pCurrLine->m_dLeft - pNextLine->m_dLeft; - } - } - else - { - pParagraph->m_dLeft = pCurrLine->m_dLeft; - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = pCurrLine->m_dRight; - pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pCurrLine->m_dWidth; - - pParagraph->m_bIsNeedFirstLineIndent = false; - pParagraph->m_dFirstLine = 0; - } - pParagraph->m_dTop = pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight; - pParagraph->m_dBaselinePos = pCurrLine->m_dBaselinePos; - pParagraph->m_dHeight = pCurrLine->m_dHeight; + // совпадает ли left, right, center со строкой ниже + struct Position { + bool left{false}; + bool center{false}; + bool right {false}; + }; + std::vector ar_positions(m_arTextLines.size()); - //размер строк во всем параграфе - // pParagraph->m_dLineHeight = avg_height; //pCurrLine->m_dHeight; - pParagraph->m_dSpaceBefore = std::max(dCurrBeforeSpacing, 0.0); + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф + std::vector ar_delims(m_arTextLines.size()); - pParagraph->m_arLines.push_back(pCurrLine); - pParagraph->m_nNumLines++; + // calcs spacings & positions + for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) + { + ar_spacings[index] = m_arTextLines[index + 1]->m_dTopWithMaxAscent - m_arTextLines[index]->m_dBotWithMaxDescent; + avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); - if (pNextLine && !bIsSingleLineParagraph && bIf1 && (bIf2 || bIf3) && (bIf4 || bIf5 || bIf6) && bIf7) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; + auto& left_curr = m_arTextLines[index]->m_dLeft; + auto& left_next = m_arTextLines[index + 1]->m_dLeft; - if (pCurrLine->IsShadingPresent(pNextLine.get())) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - } + auto& right_curr = m_arTextLines[index]->m_dRight; + auto& right_next = m_arTextLines[index + 1]->m_dRight; - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + auto center_curr = (m_arTextLines[index]->m_dRight - m_arTextLines[index]->m_dLeft) / 2; + auto center_next = (m_arTextLines[index + 1]->m_dRight - m_arTextLines[index + 1]->m_dLeft) / 2; - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - double dCorrectionBeforeSpacing = dCurrBeforeSpacing; + if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) + ar_positions[index].center = true; + if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].left = true; + if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].right = true; + } - if (bIsUseNextNextLine) - { - if (pNextLine) - { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } + // spacing check + for (size_t index = 0; index < ar_spacings.size(); ++index) + { + double spacing_top = 0.0; + double spacing_bot = 0.0; - //проверим, подходят ли следующие строчки для текущего pParagraph - while(pNextLine && bIf1 && bIf2 && bIf3 && bIf4 && bIf5) - { - pParagraph->m_arLines.push_back(pNextLine); - pParagraph->m_nNumLines++; + if (index != 0) spacing_top = ar_spacings[index - 1]; + spacing_bot = ar_spacings[index]; - pParagraph->m_dLeft = std::min(pParagraph->m_dLeft, pNextLine->m_dLeft); - pParagraph->m_dLeftBorder = pParagraph->m_dLeft; - pParagraph->m_dRight = std::max(pParagraph->m_dRight, pNextLine->m_dRight); - pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; - pParagraph->m_dWidth = pParagraph->m_dRight - pParagraph->m_dLeft; - pParagraph->m_dBaselinePos = pNextLine->m_dBaselinePos; + if (spacing_top == 0.0) spacing_top = spacing_bot; + if (spacing_bot == 0.0) spacing_bot = spacing_top; - if (!pCurrLine->IsShadingPresent(pNextLine.get())) - { - pParagraph->m_bIsShadingPresent = false; - pParagraph->m_lColorOfShadingFill = c_iWhiteColor; - } + if (fabs(spacing_top - spacing_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM * 3) + ar_delims[index] = false; + else if (spacing_top > spacing_bot) + ar_delims[index - 1] = true; + else if (spacing_top < spacing_bot) + ar_delims[index] = true; + } - //сдвигаем рабочую точку - nIndex++; - pCurrLine = pNextLine; - pNextLine = GetNextTextLine(nIndex, &nIndexForCheking); + // alignment check + for (size_t index = 1; index < ar_positions.size() - 1; ++index) + { + Position position_top; + Position position_bot; - dPrevBeforeSpacing = dCurrBeforeSpacing; - dCurrBeforeSpacing = (pCurrLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline); - dPreviousStringBaseline = pCurrLine->m_dBaselinePos; - dCorrectionBeforeSpacing = (dCorrectionBeforeSpacing + dCurrBeforeSpacing) / 2; //наверное лучше так... текст может быть уже, чем в оригинале + position_bot = ar_positions[index]; + position_top = ar_positions[index - 1]; - if (pNextLine) - { - dNextBeforeSpacing = (pNextLine->m_dBaselinePos - pCurrLine->m_dHeight) - dPreviousStringBaseline; //pCurrLine->CalculateBeforeSpacing(dPreviousStringBaseline);; - eCrossingType = pCurrLine->GetVerticalCrossingType(pNextLine.get()); - - bIf1 = fabs(pCurrLine->m_dHeight - pNextLine->m_dHeight) < c_dTHE_SAME_STRING_Y_PRECISION_MM; //высота строк должна быть примерно одинаковой - bIf2 = fabs(dCurrBeforeSpacing - dNextBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; //расстрояние между строк тоже одинаково - bIf3 = (eCrossingType == eVerticalCrossingType::vctUnknown || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || - eCrossingType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); - bIf4 = ((pParagraph->m_eTextAlignmentType == CParagraph::tatByLeftEdge && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByWidth && fabs(pCurrLine->m_dLeft - pNextLine->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM && (fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM || pCurrLine->m_dRight > pNextLine->m_dRight)) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByRightEdge && fabs(pCurrLine->m_dRight - pNextLine->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) || - (pParagraph->m_eTextAlignmentType == CParagraph::tatByCenter)); - bIf5 = (pCurrLine->m_dWidth > pNextLine->m_dWidth * c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH); - } - } - } + bool is_good = position_top.left == position_bot.left || position_top.right == position_bot.right || position_top.center == position_bot.center; + bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); - if (eCrossingType != eVerticalCrossingType::vctUnknown && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentAboveNext && - eCrossingType != eVerticalCrossingType::vctNoCrossingCurrentBelowNext) - { - CreateSingleLineShape(pNextLine); - nIndex++; - } + if (!is_good || is_unknown) + ar_delims[index - 1] = true; + } - //коррекция - pParagraph->m_dLineHeight += dCorrectionBeforeSpacing; - pParagraph->m_dSpaceBefore = fabs(pParagraph->m_dSpaceBefore - dCorrectionBeforeSpacing); + // lamda to setup and add paragpraph + auto add_paragraph = [&] () { - pParagraph->RemoveHighlightColor(); - pParagraph->MergeLines(); - } - else - { - if (pCurrLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pCurrLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - } + paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; + paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; + paragraph->m_dRight = max_right; + paragraph->m_dLeft = min_left; - if (bIsNeedParagraphToShape) - { - bool bIsSameTypeText = pPrevLine && fabs(dPrevBeforeSpacing - dCurrBeforeSpacing) < c_dLINE_DISTANCE_ERROR_MM; - CreateShapeFormParagraphs(pParagraph, bIsSameTypeText); - } + paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; + paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; + + paragraph->m_dRightBorder = m_dWidth - max_right; + paragraph->m_dLeftBorder = min_left; + + paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); + paragraph->m_bIsNeedFirstLineIndent = false; + paragraph->m_dFirstLine = 0; + paragraph->MergeLines(); + + if (ar_paragraphs.empty()) + paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; else - { - pParagraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*pParagraph); - m_arOutputObjects.push_back(pParagraph); - } + paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; - if (nIndexForCheking != c_nAntiZero) - { - nIndex = nIndexForCheking - 1; - nIndexForCheking = c_nAntiZero; - } - } + ar_paragraphs.push_back(std::move(paragraph)); + paragraph = std::make_shared(); + + min_left = m_dWidth; + max_right = 0.0; + }; - if (bIsNeedParagraphToShape) + // lamda to add line and setup min_left/max_right + auto add_line = [&min_left, &max_right, ¶graph] (std::shared_ptr& curr_line) { + min_left = std::min(min_left, curr_line->m_dLeft); + max_right = std::max(max_right, curr_line->m_dRight); + paragraph->m_arLines.push_back(curr_line); + }; + + // на основе ar_delims разбиваем на параграфы + for (size_t index = 0; index < ar_delims.size(); ++index) { - CorrectionObjectesInShapes(m_dWidth); + add_line(m_arTextLines[index]); + if (ar_delims[index] || index == ar_delims.size() - 1) + add_paragraph(); } - using output_ptr = std::shared_ptr; - std::sort(m_arOutputObjects.begin(), m_arOutputObjects.end(), [] (const output_ptr& a, const output_ptr& b) { + using paragraph_ptr_t = std::shared_ptr; + std::sort(ar_paragraphs.begin(), ar_paragraphs.end(), [] (const paragraph_ptr_t& a, const paragraph_ptr_t& b) { return a->m_dBaselinePos < b->m_dBaselinePos; }); + + for(auto&& p : ar_paragraphs) + m_arOutputObjects.push_back(std::move(p)); } - void CPage::CreateSingleLineParagraph(std::shared_ptr pLine, double dPageWidth, double pBeforeSpacing) + void CPage::CreateSingleLineParagraph(std::shared_ptr pLine, double pBeforeSpacing) { auto pParagraph = std::make_shared(); pParagraph->m_arLines.push_back(pLine); @@ -1507,7 +1399,7 @@ namespace NSDocxRenderer pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; pParagraph->m_dFirstLine = 0; pParagraph->m_dRight = pLine->m_dRight; - pParagraph->m_dRightBorder = dPageWidth - pParagraph->m_dRight; + pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; pParagraph->m_dWidth = pLine->m_dWidth; pParagraph->m_dHeight = pLine->m_dHeight; if (pBeforeSpacing < 0) @@ -1527,7 +1419,7 @@ namespace NSDocxRenderer m_arOutputObjects.push_back(std::dynamic_pointer_cast(pParagraph)); } - void CPage::CreateSingleLineShape(std::shared_ptr pLine) + std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr pLine) { auto pParagraph = std::make_shared(); @@ -1550,7 +1442,7 @@ namespace NSDocxRenderer pShape->m_dHeight = pLine->m_dHeight; pShape->m_bIsBehindDoc = false; - m_arOutputObjects.push_back(pShape); + return pShape; } void CPage::CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText) @@ -1574,13 +1466,13 @@ namespace NSDocxRenderer if (bIsSameTypeText && bIsShapesPresent) { pShape = pBackShape; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines + pParagraph->m_dSpaceBefore; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_arLines.size() + pParagraph->m_dSpaceBefore; } else { pShape = std::make_shared(); pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_nNumLines; + pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_arLines.size(); } pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; @@ -1629,7 +1521,7 @@ namespace NSDocxRenderer { auto pParagraph = std::dynamic_pointer_cast(m_arOutputObjects[i]); - if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_nNumLines == 1) + if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_arLines.size() == 1) { pParagraph->m_bIsNeedFirstLineIndent = true; pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 942b71b6bc9..8b95c05b7da 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -113,8 +113,8 @@ namespace NSDocxRenderer void BuildParagraphes(); - void CreateSingleLineParagraph(std::shared_ptr pLine, double dPageWidth, double pBeforeSpacing); - void CreateSingleLineShape(std::shared_ptr pLine); + void CreateSingleLineParagraph(std::shared_ptr pLine, double pBeforeSpacing); + std::shared_ptr CreateSingleLineShape(std::shared_ptr pLine); void CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText); void CorrectionObjectesInShapes(double dPageWidth); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 2dcd62c418b..cfad18b5d7d 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -167,7 +167,7 @@ namespace NSDocxRenderer } //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 2; + lCalculatedSpacing -= 1; if (lCalculatedSpacing != 0) { @@ -244,6 +244,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); oWriter.WriteString(L""); + if (m_bIsAddBrEnd) oWriter.WriteString(L""); oWriter.WriteString(L""); } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 23531b73036..1bd6283e500 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -69,6 +69,8 @@ namespace NSDocxRenderer NSStringUtils::CStringUTF32 m_oText{}; UINT m_iNumDuplicates{0}; + bool m_bIsAddBrEnd{false}; + CContText() = default; CContText(CFontManager* pManager) : m_pManager(pManager) {} CContText(const CContText& rCont); diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 29e46d7d4e5..92741016ae7 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -72,13 +72,13 @@ namespace NSDocxRenderer case tatByCenter: oWriter.WriteString(L""); break; - case tatByRightEdge: + case tatByRight: oWriter.WriteString(L""); break; case tatByWidth: oWriter.WriteString(L""); break; - case tatByLeftEdge: + case tatByLeft: oWriter.WriteString(L""); break; case tatUnknown: @@ -125,7 +125,7 @@ namespace NSDocxRenderer void CParagraph::MergeLines() { - for(size_t i = 0; i < m_arLines.size(); ++i) + for(size_t i = 0; i < m_arLines.size() - 1; ++i) { auto pLine = m_arLines[i]; auto pLastCont = pLine->m_arConts.back(); @@ -134,129 +134,8 @@ namespace NSDocxRenderer while(!pLastCont) pLastCont = pLine->m_arConts[--iNumConts]; - //Добавляем пробел в конец каждой строки - pLastCont->m_oText += L" "; - pLastCont->m_dWidth += pLastCont->m_oSelectedSizes.dSpaceWidth; + // добавляем br в конец каждой строки + pLastCont->m_bIsAddBrEnd = true; } } - - CParagraph::TextAlignmentType CParagraph::DetermineTextAlignmentType(std::shared_ptr pCurrentLine, - std::shared_ptr pNextLine, - std::shared_ptr pNextNextLine, - double dPageWidth, - bool &bIsUseNextNextLine, - bool &bIsSingleLineParagraph) noexcept - { - // поменять логику - if (!pCurrentLine || !pNextLine) - return tatUnknown; - - double dCurrLeft = pCurrentLine->m_dLeft; - double dNextLeft = pNextLine->m_dLeft; - double dNextNextLeft = pNextNextLine ? pNextNextLine->m_dLeft : 0; - - double dCurrRight = pCurrentLine->m_dRight; - double dNextRight = pNextLine->m_dRight; - double dNextNextRight = pNextNextLine ? pNextNextLine->m_dRight : 0; - - bool bIf1 = fabs(dCurrLeft - dNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf2 = pNextNextLine && fabs(dNextLeft - dNextNextLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf3 = dCurrLeft != dNextLeft && dCurrLeft > dNextLeft; - - bool bIf4 = fabs(dCurrRight - dNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - bool bIf5 = fabs(dNextRight - dNextNextRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - bool bIf6 = fabs(dCurrLeft + pCurrentLine->m_dWidth/2 - dNextLeft - pNextLine->m_dWidth/2) < 0.5; - bool bIf7 = pNextNextLine && fabs(dNextLeft + pNextLine->m_dWidth/2 - dNextNextLeft - pNextNextLine->m_dWidth/2) < 0.5; - - if (pNextNextLine) - { - if (bIf1 && bIf2) - { - if (bIf4) - { - return tatByWidth; - } - else - { - return tatByLeftEdge; - } - } - else if (bIf3 && bIf2) - { - if (bIf4) - { - return tatByWidth; - } - else - { - return tatByLeftEdge; - } - } - else if (bIf4 && bIf5 && !(bIf1 && !bIf2 && dNextLeft > dNextNextLeft)) - { - return tatByRightEdge; - } - else if (!bIf1 && !bIf2 && bIf3 && dNextLeft < dNextNextLeft && (bIf4 || dCurrRight > dNextRight)) - { - bIsUseNextNextLine = false; - return tatByWidth; - } - else if (bIf1 && !bIf2 && dNextLeft > dNextNextLeft && (bIf4 || dCurrRight < dNextRight)) - { - bIsSingleLineParagraph = true; - return tatByWidth; - } - else if (!bIf1 && !bIf2 && !bIf4 && !bIf5 && bIf6 && bIf7) - { - return tatByCenter; - } - else - { - return tatByWidth; - } - } - else - { - if (bIf4) - { - if (bIf1) - { - return tatByWidth; - } - else if (bIf3 && dCurrLeft < dNextLeft) - { - return tatByRightEdge; - } - else - { - return tatByWidth; - } - } - else if (dCurrRight > dNextRight) - { - if (bIf1 || bIf3) - { - return tatByWidth; - } - else - { - return tatByCenter; - } - } - else if (dCurrRight < dNextRight) - { - if (bIf1) - { - return tatByLeftEdge; - } - else if (bIf3 && bIf6) - { - return tatByCenter; - } - } - } - - return tatUnknown; - } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 95aaed48a7c..219e59a1ee7 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -11,9 +11,9 @@ namespace NSDocxRenderer enum TextAlignmentType { tatUnknown, - tatByLeftEdge, + tatByLeft, tatByCenter, - tatByRightEdge, + tatByRight, tatByWidth }; @@ -33,8 +33,6 @@ namespace NSDocxRenderer double m_dLineHeight {0.0}; std::vector> m_arLines; - - size_t m_nNumLines {0}; std::wstring m_wsStyleId; public: @@ -45,12 +43,5 @@ namespace NSDocxRenderer void RemoveHighlightColor(); void MergeLines(); - - static TextAlignmentType DetermineTextAlignmentType(std::shared_ptr pCurrentLine, - std::shared_ptr pNextLine, - std::shared_ptr pNextNextLine, - double dPageWidth, - bool &bIsUseNextNextLine, - bool &bIsSingleLineParagraph) noexcept; }; } diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp index 921aff52fa8..97d12ff7785 100644 --- a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -30,7 +30,7 @@ namespace NSDocxRenderer std::wstring CParagraphStyleManager::GetDefaultParagraphStyleId(const CParagraph& oParagraph) const noexcept { - if(oParagraph.m_nNumLines > 1) return L"Normal"; + if(oParagraph.m_arLines.size() > 1) return L"Normal"; bool isHeading = true; for(auto& val : oParagraph.m_arLines[0]->m_arConts) From c196f282afb0a16a560ee134742aec77eeabfcf9 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 11 Dec 2023 05:25:02 +0300 Subject: [PATCH 207/794] Bugfix BuildParagraphes --- DocxRenderer/src/logic/Page.cpp | 316 ++++++------------- DocxRenderer/src/logic/Page.h | 5 - DocxRenderer/src/logic/elements/TextLine.cpp | 8 + DocxRenderer/src/logic/elements/TextLine.h | 4 +- DocxRenderer/src/resources/utils.h | 21 ++ 5 files changed, 135 insertions(+), 219 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index aeb5e476978..ceb502a3b5c 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -470,11 +470,9 @@ namespace NSDocxRenderer void CPage::CalcSelected() { - for(auto& line : m_arTextLines) - if(line) - for(auto& cont : line->m_arConts) - if(cont) - cont->CalcSelected(); + for (auto& cont : m_arConts) + if (cont) + cont->CalcSelected(); } void CPage::AnalyzeShapes() @@ -548,8 +546,8 @@ namespace NSDocxRenderer void CPage::AnalyzeTextLines() { // вся логика основана на отсортированных списках объектов - using line_ptr = std::shared_ptr; - std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr& a, const line_ptr& b) { + using line_ptr_t = std::shared_ptr; + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { return a->m_dBaselinePos < b->m_dBaselinePos; }); @@ -721,6 +719,7 @@ namespace NSDocxRenderer pNextLine->m_eVertAlignType == eVertAlignType::vatSubscript)) { pCurrLine->m_pLine = pNextLine; + pNextLine->m_pLine = pCurrLine; } } else if(!is_font_effect && pCurrCont->IsDuplicate(pNextCont.get(), eVType)) @@ -980,62 +979,26 @@ namespace NSDocxRenderer if (!line) continue; - if (line->m_eVertAlignType == eVertAlignType::vatSuperscript) + if (line->m_eVertAlignType == eVertAlignType::vatSuperscript + || line->m_eVertAlignType == eVertAlignType::vatSubscript) { - auto& pBaseLine = line->m_pLine; - if (pBaseLine) + std::shared_ptr& base_line = line->m_pLine; + if (base_line) { for (auto& pCont : line->m_arConts) { - if (pBaseLine->m_dLeft > pCont->m_dLeft) - pBaseLine->m_dLeft = pCont->m_dLeft; - if (pBaseLine->m_dRight < pCont->m_dRight) - pBaseLine->m_dRight = pCont->m_dRight; + if (base_line->m_dLeft > pCont->m_dLeft) + base_line->m_dLeft = pCont->m_dLeft; + if (base_line->m_dRight < pCont->m_dRight) + base_line->m_dRight = pCont->m_dRight; - pBaseLine->m_dWidth = pBaseLine->m_dRight - pBaseLine->m_dLeft; - pBaseLine->m_arConts.push_back(pCont); + base_line->m_dWidth = base_line->m_dRight - base_line->m_dLeft; + base_line->m_arConts.push_back(pCont); pCont = nullptr; } - - using cont_ptr = std::shared_ptr; - std::sort(pBaseLine->m_arConts.begin(), pBaseLine->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { - if(!a) return false; - if(!b) return true; - return a->m_dLeft < b->m_dLeft; - }); - line = nullptr; } } - else if (line->m_eVertAlignType == eVertAlignType::vatBase) - { - auto& pSubLine = line->m_pLine; - if (pSubLine) - { - for (auto& pCont : pSubLine->m_arConts) - { - if (pCont == nullptr) - continue; - - if (line->m_dLeft > pCont->m_dLeft) - line->m_dLeft = pCont->m_dLeft; - if (line->m_dRight < pCont->m_dRight) - line->m_dRight = pCont->m_dRight; - - line->m_dWidth = line->m_dRight - line->m_dLeft; - line->m_arConts.push_back(pCont); - pCont = nullptr; - } - - using cont_ptr = std::shared_ptr; - std::sort(line->m_arConts.begin(), line->m_arConts.end(), [] (const cont_ptr& a, const cont_ptr& b) { - if(!a) return false; - if(!b) return true; - return a->m_dLeft < b->m_dLeft; - }); - pSubLine = nullptr; - } - } } } @@ -1189,25 +1152,25 @@ namespace NSDocxRenderer } // если линия пересекается с другим шейпом - bool next = false; - for (auto& shape : m_arShapes) - { - if (!shape) - continue; - - auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); - auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); - - if (!no_crossing(h_type, v_type)) - { - m_arShapes.push_back(CreateSingleLineShape(curr_line)); - curr_line = nullptr; - next = true; - break; - } - } - if (next) - continue; +// bool next = false; +// for (auto& shape : m_arShapes) +// { +// if (!shape) +// continue; + +// auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); +// auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); + +// if (!no_crossing(h_type, v_type)) +// { +// m_arShapes.push_back(CreateSingleLineShape(curr_line)); +// curr_line = nullptr; +// next = true; +// break; +// } +// } +// if (next) +// continue; // если линия пересекается с предыдущей линией if (index && m_arTextLines[index - 1]) @@ -1222,6 +1185,7 @@ namespace NSDocxRenderer if (!no_crossing(h_type, v_type)) { + m_arShapes.push_back(CreateSingleLineShape(prev_line)); m_arShapes.push_back(CreateSingleLineShape(curr_line)); prev_line = nullptr; curr_line = nullptr; @@ -1233,19 +1197,15 @@ namespace NSDocxRenderer if(m_arTextLines.empty()) return; - // переметим nullptr в конец и удалим - auto&& left = m_arTextLines.begin(), right = m_arTextLines.end() - 1; - for (;;) - { - while (!*right && left < right) right--; - while (*left && left < right) left++; - if (left >= right) break; - std::swap(left, right); - } - if (*right) - ++right; - if (right != m_arTextLines.end()) - m_arTextLines.erase(right, m_arTextLines.end()); + // переместим nullptr в конец и удалим + auto right = MoveNullptr(m_arTextLines.begin(), m_arTextLines.end()); + m_arTextLines.erase(right, m_arTextLines.end()); + + using line_ptr_t = std::shared_ptr; + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + // todo обработать все TextAssociationType // параграф будет набиваться строчками @@ -1264,7 +1224,6 @@ namespace NSDocxRenderer // если 0.0 - строка последняя std::vector ar_spacings(m_arTextLines.size(), 0.0); - // совпадает ли left, right, center со строкой ниже struct Position { bool left{false}; @@ -1288,8 +1247,8 @@ namespace NSDocxRenderer auto& right_curr = m_arTextLines[index]->m_dRight; auto& right_next = m_arTextLines[index + 1]->m_dRight; - auto center_curr = (m_arTextLines[index]->m_dRight - m_arTextLines[index]->m_dLeft) / 2; - auto center_next = (m_arTextLines[index + 1]->m_dRight - m_arTextLines[index + 1]->m_dLeft) / 2; + auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; + auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) ar_positions[index].center = true; @@ -1319,6 +1278,16 @@ namespace NSDocxRenderer ar_delims[index] = true; } + // width check (слишком большая разница в ширине) + for (size_t index = 1; index < ar_spacings.size(); ++index) + { + double width_diff = fabs(m_arTextLines[index - 1]->m_dWidth - m_arTextLines[index]->m_dWidth); + bool big_diff = width_diff > std::min(m_arTextLines[index - 1]->m_dWidth, m_arTextLines[index - 1]->m_dWidth) * 3; + + if (big_diff && !ar_delims[index]) + ar_delims[index - 1] = true; + } + // alignment check for (size_t index = 1; index < ar_positions.size() - 1; ++index) { @@ -1352,8 +1321,37 @@ namespace NSDocxRenderer paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); paragraph->m_bIsNeedFirstLineIndent = false; paragraph->m_dFirstLine = 0; + paragraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); + paragraph->MergeLines(); + // setting TextAlignmentType + if (paragraph->m_arLines.size() > 1) + { + Position position_curr = {true, true, true}; + for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) + { + auto& curr_line = paragraph->m_arLines[index]; + auto& prev_line = paragraph->m_arLines[index - 1]; + + position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; + auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; + + position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; + } + if (position_curr.left && position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; + else if (position_curr.left) + paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; + else if (position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByRight; + else if (position_curr.center) + paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; + } + if (ar_paragraphs.empty()) paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; else @@ -1373,9 +1371,15 @@ namespace NSDocxRenderer paragraph->m_arLines.push_back(curr_line); }; - // на основе ar_delims разбиваем на параграфы + // на основе ar_delims разбиваем на параграфы + IsShadingPresent for (size_t index = 0; index < ar_delims.size(); ++index) { + if (m_arTextLines[index]->m_pDominantShape) + { + paragraph->m_bIsShadingPresent = true; + paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; + paragraph->RemoveHighlightColor(); + } add_line(m_arTextLines[index]); if (ar_delims[index] || index == ar_delims.size() - 1) add_paragraph(); @@ -1390,41 +1394,16 @@ namespace NSDocxRenderer m_arOutputObjects.push_back(std::move(p)); } - void CPage::CreateSingleLineParagraph(std::shared_ptr pLine, double pBeforeSpacing) + std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr pLine) { auto pParagraph = std::make_shared(); pParagraph->m_arLines.push_back(pLine); - pParagraph->m_dLeft = pLine->m_dLeft; - pParagraph->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; - pParagraph->m_dFirstLine = 0; - pParagraph->m_dRight = pLine->m_dRight; - pParagraph->m_dRightBorder = m_dWidth - pParagraph->m_dRight; + pParagraph->m_dTop = pLine->m_dTop; + pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; pParagraph->m_dWidth = pLine->m_dWidth; pParagraph->m_dHeight = pLine->m_dHeight; - if (pBeforeSpacing < 0) - { - pParagraph->m_dHeight += pBeforeSpacing; - } - - pParagraph->m_dSpaceBefore = std::max(pBeforeSpacing, 0.0); - - if (pLine->m_pDominantShape) - { - pParagraph->m_bIsShadingPresent = true; - pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; - pParagraph->RemoveHighlightColor(); - } - - m_arOutputObjects.push_back(std::dynamic_pointer_cast(pParagraph)); - } - - std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr pLine) - { - auto pParagraph = std::make_shared(); - - pParagraph->m_arLines.push_back(pLine); - pParagraph->m_dRightBorder = 0; + pParagraph->m_dRight = pLine->m_dRight; if (pLine->m_pDominantShape) { @@ -1436,10 +1415,13 @@ namespace NSDocxRenderer auto pShape = std::make_shared(); pShape->m_arOutputObjects.push_back(pParagraph); pShape->m_eType = CShape::eShapeType::stTextBox; - pShape->m_dLeft = pLine->m_dLeft; - pShape->m_dTop = pLine->m_dBaselinePos - pLine->m_dHeight; - pShape->m_dWidth = pLine->m_dWidth; - pShape->m_dHeight = pLine->m_dHeight; + + pShape->m_dLeft = pParagraph->m_dLeft; + pShape->m_dTop = pParagraph->m_dTop; + pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; + pShape->m_dWidth = pParagraph->m_dWidth; + pShape->m_dHeight = pParagraph->m_dHeight; + pShape->m_dRight = pParagraph->m_dRight; pShape->m_bIsBehindDoc = false; return pShape; @@ -1494,96 +1476,6 @@ namespace NSDocxRenderer } } - void CPage::CorrectionObjectesInShapes(double dPageWidth) - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - if (m_arOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) - { - continue; - } - - auto pShape = std::dynamic_pointer_cast(m_arOutputObjects[i]); - - if (!pShape || - pShape->m_eType != CShape::eShapeType::stTextBox || - pShape->m_arOutputObjects.empty()) - { - continue; - } - - for (size_t j = 0; j < pShape->m_arOutputObjects.size(); ++j) - { - auto& pObj = pShape->m_arOutputObjects[j]; - switch(pObj->m_eType) - { - case COutputObject::eOutputType::etParagraph: - { - auto pParagraph = std::dynamic_pointer_cast(m_arOutputObjects[i]); - - if (pParagraph->m_dLeft > pShape->m_dLeft && pParagraph->m_arLines.size() == 1) - { - pParagraph->m_bIsNeedFirstLineIndent = true; - pParagraph->m_dFirstLine = pParagraph->m_dLeft - pShape->m_dLeft; - pParagraph->m_dLeft = 0; - } - - pParagraph->m_dLeftBorder = pParagraph->m_dLeft > pShape->m_dLeft ? fabs(pParagraph->m_dLeft - pShape->m_dLeft) : 0; - pParagraph->m_dRightBorder = pParagraph->m_dRight < pShape->m_dRight ? fabs(pShape->m_dRight - pParagraph->m_dRight) : 0; - } - break; - default: - break; - } - - } - } - } - - std::shared_ptr CPage::GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking) - { - std::shared_ptr pLine; - for (size_t nIndex = nCurrentIndex + 1; nIndex < m_arTextLines.size(); ++nIndex) - { - pLine = m_arTextLines[nIndex]; - if(pLine && (pIndexForCheking && pLine->m_iNumDuplicates > 0)) - if (*pIndexForCheking == c_nAntiZero) - *pIndexForCheking = nIndex; - - if (!pLine || (pIndexForCheking && pLine->m_iNumDuplicates > 0)) - { - nCurrentIndex++; - pLine = nullptr; - continue; - } - else - break; - } - return pLine; - } - - std::shared_ptr CPage::GetPrevTextLine(size_t nCurrentIndex) - { - std::shared_ptr pLine = nullptr; - if (nCurrentIndex) - { - for (size_t nIndex = nCurrentIndex - 1; nIndex > 0; --nIndex) - { - pLine = m_arTextLines[nIndex]; - - if (!pLine) - { - pLine = nullptr; - continue; - } - else - break; - } - } - return pLine; - } - - void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) { // section diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 8b95c05b7da..362dd5a49b9 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -113,13 +113,8 @@ namespace NSDocxRenderer void BuildParagraphes(); - void CreateSingleLineParagraph(std::shared_ptr pLine, double pBeforeSpacing); std::shared_ptr CreateSingleLineShape(std::shared_ptr pLine); void CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText); - void CorrectionObjectesInShapes(double dPageWidth); - - std::shared_ptr GetNextTextLine(size_t& nCurrentIndex, size_t* pIndexForCheking = nullptr); - std::shared_ptr GetPrevTextLine(size_t nCurrentIndex); void MergeShapes(); void CalcSelected(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 86cf7b4c4a2..dfe01996629 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -134,6 +134,14 @@ namespace NSDocxRenderer pFirst = pCurrent; } } + + auto right = MoveNullptr(m_arConts.begin(), m_arConts.end()); + m_arConts.erase(right, m_arConts.end()); + + using cont_ptr_t = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr_t& a, const cont_ptr_t& b) { + return a->m_dLeft < b->m_dLeft; + }); } void CTextLine::RecalcSizes() diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index b983d8b5ce7..8021544608b 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -22,8 +22,8 @@ namespace NSDocxRenderer AssumedTextAlignmentType m_eAlignmentType{atatUnknown}; eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; - std::shared_ptr m_pLine {nullptr}; // если не nullptr, то есть привязка к vatSubscript или vatSuperscript; - std::shared_ptr m_pDominantShape {nullptr}; + std::shared_ptr m_pLine; + std::shared_ptr m_pDominantShape {nullptr}; UINT m_iNumDuplicates {0}; diff --git a/DocxRenderer/src/resources/utils.h b/DocxRenderer/src/resources/utils.h index d1055e19d41..1bab2dca820 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,4 +1,7 @@ #pragma once + +#include + #include "../../../DesktopEditor/common/Types.h" #include "../../../DesktopEditor/common/StringUTF32.h" @@ -55,3 +58,21 @@ inline int little_endian_2_big_endian( int i ) { return ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); } + +// перемещает nullptr в конец и возвращает итератор, после которого начинаются nullptr +template +It MoveNullptr(It start, It end) +{ + It left = start, right = end - 1; + for (;;) + { + while (!*right && left < right) right--; + while (*left && left < right) left++; + if (left >= right) break; + std::swap(*left, *right); + } + if (*right) + ++right; + + return right; +} From 50cb0b543e656e3690e5df6416cf3ec2e03ace55 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 11 Dec 2023 22:41:01 +0300 Subject: [PATCH 208/794] Fix indent --- DocxRenderer/src/logic/Page.cpp | 56 +++++++++++++------- DocxRenderer/src/logic/elements/TextLine.cpp | 7 +++ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index ceb502a3b5c..cd4d3ccd253 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -648,17 +648,12 @@ namespace NSDocxRenderer oFont.Size = static_cast(drop_cap->nFontSize) / 2.0; m_pFontManager->LoadFontByName(oFont); - double box_X; - double box_Y; - double box_W; - double box_H; + auto metrics = m_pFontManager->GetFontMetrics(); + auto h = m_pFontManager->GetFontHeight(); - m_pFontManager->SetStringGid(0); - m_pFontManager->MeasureString(drop_cap->wsText, 0, 0, box_X, box_Y, box_W, box_H, CFontManager::mtPosition); - - shape->m_dBaselinePos = drop_cap->m_dBaselinePos; - shape->m_dHeight = box_H; - shape->m_dTop = drop_cap->m_dBaselinePos - shape->m_dHeight; + shape->m_dTop = drop_cap->m_dTop; + shape->m_dBaselinePos = drop_cap->m_dTop + h; + shape->m_dHeight = shape->m_dBaselinePos - shape->m_dTop; shape->m_dRight = drop_cap->m_dRight; shape->m_dLeft = drop_cap->m_dLeft; @@ -1289,19 +1284,29 @@ namespace NSDocxRenderer } // alignment check - for (size_t index = 1; index < ar_positions.size() - 1; ++index) + bool is_first_line = false; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) { Position position_top; Position position_bot; position_bot = ar_positions[index]; - position_top = ar_positions[index - 1]; + if (index == 0) + position_top = position_bot; + else + position_top = ar_positions[index - 1]; - bool is_good = position_top.left == position_bot.left || position_top.right == position_bot.right || position_top.center == position_bot.center; - bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); + if (index == 0 || ar_delims[index - 1]) + is_first_line = true; + else + is_first_line = false; - if (!is_good || is_unknown) - ar_delims[index - 1] = true; + if (is_first_line && !position_bot.right && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) + position_bot.left = true; + + bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); + if (is_unknown) + ar_delims[index] = true; } // lamda to setup and add paragpraph @@ -1329,12 +1334,19 @@ namespace NSDocxRenderer if (paragraph->m_arLines.size() > 1) { Position position_curr = {true, true, true}; + bool first_left = false; + for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) { auto& curr_line = paragraph->m_arLines[index]; auto& prev_line = paragraph->m_arLines[index - 1]; - position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + // indent check + if (index == 1) + first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + else + position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; @@ -1350,6 +1362,13 @@ namespace NSDocxRenderer paragraph->m_eTextAlignmentType = CParagraph::tatByRight; else if (position_curr.center) paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; + + // indent check + if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) + { + paragraph->m_bIsNeedFirstLineIndent = true; + paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; + } } if (ar_paragraphs.empty()) @@ -1397,11 +1416,12 @@ namespace NSDocxRenderer std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr pLine) { auto pParagraph = std::make_shared(); + pParagraph->m_arLines.push_back(pLine); pParagraph->m_dLeft = pLine->m_dLeft; pParagraph->m_dTop = pLine->m_dTop; pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - pParagraph->m_dWidth = pLine->m_dWidth; + pParagraph->m_dWidth = pLine->m_dWidth * 1.05; // чтобы текст точно уместился pParagraph->m_dHeight = pLine->m_dHeight; pParagraph->m_dRight = pLine->m_dRight; diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index dfe01996629..fee8e8d0539 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -35,6 +35,13 @@ namespace NSDocxRenderer if (m_arConts.empty()) return; + using cont_ptr_t = std::shared_ptr; + std::sort(m_arConts.begin(), m_arConts.end(), [] (const cont_ptr_t& a, const cont_ptr_t& b) { + if (!a) return false; + if (!b) return true; + return a->m_dLeft < b->m_dLeft; + }); + std::shared_ptr pFirst; size_t j = 0; From e01ba114d8d9b92966203a71fb7417600833ca0e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 13 Dec 2023 13:47:09 +0600 Subject: [PATCH 209/794] Add chart sheet conversion --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 36 +++ .../Worksheets/WorksheetChildOther.cpp | 281 +++++++++++------- .../Worksheets/WorksheetChildOther.h | 5 + 3 files changed, 216 insertions(+), 106 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 5203cd010d1..7b3d91627db 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -236,6 +236,40 @@ namespace OOX if(m_bIsChartSheet) { XLSB::ChartSheetStreamPtr chartSheetStream(new XLSB::ChartSheetStream); + + if (m_oPageMargins.IsInit()) + chartSheetStream->m_BrtMargins = m_oPageMargins->toBin(); + if (m_oHeaderFooter.IsInit()) + chartSheetStream->m_HEADERFOOTER = m_oHeaderFooter->toBin(); + if (m_oDrawing.IsInit()) + chartSheetStream->m_BrtDrawing = m_oDrawing->toBin(); + if (m_oLegacyDrawing.IsInit()) + chartSheetStream->m_BrtLegacyDrawing = m_oLegacyDrawing->toBin(); + if (m_oLegacyDrawingHF.IsInit()) + chartSheetStream->m_BrtLegacyDrawingHF = m_oLegacyDrawingHF->toBin(); + if (m_oPicture.IsInit()) + chartSheetStream->m_BrtBkHim = m_oPicture->toBin(); + + if (m_oSheetViews.IsInit()) + chartSheetStream->m_CSVIEWS = m_oSheetViews->toBin(); + + if (m_oPageSetup.IsInit()) + chartSheetStream->m_BrtCsPageSetup = m_oPageSetup->toBinCs(); + + if(m_oSheetProtection.IsInit()) + { + if (m_oSheetProtection->m_oAlgorithmName.IsInit()) + chartSheetStream->m_BrtCsProtectionIso = m_oSheetProtection->toBinCS(); + else if(m_oSheetProtection->m_oPassword.IsInit()) + chartSheetStream->m_BrtCsProtection = m_oSheetProtection->toBinCS(); + } + + if (m_oSheetPr.IsInit()) + { + if(m_oSheetPr->m_oCodeName.IsInit()) + chartSheetStream->m_BrtCsProp = m_oSheetPr->toBinCs(); + } + return chartSheetStream; } else @@ -830,6 +864,8 @@ mc:Ignorable=\"x14ac\">"); CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { + if(m_bIsChartSheet) + return OOX::SpreadsheetBin::FileTypes::ChartsheetsBin; return OOX::SpreadsheetBin::FileTypes::WorksheetBin; } return m_bIsChartSheet?OOX::Spreadsheet::FileTypes::Chartsheets:OOX::Spreadsheet::FileTypes::Worksheet; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 2d306b2ad51..91f4e37f584 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -557,117 +557,115 @@ namespace OOX } XLS::BaseObjectPtr CPageSetup::toBin() { - if(m_oErrors.IsInit() || m_oScale.IsInit()) + auto ptr(new XLSB::PageSetup); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + if (ptr->fNoColor && m_oCellComments.IsInit()) { - auto ptr(new XLSB::PageSetup); - XLS::BaseObjectPtr objectPtr(ptr); - if(m_oBlackAndWhite.IsInit()) - ptr->fNoColor = m_oBlackAndWhite->m_eValue; - if (ptr->fNoColor && m_oCellComments.IsInit()) - { - if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) - ptr->fNotes = true; - else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) - ptr->fNotes = false; - } + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } - if (m_oCopies.IsInit()) - ptr->iCopies = m_oCopies->m_eValue; + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; - if (m_oDraft.IsInit()) - ptr->fDraft = m_oDraft->m_eValue; + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; - if (m_oErrors.IsInit()) - ptr->iErrors = m_oErrors->m_eValue; + if (m_oErrors.IsInit()) + ptr->iErrors = m_oErrors->m_eValue; - if (m_oFirstPageNumber.IsInit()) - ptr->iPageStart = m_oFirstPageNumber->m_eValue; + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; - if (m_oFitToHeight.IsInit()) - ptr->iFitHeight = m_oFitToHeight->m_eValue; + if (m_oFitToHeight.IsInit()) + ptr->iFitHeight = m_oFitToHeight->m_eValue; - if (m_oFitToWidth.IsInit()) - ptr->iFitWidth = m_oFitToWidth->m_eValue; + if (m_oFitToWidth.IsInit()) + ptr->iFitWidth = m_oFitToWidth->m_eValue; - if (m_oHorizontalDpi.IsInit()) - ptr->iRes = m_oHorizontalDpi->m_eValue; + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; - if (m_oRId.IsInit()) - ptr->szRelID = m_oRId->GetValue(); + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); - if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) - ptr->fLandscape = true; - else - ptr->fLandscape = false; + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; - if ( m_oPageOrder == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) - ptr->fLeftToRight = true; - else - ptr->fLeftToRight = false; + if ( m_oPageOrder == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) + ptr->fLeftToRight = true; + else + ptr->fLeftToRight = false; - if (m_oPaperSize.IsInit()) - ptr->iPaperSize = m_oPaperSize->m_eValue; + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; - if (m_oScale.IsInit()) - ptr->iScale = m_oScale->m_eValue; + if (m_oScale.IsInit()) + ptr->iScale = m_oScale->m_eValue; - if (m_oUseFirstPageNumber.IsInit()) - ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; - if (m_oVerticalDpi.IsInit()) - ptr->iVRes = m_oVerticalDpi->m_eValue; + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; - return objectPtr; - } - else - { - auto ptr(new XLSB::CsPageSetup); - XLS::BaseObjectPtr objectPtr(ptr); + return objectPtr; + } + XLS::BaseObjectPtr CPageSetup::toBinCs() + { + auto ptr(new XLSB::CsPageSetup); + XLS::BaseObjectPtr objectPtr(ptr); - if(m_oBlackAndWhite.IsInit()) - ptr->fNoColor = m_oBlackAndWhite->m_eValue; - if (ptr->fNoColor) - { - if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) - ptr->fNotes = true; - else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) - ptr->fNotes = false; - } + if(m_oBlackAndWhite.IsInit()) + ptr->fNoColor = m_oBlackAndWhite->m_eValue; + if (ptr->fNoColor) + { + if (m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAtEnd) + ptr->fNotes = true; + else if(m_oCellComments == SimpleTypes::Spreadsheet::ECellComments::cellcommentsAsDisplayed) + ptr->fNotes = false; + } - if (m_oCopies.IsInit()) - ptr->iCopies = m_oCopies->m_eValue; + if (m_oCopies.IsInit()) + ptr->iCopies = m_oCopies->m_eValue; - if (m_oDraft.IsInit()) - ptr->fDraft = m_oDraft->m_eValue; + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; - if (m_oFirstPageNumber.IsInit()) - ptr->iPageStart = m_oFirstPageNumber->m_eValue; + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; - if (m_oHorizontalDpi.IsInit()) - ptr->iRes = m_oHorizontalDpi->m_eValue; + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; - if (m_oRId.IsInit()) - ptr->szRelID = m_oRId->GetValue(); + if (m_oRId.IsInit()) + ptr->szRelID = m_oRId->GetValue(); - if (m_oOrientation.IsInit()) - { - if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) - ptr->fLandscape = true; - else - ptr->fLandscape = false; - } + if (m_oOrientation.IsInit()) + { + if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + ptr->fLandscape = true; + else + ptr->fLandscape = false; + } - if (m_oPaperSize.IsInit()) - ptr->iPaperSize = m_oPaperSize->m_eValue; + if (m_oPaperSize.IsInit()) + ptr->iPaperSize = m_oPaperSize->m_eValue; - if (m_oUseFirstPageNumber.IsInit()) - ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; - if (m_oVerticalDpi.IsInit()) - ptr->iVRes = m_oVerticalDpi->m_eValue; - return objectPtr; - } + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; + return objectPtr; } + EElementType CPageSetup::getType() const { return et_x_PageSetup; @@ -1435,19 +1433,19 @@ namespace OOX ptr->m_arBrtSel.push_back(i->toBin()); } return castedPtr; - /*} - else - { - auto pWsView(new XLSB::BeginCsView); - XLS::BaseObjectPtr castedPtr(pWsView); - if(m_oTabSelected.IsInit()) + + } + XLS::BaseObjectPtr CSheetView::toBinCs() + { + auto pWsView(new XLSB::BeginCsView); + XLS::BaseObjectPtr castedPtr(pWsView); + if(m_oTabSelected.IsInit()) pWsView->fSelected = m_oTabSelected->m_eValue; - if(m_oWorkbookViewId.IsInit()) + if(m_oWorkbookViewId.IsInit()) pWsView->iWbkView = m_oWorkbookViewId->m_eValue; - if(m_oZoomScale.IsInit()) + if(m_oZoomScale.IsInit()) pWsView->wScale = m_oZoomScale->m_eValue; - return castedPtr; - }*/ + return castedPtr; } EElementType CSheetView::getType() const { @@ -1591,23 +1589,19 @@ namespace OOX XLS::BaseObjectPtr CSheetViews::toBin() { auto view = m_arrItems.back(); - //if(view->m_oView.IsInit() || view->m_oTopLeftCell.IsInit() || view->m_oTopLeftCell.IsInit()) - //{ + auto castedPtr(new XLSB::WSVIEWS2); XLS::BaseObjectPtr ptr(castedPtr); for(auto i:m_arrItems) castedPtr->m_arWSVIEW2.push_back(i->toBin()); return ptr; - //} - /* - else - { - auto castedPtr(new XLSB::CSVIEWS); - XLS::BaseObjectPtr ptr(castedPtr); - for(auto i:m_arrItems) - castedPtr->m_arCSVIEW.push_back(i->toBin()); - return ptr; - }*/ + } + XLS::BaseObjectPtr CSheetViews::toBinCs() + { + auto ptr(new XLSB::CSVIEWS); + for(auto i:m_arrItems) + ptr->m_arCSVIEW.push_back(i->toBinCs()); + return XLS::BaseObjectPtr{ptr}; } EElementType CSheetViews::getType() const { @@ -1816,6 +1810,19 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CSheetPr::toBinCs() + { + auto ptr(new XLSB::CsProp); + + if(m_oCodeName.IsInit()) + ptr->strName = m_oCodeName.get(); + if(m_oPublished.IsInit()) + ptr->fPublish = m_oPublished->GetValue(); + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); + return XLS::BaseObjectPtr{ptr}; + } + void CSheetPr::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeWsProp) @@ -2692,6 +2699,68 @@ namespace OOX return castedPtr; } } + XLS::BaseObjectPtr CSheetProtection::toBinCS() + { + XLS::BaseObjectPtr objectPtr; + if(m_oPassword.IsInit()) + { + auto ptr(new XLSB::CsProtection); + objectPtr = XLS::BaseObjectPtr{ptr}; + ptr->protpwd = std::stoul(m_oPassword.get()); + if(m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + else + ptr->fObjects = false; + if(m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fObjects = false; + } + else + { + auto ptr(new XLSB::CsProtectionIso); + objectPtr = XLS::BaseObjectPtr{ptr}; + + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + else + ptr->ipdPasswordData.szAlgName = false; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + else + ptr->dwSpinCount = 0; + + if(m_oHashValue.IsInit()) + { + byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + auto tempSize = 0; + NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), + m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); + ptr->ipdPasswordData.rgbHash.cbLength = tempSize; + } + + if(m_oSaltValue.IsInit()) + { + byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + + if(m_oObjects.IsInit()) + ptr->fObjects = m_oObjects->GetValue(); + else + ptr->fObjects = false; + if(m_oSheet.IsInit()) + ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fObjects = false; + + } + + return objectPtr; + } EElementType CSheetProtection::getType() const { return et_x_SheetProtection; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 34c2a938064..4560a53ae8f 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -203,6 +203,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -398,6 +399,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; private: @@ -444,6 +446,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; }; @@ -517,6 +520,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; private: @@ -745,6 +749,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBinCS(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From 03af151c302f80d2e350f55baf5fc3d568c916d8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 13 Dec 2023 22:15:23 +0600 Subject: [PATCH 210/794] Fix conversion --- OOXML/XlsxFormat/Slicer/Slicer.cpp | 8 ++++++ OOXML/XlsxFormat/Styles/Borders.cpp | 7 +----- OOXML/XlsxFormat/Styles/Fonts.cpp | 4 +-- OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 2 +- OOXML/XlsxFormat/Styles/rPr.cpp | 29 +++++++++++++++++++++- OOXML/XlsxFormat/Styles/rPr.h | 1 + OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 2 ++ 7 files changed, 42 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Slicer/Slicer.cpp b/OOXML/XlsxFormat/Slicer/Slicer.cpp index 54bc570237a..087b3f6a751 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.cpp +++ b/OOXML/XlsxFormat/Slicer/Slicer.cpp @@ -189,14 +189,22 @@ XLS::BaseObjectPtr CSlicer::toBin() if(m_oStartItem.IsInit()) ptr->dwStartSlicerItem = m_oStartItem.get(); + else + ptr->dwStartSlicerItem = 0; if(m_oColumnCount.IsInit()) ptr->dwColumnCount = m_oColumnCount.get(); + else + ptr->dwColumnCount = 1; if(m_oShowCaption.IsInit()) ptr->fCaptionVisible = m_oShowCaption.get(); if(m_oLevel.IsInit()) ptr->dwLevel = m_oLevel.get(); + else + ptr->dwLevel = 0; if(m_oLockedPosition.IsInit()) ptr->fLockedPosition = m_oLockedPosition.get(); + else + ptr->fLockedPosition = false; if(m_oRowHeight.IsInit()) ptr->dxRowHeight = m_oRowHeight.get(); diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 0089e7a5350..1801f19c78d 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -144,12 +144,7 @@ namespace OOX ptr->brtColor = m_oColor->toColor(); else { - XLSB::Color col; - col.xColorType = 0; - col.nTintAndShade = 0; - col.index = 0; - col.fValidRGB = true; - ptr->brtColor = col; + ptr->brtColor = m_oColor->GetDefaultColor(); } if(!m_oStyle.IsInit()) diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index f634cc49ff5..2a8a438d3bb 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -252,9 +252,7 @@ namespace OOX ptr->brtColor = m_oColor->toColor(); else { - XLSB::Color col; - col.xColorType = 0; - ptr->brtColor = col; + ptr->brtColor = m_oColor->GetDefaultColor(); } if(m_oScheme.IsInit()) diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index 059707090a1..51770f35450 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -229,7 +229,7 @@ namespace OOX stylesStream->m_BORDERS = m_oBorders->toBin(); if (m_oCellStyleXfs.IsInit()) - stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin();// + stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin(); if (m_oCellXfs.IsInit()) stylesStream->m_CELLXFS = m_oCellXfs->toBin(); diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 9d2b0363932..87ca7455671 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -448,10 +448,31 @@ namespace OOX { ReadAttributes(obj); } + XLSB::Color CColor::GetDefaultColor() + { + XLSB::Color ptr; + + ptr.bAlpha = 0; + ptr.bBlue = 0; + ptr.bGreen = 0; + ptr.bRed = 0; + + ptr.xColorType = 0; + ptr.nTintAndShade = 0; + ptr.index = 0; + ptr.fValidRGB = true; + + return ptr; + } XLSB::Color CColor::toColor() { XLSB::Color ptr; + ptr.bAlpha = 0; + ptr.bBlue = 0; + ptr.bGreen = 0; + ptr.bRed = 0; + if(m_oAuto.IsInit()) { if(m_oAuto->GetValue()) @@ -467,7 +488,7 @@ namespace OOX ptr.index = m_oThemeColor->GetValue(); ptr.xColorType = 3; } - else + else if(m_oRgb.IsInit()) { ptr.bAlpha = m_oRgb->Get_A(); ptr.bBlue = m_oRgb->Get_B(); @@ -475,6 +496,7 @@ namespace OOX ptr.bRed = m_oRgb->Get_R(); } + if ( m_oTint.IsInit()) { ptr.nTintAndShade = m_oTint->GetValue() * 32767.0; @@ -489,6 +511,11 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); + ptr->bAlpha = 0; + ptr->bAlpha = 0; + ptr->bAlpha = 0; + ptr->bAlpha = 0; + if(m_oAuto.IsInit()) { if(m_oAuto->GetValue()) diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index e5f60c05b7f..ddd9a2d7b7b 100644 --- a/OOXML/XlsxFormat/Styles/rPr.h +++ b/OOXML/XlsxFormat/Styles/rPr.h @@ -149,6 +149,7 @@ namespace OOX void fromBin(XLS::BaseObject* obj); XLS::BaseObjectPtr toBin(); XLSB::Color toColor(); + XLSB::Color GetDefaultColor(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 3c288b63795..4a373a35f73 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -101,6 +101,8 @@ namespace OOX ptr->helpTopic = 0xFFFFFFFF; if(m_oHidden.IsInit()) ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; if (m_oLocalSheetId.IsInit()) ptr->itab = m_oLocalSheetId->GetValue(); From 7ff4d0e1676a919298e8e6e8f76f862cff59a7f1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 13 Dec 2023 22:16:19 +0600 Subject: [PATCH 211/794] Add chart sheet conversion test --- .../test/ExampleFiles/xlsx2xlsb/simple1.xlsb | Bin 4924 -> 4928 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 12640 -> 17947 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsx | Bin 18819 -> 22955 bytes OOXML/test/xlsx2xlsb/conversion.cpp | 13 +++++++++++++ 4 files changed, 13 insertions(+) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb index 1b80dd46442977eadc04328af495951e0cfd8827..7a984b15fdefc057f782ac73c254492a73eecb1d 100644 GIT binary patch delta 421 zcmdm^c0g^zJl6U(wLE4Y7#JA1m>3v%fpkTVesM`wL)sAG_%6M7?K)oWSMwws3cri zX2fDV#UP|9a-YK-CZ1a}yY!NE^*C{F9m%z$X2F zR`WyYcCj-*5(?I+GEWufe|X{7+~$Y8?9E(o*^V412>V8fk6UjG6L-9n|y~)YVtiHEv63s$qV>pCaVbxu&ojR GsQ>_SlAmJ$ delta 421 zcmX@0wnuHlJl6Wf@18#W$iTqB#l*nC3#2P@^ovU>b5e`-k}~twPW1O?N)$L&|IYe> z-1gP&0zyqkE-@W!7SJf!kl?uAA#6ngYfxkS5xbasR~CGkk|1%^?7iOVxTYqydq2P1 z7#}`kT_Dk^((vZpgsm#MU9;OJhXg;IqbED-OGtmKx}f{#ovZ3qRr?eJHioG_=%2JY z@2~Upg$A8sH|>pX<+1)bS1opL(I;m88xrp(rs?fDa^smt_g=2c9H*B*+GBfjo5&J1 z^`NlWNi#Q?ByHqBy!_+Z^yzso5@%Q4(tdU4BL80F+UZr#s@GZaMDBCrzoV6W*6M0Z z_qJoKT{V(rhrR_*Z{01veZ4^Y{<4K%?(r{uuV*}+r=Rcs=GAOU9GpisEzjx$h6elO zYkUiMS z3Ry5dp4=v+CIdHzk%2)1XdVI_;G2A#Pipc~L4nEB_yxE@5?0Ei6$ DXa1|y diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index ba7c4c50e3e30eb82c61d417b4c199c3d80b29eb..bf92710a8a6da17c1c09cf6ae79107c3f6fcfa37 100644 GIT binary patch delta 9770 zcmaKS1yq#H_y4kV$x2Cgv%s=|bceJ{gS52LA+RD#NlQI+NF$&q-Q6vrh=`ORAPtHL z2)|X|_w}pifBv&)&l7X+%-lQo`P@5qX6bfTECv-q0~3oJ^s6v~=2TrKIf+0ZPNFKR z7hvE3&lea0TNB$jT6=nX3D~$fyLoy6m6&YwE?#_Y_V!LTcKko5x9v@Mf7h+Kl(%WqW}bA;u5(y|LWx5rU59X zKlV>b;1WmtpF1gBX21de7Ql^3h9Lx0ValUfxdCdd`#>?KCvb)Xslmd24F;02Y=LMz z2S5PN2zZMtU&BpcjDccwKY|fsfI!Az5QrG93O{FopTqOwzwP8&k<_K$BL@lZu*c1^ zX+uKfl`HitLYCwqP`^rr{PrLN9r>&38ty0PX}_XP zb>f<#*j0LFT>P<1B+}rcfgno1`1&b{frP@%UViC@)#`Vb*O8FNz|K*zn6FCKA->q+t?NM^Wy2-TgXMD+)OdT^(67rU-o!E6g%uTi^si*JSoi~Ki(fvz zvZI;Rwo#@S-kx*!sF2R!O&un^no^2gI~~v-AiFA(tu-S0UAFS6-~GXvh6MRRawCkz zf9(YittVy>ZO_@&0rZ_3kVnLc5=UKLE_y9rUP^Kk5kc#Th^}h7`-ewgQ3(%J2^Wu5 zXJSxgC4^iP^n(|{sNj|0w^L9`XdF}<8V*y|;IqO!0~$hay~&2jM1_U;wU1sGtZ-?D-4HN6Q95 zy{Nv4&e4fpqU%?zoA4EdgcMnYLgA{B*7cwsIt=bW;rCEPT?r8n5nn73=ueSIis6!A zv@yIx{~>76Y~5@So^I}50@m*C{AlCO(HXhZ1B0AX6yApxKSXrjVix0*u0>Q%x1bVc z>Pw;cYWT;CM)|#Jn-vW?xI!(^?UG4y2O=Fw(?p*k)nG%3Vi(Iqo3m;pi?U`nk9Brm z^eEL(T+a=62E{3=7&F;^1N(5q~p3#Y;d*@l95eG#uyi z0#+SuTcr?gvu0DFygz}&nAE#H=GKn|R<+-wzc4w+NBedwVVxQUH4sXi&d@7$Kiw0> ze?*S670_eQadm=-C2#mkOg%)-4YmB25s0ggvCyKm1;zpcc~_`WmTsX;39EyqkI=Vp6?(^H^nnCW(O5sxI)1xyJSVsh_y)m34;U*J}4Buf|fel|$5Y$%9uO zuTSCJ(Ozfdah}FcWSnpa3`WyMU3B0f}HnA zz@{wPAjy_R2@U#8}7qqYo8ldz)1cC2D`8q(k!6|uXR`lf1{q$9JRQZK%bTG`N# zY*^nInVJSBkdlu=k;Tc2~X;s(LmlV#z8WQRLGO7CnmkOptQN<47r6wxbd6G}Knx#EBF zi}EJS&gwUvtCEfg%eQgY23D=`AqxdqIceilTq&F;4{~>j9mSAwhaWrRJ%5^ zOrP_>?uDgH+)jSj(G3-Y!5S6c%O-}*un^X-4P^Z%WkoN>t&Xnz`F#l|^n5D727$t; zL7*Rw2MxBU|Al?QA0OF{$$Qs#*U8%%D}5)z7Kop-4P2I*vw7-~Ys@jJNm}^|E5FU= z)@3d0-K~t-5jkeLAA9`ho~nBNIUwvLS-X)$m?0%~?(KJy)1$aHG_Bm<%F9AQ5wLM1 zUU89?E+*`7a{~3ie}3cJtoO-s2^V$IN8{o?%hAOlHLU6S+<~ zBq4Ik)I$kKsAsn|lmf0u)9gvZMrw}f*B@d}bq`Fqk_Osf1;Lg4MJyNW+Ew+Uhm4n4 zSj{9MYE)B87$SvD7EDmq119)L42UsNFiK02JbUhj`6+s|}B10p) zOEB;a$+qWhdS|hgoBTbr{87ct3?#?x?L{?Cj^)&X#26l36P`B3JhDI`r(sE0{!tx5pc82lO(g&1^xr!%Q`b?YI=?f2CzAezv;p=7Qn}!(VGAUDuY_fbNt|yJ< z=$Edy@w;)GBggU!OSQzaL2cy~+njq;nHloz{1g_&WqM+>2vC*F^91u37rJB%^V1{Q zMF}s$FXE})VCF38f-NX(M~zUXC-Mo@{dewC@ruT#eD`3e9h-U*#%a&_$Wkjze{vaS zWaApX7WqL1@qvk_woy1o&{_$w4UH8iJ4MiJY2xuK=kKhRN8ysOeTbf!V3?lTG=@dM z9x{zNQM9I05P(D3T=xlv?4aqhcot0XDyfp8+lo+Ih1CV)CTrAL4u3Zlc%s_NVS4wP zadK9vUt&9(-s~iAwKZYw7>Pi&S5l^-1oG?G7SzJ!w~H4W5jPGB$3YCzm}#jfnZWuzq;DfvLurw%pUDW?P3Q$vI5MCMpo7N@B)6JFRgab7me2q$syAZ`f|C zI-)_?SU|v-FC7JqEgViYQjJ_+{16&yK{ZgJa(~``#_{3zMvu?id2jt@T;j66@5-Ms z#a-_65oneN@@ZDiUARyxNkSuc$3i})*>%lUTAef2M~V$u*yDSI&9Ksa@ZeoI`^z(3nISvuB^bVsOVU zIcGOp=94qier#0TAZU1ooVWP$JZYIg3=>hp5b zHBXFsR;nCu>+?7dn@=8gnN=AGCJ*%+V#!w^+z&0-JKAI_>pl%ox;@g~xM(k7d48EF zGOxIEtX4;B3u@FV>*;%}uM?LDchq$HN|sS7v6s^AAaI{F`(rd3WKP8 zO+n(`Jx2A(kRPM1(YDQ#)-(?6Grp6)5(kOdwIi z+&<6N2+WJHYWg$!Z;W!?$y9-9-;G(c#?0(jQ#V1y%veHUclP7^vKy~F6Ew^xDVDaN zSI5!F)_JIasWaceUip|9t`mXThoDHelsZ?wr67^a&SYbDhP5H3nYLt)@0zycif@le zbnRU}#YRtzK6Xy(G=Z1Dp<4+9y9wP)-pR{}3kmPd4$-mMn|nzW(GLKt7L|Haq0dr) zl~)?d*h%WEJX*faVL{!^W1Nxc}7SRjxQ*MIKvA9em*qWtofx8A$0h(S=YPM5eN zdvCDBWNx`Mf2uF{CVg$#V*b8Hjc&ifX5G0a`QnSDwt}jH?uLBu)C2hg+e(MPBPU5l zl&rK0-S;AOA#SO82`|Bd?lcTC8xj<%@w-=0;&mmgFb#QWsV6k3=JWl58=G})&{O#vvi6K`Y_qUe~GjUM$MU#Ro{?|%>XLeheN4vHOQ%LhSKEa=$gVa4~ zFimO+b{rf<4%6D?3=#Wr_U%HT(G zCGE{n>^2rBJ7V@HEUHb7suXGu1!zwKDjpa?Gkag96s&@d-;YYX43Va3pxmH%tKDBf z8|M5r1VhkPRVA5G%HnKmrLIkx2W7gqX~%RpDY9&)J!Ub9AGj@)CA~E~FWfsahcZm& z%5)dOJI%uCG8`gexB*Yc6wsYAj$xudYtVEOVw;;M!)}u&d>7sq5S*K!p^7KtAgDrC z_PAVl1a}Opwac-@xqsqPD=I`g^pY>nWb>ROx~3~$Nu6MOvtMN}AxUhyV7 ztr@KywtC*97bPkS@DD{2#nJln^&6$BegYY@uUu;CRo)poImv@#R-A`oQH*8tCOS-v zKCTO`3K<07{05cGuQh3(hqV|UJV<-@%)1`<{YAk&o~zFUk`AyQZ+U9i6nowA7~%F+ zlK;F%KEmo*5Pp1g*?lh6h|Puanv>O>L?mvowbo5+?DUw7%$gixQs=DhdIZ-bP%^I< zA-BemgT;23;$*pM<|@dY84uh?mM&*AcRQPEsK*7=&FaDz)Pqi`_^7xMaM#j-fvURq zid;T4kX;vQb!`gE@?`z9EAgzD_ecDYl-s23m0pPhG2Ugy$#`{{d?_euUP^cOQpv-; zt53g%6Xxj=dTLi~v^vbvB4iiYKZ*B~T~FR?llVdlaoYnOz}u6t^xJ$JEo-PtSu_Xq zu{ax9k&`$DK?V|t!Z6T)4e~X~qQNSEUIv449=Pc{jT%&!L8L5?Op=Fb?!uFd2LK3d$aGXL;kr=HWzbO&}f$1@79DO}vKF(@A^ezo0bXyHh3=d8WaSim0 z24T?!HIhdy_6<(-54uOZ?W7`-qPG%OnxoZznTZcBac_=F#Q3!$`mql9l~A}e6Y?xW zdyhdZU<<;4sz`pX-UA~auw-Agm?qA6Zmdid&9w4Rrc-ci#tKLVoS*v2gpsiLeRxPB zxHzbnH7-GJtIjOEo_jv-aNo}?D~XRBx#QfA+k)>fte$pPa^z&}%jP(SgG|s^zPF*> zxrKjVfVc5_I{$YpYV!t}Vwe6HNVz_q0HIyyUNhP;=svkZj5W8Sxr(O&&eA0UY}o=H z5_np2QE*grvy#;3QBTyjTt0Q2_bxBa6cZO64yOz$50fk2fA~D$hS0kyRj9<^p=d&J zPpblF%Ga!nI*|y|yUphH^q>sSclinhPNMzH|sxneYROd zAS0cNN@93+n}NUXFdfw{j#8VEt{F)YUv3svT~JV6_Er4o-Pyh^3<%jsfwqVHS`J+WODoPG1oGX0Ys+8djr9cZU z9a0vy<&oj|`C3Dcd#}$Zs46IQWZ7uys*04UDwB>YtLObng{Roia!yyf*m?#U7V-lO zE-kYH(?kCe`M8DFZ!OAXMXc9H6B(Yk^WKK&VY#NKfVY7OU!}s{+pzKYHHED;$lk03 z4v8z4tkCpQru#zQ^leQP7Q7S4BzrwUjbgC%iD$3t5Fe@0fESw+J&C@I zuodN(13KPA#^{*bKfgHjTy|0}bOzfD3kV`-MQOd5gF#x2KA|e-F|Tp4Ve4mLl_6hC z*6Y5OgjXq^ySM7J%K3G)Z;34zMwBOpyjggAux&fkJO@YSTwBl1y~P=zvw7>(#3hI?VJ$b&WS)8`ZaS`_Kvra<4A)(5WJt_T$^Gf#w@8v;PpJEONRbX z1@*exe;CHD^D$s-UApf)$|fu41LccH_9|-uZ}>LeS~shT^MY=zjkS#XXFj_Y<8(Pf z?IGOD2wPrIxt(%^ykpb;$e1=wn`C8!!+E*%EiKjh!JVkO>!t5Xp&;;8$y#0Noys@Z z1KBo>m7sO+V0nje)9C&{2AW16uPs}HE8kHkKGkO7V&>Zg7ZLV~p09mLH)W+WAjR4= z`#8j6%wHL{@xPR$?sPR~yk;j*2(%Ds#AoXfS71$5Lm>qTcn^Hktc%C;6{^e-=Q2Xt zo7!wyH3#-?&$^zL#_G;#fpwgo@pUR_B&j34Ns9n~n!5-#{l^g3T^!-9nrSgQU`3TLJwv2?__bM0k> z*!BI=6DNf-tIb=)gY2m z3U=hmTW;tCxDp&mC2*`T6$nEr6oxLJLOZdDFaz1}l)BU$&YW}G3Mf?9^5t+ArxT3A zjjh7V`tb^oam@XdViT>tH=RQ)w4XMAW=jq>7BfIJ3$-6=(nS&XiQIdJ-`-K2H?`7z zr~78j)mB{?{`20)^p~ygE!}v(a1@TVu+NdE?S7vnf1eki2PKv;Cc9a4kJ2+} z^aMTd01V(e3w06;G0IpQZwyRsgEhr8KZZe;)y>t3WiJO(^<-fU+lGP8AF4hTs}4gO$y@8EuNMg+!&kTwo` zr4lczB4;5T$!H+V9kfEu7I=+Sk(RZG-ahnBqR%c#1vXJJ95qelzE+9rZ@67`N4`xyu6Uk&9{ zBnV~h@w9z@wMR(>$AAMT9OnvCet#zu-s{1AjDD+?;Hp?ToFf>V2_#8EmW)lREQnh| z6eDhL#h{5nn~p0KLHM4I!`o|i`6Dbpy(i*1Ks}8OtJB@MV3kLs-1=Bxg-PA`bCI%ajXJbL>-0X%y20DhPeBTgL zOu+mS()Y_xFz)!iqp7cVx|!^@hY{>DNU24co7!^s5}hea%i?P1^mHt0;EgTY7t2=6FRtu1s`+psyD3%nVV8K_;w0ozb{*!Q_P5f_pPolsbG$f8I7D>Hb^4 z?hmCEqkLKp!kc($m>k%8{OlB5U(YN7Oi}E%>Q5gO z%lkaHkQO6YOxay+z0A^>Tm_G%>AOdyis-Pum6(i&GfcrzMJ>byihi2?ZF`g?_y@H!ax#GQT-`yg%1qhe-yW=Fj^2(Nkp31i| zKTy7LR^y~0^q^q5f?eVg=T8qpztYw4V>d4zt#n58^}ncJz|zwW<&53{{;@CnGv&bV zY3J-!kZHVa3dsFcM^noiX!-aY%c5P?fOueS+U0g@+*WF}xc!jdg{>to?CDU(KX%UlaNH6MTXMEEUZ#FDpEtF?EXf$bG#eH+^<*qd9& zw_Tv1txVoh@_H=D&SmpNXww4-Lu2ZQ+Z%0{e$1wt`=%n2?+o-AdA_0RdM zXZ8!8P~07*eENO6vHcDEZA|gUmA4W^GM~T4IVIWIm92G%?vWt9P(xbZ3Q{o?mwqeXT`cKx+<9B!smHxkHYj<1*;Aph z^g}f|PDYdK&dIQnRT2dyk)*D{9L_9Y0XvjC-WtO2ngW;9PG?)`tAp2%Nk-4{KacPq5&O?se)Ll7r^HK7!`^10YWbCl%4n}Pryzrv zb2$1wMzBSPVb5x9*j?1Zc5rd5Yv)_Zq)J4H z%{w#4elwmSP3EfGjci@3bXOGE>;`YI$RzL%Z4~yI^_MEk`6z1LHZ_pE+Cglb73&ik zHcKp08HoRxWS4coL)ZK8lk3nLqi7hM$_qpA&M>JM%1uUoj1aHDrT0_IF?LM>I}Rpx zQqQ>r8&JUoLoI6eFp>9LK6DqT&2jCI-RbVLZLpUCg-)j$=V3hC-Lcz^uddM2L=Jsh zItyF}9j&FgB5=of?^2Dcg(2tL2DK+)gw}eSNHhJbe55{@(lu@Z#WoKK#dN;#nlB^q2zf!r} z<1@>+%bxwEo=C}9%f*D}z(!KTrOd5hsQ}-X0xKL}JXKp)zJAzhj_h)R3{}{G*)tqX zLd-Gmn5Z( z;-%;Rd#~{a&95%>$o?1Je&HJ6!Amaicl!D_3nw}e@*5F*%1(k>K~3@@)$D$dk`AHhZjQk-^v@E zQTdZdlo?G#fj%CC9yHzWTgv3&Bi7AlkNY5(ZIHV0GLV)XlEA&zQG_sJ;yJV|B``09C!dT y0MknVuV5l{KQR$qv5ij5{6PQT{XisvdMHh$cYjm9e delta 4960 zcmZu#2UJtb)()YE2oVAT2}m_aGbHpL5a|etbfq^H1Q9Pq2pxoo;Gs*EB1n-?ZAgI7 zs~|{Kiu5KRD$@Sk>wWJ&@A_x0SuPa-8|=W$N#3YkEDaUXL+Kb zzJ>`b>hvbpwxq`*MuY*<4Yi_wSqA&c;uJ|26yi2;y5w}~Yt`I4$#(Fzb(O{2tDa$D zbPGN0N;}NhMa9{^GEkW$%U;Tpi{2k&V=+oduP#Q9fPl>h*3~+DdQ+$H>~;K!eqy>m z@=aHEj!774-a)Mq*{r3vA)ovow&{<*y{31&MPD2(m5mWs8+7b%6KQ=mFRq4~TGVJ) zWQs;0ZuKc|Z=}79`hL(Qk>@efF1_r-{zhdvF<#mDmV~Jc{Az4@PU-lS3QhAZI_rD# z9Mp#*F5J(ZzV?1`jTYTJ1TRGrB^C_S9nZrcP-S3A7a{U5%Gus>xiwEyT$XPnBPe^Bu^-a;Hm4L zpaK>6%;+dkz8fA>vddHJQ7T+ke!vY9#5bIcrHyo?G0k=HWPNmcZX0$icEv3F8`Ea* z(xZpf+KYq~fg;4-H{Ts%`D*IQ{f~=(>?t>1MgI&8xpLPFtlhU{s)9sBM_lO;1o;pl)prDM8ZzGJ0qxKw(<_sj#_6D6~WNYbNl4kL~qf%#cZwt?hmgu%F@gnPX1e5wy%#sITjoQ>&*MPNq z^kd4=;p7m9g+7atRZ4btMBTnW_b{scGx>&vxs1rS3uQZ5QQsGwcWFeOw^J@`mCf`p zetW%+c$lQGyK+_M8T#Jfz#=mHB(UuN#8lVLHrVPu+x#|xhYmySOL+V$nEc~0m44AB z?NWZ;bv(DJ5A!`1oAD7Y)tJ4s(M7cYzW($E=hqP8`}Vai^s~HC?-9G!Hz{5kkUUX0 zl9=A({p5=NI5yX+B*q8l-%8x+eBu7}OOC#k%fV8QV6ZOINI=u~_K`q%9CkG5UrKK& zZsKjJL7-QZt-?v!Efm57{73g>7{8dRq?l1!B)Z+Le~l5$@Cwe0h1D%Fc_L zhgyzfboT=-O`ZKM1N|KeSj^0Mc>dD#;QOw*{`v6b#>b{ZE89~MtdaPT41vqU=(TrG zh1NPvY^7~q9gA5if48+@d6yYwd?4T8aU;;7_W4=am&wfsb@+X;H<3SxFVu|np)|cz zyKJ4AC_aJP;xq5_yO0eZG5sA~vB#5}x0k-}ve)@%bI{W^WS^6>{*gcq{rQ5Pe`(IQ zZ@YvX+fb2D-b_nkYD+zfCyNwK&q0^DE<_>7j!gx|-3=z?o4r0)Qvy{u0xvg973hau z{z=uTDho#Nob%tJvB<1?y{0BDs-H{fJxAS?H}i7XyI%eU=js7!K!x#~Of4zMl+7CN zt%{@9A(-mFn`Aso{|VvVnbDcysW`(AsNrXzWsHfcag&opYU)LtsRg#Qm$iUaMI2UQrU0wiS+@iexJN+3R8LNyH7;l+wtfy z+amW6m+boGnmg1AmmB@6KvlN~2pVHS;=!-f&-`Im9O$Y2N}`2bw{*xKsEwx=JuNxS zw=(2!4#g{198>+yKUx#u;uT8VVM_}F0fR#P_^Y=bqv1h0HOC>NnzoNj-4vnPlhv;O$UFtAyaUANP76vJ&zopO%>*LK#`s9sA_QHV(-;Nf9D!! zcZ<81dD*Ly5W^3gR@N`u*D3F*Wl!GpBaeIa6ssjRt;8@6<>)-0j8b5m!EGcF+kIqY zEb%?bZGM?id(oE#nXkypXuI_1d{q_N2ZE}vL}zj-XJ=fjjhxd}NO9y&OwzL1J|!!| z6X;~gqw<(;q=Wck;d9=&QE!bPccoj*6Gj=VFVmF{SC@knWwBwL-OD5~vxMvhZCXMB zgJU12u(e~cq@-A1sG6V^OE&BUoByQS6v8*I;GZ`j$HGJHxedqbS>&#d=X|dE9NXQ) z^q~;0)Y>;#spB`oeluUWUG-3v^I`kb4N_I~#&k_isUWU%5@E%CcWP_EJGzA^qw!{z zI37?D-YqfLY36@OEPAkC;r!BqDKS;D-@z;}yjtblUItSI^T(8Sscxe$Z##=TRfq8{ zZ{AvOu#u#c%0)AF$mEh_PleNe_~ zjg;+Rk7%X6>aE%-w)&z&mK7!2CSN?Ocul-$TGKs7IS|Cf{Qc?O3ny50X))&DW1icNGdT`>Dz#|Qgr3WXNU4Y?%bb~_7h4u&~;aZRT?rzU^+SY5c84P!Vk_P<(ZDzBH|#-auXS zfI?lrV*6hq%g933cC{FahYD64e(^#i1RBVqKK0`3L zq#qa$19lB4l(NstH@-mIACXsp}+i*#(|;giI^+QsRi!P4xc5# zXUXu{X83Fye6|Tb+X|m;fzP(XSxInKGMu#;&U)cg2D#%)QhGGil9&;lrB`t+26G3~ z#lD5c@=?+A8R2I8?M!irt|4Sa#U(%&D=de4-^Fl-A*xXP0{ry`1}lY~bWNFUcTl2H zwxbgUgMN1aIqYT@GbLs$`BN({;FcyW{)Us2MO$-AGl^vUE41&aM5f5 z9H({E4P~!%5Dl@UBJ#R~!7LOIp7VMlUBjfVF>f)o)`&7?=3+Zm!IsMcF1&O`bbMiM zZq80iPD$ZnVCw%>lMc)Mmzs9J)O2xDZ-sfKrr%GWQLTonaZK<}Q(;@+W*iCeC1pD9 zT}k%bV&RyW{>rRydlY>XqquRT3-q--=Up#!F`hdo+F@OlMNkUu zM7XAhVNX8aXDFfSzN}@BZT&?#pT2|wT_^h!dBgCr7GDuZFS4Vg!cxVpFFyb!s1~7Iur6?csj_iO;)#O>dbxli4k@iLC+ymF$?S6 zYhig6eKOREW8-`U3oFQb;Vk)n0hf;2D&KJ!a%6JlpZ_teSLL`?SiV8 zpugh@^c(tz=H0CbX=O6%ty#JDyB5EwRoJ+zUPCd?=i*JKGoppQ8PR@s*ganUm}bWh z2z0x=KinmipfnJjl@lGv{PnkyOg`li)gMzr8A?ke^o0W^?iuZf`xfQhB?)(&DwRot zop@Qwhc@VVdDr_T9}#SDi^MKBU11u`XJfrJHgU}z#7?cz{0Ef7>1mH){Qg;mf;n67 zpNwrVrTcRp{%NdFhk64DOXlZv=I`48%^@jevDQsGDbH^HU=V1ENBQ%bWx0gS5%ApglVL7*=nN5{|$=}zpdy72SnAi!EvVmA9WP(zb}fv zp_HMFlGyxtZ2+ItMQQGG{q?{JtT8}=ugWk0hvNo!a{*Uzdf+u~pj=b{=*EfCxKKm^ zI64l1MMD(ag8-B?)WLyBAV@Ge4EYa@{u?we zKmoB+h?O1r54TVXEWc@ZRtU(|6bIg%=LSC!21d_c0~enG6cxk(Csi0ArU--niT-7+ rrzpztK>(hz5WxC84Eg)X`nBjUV1@_ZoJew(WFm+a0sRj&0jkM;+U?la6hD)vMPzd%xda=luuXGq0;^ z&Z<$rJiecMJfjq(LBY^~Ab_BNfPe^rq=4vgl|g`jYTlv#}pbB5b+H$k!I4WN1c!<4x7l`!0~|)14VZ zT?^#Hjq9^NlLkZvC)B4OKg~PVFO6J>kMl!^@=AeVv}is&)@m%!DJY33MyZqSIMhUe zc@Hghqr33yV~{a}Pn?0QJQwoPleVY=Pa z#OS;NmuuN>y-Gb^t+tWLZy6H3u~N=>fjy)G6yZFP?vxG7qz7=m9$4eGy$EOSJcjn@5mc(V@w&4Leq$qn z1kRojPxNjv&oA!-wkDaP2jCI(oQHBu^>23$g)TYPKSoA~Rhf%<+Mg4_<2X zYhHrqQrRCKIvL(~ul7&lYji6byFm)+Ea&lWDm&Ft^v%h_xh$mJtzCRU*w}7jOw>r+ z-IKKNLFbkn`dof`?Nq9hs5%HHFKm}68z~54UFPQu;TT~%Ro7W&S|B9va7Ix;TVbba zu{UhTS@x6S5*NAAUVekCfNxINwR(*;jnQKZ3d(D$#*S6qMa5I>*npnREL5isWIita zhon;If%_dyS>aiAenr8fC4G}AGxSe zm4Wyc5MeTaRaihS(sMMicA}^I{r=>O%+^Do&e;$-D}8Q_91Bwj;?9_H6$kc6aN z1tr=DReby;*AN>c^GR^lyU1~oRItB+iu-o>ypF7{^F$sG5#H~xRD`3TaT7PWRt6_O zJGeknkvS%bIaF--A%C5}o4-#LmvX20+7V4v-cph)J-kUQHhU#fi!@26h7FBch#QQ- zo9eGQAgi%q_*exzFQj}{8C=uMo^u>OneMxoRCEN-AId3nI+Kb%miHHT|k!ezVkTmDcSF?fTYBbZmj~%+V zeCTpGARNDB1NfhUB*dR6+Z7ZDCy~V_OD;!VHTFmB>4LZY)K@(z=t>~SxLpc~uP#=wJi)BuhxC+P7hXEAv4m(@1X_C@v_}Do zH|Fc3uy1$&8|~o(1ds}oV5^dgwFc9;h2$P`wFNjaGo4gk4&^zG2CNiQs&d&#kE1nr zjZ_cS98up6E2bBl5oPA3v+j&kBS8R$2(Wi*y{7Hd$StcqDe}Y3ij2DkXdf+giifp8 ztYXpCuueaCEA7uy()-9lKVKmFrd)eA?(V7XFQn4o$zDZKKr5D#_)F0?u)DmUXb`z<4Z6EfTnRi%ESh z1;GN3wM=6atp^L5+JpVENO*8(J^_R2g1ZSF%epl3q%8ny$WMcYj;`oDMh&i{rR-Z> zfqm*QA=o!Se>Cx=^bAx$IT9#d9RZ16JW$C8n;3k7Q!atUjrBCDb9TZf0w)9$`JoTU2U_`u{4 zQtgIVhOv73T_t!-W)tj|XWLIs^~=R$_q&GY!+lqZkDyIuSNi7qIUAOGgVbrPa`U1| zT>JBeg)w@Vn3fg;7~v<3s{>D<#D_gY}6JxAm2ql$*K8? zmDGLKwfm&0Las#1sSxZ5ly4=0)3q0(2Kqb0Q|ui;4`aypLbEvXMH>{?>$$75b#o6I z?R^`ojtQSN6w~MK!tQs*d6!8rV3(XJ-Mh`PZ;3YHbnq!+hgij%cv&-RPmC7t#HTrq z6+AvfXN^98K@`>w*eq} z1HplSuz{d}0Wtcgmi>FA{#RWC24HKzZ~x!E+7r6v{^a#`;Y4m(Zhg=OTS&439RnVL zgda8yY^6I4ORKvs0t*(fLS-!~b?Ym7zK4^}@6&VB5HwWz%t-^#;R4d})H>u4Wk)g?l6d9Mpk1%H^UKSVB z<>Nr(la#&^jM+1lVAX77tjgCE$Zc3z7tESedn*0(E#<)%l_v9&g>$B&FuWmTwtwj1 z>0)=()AjHa^`9Jcz{Sp80^qtL&_F<#|0*I*<|Zc2PV|4>7=Krjf-g4F=^RM!x}_i8 z*AHO0P)H&rP1|`|rR1v3t`F;sWVIL!jhV?d^B+D&5(LAxq_*@@1gVUZH)C!C@q4qS zRMY;{w8kBM#>a+zR%A|!cFB(yT?_G0#5U%cvq}qIVR|hC*)!4jarr8f9)qodehMd~ z8(6b_QTfYJYAW(3y;hfKN~&`|L&|1STWz;gROVWQL+3H!G|&RBWa_;8 zt!Dixbd^A#@8npX1HO)kZ|{G{BU}j2q7KtIJh}?~kkTVfiPOX|9WmZ_p3xO=wZ~w0 z_+l-SgRVOHVhZvT9;_L;kb&N&1yhyAXKg`gS{9nyk%-UaSHTwVw`f<=lulD@`qVnS zBNsC9Zlq1cR|0Dbc!l~0lh`rOie;dK4pf?7-PS);+CM#^eArJ`L$8H(wDj)pyoAk? zd{XdaqbhK#?L#D)AUZ9O)LQ<4@|jcHjLl6a*L5`Iut$op-nB09YJ$b@-UG?A{iH53 z62WnaPCrVj3qIw!sTrkee_-zs$AZ?tAn*Q~8GbeaRL`F&T+yVy z^Gdp#CinsLGME0a!fa`tM&T|}vrC}LKKGR^>`jk1m29lan*gbgkhH#!(~s^en=b_1 z)>P$e$6aNWcfkYa&kbq6Ogwsn1q4iy~|z<{vW*;72(ZSXQ5b?{KvN;4{({h zFc%a*@Qz^Ga<$$eRkakYRIc+X-=|!9DQsnwhK@f?d>-RP@CI2ARwOKJef3lBE%Vqh-OLGQ)8-AkurHx!h?5csY5Hap zhEp1m*R%A6H=3rv(9^PXFhkvHxH+LCBV=JKT>~Fikn}?;aXNIk!^U&9y2C~NYO|IZTh3_wtSv`N0xDUt9SqnNcn>krqGQm-gK3) z1UuU-m|UfLGQ-3Cr`$7Uk4SyNuMK*l7j}P*#4R9YIpQuI#MBuQI>uwLSQ!7e0iyewnS#bPOL+$3pZ zAT!33qVnKDk@AKYW{uQ;)ve9k>-bEV<~kSPGyA_{72NO|E!Hhuv9So+6MSrcOC=Pq-Vo8WV<7uC;v4z(7v zw?5d$1hez471k=K-^)ubyCpgh1FEg+6NTS}Zoe^6j%aII=F zK%hg+wCa(L+9Prr*n?W`6n^xA?uI4H@m!popJ{$w{v_hwaX(fbb^WC0Gw`(I;sIwy zbDvV?Z~JIg#-7JsvKvXi8xSMfDIu9aJCi}eI5cmxFKKTuUe=B78!M`i6+t4(ge~Zh z*eLaGR2zgEC47);!(f?ESN!Q0Xz_8_>bf5Um;D=wPfxd!enErZmm6{QAjrbXqMqmX zOoZimd_ea9PXO~CWa$$I044JPFU9&(AB@Zm9G(B8Kt#lK+wL$R1z#jSBP3mffffi5 zgB;tUhY1%ZuAHxP$QdGg=G9U?gyIeASice04C?p`1j-i9>{G1iJSzva zgYPdQ@FwEEi3YNEM1_fpk)}q_gtnx>?3he@wjTN9HqCq_9u-2e6pm{5T(>xwIlCg? zGy1tx!|4WiT>613z&4d2hB93hpIz?t{aimIR?nz>Uc(kz2iy z)Ur*~e^Hx@?+X-EW;epk!I8V*SQUiQAFLouH}}{fAu~Z2z(mDX%HxUS#xm{DUQ0Th z*7MN@kSPCPzt)BaBwv92ngRAB_+vjOYYQV2M_~gaa}z*?|JR4V>U>6=e0T-}X2?a5 zPe_a>nb>DDG#9K7IGP0Al`LsCR5Kx2B1vs+sV+~w%(Gl;L=*W~i7cKjy^U*wX=0D0 z32G~U!k}SSQ~qR#7na?_CEQ>GyRGkP)wN3u&jdXREDA5@H-`e z*Je~NcE994sj}~ROCbl@3WK~W5JT7fq8S{E(Z4&dKA0`Wpf|OH*|&-ozVEwahgRPO zrnd1?R~NzcRIxClM%v2?<+F_aRt3TV(wZ_~*u(!qGZ`g0DuHjp$hq$=HZlAzGIPI% zo7N<$zVaHtURRHLeFFg^q%%V5b)8F>4AMDuidM7Zlu_SXO6nbtE0NYm$?0Mtf3M?e zom*dI1YM(xWBB4498O{MkhkU0MBnoa^x(YOo@29%Ji{0f_}Q!@3a`jTl3h#vV`G0 znElvZTiF5WYqE-LHyRJy5sB>*@GXWRQ?}fjWcPJkTpW7N{RPP|vD|rsl*c?}7xJY# zRVgCT^qS>-d*Wj_erT+amlyvm#S;m89-&?;6y+MaS_t=h2?eqY)gy6%^6S*_{C;4i z7GbX3kftN|YlCB@fEWKDce?YY-VbdL>5m_a(LlLT4(#2LzPk_4NI&zSDp<9xGdDu! zLn;>yX=9!^^E`2^KQTkv9qHjZbl%@Cb`uZ%(!<+!ZG(5420U+dAZLT!jL-ajd?WT^ z=-8kGg^bRT+1r0Z_BehDmo>9Nl%%?HK(prdQbVs= z59$X2Q*<3yQk+Ik6Cks}5POlH;WaWVb7ZxY#(eT|LT1*JA?|pJo5Jx4&HZV|rnetB{h^X zG%IW^Xx}0j?{|e)jsBt$GiIIX0pPgOZLj0ILnK0zDIW%7+iE;d!S6an#5pFu!GSKR z(uRyeM86Qak2Z<@lQM()Ed%?5zHEvX!D?Q>K%T&fQavnY|L zbRjJ%ccOm%SMUU;W6Z!gWXyNd&^XPk1!Q$mPOm0#1S1qVT0eqX{TvN=r;c^C{0h zvYRD1rA;!X1KUeVGFP8kci@rTk(F$Gvf=aklKj_9ok~77lh$B<3|)vJ1e`;pl0!!) zeExa@R{R-cC0LhNK*6^DQQ&?j_bEh>NFOnmWTFtJbXd>LZ@%J!PPUNmkg9E59UipN z#_wJzaGUi|W)6$FwWg+i<7aK=9q#3Dji`tIDupY{`Jrrgl@FQnkL5!0zK=CDb}1X( zGvyAu*K3sP>w~=6pJ`0Ja@!3C9jX!X+4W~U7-0s*_7W-6!8paZrrl-bFcf>!l+QgV z*Px)Yd2HGT3bPT>g9%v{XQk3-5iha(&>w-D&sbc?VT*J^1P?rtcR*)NmZzeR5H?+V zUtZ{^w3{!ft_TuX=nm71`&9ei-{XeTQJ#vfr_;0)j0R#m9cQ$u+ zw>EM5t3^|lwq0dF0uX+mq0Z5z>h@QH3v!}}2?Su#LSdbyr4wWW@xSHiw2Ch3>>+dr zC+plIOhj@e?BOdl2-ejG_im?8reh5zH=>#M%Jer%+1qa$^{G_BR$)NDbBwkViX|47 z=lA%19*Arxwfy=`w<|7qZ1^a-@NmehHq= zbBrz^$h|-eEzsV^Frc|9_LHzYU!bO6bQGn{cIrNB>h6&^*i8?b37!BC)P(d-%jd#O zL7F$cD46EECU&=VE|m5JZV^c)om}3v7dI9$_YncvJ0t{0zUr-Cv$~Nf;A6Dz{p`&V zDP3tDYjB_|`13m0G{09snp{R}_HLfZ|yu8mAyMauBE%&CwDo8e8%L zCgEL8;af8`9Vr@>Q4X72vId;Y<^`kI&XCQ-k~L?<>9Z`?TS|W-e%gsK{&fv3iY?5p zZmI$SIX7H?22-av)lxY-aL&H~E8HxInaM*CDLf>T4gz7Kr>i#nC2=4i5kra9tJYbs zTB&8x-tvGe84zUu`XepxX0DGhdXUJnHF zG>8HDDvRMnZYvGUM)nQ%t?k^S#`q;hg zQPjX~gU-WWDL3$3p!ql(w%I#i46+CKU?AUDDK0xI4k2}Y1wuCLr^4H5V0w;n_*pq^o5=o8zpt#a&z}OU z&;XDO+TVT;K%pka%Fd1!wq}31zjL&plrSTbz(as5RDJUkIwg_h52SWK55LQgCH%+K z*Z0&=UcqF#j$oYH^bNueMPj0W{`t!dBZvVSy`7vahn<+A9;J9gs+YXbV_&zDrmL6QQt%4IKGhzgG89iHFFm+7rFq`K?FAGuwJkHmM&t z%j&4JE#K{0pJ{*ioJ9Sj1_Wll_HF~9zypBn|GQH(b~JGPEj<0-4}b96msMK;9`Htt z@g;byqi=KxGvXFXB$BJh6R6d)oCYyEQ)L`hZ}1&CUS(dJFZuCAnKi}Gm?oALS*i}@BDEXemY#m&!cxb2{F@jM zfh_PW3j4xW(KyVNnxvH6AICv>qF6nV1vX_w%5{hwbk6l;cxo}AM_ zP|;+rPhKsVMlxlk!?_JolltmBNonKR#8zh(16NTxG+jZ4s-b%kZIa{ z{O26Y5*4Mn!6rp$lQZhFBsgI zs}ASQ6}o5j6DGvIEqggLmt2=0@now!Jk39b+)NCBgM+IhZ5IFNda`~sg%Jzu^2Go3 z!14}p$?qcUfor;3{&Y(>>eKQf<8}Mi#V@*Je1`a$1UUMzA!a9`fAV`(MDO>g!v&wW z#kKRKA1>|Pkz6_f8v?eauw#S!g_xqh)Ob}c(2VSxuCDymQ6BlFdp~C6J?0S23!x0Z zCj-OUbw+@0C{p;J#tZNsg)l$HXV$^2LQ;CFs)>Yx=awU3gt84Zd&_RvBvx@(QZOGB z+=KN89?y3|kQr}$%R9kf;zwhku$ILiEr;2v7GOc;1DEOLMxC8@4tW*9aFnrcV^FM5fz#<6titODF8x9FsLc-aEGtNgJ2t(v;qEW-i7`;lF;9-So)2c@ zDPBhiq5?xHUE2*&$ZhGR9v4FDKlu{`%wzBAF_VP4+e)@Ri%n^CW>!A!p%3t_bm;rc za3YlyF#tsnR8=!^K0ZTv-{FX43g%x0-`|&RL!<^f!&yLNPWz3)5e>x!=~L|OBk^XA z>8mlfsDzLGI7w)#5Yr|)@iSBww+uVr9_hQh-nrhHMPUOT?J|~zv&@~Rcef`-Vax+J zdv7@p-`aXbpfm^V#+tEcRIm)n=psztI^FcoDVNW%=yU(Haj=S-C-QDE9gy2-a5tr@ zXO6=F!pQ(4uj|cw<72o+r4qpR)_d9xJ*WilFMU#`uNO7R55iOMV%qx81d>!XDT*)v z5NLw|0RdWw-yOn#r-iRJ)*^pW1S1{bIYOm7>i5uw+A+WS2IwaW5^$ANu+kOF=t`Bl zD4A0v`Y7`6AxQTp+)BMylf^>qhVVBD3BuS*FH3yfO@HWGh)MiHJ=Q=tHPf5#z>{3No5t z)K>R%`tdV|`H)t0(PIPMzWm_Ja2f8&)roN{oWqYL(YK55@Wb;8k_EmV41`jdEL-r{ z_Cn{pOQ^@Pw5#77n9HTnjQf*SzoqLBwnR^bnlPPaMfON}X`$rI94O?f(^2@OV--8o z$H|(tFXLEU5>e$Re2o`S!M1{}nL2naEf6Oc86s8+55JldT z?U`dtqMX(7-^Se^?+)8qH%=d?A$95-jQj}Afq*gU zakY+)-f%_Llu;MBk&twkP+4RxOGqo3HjbaWO=96ic-TZgQqYxfruUB}$xm=sjR8=Qp8zk6zl-u;Y{GxB3V#Yx zY%O3v2TjzKxCt6 z8Q$k0ml<;y5;-8~aamdy>Fqm{Pqe_Clg{HF`QSnE_BC{Nc3-NJc_MNdsy_!!yyX5| zx{{+fFeGhdonYZR5Hpx%*=GLw4ZY%PCX((Qhin|~p*myfc8C&%4>;4eDFacX3d4>5 zfhL2VPW)gBKgff9-TRqrGEE4HtDVyMfjVz|ZE+S&6a+46j9tAYweQRH-C+-1T9Uz) z93zwmIV!q4!fB-hRNgUgzjg?$V6vZ>*7?RH(MiKCarTXw!zCJ9qcMi*GF5NR43o|D z{5W6@l->9~U9mB8;JmgD9vO@e=Ev9^QWh{fCX@J$qIb@H@%cykW}X(4F#{0WJ*58) zeE!gH^iIEV|6dwD)wHqO0c_1s$NCC@-kMWdQn_eVI-_({-hcTqN#^jgEh@8qTh8l#!i&cq=JmZK}JZ&SM9QpAy->M9SpHD zZO>owg4`5%hThbM$GCn^QY7`XZ1ZRdz4B2S*KB80=v2+Lwe8Me*P$tC-AH7odU8g& z8u&QPy&Ye~@ey7Mhj#3wDvNNzm}qYYuYupBU-g-WHeoFt@>kL32{C=2g`Z(C>#K}X zP2&#go&g)Mh)|}M2m`h^#Hg)BmTkQ|1nmK^k?N-y!vSI=NCvveu~-}2QzgcA+4_CU zraH52U6fN&qJZ8&EYzE>K*hsRc_PwCs1hp^;t@&0(bqR~ysQ_Ud0AL1&aDdEsH*}i zov+|RUlAZ|xzh^;>w6etp`Qh?v`1h|M?U^kB&1o*kU!eXg}* z+ZY&6wRLckmatkXwP-7pUE5OBv?q1r5Vvxb11ZK0HwV5FgR$8uD4w}wPLztSnVD1< zGCn6lOp(Aj4)YK7bHkF2Wkh@XhZo2S{IqrDe^@;1}|mnHO(?iZN4m(^!ze$-99A|r98Qg`KDII#ym5&S6Pdf z+y-=(JI=<64~EFeS{qUo?8Tx=eG{XK(BX`mtaeTV>AOZSOLqAO)jgW$_mFA?S353m zg|++gO%)^Q+=uJXd6pMb0ou9zDR=bcGj^?CxId*H`2+?X>^21&0*4@U%#KP`N;PqU zO(d_>q-5=$s&cP7+rZHHTvB6i5Iw5WoPO#0ri33x6@ItA2qsFx*IIvr{HHb!7p=JD z4Nxg;0l5zSPsR8NHCvBG?Ik0TUi z$|z8waNFI|TBfD1Yu{Q5faMK()8E1m`r0#q9GBt0rR=y0+xtsmSjtvFBMB3EC2bqI zQ9sPmGRe%kF|bUYn6E+lKF10ov?n;@DnyepZ(OY5DYOZ5dPFXqdi|R+654XQ)h89- zRC&t@_z{|{iQbR2;83l}m;TxO1*I%S2k%)$`G_ttyr^t>%&wFz_qI)+dzj;}`^BN& z`{*?1z0He8E@fbLiUbPwJiec4-lwR2W6Fa&Tu^#6MPOK}k@qrdr| zcEG?FQag1V?kY5#q(4e;sDBPrTm$bciV5nzFahPD*tAnL?>)N*<&^YC_ftL{Wxw1h zODIBK!^-C<(~$IxN-%NhGI(XC{wu{m7K*_N?qk|lXVXl zacQ)P9mLFXgAImp8bAU-WU}8sEiB|Su=EGO7)Ghcl6sXUVD$BrXN43kBqW#$mZI~V zicT}21xl_FMTlHsAPL?k7a_oqS{g1#IG8Tt!4fM*6gibP>?ZFd`he*kf$Dd|R7RAY zA_E1Lm8lCNKK8#U%#u1$0Vm+GR>)i}mb8JW%dgSGT&bi2#M2RO&N|fdktV z`2l;x|2Q~7j7(AFwIE#ynoOkAgOX2ZfNWjt(=6K;2e`{%m|B(PeZi#?jkOkn(V(kSO>Q?!@1oHLVQWE6Tg z2Sh-OL%N0PCzig9Y&qKDVEzrT82aphZopefr{V)%cL;74;_VOIPb~^-f^J)bj%Q7X@ibLPHwVcr`Fkb1qwkOu8ca<*oS zK>L58MDU1mZ;`!znj~1Kuc6UsWl_g6jN$>Cn&EXe2-zB~>r35L2(oElez75rDMMl@ z->Dom>uZ3&K6AE1sF}Uz-`}FqLtv;*3gK4L5q{PG(P$-CT&E;2pM$8&IXWneX){Ig z%l#yHA%qT0XA@Cyp>n?Bt8I|*s>xYMRcNik8Wg)sriZghb;KRDB}?ebU4d^L;;sRI zs63?mRP?~7Zi_6$07*2&oehGhfp2_p@cdHZB z9QMCPBV{0$(Z92JSm{&7h<`=ulY?88^gpLS5I5{6BqtG1LNT6x7xOL1j(t_6$B!e` zu>IUd8^@vx<+ah;&hu~?!{=5vq`^S0q}cspaNB|b5oi>v#CH@@O&3kQ&Y*yOg~r$| z$*+xq&WGjou?`${g(m5(NFW2k(4!jhvaNDLRP_ZtD-O4GFpmKDnTgP;AeV}KUL}v3 zA*j?2`tD;FQn*Xa zh)5u;)-v)9Ud31tai&OtEp9bNtN9d%9!gA%za<$rXX@AZNt0 zlO~GX3FER>3s1ey0nKsE+cus*pkv^$8Wko-w1A5?{?M>-dDA)RVKlUkxE$*7KS=~|6GhHwgRn}F z7Y>9P3i_Ku2W2dYfgeY(=@KxlTB3+BFB2o^WI`uHZbM>E!{c262{)wOoEGLvg+IU1 z33_9f3IATq53)$oOhFhY2LovX22h1=GzpP5FmA61G=sSU5BN)eLsCpx*%s^mJyyvS zXM_3hp(q0rA1bBA1>5eW&jlRbrsdI=s zY(kW>Lg^sIM=*MnKoXLvHe=B4>X!It5T##4~2#@8wP zWCNXmZYXkB0Hu^qDX^RGUt&E90sIfoR<%p}ym zTv1l59c9LMge8L&#vkBI2v8DY>y*Zhv<0-Ki3=s(Di#YKlKYn>iq*I-$N3)Bv*xUE zdv60zH^as9PT$;C9fpt6<9Ke|ydlFZKB)2y@)a$beq>5jyRei+h$*6xju$x1*>*Ok z8hJNeX;${w=YVd~LD2g7*;OLoH!7-7Px)Ss$^@+BEB7_Z4h<9k>nj4820 z)R*d6ix;qU9zBMc-k`9-%CBf*_9gNa3~^`}#`{$_M8&UYwC&50{-wO9O<$rg%zC6} zYj1ERE;$zcl^=skUvi5rW6<&fw=xy@h)X{)a!gFq3+XEHaD!_cM`*blBFftD-^;+de&*>4p|Z?7$tpMu2bbbRSRhgd49fa?QCy8+2i^a6nimlb%&taZW9MLqk(wcZB( zx%@t|sXb(?qJcNoSFWetRet?R){d(K+7+`!tt?mVYcS-((fLcLJTI}hFWHRn=G^Q4 z$UX>8Jt4vBiIhNdn^P24sDmg^qNrTKx9`Zsq_eli69mm{ai3ePWvK=7ULH+)yL_|s z+NGMDuT*B{)+BKcJxM1Yle0IG_R?WrGbr!6llSe`?$9?9AM6){gKOKHvfHc|38&Qp z-8!+`zN-;i?YRFMg(q2A;9a*A^E7HM)KR_R_vU&28vG5{b15BJi+FVFj8&DM^M)PO zmsYNn3Ss-qqA2*CC!{<;t=1kHE43}soefO3(+RgaEB@TE7Ej*Red+00s`p>>l7G$gR>Y42xDO=J z2Z>kVJ>IMWfpCRcx{{b5qWho`yzZe(Q9MOcU1ntoA&OcmrPSQa*Byhd8Aq?ZUzf2# z8#fa3Vp@l$EbKJZl6Tzi++4_+zK>wdyN47m5rjRRUK>6KW`6eyO=~KSP{mEm3#;vd zBv{W;CGn1q;!Z^TBKi);dMnjchHa2=Xav>8+D9`zmQ;jhU{NL7v~qj;+SOED_GP!{ zggu<@ywlPbDMX z!mJbDe32(@>Jcc?#^rLaoT9Or0WK^=Ste&_mK>-Sx&$r_(yp0UhCK1!&D3I>V)cwO ze#grCh@$(23a`I~lQz%mnjHW5(Lbcml>!;=q?w!K9m;Ka?gVI?1)%x=tJeRT zllx2SfzjPCfCfV3BH#n*-gd?VDYmF1bW8OZvf`)-zDaUOY`Tkm5GJ5``Sbm_+;_RXfW;oh))ezCHdoYf6&aI z`P_f>y1?l1-|`1u1Y7{*SMvNX`9W!h?;%%7jCVIz)5CKJ+*X%Ox>8Hi26@78MDaRi zYm&gB90yjX@31G%3>v|^p)>o3xo0j(f{S$N%1~ufu2B(<^kXTbSm7vxGL@_$(qan{ z_pS?X017ZURTXgR&Qj4p!$IfAQt)N$pSBDYZ-bcT6aM->d9TBcz2fPVIb4X3F(TG} zXo?k9TU;PG@({HtOzC8-;8NI0wLlLL?muG=MiB0}53nK*5TEjo`2T8pocqMqnW|0cMU56q0p_}-HaA)%7NY;+A5#08TRv+wD3iX?B}M6_gtk!XJuD4LN1ly?V-gEZpF-lQtV1ER5!a5vEe%S4T`-}TuhRE%0p>dAENe%uPo@zT za2?m?=S%S`X3K&>@(>AnGK$UELhABmX@2;D@v3KLZdx8X)}dIYq!W$KRm-kLZ7W_?Pu7V!EaJe$OHT zBH+Mw_Eb=WZT%a;sp=vm)KLR`x^a&T(#w6(r`mAwXy)DzZ+<5p@4^zkSW<;1{U3N} zrt(HZ^+D02C%vc?rF7ABN@B3oFd4xwZM!&PYFZLW3L>mh7_icn`x;hPuw>+)(Z|l1 zkjd3nhwAAj^wuMuryioye3|u^80Xy^ejZ){9oHq9b{Z6Kr3MzQxJ#uKQ9edmj%Ag- z?X+|%koZ(v^@%z07&UG+XQou4gS|DczJ|PrQEP?cmv3}9JOVnI{|pP%kqs6A-f^7NYA}*wSK8yi1;=C*G?@>Tjlw^dw)-B- zCZbZ17_k2sX5q!@`*CilS9+>gjRpdo%j`DpU?Y?K)LF#3D-vxy2zFXkxYPHueC08b zD4JkgiytPSZ!y!bV20JmbpB#XFuGkZGG1(}wLHRWu5KN>38^8eOz)&X>;+diME?Hh zq1@UIDQMp!uE2q-H?+qVWjw%~jr-j+UqX$&K_!s64_cLJuvgH~)w|A}9aoh9^c>By z3|AZzdT8Wodvtqs`|k2?(9F#zWRe<2@SCy1&q_Aoz^1a{D<=)HQAx!CUFg_PkfTdl z7*}J|`Bx30GuKqu>B1-l;wX1PPq8NZgF<&Nl z)UKUW3a;jvGTlUZG~BN^q}oL_19gE02jUHDG0C^X?*?4w@w;?Bb!NgY`q`JXH6H7~XB-naWE~cKoIm(fwzwc+a|@qRIs5syiJtuAE;X7_h#bf7L1!!= zzuH8VwaSBw$xRK1Ai0H~U89Bv`EYLasGyc?&VZiXWa!sq|NO(2D>8QERG}=r%=NiB z>hqwUDMz@RAUw}1L_?)uQWvR<&-_~6n_0>Sz;*u9v5=nhoGAg0RR&lk|F?Ym*Rbdx zzUi+=5ff7jTMK6kJKMj4u03JWHeCQ|;P>pW`30uExpfTTwcfDOs&M>4r|!T#)hXSI zj&>eZ$N}p!k$1#iB$uBm*dfP5M-{2Lz$rFy@@gs43}Y`aitNXIzpZN z6>E$R5rs_ot#L6iW(<3DZ;u8_m*47~M(%6;Xp`6S{Jt5^kQm$9AbVzY=j52?z{FrK zQ_+_6Yjxbn_se-_Q_xWP-cFYr+4LYRbW&HekklHYW5u1`f z9YUIR(Oy9JeID%XziH6*at#u%cdq>uC#Sx?=c#H55#>!6a}qKmFMGk@@q^EFi<-pP z2Z#Q+yYwYJrg_uOcf+@%3!+b&Tvz_Qq+=(>48TMi`mV;R==TFrr}ECnRMLiWscB|> zazYI7-9|S?gbI#V<6a1=unlf$zH3Co`I(hFtFxe~x%ByAs#iQMSsh^+yfTWt+x!)= z-Jk;q^Ih*}2_gqx=2atI^FR@5$*Gx9dcCq`R0lphzie{v(M)6yg?;Z8#M-hw#*b}B zjL4q(*8%(x`eH`Jo_fSzWtDU*Qqmv)h^X0jJ;Z+k zyo?u+)k*#@-lk+?Wanu7haHZL7PR~gsjG=hvxkQB90K-flpOtL@C1f-)%C}r#`_AI zs|oy@jN{ioUI)Kzezvn#$U_2GrtC?-a*otp!%3`cbcocwvQfKYFTf`TT5;C8S@y;>J{rumH@AIf z%OL`IlT#ZtZi5uutoklUh7mU9r-JZ0WyFum?J^(@UP!zE2J0*1F$hD`h-?a_ zB-%W;c7fN7XEYy)>pq(|?u>l91hW_3A??9A<3K1}x%a#5b}&8Nd^O|A%BW5xan;Xc z;3__1$OUsYkjhQw>}btGl%sUWI*F6cCoIOXzx8_FHQ#v>0_mPz*>~Re&SX6Jj!tnN zTm%uBHKN|n`@TZz)CjKo1Km$8E;4Q}kdlriGEfFx&!589F5N=`Q`LzcLkOnpNIjv1 zs7>9{=v!Gv6|KhV6{MHV!~7Svpp?2;>X4RS4vV-(T_ z>{K?Zo@=|AXkZ^R11Sh6-1XaS&m0k_py5XOGpCoC&c^DC=rd+Rscp+)c3%WfS{2T> zRMUDRuFT7U^wtG#xq zH~w)JrWYjOw!#Msm=C>-D0Udt7ZgNKnzA!@*+C<25FPr55jzs?Un95N)xxMQ1Dgup z#SCPcnI4=BGNViP(KaP(-gZ2Tq@8^CD@%Yk!FA=9&=GAaB_(KJQvdl7XtB}f7}+fR|E==Jrz7HItpFAdzJPs06mk_0TlJb-qO+;<@4>sDy049%s(S+IP*g>Vqa)*@ERvmnj6Y>)Ch~Cd|%m8kT|~IeYj4 zjR*4tL2)rsuGb1Z;ZKeRcd0&iX^>s9y% z;qyDhYTo9Y*khP!4}(PB(8#$|dk13Q-`{sTV|d^zTwuSg_n(?CdutfdrRD5`#V+b? zd@UQh%H}vKifN7$U4xMC@R@P3e?C>ob}jX)t=6dG(9Yb2?Cak?%r#xI?9Jb5CGJC& zcxMNbFm&Vl$cwFhmYTQkk?d+TS5bfe$K9zd*-d_0fSDiwW)it&=QgF1hccKSm zACun$wt&B$_}?SC0ROd)9kuNx0MHtV&xjbFI7a2Ff!0Kgs$U{iN{@us2~$WYAc%7u zt{?hYTxJIyTU-%bP1BwPU6=7P)H*DXDWwwpkvmjOXY-2ZiL!IYAZquZ zx=%w%i(YJX-(hGgY}HFJWx=fG*+3;3p7vv~Jcv4{P*iyqyN4F8>W}tE*#W7UxJR;r z(YbHAfgOA$%0pH94sEfilMJM!|4ZN-G+unbmYp3?@mm+XB&U-ldKBA)^LNjQq#fmq zHOOkRT?V**ghe2?y&_W)1& zPk=>{hd9;^Sm^~Me58N(F#~)1|8+5dZ~c8`DD&F=o@Ix<<%e1`8j(aogXkx)*EBX) z1pQi9KQ~M!6$|E$d@5(NShfC44q`kUgHQO8uk@utLJ}!QC-BA1?cw}rNN%xEj_OiS zBR=+uf)pCl!pS5Ft5w^J!%aNSuV+t43lwWvfS~yG42SJz!CxGlFbs{%*f{7HSpr0B zfKs5Mb@~!z1wHt{9DOM*4C(gT$O#JEOfL&>ZjBfN=N@DgF$wK%LC**2c%}7iP^?XK^ALX7gTl!Y$hpNc@8pblS8}yr_#)%%bjgaB;-FGF!4xFAK_z&@Z3}K8z*s z(1C_j1wQ*P+XWzD3*>^{;Z2|8_rjs3hK40b+fg9$DlTCeP@_ zh;wMqd-$60%Z+?mK>M~-w|f0H?{vJCH*LEHFTA}!N;1QR$4auE_m0Oc{A%{N%#;sT1u0Tk)6+o;wL^~)2;Vp z!3Mqo!-ZRSqTpS-F|YeOgMUT-=vagwb|xJ|x#m4^&*xk$zn8tf8m8ct+9kcWjNt3! zd;iCCt~=Dep4|Y`G6P(n32+DW?|-p2fBK3)J^a7E`2Tem|3&Eh#(g3eLGRy|JZZT@ z6u$4{qJXqQ9D-t4*n}@>=Bf(4K1?&_2H}MmY>YLu4KkH;lV0J%v8cj-4=_3GHUIw# zIU8W8^DvID7ImF6ZmyMx4qKT^mu|+pLtdIqt3_VNh3q<0tCg3nVYpM7xhT1@Ih-<; z-8)2F7@BZH=l!Ln6NRxtD!FjyjL7}=zk7cFeRi)H<7MXgc>cfr|9|`Zp6~NKqrFBA z_0Eju(dbDhO}|eD;tPyk=SFnWO|!1t+(`dE#q9awt*U{GG(nn4>X=qOtd6eQ|0iJbT3bwv_h^oL zyJm7A(^qtUCTN9Um8dfG?Vr3hH-i?!6D^3m5+a%t6U#e=RDI&RbTi;&c1f@KLWtY+ zaQ5^7eN#2nGkmw;dhdwu$?fSuj*)+4vX*9i86Mg;-JRVnBh)3Vtj$#j+oY54&s!ZO4>>z_}%o0wT8Xk`q2Ixp6n z5izc`wyhVWMLdY49ZNgj^=vu(#vy;rDASrb%jfzx=OcYAYeU(G_Z#rej%DZ@Ok89PCydQuyU1fF)CH&T z2O?VLp!cTp(v$iHVyGrQsN34cF+q%x1Yr=IaDt?#9{E3-$S(sb~{JS6G>kQwfqiGFC$`=FJ!}pyX8w2!&PIl?` z?oSPRx=YQ3{2b@MEmac-6xe`YAUMdElYA<;N* zOJxBw!l!P2f}cEAkyD&3u4x@wH5Y68WW3sNtD>VK)Yvp%XRmFyPi~>{X7*x=_+{U| zrKrwXUF|^MbP@fwxyf96;SOfN>E7)70?yI)>WlRjLHtttS=at$SJ&-Urnif!ItNVO zF%F3RgqO4{9%nRI{F-D}Q#<_4iO0!r9C%HQe2rl1^3B6{&$dnN-LrpbwE2wT9o8}$ zyrs6z934JXj{!t0ukfK_C?EtV&h8>xUqV?0*|SbO($EmjGs317C|*Nb26<)*G*%q6 zf=wwD-;W7n**_*DR5}6YVPMh%YPga+q15~gy@7rGm=dR>l0u~GAO-ebV+su&7T0p1 za8w7xz!qSP=|@`+!jO7^|0~@kHfG|1f;8BZifLJB>qj)$p$Y-8hYbS?Q3boyowbfO zXbRhauxUOjkCK|grXWawZ8Vs09p#k~VJ)XF|3T#%z^Z#psX`hRnF4C?p*ygI8iOo$ z$}UK`pc*n@i7;kdMJYVwj67403x**9mgQkW_#QHWRHO$Huu=^pvdjqt7HO2~)*uU3 z@L*QUJ_UEy>UkgmO0}4<1L+HBNj@apLLgKjF)-WuJwPnQKp@ohFz~7k=^Edo@y)i}I2`}9Ta^MgOlbaYCbKw7>tgrPLuLz(f=# z1i29eg|rm3R?LrJTM9+(AcdloErI5WM_;lzhe0xzAB3SbJV9Xl;KOh^Nq4s@wL;~6 y4g+$`k7COBO5r(l5r(W7k>M$OeH7!>Sd{@R%R>WceiVu^`po=@LeXGJfBP54j(O_< literal 18819 zcmb_^1zeTe(l;H_-3`)>ba!`mZMr+8OX)_CF6l0jZlqHLk?s-+X}+zVb5P!M&%O71 z-|cVLvz`B%HEZfwGYdr-a0qmepAQm{c$nr@PdE^e?@u(~MI8})I~RbRi-D@A1Hf62 z!Nb;uR{;1z>;`ahwzRk7BV}e_A|(dcnb@0J+L`l_s;P?8bCMD}yBOJ-8rj&}0r*Hg z0nVfX{7-m)KoA3o?VR~YEnHk2xEUFpO)LPmM$QcO4gfpgFJ|^mwni?%uTJKS4n`){ zM&LAhGy#~}o4DEnr^o=L7j-gn2Tp^O@$W})w>5h-f~D{ z|MD-09DsPgv-Okc`}Kc8V&wq%dzv3V{0kzW_#Tb(>-4|>`Y#Bb05;D5K>0U<`(tSs zfRsOk>uh1^;7t1uLl|4y{dXfgS{i#BfP%3Vz{KVI929`M=VWOLASPBca&nP3vIVX* zqlXQngQc6ji--|Wqkj1aR1`})%kLV%{9SqfS6nzdI01}Ioh<+W7h4;Khv6Q^_)`Y| zibWTT?+5@>5qsP3D(B4j=)!-(qpdSNz{3P!!|*4q$sb_12Q8vt<1-{1bPdH4bP?-+0fIs>5FV*L63pRn+ktbdaH;{ZTEqUdDr;LHd# zyZ^PS0lvF6prX(_03iWRE|!45?CW3Ymg!I5<;?iUhyP@L|Gdn90R7{vfp+I^?_~YM zD1egvZX5smfq&PpzwrMZBR?!s^{19SeEz>?=K=ZO@&i;hdpl=F-~s~Q{{x-)OWl4_ z{5$-=1oMaBS^k3|{&~g!KLzgs4B`NwF9W{*@1^|%=HE@-*}}*PV5;Kc1dP_s|Hsq* z4g23R^24Y6h&q2dmLFgK6FK~~+&{g`54wLG?=Kf)V($d_?`QpI*#1uaUpN+L7f+zy z{_lr-6vKblt)HO(INN^}(v<+wn-M><&IY?%CLw&bkh zG8ho5WQ6oUo1L|Pa@nj)jz%3@XR!CwgKC{8yM@siEgf8es%g=L#5$K<<%t}Eya{97 z@>}JQZ8qjeybxQ6);?T+-MmR(zx?zDeL@@-^9mA2?l#+n;29k`Hvpc@5p)Hs9G2e% zr?qj1qEgI)Y7vd~@&~pc9th# zPz5f{_uDGqvi#;xzAHR#s{+uoQ;Y zP`qlqqu9>_=qQ~Px(G{SOiLVQC)kwr-NPhtAse~iA=7V2#%H@056(VPP+=+rWufMT zP@2whcGH#EqUvCaZPw3zioxb%oQ#}KyiUwZfjUt?NuNOCC6!J;_54uoavC6bRvfFT z89;+h_(cD9*^QW!jN!$^Y9xQIePKFN;PbAT4_8`Ch+}81BeyFXF}{&)n;*ZGD-QL& za)&uA6jl3nCPII2-hNTPcaHT9@^>jzlJ!oS0Tq)H3Iqh<4=McRMaoqd>=u~dZ!v_9 ziWy~^pH}G+%ORj|hl9!mw9+)B!%X$Yu6KQ`@*|?)a%4cFZP*|ojTz_`QF3xyf{XrK z%q}~KPszb7uBu*Q=Ja~4(Ut3M_kbp;byre8*JqWWqln=-zBiRT()3_pmQF3T4SJ$+ z#cry|&UxB2MsJj~k>M&nix z)&P>vSU?Y!m?>(h*flst=%EF z&X{K9*Cs%;3ob@YKGU6_3I$g+O=rivyyi*_q6@=FHCtGmNrsLXE;)CCChoT?M@`WI zrLRegD~}I0I3#i)!Zk&JvZ$oms${s+ah?@iB6crPaE)HUXcmWNHARfx7o|oN%D26| zD?r05k-3+|R}qw+s7z4;h_{p>k?u>SwG#;aAR< z>u&;lO=tSj0db{dy&u!&UQp)UyjAaCT!^sKq({Wz%sX#jF~S{3nAcY04hSon@OAq@ z@z#~w!aghNjCPl8=y<^sJ%fE;?#%+O#scuDy zt}UY$fpIjsPER;F*~=ei4jB#QHNTs|rC%g);Rb>Yi|`P~lWMlZvz50+bl`n37Cz zFt}09eMnA;wBnuk#6q$Rk06`<3)fXSdTwx}_xu*Bo3|^q%RJ5l-$>>R;0C8F{Et8J zUD!o-p$BFN7{HnBfr)df0SBJgQ+(jsvKzc$8IhiUuU>~?+6`VH`)|N zgd{+8MARNOI>ztQ`N`+A&R&U*QBU&<@^**=q)%r&;T5GI8>pxsXukdoRmiclhism z-It%Y+%I|C^_Z@_{ngwYz$8YuRrx66IB*3-X5jV(kJVp+MCyY#aJhPan5%!`ka>+) zlYtIZQn!|B0M@V<0-eN=HiypSb;)xN^}Cp?WkDvN07dlOVo-h+)1P^#ZJeG$H!*tX zy>z#aOwKV`{s9BqyUCs&+$eX5QEuZL2#3YHR`f>h6urzAB&4tuulf%n4d7cd7Pz9} zr~tzrs-zvf)7kP9@5IZFsP%4(Y$50`7BjP5EX>>*|O7I=XGZ0~Bw z5g!y-wC<5@HY7(Ez6Rar$AnDuLpo(74ujzRwM>l>CZNG64&6r z3vLDl6Lu3QFgalC1MZ-L7<}JbWBk5P=3E}HBm>S2?|%Jj;cuDxk;M5LxP*HWrU!$D~89rXTkxXaT=-CE7fS_he~9>&zu3 zxO}SgK}JA}J4ZHRzvzdKw|gxG1PdPomF~8WY4hTlzmY?2O0_!^8ocT+6c);g)6!#f z_Ejd39M8#aNVkl0Dj!|l({J~|U+BkW$il&jO1^(fm==;t=Kc{@b%dNNxlM?+`n^AVF3zrBF zN6ivB$5gxX)fJ}*IIr%mtQO`j`xdnW58sbCYE6xLvob#E=h;rhvjl%qUf#fW(o`2C zX7Um0rMH$Uz*CFUB;Z*E_?N~(VOAn}+n}gPRoOc(!;Z&!D&DS!JG?!@b#f-woZ%V>^{O5p84b#Z~-X%T<1`qHt=* z#fiC446I`oE&9cAS=xy7K9hu`t5SvnrCP`7^E)B0s&LPyiT5TqBAYi9O5cVVG&Upm zJ{ulm3O{L&h?^SlnX)XCHFH7j!y1$H?ksm}J|iO^EWp2tkX@atNlHR_yU zW7(+T)i&eqJfhnpIVd`Nlh<1LR`urFnTCvL&`$en)v4XDi@~TN{%NEt)nWS+Z^-ut zl?>Pnn(t|~c)uBFB2A=+D&BCm+FE-X*H==rzfJ18Y4E$IZ3(%kZW2(Gfrl6YJwqEz zrz9qIqFb5Hdyn7xnPqI?efa&SBd6_eXBZ8hnV8U!t(lA*Iv24$0as1XB-?AQqhE`A z!dolydX8Qt!u6$4_fQosufgx&h==0!m~`eV4z((kAB{NcC42K>daHCX=gS1DT!9Yq zvxDIgFnS(CXr|Y^+ZSM?k;#r6VFd5YS$R9-*vQ$0y>~-7&Iil*tiHoX6-~#_kzWW} zGE!A$;u9=2^b(%sVA^1s9rp@Jf`E{e7&}Qu);j@hkh4#%Fn3(ejbjV;elsHs4s>6z z;3Azz?*n4gt#~8W>a!sP@|G0NjfL`0zWGv;FvxoJ;A-c`(ZNe7nlBwXa{Bfc^#d64 z+I_c!$tp~sUO?hIAhs7qGp&9U29t8aiwn!c(55$3;d7)lsXH4-&Ut|(>dAt(7$2j9 z=ybX{vV|!Z8#Biw;gvpHE-5dIVyOP4YD{+tH40T`l+!#Jt~_O8soK>knkmqr(9+*5 zvvH@+1)NKz-J=Gi#%VlK_@fV;N=LzuUuS`9xD}Gs@3xfe8m6Vt)cR2Gm{6{OOy<)=_Cv=yPl#Oi+M zXV0{TllnZ;LodTr$Pm>ypGlaFWu5YqUnls~s)eQF@Mfkd)Q7A|aV4AJ#wCjBe#K&c zM&NC#MZotOYIdNyX>&biUVfyG47bYSMK0_!R#!N+0dupPWM0}CA;Y(cwCb^$trC!t z`7kD$Z42?ikix{YU<8%0rJF5W18qp90BRu2aMf5kJrdY z;V#@vGE{!DK5f3tQ3zP1@xqwfQ3!};2{YrVvIQ*S{lPpG^|mi9ElN)M4(c-_0Du8m zy!!G6Orz7t`dL67t)}ew>&|-?=clZ**-w^sv}YyE3k&x9(p#d>_d|s}$+vp4dY=2O zD?SnC9pwE=8^|YmHe^wHnJ~|Tb((FqO}S=viwF04XY_;eL|z%+KyEqRjZioUq9L31d5n+aSU!syK79M7jD|$PD@wPRJ`R-S6@8!uTI+aU zDpu|*x7!~1kd_a&=Pp3uFaU!)Fa@8L%45ZCoKN)M6qjs$ zzddE_#hTsYSqMoR85()mF)_hJztMNWyk`AMkfHwcf=7t@fTj7oO*VIcr1+I}Dk>Yx z+v;#nx&s=g0?4PIa63v#ck32fC7FwNlt`-mCYU@KxMblg(JlPYs}-wad&&VjRMjuh zaq3x7RJtZ6f;{*Y=EZQG;ILQmit>GVS8cR9Lf#@Ae9~lQPddjr7&m&~ec`O4h1hc> ztvgy;&3L9dpx>rIu$?^N$e0=&0>ztm9do<2a`1(4%Howc!rO#%RbdkR6#+WyR~Cii z%;Ly-+Q_U(G^bWEuU(uKzv|lw(J^6vh8Xk8X(^9c@F%3HhrpX=7?<_d%wYO7$Vy97 z*S#NZt04A?DBF9wNN-D8c45&Ev^VwI$3Sp$Q)j)5C=%1-{1gn|QWnua4VBR%p&b(f-uN9rW)KST7_k6aj`m zVqo|q{6zwPUpLA~lmYHlA%|89J7f*GO=dIELCb@Yfd+O-PP&aql39cBLpUYQQEt}^ z>F2!$TRcS^jd~wO#}fl4gcUlN)g2>X&Y6~8k!Xr!NPwGhva;gOIvzr;#OQo?Y3KVT zj#WZ9MHm->%OGg&&6HFSQs`k%YcO1qBH87^a9-Vzr`&X8?J&kOsue^z@cByBJ{lok ztCUo0x)+l(Ao-^3xbX5U6pAOJ*bCp7WYvs7u?j6PEToa)lp!c9`uZFTL%v31wa$>3 zhkWTNW!bvR%(Yy%)-%WBN>Y-)L0cp4w$JtP3ri#eGy`ArqMncBX=WMU@B%PW4yp7r4hh zT$}XKq*F7Sj!ywB@dsUZ)_#l;y3m(7V_yErv0vS*y8c!qAzR3O>u^vd=M&jPIcy;rhjggM|k z7~pQt{ot&>zf^zzX9+1I-r#!**4zH% zD-SbbFgaEJY9)H{JmF+L(dSF_KPxD&x*EKMX*7P))+Mle}XC0KzRd&m5N{D6HpO7MH zCAO~;vEuDg?V%j4uIG%u4LYgqxB*5}+NE2XV4uTc+ibGATx!1KWK z4hw=9oyyZcm{$vVCGCKyLdR!xZ2v3#S>1z}5H3N_3~S~<69 z{6cyV{T+B}vNbZT3C5Y?JTCtETs^42&Tg-ek>_U|tvw6XUfeyF^W`*haKH7wFd5hzt4_tv} z;0pXvg89)N@@wl!Mw|>VrlE^98WUzdb>a^;UWLGgftW{3a{(>6#gEuEA?K>*7!PrQ z+$kHEYvL&}-kMsK+EM(*Pe71ac%tlJA2!cKL56(_{zb8m#>fe;bIR=FJJ2yr8npLG zJuozEOj&aDKAYQb-%X0fYP}8%e#I#wBxkTerI$cMU*sy$O7ZlABw7NAcIO}y%u`Xt zr#TeCq<3(linq$^t(q^>wa-GKtND`TEs661K$f`2U=q>XdLMLCkC3%VK?cqVx|*MUkk#)l`abQ zPNZ_On(?j09qh;JK=w-~l}wg|k)F+p%wWRi>u(#>(yPf(+=cLuReHpyR=q>0lYA|b zh|_-5dc-H-XQEJ{@4e0HA{m^|yRBI-qXrk(v0{STM6h@0;81N#QtZIg7YUtjGV-FX z!dAamBT?dcAPB(#ZIg+obchBG#!iPV9piB<1QYv8SN{`+5FH%2=Mefn>ctwR<>4`w zhB+YD%crBJ!UTb#^9A)U6?falmT488(DeLu5YevX(Pu;hZbM+0`HMOgY^ls^`XRV` z%1nd?m<4d-!`=(S%Rqt?l;Zl7NyC@t&kZ1`Y}mnL1#O!&y>Nt0@Y)q_${Uuj9sktS zk`bYuB|#s2dVQAh>qBJ=SGyeGtRtp4q;xW5Q?I^g56h@ zAsF_ReQ}%`gn@>So}txk!(Pu>&(Vw2=#SQ*b>TaxV0)`_L6vJ`Wvjq9`SxQVdX+f& z#aNsKGHmc@v`N4VOZZEnQa>+?(W$LQk=Ty0z&udPW4V1e5&cRUNI zY`I9f-v<3 z$=OTM#zB<%HGXm}{LsjrVj&SE6|_2xCRAw6?r>0_jSY}S^H(dzQw)PCXPF>AG}W#A zKCxu&M=y(WdmA|T1kB%cbL}}PC9ld6OqUI@Iml?eD7I`4J2rxS`B@nJ^bH9esP<~p zRvi9@9u!}I9x8IkDYgJ{KDKApq;9Kw5n0nZTF9ZwbZ=dmqzJciZxh~h81?HUrjXD9 zHR~Z`A+bZslwio1Mqy!TnBE-=;gVOMTb9h}feFzNzjuqAGp z<7yz>B!-=)?TwL}YTD+ESOx6q(D|sC+d{ZFq8cxS#=3nq`?8=iE$`xZ{eAl^Qc79a zdD|;apUI*is-Jc9NlzEgtT4E?u0EY4Q!(Ntl}(BPWI@@-`G^aBTT0yzYHPbX-+`vN z(D@=rrzH`=(%$8w^vPQ{awn|dV8H`-A61iNYtonD0Qf>`X^;c+2E|3BeT`MHdE^81 z-ph8UF@c=OgHjx_M$?je)UVh`%WZAZk+~+EgYpD9&;n@lNs!)EZjjLoam%}CB`rQk zVaQEpfIHn((THJ+CvSsQ6xrHH4cW?2zIZ4f`)3fetf9P|K_u!oi7H{n)}V35>#x{e zj$p%`-@++kW2nrKrVq`?lo`?Q?B!=p@nCyhb}<5GgHYw0s$xB3;x%6LDy}+nxr|~G z)5Cy(gpc>Bl+5&d=gMcJY)A(xazUMdylOXwH~X*&vd$Pd*96bR>Z_>ZQ!qRaUg|-@ zS@nRqK&&4$+mb+s5mwI-w?QwvnhIG86r(1vxuCdEUYyTLAGz^^B7RkgY`WFWA%~} zH$~g5U7fMe%jbFus;{3?em8irImxDe- zacI~EDYPxITC$Bbo!Kzh@kLSY_04N#`f#WkDAhFIR=SChq$kAP1)7s!Ad;y|>)3mQ zK1bq4283Zj$ZQz%C?)T2!Z=xvQTG|ujon*?@nx-?mza4oLKB$a;*}O2uba-YM!9v; z%~PiLcsNMC$hCFy3S1Jcp6SZ^h@!*q1@gRM5JDj}K53o7vk2m_zz+;)IRm^lcaLJd zN#jsV6)=@91O}Gx{p!F9!!NPrN2+z8Dd)UEjC@NQd05_7&WYBTFn4?!+rTQv&1V8D zMGj*L(m&G92=!4|JbbZ_&!up*vuc0A=N(D03cbbJ&Ey&g|r`@nlEhMzu2q1v7axSS@QzL6nR>r6O-OD;%p`2~DmL?v2 z=?Xh>*%19K^6QOq2Y-)FIVZ=xFRFo|*UW({r4R{UzQJ65zQmC?0C=oqb&WrB(a`w`}l#6Pqo2)LM$p)>W3kF+F@7{7nTFK0hDM12?19%nKqamynE8^PFNhwmiGX zobmO}spbrXh!Qq_LPP>pTeY3;^%ZHI063l}LU46mvhc?j8(%Aux=Z5Bxajdgq)4uZ zRqJ@pHis&Wbm@p0pNZ334%-O{Ab>FoI#7(IRHsUpi4+ic3rM#3rQS_nW7QrJCZoQ0 zP7Ftp;;{X&ThHcZV1`#kYJHCI-k(fw8fVjZ6XG2#>u$!(Dm3PX4=i3?`f zrF2n24!3p14A%kIHeqhwRZp@y1UNT=X+n<5GznQD{6rVP6~Pb1@8Cz}8A5c0!c~D|kpvq|*@nzUthnUPTkf@7LR3NO zTmCd}N}kWtka|Y75ffaSpxrR1hJ9jL&NrXy*Zt#MTM4ftCSunVsxCB57h8k`x-@YL z1bHHO#TW3$M$4%S++GQtu`3Q$;aES#f)`g}l^X(?uDCYf0q1nh2|NaOb^qkhzapUT zy3^Zyc5=C{E7`{T>>0Nr368zS-0NoS3HB{WYj@h4 z58Y;{Cgd2FaLOmi6<=7BE@aa1-+Cls6g&y=qt$3qF45tR9;Tf~=Gq{z6;g4UK!%j4 zb~dG?qK;Hi;c43wmlx5Dpzl)F4eT6>-(Xw2Y|AOHAr71s1@+ddmT$}9!@yd>2*h70 zw0{nT&RV*2-0}rnzuT#kf^mjzYlOBwrcswO!u^}gSD6>jM0pS2!GgFuyrnNq^>#grM_Fygm+S`y#}A8nW(X=S*Vgj6UN_bjVZ(Yd zbgD=5eq>t-F>?ZLYs5#sE@w-aa+_w!>8>d0L+_J!^9i$TAI?HyZt%C$X3w4&czQTA zG)Uf|*0FI@%BAxUf4QW;>1(;>33#F%?^Axa-fy3HKm#e;RV*+C)4=eO)ROc9rPDen zn=*oJupU0QV36eOriV)~|3>Ww!=_Uex8Pd8k#M&~e@iftKT!bleIsF~7S%oc093WI zA3i^J5E4|~XeAo9B~vtJbhZydlmy!$N|Z-gUbVNWI&SpZaKFQ59~pml^<*!nJZ~tP z4*!WWIc?0Ax#DQHA$O;?>q08mOBxHTSGJSrJMvYlq4m@0+3&e)@|IrCF*B7}!jga5 z`Q*BF%p1&}5mt?N5o=%+;jH?`!<>!P9;KI+Lla^aCXZetoTFXIN?X;Upq=yDP}Qlz z_sw&FkHSow2*FNKlR4vf_wrNdMO~J&4!;^H|tL0@Ny4u zgoB&uuz3}`i`aEP$D!jarP(Fy04ffdpeL7U33>@i%837JTB|?X^en?a+xSv3{v=vS z1ai_?rJ4C{P@sq3b3I>4I-FrzM?Hx7f{##nKDH+{7e(Z>AR)yZP^oS_~2ToB7|^nytUnH6&S!j z9P_^OpMog7SDrO|YWGU@e#wf6G%G$EI>cGIg=hPM*xzQ(J^}B|y++dG?d_TDK?5|P z;bJ|sTs$`1AIAhT)PPNxoXEErfk*X+4ft~mH3*UPRqtTgKc1%+iesX@T#v8ISl{Ex zM-{7A?kED)TGd4ygE!|a9aGSgi8d@#bdpQZl7*G5pdtBYeYMnmt|Il)RaU)B4R!Vu zhwipTDnBFoCCah6;~8}z#J@@&l+p4$CNcx3whSEYakv# z?Z8aewQ{;pi6L)8!O`so)tG=a2Kp8@;2BgSTDikmz}gGs*Q9##FONYj(||S`kFVl~ z-sbQ*XL6~B2CD3ofbLoj*t3$XG0J!JP_NlWV(U`-WOfN6eSiCP3)Re`^Cm(9 zHczLuakuu zD^|GLO+e(|D3h$^)q%(=TB@*z+MF{3OusZNH+=IaWdh3An0uSFp##tm+`JHU)_>C62Rh!f^@x=W^=aTD?$tke4 zq@Az(5>n-f*GXTK&iI;wo~BtceOraR2|(r9J=AW3K5J#XU3cYTBcLE$orQo(;vNix zTBk>pmQFojbTYU*{h1e83OkR?V0{NubJo5U6x2AoY1NwyEqP8N$?E4cj%LoAW?mE7EAlOjwj!kNrWgb zG`o^8k&6tquM+J<4y%Yqle-m{9!J3DoKqEkVA6370Rn>iGx7M@&Gl>F=#S2>*2D?< zASU!sgMyt_^g=|FKDQO)8l4QJ@kDU8pv=PZsn%BW*I+vAxvCRqv_d^Os4Hq_6 z4Uk*U(jqC9hHMJFV?>OrGx5R_%b((s=3P@U^zr8}lCS+rOV2AxtX zhhY~a(n@#5Q{RTKOYe{$EeG{Sd#}un-~`34F*(Y3w1vcnCAps|;u+ zFMqQ_usG^q)V#)&0tSP-ma)+z`ckZCQXvHUl;GhW)YhxZ%f9dS<+Jn2Dqq1R1R=o= zf7YiqA;NlD9F7YW5j5w`XH74Yj{u-a@<^1h#5-r!8OKPWgqnmliEh5dT`s>9xqVdH z!LMRHuL1JR0@NCopS(YuDPjD{{lkTaL!&)R<+T?kL;#i}P^s9e`e?ixW71d78t6@k3lbB-*yi&TWV5u zRaY>u8NH`CnfNi%UtWPT%hnfkDHp9xM_jvE{auYNU zIYdpE2M+&;WckeM5=^_tg?w5LPw{`ofZ^kdLJ#t(- z*fb-_#bqlK+uN1zgzfpd`v#G~+4U{r#E%O}M7XFVOz_w3q+>_7qp-4eqF8Zftl#jH zEy7G6Bq~}(N+NKYxU;=RrHq=1!C=W0!rwByf34M!U3S4kQxBaZ$ae;Lk~7#^JJRmJ zc3n_v|NFh5BnwmacLQSu%J?7U`y<2o!=gG71Ai!%mX|v?QXe)HmPyylGWfKTp`*v=)Pj!V2SL?^IDNy)kLR6X@J_7>zmgXwzx*s zZ1lQ)PurK+FoQ2{+0o4>*zY#-sK;7n)9*Y^fBS%mgxsVd0;geIOV^>;je-4G0Ni} z&j*w>oZnF%b$mVsdfW;300c$w1L%MD#XW|2+$;6~K?&@?0nX?lCjRpAQFwd|`nZqj z0dyHyW&Bs5zjie}Mts~C^nkcZ{DAoPT|$qs9yfVBU>O1Z7LdDtZ25SM_PC?q0Zo|V z7qs8{3m#)Uu8BWj^gR86@joi$j}abMaUT#=f%|g6IsLNl{=KIAnEvrj{R4d!!(;j% ziNRxl$2)-!0CB)<>jwk>!M@;Q)W;iL52!F~KTv;(;199;G0Nk+?gx}kj=x3u5uqNV zJig_4KzYLR1LddR_|@tCtq*yeL_gs8^Zvm3%ZK~~{MD2EE#TwK_5qNW?+4&7Cj1lf z;ld+B{#*RVdE)~ fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + } \ No newline at end of file From 48053414c9559d6a512f791d72e3c3a3a81690c1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 15 Dec 2023 20:02:44 +0600 Subject: [PATCH 212/794] Add frtpivot cache def version set --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 8 ++++++++ .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 17947 -> 17943 bytes 2 files changed, 8 insertions(+) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index f9a1415e407..a8592dbdbfc 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -741,6 +741,14 @@ namespace OOX XLS::BaseObjectPtr COfficeArtExtensionList::toBinPivotCache() { auto ptr(new XLSB::FRTPIVOTCACHEDEF); + + auto ptr1(new XLSB::FRTBegin); + XLSB::FRTProductVersion version; + version.product = 0; + version.version = 0x0F03; + ptr1->productVersion = version; + ptr->m_BrtFRTBegin = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); if (!m_arrExt.empty()) diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index bf92710a8a6da17c1c09cf6ae79107c3f6fcfa37..6aac6466dfa0cc1bbc50ae378559a2570c8a0888 100644 GIT binary patch delta 369 zcmbQ;!#KT%af62jtI>!Wx^g$7dr3>XKH8(>lhpkc`UK0s*lmFz~a)r^7A=O zfsU(peNmaX&w?d1sLj}|Qqk|oG$E<#Yb^Kg8wI>9NHu-B{N{)CPt^ap$^1Bf`|sCn z;zs#aXZBhz(p6)dwoQiZW9-IFFA|(>7&l96){8@(Io~0RMO>4CVRAl~#N;;|Jd?lJ z2uyZ#lw!=89OLNC)T=dlt(MZ{(~ep!?Akz8j%;F+`JJ>Fb0=FlIWo#ju5of;{5g5A zQz%n`;p7R1Qj_(ZwU~U3fK1WJ`Of-`izd%^c4yKvo$P0-IGNK$i_vJZiAx}(%H%ee z07j9?*InY7q%0>}S!z#Cu@jiAZ6(0N00fL6fYi~*aB0kB9Y1%L$VA)J#h2XZviQy`mLJ<)J_Z-_wv+hFD;Rsm2JRdX6E+usG1X zcTa4BUQVmJ^dyvlSU6Qsx--7=OdN>~#Wi-U3BJFjpwi;PYQj&m5xi0`39iJR|GXdF zUvDe*CZo)|CE5~~?)}&l-JpC^EDbtX6Hib}0|b-dKpL|(DPb1{fCTCxoRgbCY6Kf8 z005J33K)}3DGZY>K`H@olUPAZ0+A|{sVX9q$3ZFt3o8HslR*X+lM6yB0dbQyLO}r_ zlXyZv0sWJ?LRA5DlMh2h0#P!P5JMG{YeO#rrZbbiGaQq+Ln;C?HIqs;A(N;?5R(-| z8UZ$wFho%TC^wTpHzkv(L@ELpIFm3qG?NHLDgquklQuaklV3$D0v$S&+(jFcP&x{e Tuth2X5R= Date: Fri, 15 Dec 2023 17:55:00 +0300 Subject: [PATCH 213/794] Adding conversion of indexed brackets, diacritics and attributes. Editing operator conversion. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 123 +++- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 257 +++++-- .../StarMath2OOXML/cconversionsmtoooxml.h | 23 +- .../StarMath2OOXML/cstarmathpars.cpp | 648 +++++++++++++++--- .../Converter/StarMath2OOXML/cstarmathpars.h | 73 +- .../Converter/StarMath2OOXML/typeselements.h | 8 +- 6 files changed, 932 insertions(+), 200 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 41495fe80ed..b81713a1a7c 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -20,7 +20,7 @@ TEST(SMConvectorTest,BinOperatorOver) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"23"; + std::wstring XmlString = L"23"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -70,7 +70,7 @@ TEST(SMConvectorTest,BinOperatorDivision) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"42"; + std::wstring XmlString = L"42"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -110,7 +110,7 @@ TEST(SMConvectorTest,OperatorSum) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"5"; + std::wstring XmlString = L"5"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -120,7 +120,7 @@ TEST(SMConvectorTest,OperatorSumFrom) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -130,7 +130,7 @@ TEST(SMConvectorTest,OperatorSumTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -140,7 +140,7 @@ TEST(SMConvectorTest,OperatorSumFromTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"666777567"; + std::wstring XmlString = L"666777567"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -660,7 +660,7 @@ TEST(SMConvectorTest,BracketLangle) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1011"; + std::wstring wsXmlString = L"1011"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -690,7 +690,7 @@ TEST(SMConvectorTest,BracketLline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1617"; + std::wstring wsXmlString = L"1617"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -720,7 +720,7 @@ TEST(SMConvectorTest,FunctionSin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sin45"; + std::wstring wsXmlString = L"sin45"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -730,7 +730,7 @@ TEST(SMConvectorTest,FunctionTan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"tan67"; + std::wstring wsXmlString = L"tan67"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -740,7 +740,7 @@ TEST(SMConvectorTest,FunctionCot) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cot89"; + std::wstring wsXmlString = L"cot89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -810,7 +810,7 @@ TEST(SMConvectorTest,FunctionArctan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arctan1718"; + std::wstring wsXmlString = L"arctan1718"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -830,7 +830,7 @@ TEST(SMConvectorTest,FunctionArsinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arsinh231510"; + std::wstring wsXmlString = L"arsinh231510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -840,7 +840,7 @@ TEST(SMConvectorTest,FunctionArcosh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"35+27arcosh2378"; + std::wstring wsXmlString = L"35+27arcosh2378"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -860,7 +860,7 @@ TEST(SMConvectorTest,MatrixBinom) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"27\u2283277arcoth89"; + std::wstring wsXmlString = L"27\u2283277arcoth89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -870,7 +870,7 @@ TEST(SMConvectorTest,MatrixMatrix) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; + std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -880,7 +880,7 @@ TEST(SMConvectorTest,MatrixStack) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"210231234"; + std::wstring wsXmlString = L"210231234"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -890,7 +890,7 @@ TEST(SMConvectorTest,IndexLower) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2512"; + std::wstring wsXmlString = L"2512"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -900,7 +900,7 @@ TEST(SMConvectorTest,IndexUpper) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cos52410"; + std::wstring wsXmlString = L"cos52410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -910,7 +910,7 @@ TEST(SMConvectorTest,IndexLsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3cos1527"; + std::wstring wsXmlString = L"2+3cos1527"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -920,10 +920,90 @@ TEST(SMConvectorTest,IndexLsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"22222103"; + std::wstring wsXmlString = L"22222103"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,BracketWithIndexOverbrace) +{ + std::wstring wsString = L"color red size 16 {2/3} overbrace color navy size 18 stack{10 # 100 # 10 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"231010010"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OperatorLllint) +{ + std::wstring wsString = L"color red bold lllint from color navy bold 2 over color crimson 10 to color green (2 color orange bold + 3) 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2102+3100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketLdlineAttribute) +{ + std::wstring wsString = L"color green left ldline color navy bold 10 over color purple dot underline 100 color orange bold ital + 3 right rdline + ital bold 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"10100+3+10"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + +//TEST(SMConvectorTest,FunctionCos) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString = L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + //TEST(SMConvectorTest,FunctionCos) //{ // std::wstring wsString = L""; @@ -935,3 +1015,4 @@ TEST(SMConvectorTest,IndexLsub) //} + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 8a378998660..a29aa78430d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -2,40 +2,100 @@ #include "../../../../DesktopEditor/common/File.h" #include namespace StarMath { - CConversionSMtoOOXML::CConversionSMtoOOXML() + CConversionSMtoOOXML::CConversionSMtoOOXML(): m_pXmlWrite(nullptr) { } + //check XMLWrite(if not nullptr == delete) void CConversionSMtoOOXML::StartConversion(std::vector arPars) { - m_oXmlWrite = new XmlUtils::CXmlWriter; - m_oXmlWrite->WriteNodeBegin(L"m:oMathPara",false); - m_oXmlWrite->WriteNodeBegin(L"m:oMath",false); + m_pXmlWrite = new XmlUtils::CXmlWriter; + m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); for(CElement* oTempElement:arPars) { - oTempElement->ConversionToOOXML(m_oXmlWrite); + oTempElement->ConversionToOOXML(m_pXmlWrite); } EndConversion(); -// NSFile::CFileBinary oFile; -// oFile.CreateFileW(L"Test.txt"); -// oFile.WriteStringUTF8(m_oXmlWrite->GetXmlString()); -// oFile.CloseFile(); + NSFile::CFileBinary oFile; + oFile.CreateFileW(L"Test.txt"); + oFile.WriteStringUTF8(m_pXmlWrite->GetXmlString()); + oFile.CloseFile(); } - void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + if(pAttribute == nullptr) + { + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + if(pAttribute->GetSize() == 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!pAttribute->EmptyColor() && pAttribute != nullptr) + { + pXmlWrite->WriteNodeBegin(L"w:color",true); + pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetBold()) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",L"b"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:b",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:bCs",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetItal()) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",L"i"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:i",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetStrike()) + { + pXmlWrite->WriteNodeBegin(L"w:strike",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) @@ -44,33 +104,60 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsType); pXmlWrite->WriteNodeEnd(L"w",true,true); } - pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNode(L"w:i",L""); - //m_pXmlWrite->WriteNode(L"w:iCs",L""); - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + WriteCtrlPrNode(pXmlWrite,pAttribute); +// pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); +// pXmlWrite->WriteNodeBegin(L"w:rPr",false); +// pXmlWrite->WriteNodeBegin(L"w:rFonts",true); +// pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); +// pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); +// pXmlWrite->WriteNodeEnd(L"w",true,true); +// pXmlWrite->WriteNode(L"w:i",L""); +// //m_pXmlWrite->WriteNode(L"w:iCs",L""); +// pXmlWrite->WriteNodeBegin(L"w:sz",true); +// pXmlWrite->WriteAttribute(L"w:val",L"40"); +// pXmlWrite->WriteNodeEnd(L"w",true,true); +// pXmlWrite->WriteNodeBegin(L"w:szCs",true); +// pXmlWrite->WriteAttribute(L"w:val",L"40"); +// pXmlWrite->WriteNodeEnd(L"w",true,true); +// pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); +// pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } - void CConversionSMtoOOXML::PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:naryPr",false); - pXmlWrite->WriteNodeBegin(L"m:chr",true); - pXmlWrite->WriteAttribute(L"m:val",wsTypeOperator); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"m:limLoc",true); - pXmlWrite->WriteAttribute(L"m:val",L"undOvr"); - pXmlWrite->WriteNodeEnd(L"w",true,true); + switch(enTypeOp) + { + case TypeElement::sum: + { + WriteChrNode(L"\u2211",pXmlWrite); + break; + } + case TypeElement::prod: + WriteChrNode(L"\u220F",pXmlWrite); + break; + case TypeElement::coprod: + WriteChrNode(L"\u2210",pXmlWrite); + break; + case TypeElement::iint: + WriteChrNode(L"\u222C",pXmlWrite); + break; + case TypeElement::iiint: + WriteChrNode(L"\u222D",pXmlWrite); + break; + case TypeElement::lint: + WriteChrNode(L"\u222E",pXmlWrite); + break; + case TypeElement::llint: + WriteChrNode(L"\u222F",pXmlWrite); + break; + case TypeElement::lllint: + WriteChrNode(L"\u2230",pXmlWrite); + break; + default: + break; + } + WriteLimLocNode(L"undOvr",pXmlWrite); if(bEmptySub) { pXmlWrite->WriteNodeBegin(L"m:subHide",true); @@ -83,15 +170,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"1"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNode(L"w:i",L""); - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + WriteCtrlPrNode(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock,XmlUtils::CXmlWriter* pXmlWrite) @@ -102,24 +181,23 @@ namespace StarMath { } std::wstring CConversionSMtoOOXML::GetOOXML() { - return m_oXmlWrite->GetXmlString(); + return m_pXmlWrite->GetXmlString(); } void CConversionSMtoOOXML::EndConversion() { - //m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_oXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - m_oXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } - void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:funcPr", false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr", false); - StandartProperties(pXmlWrite); + StandartProperties(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } - void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket) + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:dPr",false); switch(enTypeBracket) @@ -150,7 +228,7 @@ namespace StarMath { break; } pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); - StandartProperties(pXmlWrite); + StandartProperties(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); } @@ -163,7 +241,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix) + void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:mPr",false); pXmlWrite->WriteNodeBegin(L"m:mcs",false); @@ -187,11 +265,11 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:mc",false,false); pXmlWrite->WriteNodeEnd(L"m:mcs",false,false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite); + StandartProperties(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:mPr",false,false); } - void CConversionSMtoOOXML::BlocGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade) + void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:d",false); pXmlWrite->WriteNodeBegin(L"m:dPr",false); @@ -202,7 +280,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"\u23AA"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite); + StandartProperties(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); @@ -210,5 +288,50 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:d",false,false); } + void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute) + { + pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); + StandartProperties(pXmlWrite,pAttribute); + pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + } + void CConversionSMtoOOXML::WriteChrNode(const std::wstring &wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeOp); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::WriteLimLocNode(const std::wstring &wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:limLoc",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + void CConversionSMtoOOXML::WrtieRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"m:rPr",false); + pXmlWrite->WriteNodeBegin(L"m:sty",true); + pXmlWrite->WriteAttribute(L"m:val",L"p"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute); + pXmlWrite->WriteNodeBegin(L"m:t",false); + switch(enTypeOp) + { + case TypeElement::lim: + pXmlWrite->WriteString(L"lim"); + break; + case TypeElement::liminf: + pXmlWrite->WriteString(L"lim inf"); + break; + case TypeElement::limsup: + pXmlWrite->WriteString(L"lim sup"); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index e1932e7a39a..c7f8a599381 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -6,24 +6,29 @@ namespace StarMath { +//delete XmlWrite class CConversionSMtoOOXML { public: CConversionSMtoOOXML(); void StartConversion(std::vector arPars); - static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesNaryPr(const std::wstring& wsTypeOperator,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite); + static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket); - static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix); - static void BlocGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute); + static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute); + static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); + static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); + static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); + static void WrtieRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); void EndConversion(); - std::wstring GetOOXML() ; + std::wstring GetOOXML(); private: static void BracketTypeNotation(const std::wstring& wsOpenBracket,const std::wstring& wsCloseBracket, XmlUtils::CXmlWriter* pXmlWrite); - XmlUtils::CXmlWriter* m_oXmlWrite; + XmlUtils::CXmlWriter* m_pXmlWrite; }; } #endif // CCONVERSIONSMTOOOXML_H diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 95511ad53ba..fe620a13bea 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -31,7 +31,6 @@ namespace StarMath CElement* CParserStarMathString::ParseElement(CStarMathReader* pReader) { CElement* pElement; - std::vector arAttributes; if(pReader->EmptyString()) { @@ -39,18 +38,14 @@ namespace StarMath pReader->SetTypesToken(); } - while(pReader->GetGlobalType() == TypeElement::Attribute) - { - if(pReader->GetLocalType() != TypeElement::color) arAttributes.push_back(new CAttribute(pReader->GetLocalType())); - pReader->GetToken(); - pReader->SetTypesToken(); - } - pElement = CElement::CreateElement(pReader); if(pElement != nullptr) { - pElement->SetAttribute(arAttributes); + if(pReader->GetAttribute() != nullptr) + pElement->SetAttribute(pReader->GetAttribute()); + else if(pReader->GetAttributeTemp() != nullptr) + pElement->SetAttribute(pReader->GetAttributeTemp()); pReader->ClearReader(); pElement->Parse(pReader); return pElement; @@ -98,13 +93,14 @@ namespace StarMath break; } } - CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) + CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader,CAttribute* pAttribute) { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); while(CheckForLeftArgument(pReader->GetGlobalType())) { + pReader->SetAttributeTemp(pAttribute); CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); if(pFirstTempElement != nullptr) { @@ -117,6 +113,7 @@ namespace StarMath pReader->SetTypesToken(); } } + pReader->ClearAttributeTemp(); return pFirstTempElement; } bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType) @@ -138,42 +135,227 @@ namespace StarMath } } //class methods CAttribute + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0) + { + } CAttribute::~CAttribute() {} - CAttribute::CAttribute(const TypeElement &enType) + void CAttribute::SetSize(const unsigned int &iSize) + { + m_iSize = iSize; + } + void CAttribute::SetBold() + { + m_bBold = true; + } + void CAttribute::SetItal() + { + m_bItal = true; + } + void CAttribute::SetPhantom() + { + m_bPhantom = true; + } + void CAttribute::SetStrike() + { + m_bStrike = true; + } + void CAttribute::SetColor(const TypeElement &enColor) + { + if(enColor != TypeElement::undefine) + { + switch (enColor) { + case TypeElement::black: + m_wsColor = L"000000"; + break; + case TypeElement::blue: + m_wsColor = L"0400ff"; + break; + case TypeElement::green: + m_wsColor =L"00FF00"; + break; + case TypeElement::red: + m_wsColor =L"FF0000"; + break; + case TypeElement::fuchsia: + m_wsColor =L"ED0DD9"; + break; + case TypeElement::aqua: + m_wsColor =L"30D5C8"; + break; + case TypeElement::yellow: + m_wsColor =L"FFFF00"; + break; + case TypeElement::gray: + m_wsColor =L"808080"; + break; + case TypeElement::lime: + m_wsColor =L"00FF00"; + break; + case TypeElement::maroon: + m_wsColor =L"800000"; + break; + case TypeElement::navy: + m_wsColor =L"000080"; + break; + case TypeElement::olive: + m_wsColor =L"808000"; + break; + case TypeElement::purple: + m_wsColor =L"800080"; + break; + case TypeElement::silver: + m_wsColor =L"C0C0C0"; + break; + case TypeElement::teal: + m_wsColor =L"008080"; + break; + case TypeElement::coral: + m_wsColor =L"FF7F50"; + break; + case TypeElement::midnightblue: + m_wsColor =L"191970"; + break; + case TypeElement::crimson: + m_wsColor =L"DC143C"; + break; + case TypeElement::violet: + m_wsColor =L"EE82EE"; + break; + case TypeElement::orange: + m_wsColor =L"FFA500"; + break; + case TypeElement::orangered: + m_wsColor =L"FF4500"; + break; + case TypeElement::seagreen: + m_wsColor =L"2E8B57"; + break; + case TypeElement::indigo: + m_wsColor =L"4B0082"; + break; + case TypeElement::hotpink: + m_wsColor =L"FF69B4"; + break; + case TypeElement::lavender: + m_wsColor =L"FFF0F5"; + break; + default: + break; + } + } + } + void CAttribute::SetFont(const TypeElement &enFont) + { + switch (enFont) { + case TypeElement::ital: + SetItal(); + break; + case TypeElement::bold: + SetBold(); + break; + case TypeElement::phantom: + SetPhantom(); + break; + case TypeElement::overstrike: + SetStrike(); + break; + default: + break; + } + } + bool CAttribute::GetBold() + { + return m_bBold; + } + bool CAttribute::GetItal() + { + return m_bItal; + } + bool CAttribute::GetPhantom() + { + return m_bPhantom; + } + bool CAttribute::GetStrike() + { + return m_bStrike; + } + std::wstring CAttribute::GetColor() + { + return m_wsColor; + } + unsigned int CAttribute::GetSize() { - m_enTypeAttr = enType; + return m_iSize; } - TypeElement CAttribute::GetType() + bool CAttribute::EmptyColor() { - return m_enTypeAttr; + return m_wsColor.empty(); } + void CAttribute::ParseColorAttribute(const std::wstring &wsToken,CStarMathReader* pReader) + { + TypeElement enTempColor = GetTypeColorAttribute(wsToken); + switch(enTempColor) + { + case TypeElement::hex: + pReader->GetToken(); + m_wsColor = pReader->GetString(); + break; + case TypeElement::rgb: + { + const int iTempLen = 7; + wchar_t arTemp[iTempLen]; + unsigned int wsRed,wsGreen,wsBlue; + pReader->GetToken(); + wsRed = std::stoi(pReader->GetString()); + pReader->GetToken(); + wsGreen = std::stoi(pReader->GetString()); + pReader->GetToken(); + wsBlue = std::stoi(pReader->GetString()); + if(wsRed > 255 || wsGreen > 255 || wsBlue > 255) + m_wsColor = L"000000"; + else + { + swprintf(arTemp,iTempLen,L"%02X%02X%02X",wsRed,wsGreen,wsBlue); + m_wsColor = std::wstring(arTemp,6); + } + break; + } + default: + SetColor(enTempColor); + break; + } + } + void CAttribute::ParseFontAttribute(const TypeElement& enTypeFont, CStarMathReader *pReader) + { + switch(enTypeFont) + { + case TypeElement::size: + { + pReader->GetToken(); + int iTemp = std::stoi(pReader->GetString()); + if (iTemp >= 0) + m_iSize = iTemp*2; + else + m_iSize = 24; + break; + } + case TypeElement::font: + { + break; + } + default: + SetFont(enTypeFont); + break; + } + } + //нет phantom, rgb, 16 , гарнитуры и кегля - TypeElement CAttribute::GetTypeAttribute(const std::wstring &wsToken) + TypeElement CAttribute::GetTypeColorAttribute(const std::wstring &wsToken) { - if(L"acute" == wsToken) return TypeElement::acute; - else if(L"color" == wsToken) return TypeElement::color; - else if(L"breve" == wsToken) return TypeElement::breve; - else if(L"dot" == wsToken) return TypeElement::dot; - else if(L"dddot" == wsToken) return TypeElement::dddot; - else if(L"vec" == wsToken) return TypeElement::vec; - else if(L"tilde" == wsToken) return TypeElement::tilde; - else if(L"check" == wsToken) return TypeElement::check; - else if(L"grave" == wsToken) return TypeElement::grave; - else if(L"circle" == wsToken) return TypeElement::circle; - else if(L"ddot" == wsToken) return TypeElement::ddot; - else if(L"bar" == wsToken) return TypeElement::bar; - else if(L"harpoon" == wsToken) return TypeElement::harpoon; - else if(L"hat" == wsToken) return TypeElement::hat; - else if(L"widevec" == wsToken) return TypeElement::widevec; - else if(L"widetilde" == wsToken) return TypeElement::widetilde; - else if(L"overline" == wsToken) return TypeElement::overline; - else if(L"overstrike" == wsToken) return TypeElement::overstrike; - else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; - else if(L"widehat" == wsToken) return TypeElement::widehat; - else if(L"underline" == wsToken) return TypeElement::underline; - else if(L"ital" == wsToken) return TypeElement::ital; - else if(L"bold" == wsToken) return TypeElement::bold; + if(L"color" == wsToken) return TypeElement::color; + else if(L"hex"==wsToken) return TypeElement::hex; + else if(L"rgb" == wsToken) return TypeElement::rgb; else if(L"black" == wsToken) return TypeElement::black; else if(L"green" == wsToken) return TypeElement::green; else if(L"aqua" == wsToken) return TypeElement::aqua; @@ -201,15 +383,22 @@ namespace StarMath else if(L"lavender" == wsToken) return TypeElement::lavender; else return TypeElement::undefine; } + TypeElement CAttribute::GetTypeFontAttribute(const std::wstring &wsToken) + { + if(L"bold" == wsToken) return TypeElement::bold; + else if(L"size" == wsToken) return TypeElement::size; + else if(L"font" == wsToken) return TypeElement::font; + else if(L"ital" == wsToken) return TypeElement::ital; + else if(L"phantom" == wsToken ) return TypeElement::phantom; + else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else return TypeElement::undefine; + } //class methods CElement CElement::~CElement() { - for(CAttribute* pTemp:m_arElementAttributes) - { - delete pTemp; - } + delete m_pAttribute; } - CElement::CElement() + CElement::CElement(): m_pAttribute(nullptr) {} CElement* CElement::CreateElement(CStarMathReader* pReader) { @@ -238,13 +427,15 @@ namespace StarMath return new CElementSpecialSymbol(pReader->GetLocalType()); case TypeElement::Index: return new CElementIndex(pReader->GetLocalType()); + case TypeElement::Mark: + return new CElementDiacriticalMark(pReader->GetLocalType()); default: return nullptr; } } - void CElement::SetAttribute(const std::vector arAttr) + void CElement::SetAttribute(CAttribute* pAttribute) { - m_arElementAttributes = arAttr; + m_pAttribute = pAttribute; } const TypeElement& CElement::GetBaseType() { @@ -254,6 +445,10 @@ namespace StarMath { m_enBaseType = enType; } + CAttribute* CElement::GetAttribute() + { + return m_pAttribute; + } //class methods CElementString CElementString::CElementString(const std::wstring& wsTokenString) { @@ -273,7 +468,7 @@ namespace StarMath void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) { oXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(oXmlWrite); + CConversionSMtoOOXML::StandartProperties(oXmlWrite,GetAttribute()); oXmlWrite->WriteNodeBegin(L"m:t",false); oXmlWrite->WriteString(m_wsString); oXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -316,11 +511,13 @@ namespace StarMath { if(m_enTypeBinOp == TypeElement::frac) { - SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader)); - SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } else { + if(m_enTypeBinOp == TypeElement::plus || TypeElement::minus == m_enTypeBinOp) + pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); @@ -339,8 +536,8 @@ namespace StarMath if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division) { oXmlWrite->WriteNodeBegin(L"m:f",false); - if(m_enTypeBinOp == TypeElement::division) CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite); - else CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite); + if(m_enTypeBinOp == TypeElement::division) CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite,GetAttribute()); + else CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite,GetAttribute()); CConversionSMtoOOXML::BlockRecording(L"m:num",m_pLeftArgument,oXmlWrite); CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); oXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -349,7 +546,7 @@ namespace StarMath { m_pLeftArgument->ConversionToOOXML(oXmlWrite); oXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(oXmlWrite); + CConversionSMtoOOXML::StandartProperties(oXmlWrite,GetAttribute()); oXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeBinOp) { @@ -504,6 +701,7 @@ namespace StarMath } while(enBracketClose == TypeElement::undefine) { + pReader->SetAttributeTemp(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) { @@ -523,6 +721,7 @@ namespace StarMath else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() + pReader->ClearAttributeTemp(); pReader->ClearReader(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -530,7 +729,7 @@ namespace StarMath if(m_enTypeBracket != TypeElement::brace) { pXmlWrite->WriteNodeBegin(L"m:d",false); - CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* oTemp:m_arBrecketValue) { @@ -624,7 +823,7 @@ namespace StarMath { m_pLeftArgument->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeBegin(L"m:r", false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeSet) { @@ -728,11 +927,13 @@ namespace StarMath } void CElementConnection::Parse(CStarMathReader *pReader) { + pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) { + pReader->SetAttribute(GetAttribute()); CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); SetRightArg(pBinOp); @@ -744,7 +945,7 @@ namespace StarMath { m_pLeftArgument->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeCon) { @@ -943,7 +1144,7 @@ namespace StarMath pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); @@ -963,7 +1164,7 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:sPre",false); pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); if(m_enTypeIndex==TypeElement::lsup) @@ -977,6 +1178,15 @@ namespace StarMath CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); } +// else if(m_enTypeIndex == TypeElement::csup || TypeElement::csub == m_enTypeIndex) +// { +// pXmlWrite->WriteNodeBegin(L"m:acc",false); +// pXmlWrite->WriteNodeBegin(L"m:accPr",false); +// pXmlWrite->WriteNodeBegin(L"m:chr",true); +// pXmlWrite->WriteAttribute(L"m:val",L""); +// pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); +// pXmlWrite->WriteNodeEnd(L"m:acc",false,false); +// } } //class methods CElementFunction CElementFunction::CElementFunction(const TypeElement &enType): m_pValue(nullptr) @@ -1014,7 +1224,7 @@ namespace StarMath void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:fName",false); pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -1022,7 +1232,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",L"p"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeFunction) { case TypeElement::cos: @@ -1160,7 +1370,7 @@ namespace StarMath if(L"limsup" == wsToken) return TypeElement::limsup; if(L"prod" == wsToken) return TypeElement::prod; if(L"coprod" == wsToken) return TypeElement::coprod; - if(L"Int" == wsToken) return TypeElement::Int; + if(L"int" == wsToken) return TypeElement::Int; if(L"iint" == wsToken) return TypeElement::iint; if(L"iiint" == wsToken) return TypeElement::iiint; if(L"lint" == wsToken) return TypeElement::lint; @@ -1170,54 +1380,110 @@ namespace StarMath } void CElementOperator::Parse(CStarMathReader* pReader) { + pReader->SetAttributeTemp(GetAttribute()); pReader->GetToken(); pReader->SetTypesToken(); if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); - SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } if(pReader->GetLocalType() == TypeElement::to) { pReader->ClearReader(); - SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } - - SetValueOperator(CParserStarMathString::ReadingWithoutBracket(pReader)); + pReader->SetAttributeTemp(GetAttribute()); + SetValueOperator(CParserStarMathString::ParseElement(pReader)); + pReader->ClearAttributeTemp(); } - void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) + void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { - if(m_enTypeOperator == TypeElement::sum) + if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator) { - oXmlWrite->WriteNodeBegin(L"m:nary",false); - CConversionSMtoOOXML::PropertiesNaryPr(L"\u2211",nullptr == m_pValueFrom,nullptr == m_pValueTo,oXmlWrite); - if(m_pValueFrom == nullptr) oXmlWrite->WriteNode(L"m:sub",L""); + std::wstring wsTempNameNode; + if(m_pValueFrom != nullptr) + wsTempNameNode = L"m:limLow"; + else if(m_pValueTo != nullptr) + wsTempNameNode = L"m:limUpp"; + pXmlWrite->WriteNodeBegin(L"m:func",false); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:fName",false); + if(m_pValueFrom == nullptr && m_pValueTo == nullptr) + CConversionSMtoOOXML::WrtieRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); else { - CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueFrom,oXmlWrite); + pXmlWrite->WriteNodeBegin(wsTempNameNode,false); + pXmlWrite->WriteNodeBegin(wsTempNameNode+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); + pXmlWrite->WriteNodeEnd(wsTempNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::WrtieRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:lim",false); + if(wsTempNameNode == L"m:limLow") + m_pValueFrom->ConversionToOOXML(pXmlWrite); + else if(wsTempNameNode == L"m:limUpp") + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + pXmlWrite->WriteNodeEnd(wsTempNameNode,false,false); } - if(m_pValueTo == nullptr) oXmlWrite->WriteNode(L"m:sup",L""); + pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + m_pValueOperator->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:func",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:nary",false); + CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,nullptr == m_pValueFrom,nullptr == m_pValueTo,pXmlWrite,GetAttribute()); + if(m_pValueFrom == nullptr) pXmlWrite->WriteNode(L"m:sub",L""); else { - CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueTo,oXmlWrite); + CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueFrom,pXmlWrite); } - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueOperator,oXmlWrite); - oXmlWrite->WriteNodeEnd(L"m:nary",false,false); + if(m_pValueTo == nullptr) pXmlWrite->WriteNode(L"m:sup",L""); + else + { + CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueTo,pXmlWrite); + } + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueOperator,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:nary",false,false); } } // class methods CStarMathReader - CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty) + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_pAttributeTemp(nullptr) { m_itStart = itStart; m_itEnd = itEnd; + //m_pAttribute = new CAttribute(); } CStarMathReader::~CStarMathReader() - {} + { + delete m_pAttribute; + } + //TODO :: ParseColor and ParseFont void CStarMathReader::GetToken() { if(m_itStart != m_itEnd) { m_wsToken = GetElement(); + TypeElement enTypeFont =CAttribute::GetTypeFontAttribute(m_wsToken),enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); + if(enTypeFont != TypeElement::undefine ||enTypeColor != TypeElement::undefine) + m_pAttribute = new CAttribute(); + while((enTypeFont != TypeElement::undefine ||enTypeColor != TypeElement::undefine) && m_itStart != m_itEnd) + { + if(enTypeColor == TypeElement::color) m_pAttribute->ParseColorAttribute(GetElement(),this); + else if(enTypeFont != TypeElement::undefine) m_pAttribute->ParseFontAttribute(enTypeFont,this); + + if(m_itStart != m_itEnd) + { + m_wsToken = GetElement(); + enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); + } + } if(m_wsToken == L"left") m_wsToken = GetElement(); else if(L"right" == m_wsToken ) m_wsToken = GetElement(); } @@ -1225,12 +1491,6 @@ namespace StarMath } void CStarMathReader::SetTypesToken() { - m_enUnderType = CAttribute::GetTypeAttribute(m_wsToken); - if(m_enUnderType != TypeElement::undefine) - { - m_enGlobalType = TypeElement::Attribute; - return; - } m_enUnderType = CElementOperator::GetFromOrTo(m_wsToken); if(m_enUnderType != TypeElement::undefine) { @@ -1261,6 +1521,12 @@ namespace StarMath m_enGlobalType = TypeElement::Matrix; return; } + m_enUnderType = CElementDiacriticalMark::GetMark(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::Mark; + return; + } m_enUnderType = CElementBracket::GetBracketOpen(m_wsToken); if(m_enUnderType != TypeElement::undefine) { @@ -1332,6 +1598,7 @@ namespace StarMath m_wsToken.clear(); m_enGlobalType = TypeElement::Empty; m_enUnderType = TypeElement::Empty; + m_pAttribute = nullptr; } bool CStarMathReader::EmptyString() { @@ -1342,6 +1609,26 @@ namespace StarMath if(m_itStart !=m_itEnd) return false; else return true; } + void CStarMathReader::SetAttributeTemp(CAttribute *pAttribute) + { + m_pAttributeTemp = pAttribute; + } + void CStarMathReader::SetAttribute(CAttribute *pAttribute) + { + m_pAttribute = pAttribute; + } + CAttribute* CStarMathReader::GetAttribute() + { + return m_pAttribute; + } + CAttribute* CStarMathReader::GetAttributeTemp() + { + return m_pAttributeTemp; + } + void CStarMathReader::ClearAttributeTemp() + { + m_pAttributeTemp = nullptr; + } std::wstring CStarMathReader::GetElement() { std::wstring m_wsElement{}; @@ -1396,7 +1683,67 @@ namespace StarMath } void CElementBracketWithIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - + std::wstring wsNameNode; + switch (m_enTypeBracketWithIndex) { + case TypeElement::overbrace: + wsNameNode = L"m:limUpp"; + break; + case TypeElement::underbrace: + wsNameNode = L"m:limLow"; + break; + default: + break; + } + pXmlWrite->WriteNodeBegin(wsNameNode,false); + pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + pXmlWrite->WriteNodeBegin(L"m:groupChr",false); + pXmlWrite->WriteNodeBegin(L"m:groupChrPr",false); + if(TypeElement::overbrace == m_enTypeBracketWithIndex) + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",L"\u23DE"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:pos",true); + pXmlWrite->WriteAttribute(L"m:val",L"top"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"m:vertJc",true); + pXmlWrite->WriteAttribute(L"m:val",L"bot"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + switch(m_enTypeBracketWithIndex) + { + case TypeElement::overbrace: + m_pLeftArg->ConversionToOOXML(pXmlWrite); + break; + case TypeElement::underbrace: + m_pValue->ConversionToOOXML(pXmlWrite); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:groupChr",false,false); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:lim",false); + switch(m_enTypeBracketWithIndex) + { + case TypeElement::overbrace: + m_pValue->ConversionToOOXML(pXmlWrite); + break; + case TypeElement::underbrace: + m_pLeftArg->ConversionToOOXML(pXmlWrite); + break; + default: + break; + } + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + pXmlWrite->WriteNodeEnd(wsNameNode,false,false); } TypeElement CElementBracketWithIndex::GetBracketWithIndex(const std::wstring &wsToken) { @@ -1449,7 +1796,7 @@ namespace StarMath { if(m_pValueFrom == nullptr && m_pValueTo == nullptr) { - CConversionSMtoOOXML::BlocGrade(pXmlWrite,m_pValueGrade); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); } else { @@ -1469,11 +1816,11 @@ namespace StarMath pXmlWrite->WriteNodeBegin(wsNodeGrade,false); pXmlWrite->WriteNodeBegin(wsNodeGrade + L"Pr",false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(wsNodeGrade + L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::BlocGrade(pXmlWrite,m_pValueGrade); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(m_pValueFrom != nullptr) { @@ -1525,18 +1872,21 @@ namespace StarMath { if(m_enTypeMatrix == TypeElement::binom) { - SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); - SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); + pReader->SetAttribute(GetAttribute()); + SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + pReader->SetAttribute(GetAttribute()); + SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } else { + pReader->SetAttribute(GetAttribute()); SetFirstArgument(CParserStarMathString::ParseElement(pReader)); } } void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:m",false); - CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:mr",false); switch(m_enTypeMatrix) { @@ -1586,6 +1936,128 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeEnd(L"m:m",false,false); } +//class CElementDiacriticalMark + CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType):m_pValueMark(nullptr) + { + m_enTypeMark = enType; + SetBaseType(TypeElement::Mark); + } + CElementDiacriticalMark::~CElementDiacriticalMark() + { + delete m_pValueMark; + } + void CElementDiacriticalMark::SetValueMark(CElement *pValue) + { + m_pValueMark = pValue; + } + TypeElement CElementDiacriticalMark::GetMark(const std::wstring &wsToken) + { + if(L"acute" == wsToken) return TypeElement::acute; + else if(L"breve" == wsToken) return TypeElement::breve; + else if(L"dot" == wsToken) return TypeElement::dot; + else if(L"dddot" == wsToken) return TypeElement::dddot; + else if(L"vec" == wsToken) return TypeElement::vec; + else if(L"tilde" == wsToken) return TypeElement::tilde; + else if(L"check" == wsToken) return TypeElement::check; + else if(L"grave" == wsToken) return TypeElement::grave; + else if(L"circle" == wsToken) return TypeElement::circle; + else if(L"ddot" == wsToken) return TypeElement::ddot; + else if(L"bar" == wsToken) return TypeElement::bar; + else if(L"harpoon" == wsToken) return TypeElement::harpoon; + else if(L"hat" == wsToken) return TypeElement::hat; + else if(L"widevec" == wsToken) return TypeElement::widevec; + else if(L"widetilde" == wsToken) return TypeElement::widetilde; + else if(L"overline" == wsToken) return TypeElement::overline; + else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; + else if(L"widehat" == wsToken) return TypeElement::widehat; + else if(L"underline" == wsToken) return TypeElement::underline; + } + void CElementDiacriticalMark::Parse(CStarMathReader *pReader) + { + pReader->SetAttribute(GetAttribute()); + SetValueMark(CParserStarMathString::ParseElement(pReader)); + } + void CElementDiacriticalMark::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + std::wstring wsTypeMark; + switch(m_enTypeMark) + { + case TypeElement::dot: + wsTypeMark = L"\u0307"; + break; + case TypeElement::overline: + wsTypeMark = L"\u0305"; + break; + case TypeElement::vec: + wsTypeMark = L"\u279E"; + break; + case TypeElement::acute: + wsTypeMark = L"\u0301"; + break; + case TypeElement::grave: + wsTypeMark = L"\u0300"; + break; + case TypeElement::breve: + wsTypeMark = L"\u0306"; + break; + case TypeElement::circle: + wsTypeMark = L"\u030A"; + break; + case TypeElement::ddot: + wsTypeMark = L"\u0308"; + break; + case TypeElement::bar: + wsTypeMark = L"\u0304"; + break; + case TypeElement::dddot: + wsTypeMark = L"\u0309"; + break; + case TypeElement::harpoon: + wsTypeMark = L"\u21C0"; + break; + case TypeElement::tilde: + wsTypeMark = L"\u0342"; + break; + case TypeElement::hat: + wsTypeMark = L"\u0302"; + break; + case TypeElement::check: + wsTypeMark = L"\u030C"; + break; + case TypeElement::widevec: + wsTypeMark = L"\u27F6"; + break; + case TypeElement::widetilde: + wsTypeMark = L"\u0360"; + break; +// case TypeElement::wideharpoon: +// wsTypeMark = L"\u"; +// break; +// case TypeElement::widehat: +// wsTypeMark = L"\u"; +// break; + case TypeElement::underline: + wsTypeMark = L"\u0332"; + break; +// case TypeElement::: +// wsTypeMark = L"\u"; +// break; + default: + break; + } + pXmlWrite->WriteNodeBegin(L"m:acc",false); + pXmlWrite->WriteNodeBegin(L"m:accPr",false); + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeMark); + pXmlWrite->WriteNodeEnd(L"w",true,true); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + m_pValueMark->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:acc",false,false); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index fd08ad4af82..e1ff22d467e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -9,6 +9,40 @@ namespace StarMath { + class CStarMathReader; + + class CAttribute + { + public: + CAttribute(); + ~CAttribute(); + static TypeElement GetTypeColorAttribute(const std::wstring& wsToken); + static TypeElement GetTypeFontAttribute(const std::wstring& wsToken); + bool GetBold(); + bool GetItal(); + bool GetPhantom(); + bool GetStrike(); + unsigned int GetSize(); + std::wstring GetColor(); + bool EmptyColor(); + void ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); + void ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); + private: + void SetSize(const unsigned int& iSize); + void SetBold(); + void SetItal(); + void SetPhantom(); + void SetStrike(); + void SetColor(const TypeElement& enColor); + void SetFont(const TypeElement& enFont); + std::wstring m_wsColor; + bool m_bBold; + bool m_bItal; + bool m_bPhantom; + bool m_bStrike; + unsigned int m_iSize; + std::wstring m_wsNameFont; + }; //Сlass for working with tokens (reading, defining types, passing) class CStarMathReader { @@ -26,6 +60,11 @@ namespace StarMath void ClearReader(); bool CheckIteratorPosition(); bool EmptyString(); + void SetAttribute(CAttribute* pAttribute); + void SetAttributeTemp(CAttribute* pAttribute); + CAttribute* GetAttributeTemp(); + CAttribute* GetAttribute(); + void ClearAttributeTemp(); private: //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); @@ -33,17 +72,8 @@ namespace StarMath TypeElement m_enGlobalType; TypeElement m_enUnderType; std::wstring m_wsToken; - }; - - class CAttribute - { - public: - CAttribute(const TypeElement& enType); - ~CAttribute(); - static TypeElement GetTypeAttribute(const std::wstring& wsToken); - TypeElement GetType(); - private: - TypeElement m_enTypeAttr; + CAttribute* m_pAttribute; + CAttribute* m_pAttributeTemp; }; class CElement @@ -55,11 +85,12 @@ namespace StarMath //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) static CElement* CreateElement(CStarMathReader* pReader); virtual void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) = 0; - void SetAttribute(const std::vector arAttr); + void SetAttribute(CAttribute* pAttribute); void SetBaseType(const TypeElement& enType); + CAttribute* GetAttribute(); const TypeElement& GetBaseType(); private: - std::vector m_arElementAttributes; + CAttribute* m_pAttribute; TypeElement m_enBaseType; }; @@ -264,6 +295,20 @@ namespace StarMath TypeElement m_enTypeMatrix; }; + class CElementDiacriticalMark: public CElement + { + public: + CElementDiacriticalMark(const TypeElement& enType); + virtual ~CElementDiacriticalMark(); + void SetValueMark(CElement* pValue); + static TypeElement GetMark(const std::wstring& wsToken); + private: + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pValueMark; + TypeElement m_enTypeMark; + }; + class CParserStarMathString { public: @@ -272,7 +317,7 @@ namespace StarMath //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static void AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); static bool CheckForLeftArgument(const TypeElement& enType); - static CElement* ReadingWithoutBracket(CStarMathReader* pReader); + static CElement* ReadingWithoutBracket(CStarMathReader* pReader,CAttribute* pAttribute); private: std::vector m_arEquation; }; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index e997664bd49..bff250cba00 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -12,6 +12,7 @@ enum class TypeElement{ Bracket, BracketWithIndex, Grade, + Mark, //BracketEnd, UnarSign, Attribute, @@ -67,6 +68,10 @@ enum class TypeElement{ //attribute ital, bold, + phantom, + overstrike, + size, + font, //top element acute, breve, @@ -84,11 +89,12 @@ enum class TypeElement{ widevec, widetilde, overline, - overstrike, wideharpoon, widehat, underline,//top elements color, + hex, + rgb, black, green, aqua, From 8ee116de7e5dc0f4ad1cd90528a49cf9e7d5535a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 19 Dec 2023 15:04:56 +0600 Subject: [PATCH 214/794] Fix included headers paths --- OOXML/XlsxFormat/Worksheets/MergeCells.cpp | 2 +- OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index ea9f80a7a57..c6ff8045278 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -34,7 +34,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/MergeCell.h" -#include "../../XlsbFormat\Biff12_unions\MERGECELLS.h" +#include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 79292d33316..19479f6c121 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -35,7 +35,7 @@ #include "../../Common/SimpleTypes_Shared.h" -#include "..\..\XlsbFormat\Biff12_unions\HLINKS.h" +#include "../../XlsbFormat/Biff12_unions/HLINKS.h" namespace OOX { From bc6e7e2831482095382eb6b9934e8571daae9612 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 22 Dec 2023 17:17:18 +0300 Subject: [PATCH 215/794] Refinement of attributes. Code refactoring. Editing logic. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 74 ++-- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 39 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 3 +- .../StarMath2OOXML/cstarmathpars.cpp | 344 ++++++++++++++---- .../Converter/StarMath2OOXML/cstarmathpars.h | 31 +- 5 files changed, 346 insertions(+), 145 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index b81713a1a7c..3b970281042 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -750,7 +750,7 @@ TEST(SMConvectorTest,FunctionSinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sinh2\u22833"; + std::wstring wsXmlString = L"sinh2\u22833"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -850,7 +850,7 @@ TEST(SMConvectorTest,FunctionArtanhArcoth) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arcoth30\u2282artanh27"; + std::wstring wsXmlString = L"arcoth30\u2282artanh27"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -940,7 +940,7 @@ TEST(SMConvectorTest,OperatorLllint) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2102+3100"; + std::wstring wsXmlString = L"2102+3100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -950,41 +950,31 @@ TEST(SMConvectorTest,BracketLdlineAttribute) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"10100+3+10"; + std::wstring wsXmlString = L"10100+3+10"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } -//TEST(SMConvectorTest,FunctionCos) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString = L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} - -//TEST(SMConvectorTest,FunctionCos) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString = L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} +TEST(SMConvectorTest,Example11) +{ + std::wstring wsString = L"f(x) = sum from { n=0 } to { infinity } { {f^{(n)}(x_0) } over { fact{n} } (x-x_0)^n }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} -//TEST(SMConvectorTest,FunctionCos) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString = L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} +TEST(SMConvectorTest,AttributeGrade) +{ + std::wstring wsString = L"color green bold evaluate {E = color black m c^ color yellow 2} from {color crimson b over color teal a} to color navy overstrike infinity"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"E=mc2ba\u221E"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} -//TEST(SMConvectorTest,FunctionCos) +//TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; // StarMath::CParserStarMathString oTemp; @@ -994,25 +984,7 @@ TEST(SMConvectorTest,BracketLdlineAttribute) // EXPECT_EQ(oTest.GetOOXML(),wsXmlString); //} -//TEST(SMConvectorTest,FunctionCos) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString = L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} -//TEST(SMConvectorTest,FunctionCos) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString = L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index a29aa78430d..4173b638d76 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -54,7 +54,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"w:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - else + else if(pAttribute->GetSize() != 0) { pXmlWrite->WriteNodeBegin(L"w:sz",true); pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); @@ -63,13 +63,17 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); pXmlWrite->WriteNodeEnd(L"w",true,true); } - if(!pAttribute->EmptyColor() && pAttribute != nullptr) + if(!pAttribute->EmptyColor()) { pXmlWrite->WriteNodeBegin(L"w:color",true); pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); pXmlWrite->WriteNodeEnd(L"w",true,true); } - if(pAttribute->GetBold()) + if(pAttribute->GetBold() && pAttribute->GetItal()) + { + WriteStyNode(pXmlWrite,L"bi"); + } + else if(pAttribute->GetBold()) { pXmlWrite->WriteNodeBegin(L"m:sty", true); pXmlWrite->WriteAttribute(L"m:val",L"b"); @@ -79,11 +83,8 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"w:bCs",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } - if(pAttribute->GetItal()) + else if(pAttribute->GetItal()) { - pXmlWrite->WriteNodeBegin(L"m:sty", true); - pXmlWrite->WriteAttribute(L"m:val",L"i"); - pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"w:i",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } @@ -105,22 +106,6 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w",true,true); } WriteCtrlPrNode(pXmlWrite,pAttribute); -// pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); -// pXmlWrite->WriteNodeBegin(L"w:rPr",false); -// pXmlWrite->WriteNodeBegin(L"w:rFonts",true); -// pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); -// pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); -// pXmlWrite->WriteNodeEnd(L"w",true,true); -// pXmlWrite->WriteNode(L"w:i",L""); -// //m_pXmlWrite->WriteNode(L"w:iCs",L""); -// pXmlWrite->WriteNodeBegin(L"w:sz",true); -// pXmlWrite->WriteAttribute(L"w:val",L"40"); -// pXmlWrite->WriteNodeEnd(L"w",true,true); -// pXmlWrite->WriteNodeBegin(L"w:szCs",true); -// pXmlWrite->WriteAttribute(L"w:val",L"40"); -// pXmlWrite->WriteNodeEnd(L"w",true,true); -// pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); -// pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) @@ -306,7 +291,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WrtieRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -333,5 +318,11 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); } + void CConversionSMtoOOXML::WriteStyNode(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsAttributeNode) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",wsAttributeNode); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index c7f8a599381..692a6722917 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -23,7 +23,8 @@ namespace StarMath { static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); - static void WrtieRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); void EndConversion(); std::wstring GetOOXML(); private: diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index fe620a13bea..12584ca4a34 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -42,12 +42,14 @@ namespace StarMath if(pElement != nullptr) { - if(pReader->GetAttribute() != nullptr) - pElement->SetAttribute(pReader->GetAttribute()); - else if(pReader->GetAttributeTemp() != nullptr) - pElement->SetAttribute(pReader->GetAttributeTemp()); + if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) + pElement->SetBaseAttribute(pReader->GetAttribute()); + else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType())) + pElement->SetBaseAttribute(pReader->GetAttribute()); pReader->ClearReader(); pElement->Parse(pReader); + if(pElement->GetAttribute() != nullptr && TypeElement::Function != pElement->GetBaseType()) + pElement->SetAttribute(pElement->GetAttribute()); return pElement; } else return pElement; @@ -100,7 +102,7 @@ namespace StarMath pReader->SetTypesToken(); while(CheckForLeftArgument(pReader->GetGlobalType())) { - pReader->SetAttributeTemp(pAttribute); +// pReader->SetAttributeTemp(pAttribute); CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); if(pFirstTempElement != nullptr) { @@ -113,7 +115,7 @@ namespace StarMath pReader->SetTypesToken(); } } - pReader->ClearAttributeTemp(); +// pReader->ClearAttributeTemp(); return pFirstTempElement; } bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType) @@ -245,6 +247,10 @@ namespace StarMath } } } + void CAttribute::SetColor(const std::wstring &wsColor) + { + m_wsColor = wsColor; + } void CAttribute::SetFont(const TypeElement &enFont) { switch (enFont) { @@ -298,9 +304,15 @@ namespace StarMath switch(enTempColor) { case TypeElement::hex: - pReader->GetToken(); - m_wsColor = pReader->GetString(); + { + std::wstring wsTempHex; + do + { + wsTempHex += pReader->GetElement(); + }while(wsTempHex.size()< 6); + m_wsColor = wsTempHex; break; + } case TypeElement::rgb: { const int iTempLen = 7; @@ -433,10 +445,6 @@ namespace StarMath return nullptr; } } - void CElement::SetAttribute(CAttribute* pAttribute) - { - m_pAttribute = pAttribute; - } const TypeElement& CElement::GetBaseType() { return m_enBaseType; @@ -445,6 +453,26 @@ namespace StarMath { m_enBaseType = enType; } + void CElement::SetBaseAttribute(CAttribute *pAttribute) + { + if(m_pAttribute == nullptr && pAttribute != nullptr) + m_pAttribute = pAttribute; + else if(pAttribute != nullptr && pAttribute != m_pAttribute) + { + if(!m_pAttribute->GetBold() && pAttribute->GetBold()) + m_pAttribute->SetBold(); + if(!m_pAttribute->GetItal() && pAttribute->GetItal()) + m_pAttribute->SetItal(); + if(!m_pAttribute->GetPhantom() && pAttribute->GetPhantom()) + m_pAttribute->SetPhantom(); + if(!m_pAttribute->GetStrike() && pAttribute->GetStrike()) + m_pAttribute->SetStrike(); + if(m_pAttribute->EmptyColor() && !pAttribute->EmptyColor()) + m_pAttribute->SetColor(pAttribute->GetColor()); + if(m_pAttribute->GetSize() == 0 && pAttribute->GetSize() != 0) + m_pAttribute->SetSize(pAttribute->GetSize()); + } + } CAttribute* CElement::GetAttribute() { return m_pAttribute; @@ -465,14 +493,14 @@ namespace StarMath { pReader->ClearReader(); } - void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) + void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { - oXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(oXmlWrite,GetAttribute()); - oXmlWrite->WriteNodeBegin(L"m:t",false); - oXmlWrite->WriteString(m_wsString); - oXmlWrite->WriteNodeEnd(L"m:t",false,false); - oXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(m_wsString); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); } std::wstring CElementString::GetString() { @@ -488,6 +516,20 @@ namespace StarMath } return TypeElement::String; } + TypeElement CElementString::GetWord(const std::wstring &wsToken) + { + if(wsToken.empty()) return TypeElement::undefine; + + for(wchar_t cOneElement: wsToken) + { + if(!isalpha(cOneElement)) return TypeElement::undefine; + } + return TypeElement::String; + } + void CElementString::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + } //class methods CElementBinOperator CElementBinOperator::CElementBinOperator(const TypeElement& enType): m_pLeftArgument(nullptr) , m_pRightArgument(nullptr) { @@ -516,8 +558,6 @@ namespace StarMath } else { - if(m_enTypeBinOp == TypeElement::plus || TypeElement::minus == m_enTypeBinOp) - pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); @@ -529,6 +569,8 @@ namespace StarMath } else SetRightArg(pTempElement); +// if(TypeElement::plus == m_enTypeBinOp || TypeElement::minus == m_enTypeBinOp) +// m_pRightArgument->SetAttribute(GetAttribute()); } } void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) @@ -586,7 +628,7 @@ namespace StarMath default: break; } - if(m_pRightArgument->GetBaseType() == TypeElement::String) + if(m_pRightArgument->GetBaseType() == TypeElement::String && GetAttribute() == m_pRightArgument->GetAttribute()) { CElementString* oNumber = dynamic_cast (m_pRightArgument); oXmlWrite->WriteString(oNumber->GetString()); @@ -644,6 +686,14 @@ namespace StarMath return false; } } + void CElementBinOperator::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument !=nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument!=nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) { @@ -701,7 +751,6 @@ namespace StarMath } while(enBracketClose == TypeElement::undefine) { - pReader->SetAttributeTemp(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) { @@ -721,7 +770,7 @@ namespace StarMath else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() - pReader->ClearAttributeTemp(); + SetAttribute(GetAttribute()); pReader->ClearReader(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -747,16 +796,41 @@ namespace StarMath } } + void CElementBracket::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + for(CElement* pTempElement:m_arBrecketValue) + { + if(pTempElement!=nullptr) + pTempElement->SetAttribute(pAttribute); + } + } //class methods CElementSpecialSymbol - CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType):m_pValue(nullptr) { m_enTypeSpecial = enType; SetBaseType(TypeElement::SpecialSymbol); } CElementSpecialSymbol::~CElementSpecialSymbol() - {} + { + delete m_pValue; + } void CElementSpecialSymbol::Parse(CStarMathReader* pReader) { + switch(m_enTypeSpecial) + { + case TypeElement::fact: + { + SetValue(CParserStarMathString::ParseElement(pReader)); + break; + } + default: + break; + } + } + void CElementSpecialSymbol::SetValue(CElement* pValue) + { + m_pValue = pValue; } TypeElement CElementSpecialSymbol::GetSpecialSymbol(const std::wstring &wsToken) { @@ -769,15 +843,47 @@ namespace StarMath else if(L"setQ" == wsToken) return TypeElement::setQ; else if(L"setR" == wsToken) return TypeElement::setR; else if(L"setc" == wsToken) return TypeElement::setC; + else if(L"infinity" == wsToken) return TypeElement::infinity; + else if(L"fact" == wsToken) return TypeElement::fact; + else if(L"abs" == wsToken) return TypeElement::abs; else return TypeElement::undefine; } void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - if(m_enTypeSpecial == TypeElement::transition) + switch(m_enTypeSpecial) + { + case TypeElement::transition: { pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeBegin(L"m:mr",false); + break; } + case TypeElement::infinity: + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(L"\u221E"); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + break; + } + case TypeElement::fact: + { + if(m_pValue!= nullptr) + m_pValue->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(L"\u0021"); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + } + } + void CElementSpecialSymbol::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); } //class methods CElementSetOperations CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) @@ -898,6 +1004,14 @@ namespace StarMath else if(L"owns" == wsToken) return TypeElement::owns; else return TypeElement::undefine; } + void CElementSetOperations::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument!= nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument != nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } //class methods CElementConnection CElementConnection::CElementConnection(const TypeElement& enType): m_pLeftArgument(nullptr), m_pRightArgument(nullptr) { @@ -1090,6 +1204,14 @@ namespace StarMath else if(L"drarrow" == wsToken) return TypeElement::drarrow; else return TypeElement::undefine; } + void CElementConnection::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pLeftArgument!= nullptr) + m_pLeftArgument->SetAttribute(pAttribute); + if(m_pRightArgument != nullptr) + m_pRightArgument->SetAttribute(pAttribute); + } //class methods CIndex CElementIndex::CElementIndex(const TypeElement& enType): m_pValueIndex(nullptr),m_pValue(nullptr) { @@ -1107,7 +1229,8 @@ namespace StarMath } void CElementIndex::SetLeftArg(CElement *pElement) { - m_pValue = pElement; + if(m_pValue == nullptr) + m_pValue = pElement; } CElement* CElementIndex::GetValueIndex() { @@ -1121,11 +1244,19 @@ namespace StarMath else if(L"lsub" == wsCheckToken) return TypeElement::lsub; else if(L"csup" == wsCheckToken) return TypeElement::csup; else if(L"csub" == wsCheckToken) return TypeElement::csub; + else if(L"nroot" == wsCheckToken) return TypeElement::nroot; + else if(L"sqrt" == wsCheckToken) return TypeElement::sqrt; else return TypeElement::undefine; } void CElementIndex::Parse(CStarMathReader *pReader) { - SetValueIndex(CParserStarMathString::ParseElement(pReader)); + if(m_enTypeIndex == TypeElement::nroot) + { + SetLeftArg(CParserStarMathString::ParseElement(pReader)); + SetValueIndex(CParserStarMathString::ParseElement(pReader)); + } + else + SetValueIndex(CParserStarMathString::ParseElement(pReader)); } void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1178,6 +1309,26 @@ namespace StarMath CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); } + else if(m_enTypeIndex == TypeElement::nroot || TypeElement::sqrt == m_enTypeIndex) + { + pXmlWrite->WriteNodeBegin(L"m:rad",false); + pXmlWrite->WriteNodeBegin(L"m:radPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); + if(m_pValue != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:deg",false); + m_pValue->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:deg",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:deg",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:rad",false,false); + } // else if(m_enTypeIndex == TypeElement::csup || TypeElement::csub == m_enTypeIndex) // { // pXmlWrite->WriteNodeBegin(L"m:acc",false); @@ -1188,6 +1339,14 @@ namespace StarMath // pXmlWrite->WriteNodeEnd(L"m:acc",false,false); // } } + void CElementIndex::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValue != nullptr) + m_pValue->SetAttribute(pAttribute); + if(m_pValueIndex != nullptr) + m_pValueIndex->SetAttribute(pAttribute); + } //class methods CElementFunction CElementFunction::CElementFunction(const TypeElement &enType): m_pValue(nullptr) { @@ -1212,11 +1371,11 @@ namespace StarMath CElement* pTemp = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::Index) + if(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) { - CElement* pBinOp = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTemp,pBinOp); - pTemp = pBinOp; + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTemp,pTempElement); + pTemp = pTempElement; } SetValueFunction(pTemp); //pReader->ClearReader(); @@ -1283,6 +1442,15 @@ namespace StarMath case TypeElement::arcoth: pXmlWrite->WriteString(L"arcoth"); break; + case TypeElement::log: + pXmlWrite->WriteString(L"log"); + break; + case TypeElement::ln: + pXmlWrite->WriteString(L"ln"); + break; + case TypeElement::exp: + pXmlWrite->WriteString(L"exp"); + break; default: break; } @@ -1296,10 +1464,7 @@ namespace StarMath } TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) { - if(L"abs" == wsToken) return TypeElement::abs; - else if(L"fact" == wsToken) return TypeElement::fact; - else if(L"sqrt" == wsToken) return TypeElement::sqrt; - else if(L"sin" == wsToken) return TypeElement::sin; + if(L"sin" == wsToken) return TypeElement::sin; else if(L"cos" == wsToken) return TypeElement::cos; else if(L"tan" == wsToken) return TypeElement::tan; else if(L"cot" == wsToken) return TypeElement::cot; @@ -1320,6 +1485,12 @@ namespace StarMath else if(L"log" == wsToken) return TypeElement::log; else return TypeElement::undefine; } + void CElementFunction::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValue != nullptr) + m_pValue->SetAttribute(pAttribute); + } //class methods CElementOperation CElementOperator::CElementOperator(const TypeElement &enType): m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr) { @@ -1380,7 +1551,7 @@ namespace StarMath } void CElementOperator::Parse(CStarMathReader* pReader) { - pReader->SetAttributeTemp(GetAttribute()); +// pReader->SetAttributeTemp(GetAttribute()); pReader->GetToken(); pReader->SetTypesToken(); if(pReader->GetLocalType() == TypeElement::from) @@ -1393,9 +1564,9 @@ namespace StarMath pReader->ClearReader(); SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } - pReader->SetAttributeTemp(GetAttribute()); +// pReader->SetAttributeTemp(GetAttribute()); SetValueOperator(CParserStarMathString::ParseElement(pReader)); - pReader->ClearAttributeTemp(); +// pReader->ClearAttributeTemp(); } void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { @@ -1410,7 +1581,7 @@ namespace StarMath CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:fName",false); if(m_pValueFrom == nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WrtieRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); else { pXmlWrite->WriteNodeBegin(wsTempNameNode,false); @@ -1418,7 +1589,7 @@ namespace StarMath CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); pXmlWrite->WriteNodeEnd(wsTempNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WrtieRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeBegin(L"m:lim",false); if(wsTempNameNode == L"m:limLow") @@ -1452,8 +1623,18 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:nary",false,false); } } + void CElementOperator::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueOperator!= nullptr) + m_pValueOperator->SetAttribute(pAttribute); + if(m_pValueFrom!= nullptr) + m_pValueFrom->SetAttribute(pAttribute); + if(m_pValueTo!=nullptr) + m_pValueTo->SetAttribute(pAttribute); + } // class methods CStarMathReader - CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_pAttributeTemp(nullptr) + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr) { m_itStart = itStart; m_itEnd = itEnd; @@ -1575,6 +1756,12 @@ namespace StarMath m_enGlobalType = TypeElement::Operation; return; } + m_enUnderType = CElementString::GetWord(m_wsToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::String; + return; + } if(m_enUnderType == TypeElement::undefine) { m_enGlobalType = TypeElement::Empty; @@ -1609,10 +1796,6 @@ namespace StarMath if(m_itStart !=m_itEnd) return false; else return true; } - void CStarMathReader::SetAttributeTemp(CAttribute *pAttribute) - { - m_pAttributeTemp = pAttribute; - } void CStarMathReader::SetAttribute(CAttribute *pAttribute) { m_pAttribute = pAttribute; @@ -1621,14 +1804,6 @@ namespace StarMath { return m_pAttribute; } - CAttribute* CStarMathReader::GetAttributeTemp() - { - return m_pAttributeTemp; - } - void CStarMathReader::ClearAttributeTemp() - { - m_pAttributeTemp = nullptr; - } std::wstring CStarMathReader::GetElement() { std::wstring m_wsElement{}; @@ -1640,11 +1815,11 @@ namespace StarMath m_itStart++; break; } - else if(!m_wsElement.empty() && (*m_itStart == L'[' || *m_itStart == L']' || *m_itStart == L'(' || L')' == *m_itStart || *m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart ||(L'#' == *m_itStart && L'#' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) { return m_wsElement; } - else if(((*m_itStart == L'{' || *m_itStart == L'}' || *m_itStart == L'+' || *m_itStart == L'-' || *m_itStart == L'/' || *m_itStart == L'*' || L'^' == *m_itStart || L'_' == *m_itStart || L'=' == *m_itStart || *m_itStart == L'[' || *m_itStart == L']') && m_wsElement.empty()) || (!m_wsElement.empty() && ((m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) + else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) { m_wsElement.push_back(*m_itStart); m_itStart++; @@ -1658,6 +1833,20 @@ namespace StarMath if(!m_wsElement.empty()) return m_wsElement; else return {}; } + bool CStarMathReader::CheckTokenForGetElement(const char &cToken) + { + if(L'[' == cToken) return true; + else if(L']' == cToken) return true; + else if(L'{' == cToken) return true; + else if(L'}' == cToken) return true; + else if(L'_' == cToken) return true; + else if(L'^' == cToken) return true; + else if(L'*' == cToken) return true; + else if(L'/' == cToken) return true; + else if(L'-' == cToken) return true; + else if(L'+' == cToken) return true; + else return false; + } //class methods CElementBracketWithIndex CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType): m_pLeftArg(nullptr), m_pValue(nullptr) { @@ -1751,6 +1940,14 @@ namespace StarMath else if(L"underbrace" == wsToken) return TypeElement::underbrace; else return TypeElement::undefine; } + void CElementBracketWithIndex::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValue!= nullptr) + m_pValue->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr) + m_pLeftArg->SetAttribute(pAttribute); + } //class methods CElementGrade CElementGrade::CElementGrade(): m_pValueFrom(nullptr), m_pValueGrade(nullptr), m_pValueTo(nullptr) { @@ -1791,6 +1988,8 @@ namespace StarMath pReader->ClearReader(); SetValueTo(CParserStarMathString::ParseElement(pReader)); } + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); } void CElementGrade::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1842,6 +2041,16 @@ namespace StarMath if(L"evaluate" == wsToken) return TypeElement::evaluate; else return TypeElement::undefine; } + void CElementGrade::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueGrade!=nullptr) + m_pValueGrade->SetAttribute(pAttribute); + if(m_pValueFrom!=nullptr) + m_pValueFrom->SetAttribute(pAttribute); + if(m_pValueTo!=nullptr) + m_pValueTo->SetAttribute(pAttribute); + } //class methods CElementMatrix CElementMatrix::CElementMatrix(const TypeElement &enType): m_pFirstArgument(nullptr), m_pSecondArgument(nullptr) { @@ -1872,16 +2081,15 @@ namespace StarMath { if(m_enTypeMatrix == TypeElement::binom) { - pReader->SetAttribute(GetAttribute()); SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); - pReader->SetAttribute(GetAttribute()); SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); } else { - pReader->SetAttribute(GetAttribute()); SetFirstArgument(CParserStarMathString::ParseElement(pReader)); } + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); } void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1936,6 +2144,14 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeEnd(L"m:m",false,false); } + void CElementMatrix::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pFirstArgument != nullptr) + m_pFirstArgument->SetAttribute(pAttribute); + if(m_pSecondArgument != nullptr) + m_pSecondArgument->SetAttribute(pAttribute); + } //class CElementDiacriticalMark CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType):m_pValueMark(nullptr) { @@ -1975,7 +2191,7 @@ namespace StarMath } void CElementDiacriticalMark::Parse(CStarMathReader *pReader) { - pReader->SetAttribute(GetAttribute()); + //pReader->SetAttribute(GetAttribute()); SetValueMark(CParserStarMathString::ParseElement(pReader)); } void CElementDiacriticalMark::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -2058,6 +2274,12 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:acc",false,false); } + void CElementDiacriticalMark::SetAttribute(CAttribute *pAttribute) + { + SetBaseAttribute(pAttribute); + if(m_pValueMark != nullptr) + m_pValueMark->SetAttribute(pAttribute); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index e1ff22d467e..915c2f646a4 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -27,14 +27,15 @@ namespace StarMath bool EmptyColor(); void ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); void ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); - private: void SetSize(const unsigned int& iSize); void SetBold(); void SetItal(); void SetPhantom(); void SetStrike(); void SetColor(const TypeElement& enColor); + void SetColor(const std::wstring& wsColor); void SetFont(const TypeElement& enFont); + private: std::wstring m_wsColor; bool m_bBold; bool m_bItal; @@ -61,19 +62,16 @@ namespace StarMath bool CheckIteratorPosition(); bool EmptyString(); void SetAttribute(CAttribute* pAttribute); - void SetAttributeTemp(CAttribute* pAttribute); - CAttribute* GetAttributeTemp(); CAttribute* GetAttribute(); - void ClearAttributeTemp(); - private: //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); + private: + bool CheckTokenForGetElement(const char& cToken); std::wstring::iterator m_itStart,m_itEnd; TypeElement m_enGlobalType; TypeElement m_enUnderType; std::wstring m_wsToken; CAttribute* m_pAttribute; - CAttribute* m_pAttributeTemp; }; class CElement @@ -85,7 +83,8 @@ namespace StarMath //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) static CElement* CreateElement(CStarMathReader* pReader); virtual void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) = 0; - void SetAttribute(CAttribute* pAttribute); + virtual void SetAttribute(CAttribute* pAttribute) = 0; + void SetBaseAttribute(CAttribute* pAttribute); void SetBaseType(const TypeElement& enType); CAttribute* GetAttribute(); const TypeElement& GetBaseType(); @@ -104,6 +103,7 @@ namespace StarMath CElement* GetValueIndex(); static TypeElement GetIndex(const std::wstring& wsCheckToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueIndex; @@ -119,9 +119,11 @@ namespace StarMath void SetString(const std::wstring& wsTokenString); std::wstring GetString(); static TypeElement GetDigit(const std::wstring& wsCheckToken); + static TypeElement GetWord(const std::wstring& wsToken); + void SetAttribute(CAttribute* pAttribute) override; private: void Parse(CStarMathReader* pReader) override; - void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; std::wstring m_wsString; }; @@ -137,6 +139,7 @@ namespace StarMath CElement* GetLeftArg(); static TypeElement GetBinOperator(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; bool IsBinOperatorLowPrior(); void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; @@ -159,6 +162,7 @@ namespace StarMath static TypeElement GetOperator(const std::wstring& wsToken); static TypeElement GetFromOrTo(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute); void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) override; CElement* m_pValueOperator; @@ -177,6 +181,7 @@ namespace StarMath void SetValueTo(CElement* pElement); static TypeElement GetGrade(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueGrade; @@ -193,6 +198,7 @@ namespace StarMath static TypeElement GetBracketOpen(const std::wstring& wsToken); std::vector GetBracketValue(); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override;// TypeElement GetBracketClose(const std::wstring& wsToken); @@ -209,6 +215,7 @@ namespace StarMath void SetBracketValue(CElement* pElement); static TypeElement GetBracketWithIndex(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pLeftArg; @@ -227,6 +234,7 @@ namespace StarMath CElement* GetRightArg(); static TypeElement GetSetOperation(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pLeftArgument; @@ -245,6 +253,7 @@ namespace StarMath CElement* GetLeftArg(); static TypeElement GetConnection(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pLeftArgument; @@ -261,6 +270,7 @@ namespace StarMath CElement* GetValueFunction(); static TypeElement GetFunction(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValue; @@ -273,9 +283,12 @@ namespace StarMath CElementSpecialSymbol(const TypeElement& enType); virtual ~CElementSpecialSymbol(); static TypeElement GetSpecialSymbol(const std::wstring& wsToken); + void SetValue(CElement* pValue); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + CElement* m_pValue; TypeElement m_enTypeSpecial; }; @@ -288,6 +301,7 @@ namespace StarMath void SetSecondArgument(CElement* pElement); static TypeElement GetMatrix(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader *pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pFirstArgument; @@ -303,6 +317,7 @@ namespace StarMath void SetValueMark(CElement* pValue); static TypeElement GetMark(const std::wstring& wsToken); private: + void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueMark; From 057eed59c102f3d8141cfaa4a9ba6ff51330bb17 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 25 Dec 2023 19:42:49 +0300 Subject: [PATCH 216/794] xlst->xlsb --- .../Sheets/Common/BinReaderWriterDefines.h | 6 +- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 41 +++++++++--- OOXML/XlsxFormat/Styles/Borders.cpp | 2 +- OOXML/XlsxFormat/Styles/Fills.cpp | 2 +- OOXML/XlsxFormat/Styles/Fonts.cpp | 2 +- OOXML/XlsxFormat/Styles/NumFmts.cpp | 2 +- OOXML/XlsxFormat/Styles/Xfs.cpp | 4 +- OOXML/XlsxFormat/Styles/dxf.cpp | 2 +- X2tConverter/src/ASCConverters.cpp | 11 +++ X2tConverter/src/cextracttools.cpp | 2 + X2tConverter/src/cextracttools.h | 3 + X2tConverter/src/lib/xlsx.h | 67 +++++++++++++++++-- 12 files changed, 116 insertions(+), 28 deletions(-) diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index f7469f9bac3..e88d7c0c81d 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -47,9 +47,9 @@ namespace BinXlsxRW namespace c_oFileTypes{enum c_oFileTypes { XLSX = 1, - CSV = 2, - JSON = 3, - XLSB = 4 + CSV = 2, + JSON = 3, + XLSB = 4 };} diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 5049cda88f1..8dcce5462b7 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -8117,7 +8117,7 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD if (NULL != pData) { - // File Type + // File Type std::wstring sDstPathCSV = sDstPath; BYTE fileType; UINT nCodePage; @@ -8125,8 +8125,8 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD BYTE saveFileType; SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType); - // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. - + // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. + if (BinXlsxRW::c_oFileTypes::CSV == fileType) { sDstPath = pOfficeDrawingConverter->GetTempPath(); @@ -8135,36 +8135,55 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD sDstPath = NSDirectory::CreateDirectoryWithUniqueName(sDstPath); } - - OOX::Spreadsheet::CXlsx oXlsx; - + std::wstring themePath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath(); std::wstring drawingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Drawings.DefaultDirectory().GetPath(); std::wstring embeddingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::MicrosoftOfficeUnknown.DefaultDirectory().GetPath(); std::wstring chartsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Chart.DefaultDirectory().GetPath(); oBufferedStream.m_pRels->m_pManager->SetDstCharts(chartsPath); - + bResultOk = true; - + if (BinXlsxRW::c_oFileTypes::XLSX == fileType) { + OOX::Spreadsheet::CXlsx oXlsx; SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); - + try { ReadMainTable(oXlsx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); } - catch(...) + catch (...) { bResultOk = false; } - + oXlsx.PrepareToWrite(); oXlsx.Write(sDstPath, *oSaveParams.pContentTypes); } + else if (BinXlsxRW::c_oFileTypes::XLSB == fileType) + { + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); + + try + { + ReadMainTable(oXlsb, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); + } + catch (...) + { + bResultOk = false; + } + + oXlsb.PrepareToWrite(); + oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); + } else { + OOX::Spreadsheet::CXlsx oXlsx; CSVWriter oCSVWriter; oCSVWriter.Init(oXlsx, nCodePage, sDelimiter, false); diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 1801f19c78d..5350fe6b444 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -39,7 +39,7 @@ #include "../../XlsbFormat/Biff12_records/BeginBorders.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" -#include "../../../XlsbFormat/Biff12_unions/BORDERS.h" +#include "../../XlsbFormat/Biff12_unions/BORDERS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index c62f0bdca5a..75880f33815 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -39,7 +39,7 @@ #include "../../XlsbFormat/Biff12_records/BeginFills.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" -#include "../../../XlsbFormat/Biff12_unions/FILLS.h" +#include "../../XlsbFormat/Biff12_unions/FILLS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 2a8a438d3bb..fd18d078e3b 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -36,7 +36,7 @@ #include "../../XlsbFormat/Biff12_records/CommonRecords.h" #include "../../XlsbFormat/Biff12_records/BeginFonts.h" -#include "../../../XlsbFormat/Biff12_unions/FONTS.h" +#include "../../XlsbFormat/Biff12_unions/FONTS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index 267cc2a10eb..9109cf6fe96 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -36,7 +36,7 @@ #include "../../XlsbFormat/Biff12_unions/ACFMT.h" #include "../../Common/SimpleTypes_Shared.h" -#include "../../../XlsbFormat/Biff12_unions/FMTS.h" +#include "../../XlsbFormat/Biff12_unions/FMTS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 65bb8bb1b25..b12160f9f79 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -39,8 +39,8 @@ #include "../../XlsbFormat/Biff12_records/BeginCellStyleXFs.h" #include "../../XlsbFormat/Biff12_records/BeginCellXFs.h" -#include "../../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" -#include "../../../XlsbFormat/Biff12_unions/CELLXFS.h" +#include "../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" +#include "../../XlsbFormat/Biff12_unions/CELLXFS.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Styles/dxf.cpp b/OOXML/XlsxFormat/Styles/dxf.cpp index a1a55855956..15dd9aee751 100644 --- a/OOXML/XlsxFormat/Styles/dxf.cpp +++ b/OOXML/XlsxFormat/Styles/dxf.cpp @@ -46,7 +46,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include -#include "../../../XlsbFormat/Biff12_unions/DXFS.h" +#include "../../XlsbFormat/Biff12_unions/DXFS.h" namespace OOX { diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index d10bb637db0..42badaa106f 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -799,6 +799,10 @@ namespace NExtractTools { nRes = xlst_bin2csv(sFrom, sTo, params, convertParams); } + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatTo) + { + nRes = xlst_bin2xlsb(sFrom, sTo, params, convertParams); + } else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; @@ -1536,6 +1540,13 @@ namespace NExtractTools result = xlst2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; + case TCD_XLST2XLSB: + { + oInputParams.m_bMacro = true; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB); + result = xlst2xlsb(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; case TCD_XLST2XLTX: { oInputParams.m_bMacro = false; diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index abc8ed5dc8f..bf4144f9123 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -329,6 +329,8 @@ namespace NExtractTools res = TCD_T2BIN; else if (0 == sExt2.compare(L".csv")) res = TCD_XLST2CSV; + else if (0 == sExt2.compare(L".xlsb")) + res = TCD_XLST2XLSB; } break; case AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY: diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index fcde055f1d5..d4d8948ba30 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -95,6 +95,7 @@ namespace NExtractTools TCD_XLTM2XLSM, TCD_XLSB2XLST, TCD_XLSX2XLSB, + TCD_XLST2XLSB, TCD_PPTX2PPTT, TCD_PPTT2PPTX, @@ -915,6 +916,8 @@ namespace NExtractTools sSaveType = _T(" saveFileType='3'"); else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == *m_nFormatTo) nFileType = 2; + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == *m_nFormatTo) + nFileType = 4; } sRes = L" Date: Tue, 26 Dec 2023 16:49:50 +0300 Subject: [PATCH 217/794] . --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 7b3d91627db..5b0a9b9ddc9 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -385,8 +385,10 @@ namespace OOX void CWorksheet::PrepareAfterRead() { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); - if (!(xlsb) && (xlsb->m_bWriteToXlsb)) + if (!xlsb || ((xlsb) && (xlsb->m_bWriteToXlsb))) + { PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); + } PrepareConditionalFormatting(); PrepareDataValidations(); } From 6f5fa6c4caedb87dcb746e8209388e9d72c3e5fc Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 26 Dec 2023 20:31:04 +0300 Subject: [PATCH 218/794] Switching to case-insensitive search in html2 --- Common/3dParty/html/htmltoxhtml.h | 117 ++++++++------------------ HtmlFile2/HtmlFile2.pro | 6 +- HtmlFile2/htmlfile2.cpp | 4 +- HtmlFile2/src/StringFinder.h | 133 ++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 84 deletions(-) create mode 100644 HtmlFile2/src/StringFinder.h diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 945bb8286ee..1bc7737a5ae 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -12,6 +12,7 @@ #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/common/StringBuilder.h" #include "../../../UnicodeConverter/UnicodeConverter.h" +#include "../../../HtmlFile2/src/StringFinder.h" static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|"; static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|"; @@ -234,90 +235,50 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun nContentTag += 2; // Content-Type - size_t nTag = sFileContent.find("Content-Type: ", nFound); - if(nTag == std::string::npos || nTag > nContentTag) - { - nFound = nNextFound; - return; - } - size_t nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 14; - if(nTagEnd == std::string::npos || nTagEnd > nContentTag) + std::string sContentType = NSStringFinder::FindPropety(sFileContent, "content-type", {":"}, {";", "\\n", "\\r"}, nFound); + + if (sContentType.empty()) { nFound = nNextFound; return; } - std::string sContentType = sFileContent.substr(nTag, nTagEnd - nTag); - if(sContentType == "multipart/alternative") + + if (NSStringFinder::Equals(sContentType, std::string("multipart/alternative"))) nContentTag = nFound; + size_t nTag = 0, nTagEnd = 0; + // name - std::string sName; - nTag = sFileContent.find(" name=", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 6; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sName = sFileContent.substr(nTag, nTagEnd - nTag); - } + std::string sName = NSStringFinder::FindPropety(sFileContent, "name", {"="}, {";", "\\n", "\\r"}, nFound); // charset - std::string sCharset; - nTag = sFileContent.find("charset=", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 8; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - { - if(sFileContent[nTag] == '\"') - { - nTag++; - nTagEnd--; - } - sCharset = sFileContent.substr(nTag, nTagEnd - nTag); - } - } + std::string sCharset = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r"}, nFound); + NSStringFinder::CutInside(sCharset, std::string("\"")); // Content-Location - std::string sContentLocation; - nTag = sFileContent.find("Content-Location: ", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 18; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentLocation = sFileContent.substr(nTag, nTagEnd - nTag); - } + std::string sContentLocation = NSStringFinder::FindPropety(sFileContent, "content-location", {":"}, {";", "\\n", "\\r"}, nFound); if (sContentLocation.empty()) { // Content-ID - std::string sContentID; - nTag = sFileContent.find("Content-ID: <", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(">", nTag); - nTag += 13; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentID = sFileContent.substr(nTag, nTagEnd - nTag); - } + std::string sContentID = NSStringFinder::FindPropety(sFileContent, "content-id", {":"}, {";", "\\n", "\\r"}, nFound); + NSStringFinder::CutInside(sCharset, std::string("<"), std::string(">")); if (!sContentID.empty()) sContentLocation = "cid:" + sContentID; } // Content-Transfer-Encoding - std::string sContentEncoding; - nTag = sFileContent.find("Content-Transfer-Encoding: ", nFound); - if(nTag != std::string::npos && nTag < nContentTag) - { - nTagEnd = sFileContent.find_first_of(";\n\r", nTag); - nTag += 27; - if(nTagEnd != std::string::npos && nTagEnd < nContentTag) - sContentEncoding = sFileContent.substr(nTag, nTagEnd - nTag); - } + std::string sContentEncoding = NSStringFinder::FindPropety(sFileContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, nFound);; + +// nTag = sFileContent.find("Content-Transfer-Encoding: ", nFound); +// if(nTag != std::string::npos && nTag < nContentTag) +// { +// nTagEnd = sFileContent.find_first_of(";\n\r", nTag); +// nTag += 27; +// if(nTagEnd != std::string::npos && nTagEnd < nContentTag) +// sContentEncoding = sFileContent.substr(nTag, nTagEnd - nTag); +// } // Content nTagEnd = nNextFound - 2; @@ -335,7 +296,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); // Основной документ - if(sContentType == "multipart/alternative") + if (NSStringFinder::Equals(sContentType, std::string("multipart/alternative"))) oRes.WriteString(mhtTohtml(sContent)); else if((sContentType.find("text") != std::string::npos && (sExtention.empty() || sExtention == L"htm" || sExtention == L"html" || sExtention == L"xhtml" || sExtention == L"css")) || (sContentType == "application/octet-stream" && (sContentLocation.find("css") != @@ -348,17 +309,17 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun oRes.WriteString(Base64ToString(sContent, sCharset)); else if(sContentEncoding == "8bit" || sContentEncoding == "7bit" || sContentEncoding.empty()) { - if (sCharset != "utf-8" && sCharset != "UTF-8" && !sCharset.empty()) + if (!NSStringFinder::Equals(sCharset, std::string("utf-8")) && !sCharset.empty()) { NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); } oRes.WriteString(sContent); } - else if(sContentEncoding == "quoted-printable" || sContentEncoding == "Quoted-Printable") + else if (NSStringFinder::Equals(sContentEncoding, std::string("quoted-printable"))) { sContent = QuotedPrintableDecode(sContent, sCharset); - if (sCharset != "utf-8" && sCharset != "UTF-8" && !sCharset.empty()) + if (!NSStringFinder::Equals(sCharset, std::string("utf-8")) && !sCharset.empty()) { NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); @@ -391,26 +352,20 @@ static std::string mhtTohtml(std::string& sFileContent) NSStringUtils::CStringBuilderA oRes; // Поиск boundary - size_t nFound = sFileContent.find("boundary="); - if(nFound == std::string::npos) + std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r","\\n"}, 0); + + size_t nFound = 0; + if (sBoundary.empty()) { size_t nFoundEnd = sFileContent.length(); nFound = 0; ReadMht(sFileContent, nFound, nFoundEnd, "no", sRes, oRes); return oRes.GetData(); } - size_t nFoundEnd = sFileContent.find_first_of(";\n\r", nFound); - if(nFoundEnd == std::string::npos) - return ""; - nFound += 9; - if(sFileContent[nFound] == '\"') - { - nFound++; - nFoundEnd--; - } - if(nFound > nFoundEnd) - return ""; - std::string sBoundary = sFileContent.substr(nFound, nFoundEnd - nFound); + + NSStringFinder::CutInside(sBoundary, "\""); + + size_t nFoundEnd = 0; size_t nBoundaryLength = sBoundary.length(); // Удаляем лишнее diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index ea196402003..96ea48deafd 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -27,6 +27,8 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network) -SOURCES += htmlfile2.cpp +SOURCES += htmlfile2.cpp \ + ./src/StringFinder.cpp -HEADERS += htmlfile2.h +HEADERS += htmlfile2.h \ + ./src/StringFinder.h diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 67e797953bd..c2d829732bf 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -487,8 +487,10 @@ class CHtmlFile2_Private file.CloseFile(); std::string xml_string = XmlUtils::GetUtf8FromFileContent(buffer, dwReadBytes); + const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); bool bRes = false; - if (std::string::npos != xml_string.find("Content-Type: multipart/related")) + + if(NSStringFinder::Equals(sContentType, std::string("multipart/related"))) { BYTE* pData; DWORD nLength; diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h new file mode 100644 index 00000000000..280736069a2 --- /dev/null +++ b/HtmlFile2/src/StringFinder.h @@ -0,0 +1,133 @@ +#ifndef STRINGFINDER_H +#define STRINGFINDER_H + +#include +#include +#include + +namespace NSStringFinder +{ + template + StringType FindPropety(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding) + { + size_t unEndPosition = 0; + return FindPropety(sString, sProperty, sDelimiter, sEnding, 0, unEndPosition); + } + + template + StringType FindPropety(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) + { + if (sString.length() < unStarting) + return StringType(); + + typedef const boost::iterator_range StringRange; + + StringRange itFound = boost::algorithm::ifind_first(StringRange(sString.begin() + unStarting, sString.end()), sProperty); + + if (itFound.empty()) + return StringType(); + + StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(itFound.end(), sString.end()), sDelimiter); + + if (itFoundBegin.empty()) + return StringType(); + + StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.end()), sEnding); + + if (itFoundEnd.empty()) + return StringType(); + + unEndPosition += (itFoundEnd.end() - sString.begin()); + + StringType sValue{itFoundBegin.end(), itFoundEnd.begin()}; + boost::algorithm::trim(sValue); + return sValue; + } + + template + StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) + { + if (sString.length() < unStarting) + return StringType(); + + std::string sRegexValue = "(?i)" + sProperty; + + if (!arDelimiters.empty()) + { + sRegexValue += "\\s*["; + for (const StringType& sDelimiter : arDelimiters) + sRegexValue += sDelimiter + "|"; + sRegexValue.pop_back(); + sRegexValue += "]{1}"; + } + + if (!arEndings.empty()) + { + std::string sEndingValue; + + for (const StringType& sEnding : arEndings) + sEndingValue += sEnding + "|"; + + sEndingValue.pop_back(); + + sRegexValue += "\\s*(.[^" + sEndingValue + "]*)\\s*[" + sEndingValue + "]{1}"; + } + else + sRegexValue += "\\s*(.*)[\\n|\\r]{1}"; + + boost::regex oRegex(sRegexValue); + boost::match_results oResult; + + if (!boost::regex_search(sString.begin() + unStarting, sString.end(), oResult, oRegex)) + return StringType(); + + unEndPosition = unStarting + oResult.position() + oResult.length(); + + StringType sValue(oResult[1]); + boost::algorithm::trim(sValue); + + return sValue; + } + + template + StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting) + { + size_t unTempEnding = 0; + return FindPropety(sString, sProperty, arDelimiters, arEndings, unStarting, unTempEnding); + } + + template + void CutInside(StringType& sString, const StringType& sLeftEdge, const StringType& sRightEdge) + { + typedef const boost::iterator_range StringRange; + + StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(sString.begin(), sString.end()), sLeftEdge); + + if (itFoundBegin.empty()) + return; + + StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.cend()), sRightEdge); + + if (itFoundEnd.empty()) + { + sString = StringType{itFoundBegin.end(), sString.cend()}; + return; + } + + sString = StringType{itFoundBegin.end(), itFoundEnd.begin()}; + } + + template + void CutInside(StringType& sString, const StringType& sEdge) + { + CutInside(sString, sEdge, sEdge); + } + + template + bool Equals(const StringType& sFirstString, const StringType& sSecondString) + { + return boost::iequals(sFirstString, sSecondString); + } +} + +#endif // STRINGFINDER_H From 4ae8962af23fb5045cf4579a2c43cd5037af0571 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 27 Dec 2023 16:53:05 +0300 Subject: [PATCH 219/794] . --- X2tConverter/src/ASCConverters.cpp | 4 ++++ X2tConverter/src/lib/xlsx.h | 28 ++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 42badaa106f..b375299619e 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -769,6 +769,10 @@ namespace NExtractTools convertParams.m_bIsTemplate = false; nRes = xlsx_dir2ods(sFrom, sTo, params, convertParams); } + else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB == nFormatTo) + { + nRes = xlsx_dir2xlsb(sFrom, sTo, params, convertParams); + } // else if (AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatTo) //{ // nRes = xlsx_dir2csv(sFrom, sTo, sTemp, params); diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 2a5afef34f3..396b6233c5e 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -358,32 +358,36 @@ namespace NExtractTools } return nRes; } - _UINT32 xlsx_dir2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); - if(!SUCCEEDED_X2T(nRes)) - return nRes; - - const OOX::CPath oox_path(sTempUnpackedXLSX); + const OOX::CPath oox_path(sFrom); OOX::Spreadsheet::CXlsb oXlsb; oXlsb.m_bWriteToXlsb = true; oXlsb.Read(oox_path); OOX::CContentTypes oContentTypes; - nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; + _UINT32 nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; return nRes; } - _UINT32 xlsx2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + _UINT32 xlsx_dir2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsb", xlsx_dir2xlsb_dir); } + _UINT32 xlsx2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); + if (SUCCEEDED_X2T(nRes)) + { + nRes = xlsx_dir2xlsb(sTempUnpackedXLSX, sTo, params, convertParams); + } + return nRes; + } _UINT32 xml2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xml2xlsx_dir); From 189269031a329171906d83f43b1c527dcb137be9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Dec 2023 17:49:12 +0600 Subject: [PATCH 220/794] Fix shared string conversion --- OOXML/XlsxFormat/SharedStrings/Si.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index dbe89aee6d8..e008680be19 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -139,15 +139,18 @@ namespace OOX ptr->fRichStr = false; for(auto i = 0; i < m_arrItems.size(); i++) { - auto text = static_cast(m_arrItems[i]); - if(text) + + + if(m_arrItems[i]->getType() == OOX::et_x_t) { + auto text = static_cast(m_arrItems[i]); ptr->str = text->ToString(); continue; } - auto crunPtr = static_cast(m_arrItems[i]); - if(crunPtr) + + if(m_arrItems[i]->getType() == OOX::et_x_r) { + auto crunPtr = static_cast(m_arrItems[i]); ptr->fRichStr = true; USHORT ind = 0; ptr->str = ptr->str.value() + crunPtr->toBin(ind); @@ -155,6 +158,7 @@ namespace OOX run.ifnt = ind; run.ich = ptr->str.value().size(); ptr->rgsStrRun.push_back(run); + continue; } auto phonPtr = static_cast(m_arrItems[i]); if(phonPtr) From 9b06b9e7a81ee90b6ff3a4819aa3e6e847a4d71d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Dec 2023 19:04:40 +0600 Subject: [PATCH 221/794] Remove unused code --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 91f4e37f584..9ec554e55fc 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1342,8 +1342,6 @@ namespace OOX } XLS::BaseObjectPtr CSheetView::toBin() { - //if(m_oView.IsInit() || m_oTopLeftCell.IsInit() || m_oTopLeftCell.IsInit()) - //{ auto ptr(new XLSB::WSVIEW2); XLS::BaseObjectPtr castedPtr(ptr); auto pWsView(new XLSB::BeginWsView); @@ -1588,8 +1586,6 @@ namespace OOX } XLS::BaseObjectPtr CSheetViews::toBin() { - auto view = m_arrItems.back(); - auto castedPtr(new XLSB::WSVIEWS2); XLS::BaseObjectPtr ptr(castedPtr); for(auto i:m_arrItems) From 1f92b15aae47e7e6766f2f42a55967ff2a0819bf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Dec 2023 19:05:03 +0600 Subject: [PATCH 222/794] Fix blank cell conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 44 +++++++++++++++++------ 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index f0f0ab6d256..f859b1bd5f3 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1806,21 +1806,34 @@ namespace OOX { case SimpleTypes::Spreadsheet::celltypeNumber: { - auto pCellRk = new(XLSB::CellRk); - if( m_oValue->m_sText.find('.') == std::string::npos) + if(m_oValue.IsInit()) { - pCellRk->value.fInt = 1; - pCellRk->value.fX100 = 0; - pCellRk->value.num = std::stoi(m_oValue->m_sText); + auto pCellRk = new(XLSB::CellRk); + if( m_oValue->m_sText.find('.') == std::string::npos) + { + pCellRk->value.fInt = 1; + pCellRk->value.fX100 = 0; + pCellRk->value.num = std::stoi(m_oValue->m_sText); + } + else + { + pCellRk->value.fInt = 0; + pCellRk->value.fX100 = 1; + pCellRk->value.num = std::stod(m_oValue->m_sText) * 100; + } + oCell = &pCellRk->cell; + pSource = pCellRk; } else { - pCellRk->value.fInt = 0; - pCellRk->value.fX100 = 1; - pCellRk->value.num = std::stod(m_oValue->m_sText) * 100; + auto pCellblank = new(XLSB::CellBlank); + oCell = &pCellblank->cell; + oCell->fPhShow = false; + pSource = pCellblank; } - oCell = &pCellRk->cell; - pSource = pCellRk; + + + } break; case SimpleTypes::Spreadsheet::celltypeError: @@ -2053,7 +2066,16 @@ namespace OOX pSHRFMLACELL->m_source = m_oFormula->toBin(); } } - oCell->column = m_oCol.get(); + if(m_oCol.IsInit()) + oCell->column = m_oCol.get(); + else if(m_oRef.IsInit()) + { + std::wstring strRef(m_oRef.get().begin(), m_oRef.get().end()); + XLS::CellRef reference(strRef); + oCell->column = reference.getColumn(); + } + else + oCell->column = 0; if(m_oShowPhonetic.IsInit()) oCell->fPhShow = m_oShowPhonetic->GetValue(); else From 2588d45ffe3d01619a333dc3f30b460878713989 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Jan 2024 12:33:57 +0300 Subject: [PATCH 223/794] . --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 5b0a9b9ddc9..996fb65a23e 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -49,7 +49,7 @@ #include "../../XlsbFormat/Biff12_unions/HLINKS.h" #include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { From fc99dedbd4e29e85ddc24e0cd4d46e461b169be0 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Jan 2024 12:37:47 +0300 Subject: [PATCH 224/794] fix build --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 91f4e37f584..94845c05221 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -152,13 +152,13 @@ namespace OOX if (m_oName.IsInit()) ptr->rangeProtectionTitleSDRel.rgchTitle = m_oName.get(); - byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + BYTE * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); auto tempSize = 0; NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); ptr->ipdPasswordData.rgbHash.cbLength = tempSize; - byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + BYTE* temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); auto tempSize2 = 0; NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); @@ -2632,7 +2632,7 @@ namespace OOX ptr->dwSpinCount = m_oSpinCount->GetValue(); if(m_oHashValue.IsInit()) { - byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + BYTE * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); auto tempSize = 0; NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); @@ -2641,7 +2641,7 @@ namespace OOX if(m_oSaltValue.IsInit()) { - byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + BYTE * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); auto tempSize2 = 0; NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); @@ -2732,7 +2732,7 @@ namespace OOX if(m_oHashValue.IsInit()) { - byte * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + BYTE * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); auto tempSize = 0; NSFile::CBase64Converter::CBase64Converter::Decode(std::string{m_oHashValue.get().begin(), m_oHashValue.get().end()}.c_str(), m_oHashValue.get().size(), temp, tempSize); @@ -2741,7 +2741,7 @@ namespace OOX if(m_oSaltValue.IsInit()) { - byte * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + BYTE * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); auto tempSize2 = 0; NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); From 5bb50ffd479b9b14b2e162dce266367bc6a69a9b Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Jan 2024 14:00:21 +0300 Subject: [PATCH 225/794] . --- OOXML/XlsxFormat/Table/Tables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 9aeba06f02c..1a434f56383 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -64,7 +64,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { From 83a053a1dd66c161f34fbd2623412a64ee699a97 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 9 Jan 2024 18:15:15 +0600 Subject: [PATCH 226/794] Fix numbers conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 122 ++++++++++++++++------ 1 file changed, 89 insertions(+), 33 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index f859b1bd5f3..5855d5cd398 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1796,44 +1796,90 @@ namespace OOX XLSB::SHRFMLACELL* pSHRFMLACELL = nullptr; BiffRecord* pSource = nullptr; XLSB::Cell* oCell; + bool isReal = false; if(!m_oType.IsInit()) { m_oType.Init(); - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + if(m_oValue.IsInit()) + { + if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); + else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10) + { + if(m_oValue->m_sText.size() < 10) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } + else if(m_oValue->m_sText.size() == 10) + { + _INT64 tempVal = std::stoll(m_oValue->m_sText); + if(tempVal < MAXINT32 && tempVal > MININT32) + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } + } + + if((m_oValue->m_sText.find(L".") == std::string::npos || m_oValue->m_sText.find(L".") == m_oValue->m_sText.rfind(L".")) + && m_oValue->m_sText.size() <=17) + { + if(m_oValue->m_sText.size() < 17) + { + double tempVal = std::stod(m_oValue->m_sText); + if(!isnan(tempVal)) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + isReal = true; + } + } + else + { + long double tempVal = std::stold(m_oValue->m_sText); + if(!isnan(tempVal)) + if(tempVal <= DBL_MAX) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + isReal = true; + } + } + } + else if((m_oValue->m_sText.find(L"E") == std::string::npos || m_oValue->m_sText.find(L"E") == m_oValue->m_sText.rfind(L"E"))) + { + long double tempVal = std::stold(m_oValue->m_sText); + if(!isnan(tempVal)) + if(tempVal <= DBL_MAX) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + isReal = true; + } + } + + } } switch (m_oType->GetValue()) { case SimpleTypes::Spreadsheet::celltypeNumber: { - if(m_oValue.IsInit()) + if(!isReal) { auto pCellRk = new(XLSB::CellRk); - if( m_oValue->m_sText.find('.') == std::string::npos) - { - pCellRk->value.fInt = 1; - pCellRk->value.fX100 = 0; - pCellRk->value.num = std::stoi(m_oValue->m_sText); - } - else - { - pCellRk->value.fInt = 0; - pCellRk->value.fX100 = 1; - pCellRk->value.num = std::stod(m_oValue->m_sText) * 100; - } + pCellRk->value.fInt = 1; + pCellRk->value.fX100 = 0; + pCellRk->value.num = std::stoi(m_oValue->m_sText); + + oCell = &pCellRk->cell; pSource = pCellRk; } - else + else if(isReal) { - auto pCellblank = new(XLSB::CellBlank); - oCell = &pCellblank->cell; - oCell->fPhShow = false; - pSource = pCellblank; + auto pCellReal = new(XLSB::CellReal); + + pCellReal->value.data.value = std::stod(m_oValue->m_sText); + + oCell = &pCellReal->cell; + pSource = pCellReal; } - - - } break; case SimpleTypes::Spreadsheet::celltypeError: @@ -1987,23 +2033,33 @@ namespace OOX case SimpleTypes::Spreadsheet::celltypeInlineStr: case SimpleTypes::Spreadsheet::celltypeStr: { - if(m_oFormula.IsInit()) + if(m_oValue.IsInit()) { - auto str(new XLSB::FmlaString); - if(m_oValue.IsInit()) - str->value = m_oValue->m_sText; - oCell = &str->cell; + if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + oCell = &str->cell; - pSource = str; + pSource = str; + } + else + { + auto str(new XLSB::CellSt); + if(m_oValue.IsInit()) + str->value = m_oValue->m_sText; + oCell = &str->cell; + pSource = str; + } } else { - auto str(new XLSB::CellSt); - if(m_oValue.IsInit()) - str->value = m_oValue->m_sText; - oCell = &str->cell; - pSource = str; + auto pCellblank = new(XLSB::CellBlank); + oCell = &pCellblank->cell; + oCell->fPhShow = false; + pSource = pCellblank; } } break; From 54ec8853163a8dab6eb38a9e1802e9ee92ba753a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 9 Jan 2024 20:21:40 +0600 Subject: [PATCH 227/794] Fix cell value parsing --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 25 +++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 5855d5cd398..e0b55497aa1 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1825,8 +1825,9 @@ namespace OOX { if(m_oValue->m_sText.size() < 17) { - double tempVal = std::stod(m_oValue->m_sText); - if(!isnan(tempVal)) + wchar_t *tail; + double tempVal = std::wcstod(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') { m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); isReal = true; @@ -1834,8 +1835,9 @@ namespace OOX } else { - long double tempVal = std::stold(m_oValue->m_sText); - if(!isnan(tempVal)) + wchar_t *tail; + long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') if(tempVal <= DBL_MAX) { m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); @@ -1845,13 +1847,14 @@ namespace OOX } else if((m_oValue->m_sText.find(L"E") == std::string::npos || m_oValue->m_sText.find(L"E") == m_oValue->m_sText.rfind(L"E"))) { - long double tempVal = std::stold(m_oValue->m_sText); - if(!isnan(tempVal)) - if(tempVal <= DBL_MAX) - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - isReal = true; - } + wchar_t *tail; + long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); + if(*tail == L'\0') + if(tempVal <= DBL_MAX) + { + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + isReal = true; + } } } From cdf10bbc38e5acac5b85c7cd50279ca1b48686ed Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Jan 2024 17:22:38 +0300 Subject: [PATCH 228/794] fix build --- OOXML/XlsxFormat/Comments/XlsxComments.cpp | 2 +- OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp | 2 +- OOXML/XlsxFormat/Pivot/Pivots.cpp | 2 +- OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp | 2 +- OOXML/XlsxFormat/Slicer/Slicer.cpp | 2 +- OOXML/XlsxFormat/Slicer/SlicerCache.cpp | 2 +- OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 2 +- OOXML/XlsxFormat/Table/Connections.cpp | 2 +- OOXML/XlsxFormat/Workbook/Workbook.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index 9a3682e79c7..05a8a7f3238 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -49,7 +49,7 @@ #include "../SharedStrings/Si.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index 98fa67fb02c..4ffd81b7ed3 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -65,7 +65,7 @@ #include "../../XlsbFormat/Biff12_records/SupName.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include namespace OOX diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 7eb31e565da..71eba1bd805 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -140,7 +140,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../ComplexTypes_Spreadsheet.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include namespace OOX diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index a9cc1c86ec3..136a189d72b 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -38,7 +38,7 @@ #include "../../XlsbFormat/Biff12_unions/SHAREDSTRINGS.h" #include "../../XlsbFormat/Biff12_records/SSTItem.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Slicer/Slicer.cpp b/OOXML/XlsxFormat/Slicer/Slicer.cpp index 087b3f6a751..915cd4ad9c5 100644 --- a/OOXML/XlsxFormat/Slicer/Slicer.cpp +++ b/OOXML/XlsxFormat/Slicer/Slicer.cpp @@ -38,7 +38,7 @@ #include "../../DocxFormat/Drawing/DrawingExt.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp index 2f437cfa67f..34ec92e7273 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp @@ -59,7 +59,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { namespace Spreadsheet diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index 51770f35450..c9baa4c890c 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -61,7 +61,7 @@ #include "../../XlsbFormat/Biff12_unions/STYLES.h" #include "../../XlsbFormat/Biff12_unions/DXFS.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index e5fd67ad72c..1eca709bf4f 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -55,7 +55,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 0a5fbee6cb3..75e2b8b35bf 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -49,7 +49,7 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../../DocxFormat/Drawing/DrawingExt.h" -#include "../../binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX { From 7266619e24c4e3747379d223fe113c08f31cf69b Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Jan 2024 17:58:25 +0300 Subject: [PATCH 229/794] fix build --- .../XlsFile/Format/Logic/Biff_structures/BiffString.h | 4 ++++ OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h index 0be5d56720f..50786da3a4a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h @@ -116,6 +116,10 @@ class XLUnicodeString_T : public BiffString cch_ = str.length(); return *this; } + XLUnicodeString_T operator=(const bool& boolVal) + { + return *this; + } const size_t getStructSizeWouldWritten() const // Number of unsigned chars that would be written { return recalculateStructSize(); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 69eec4ffe35..e7a7eed4e66 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -109,9 +109,9 @@ namespace OOX else ptr->fCheckCompat = false; if(m_oCodeName.IsInit()) - ptr->strName.value = m_oCodeName->GetValue(); + ptr->strName.value = m_oCodeName->GetValue(); else - ptr->strName.value = false; + ptr->strName.value = false; if(m_oDate1904.IsInit()) ptr->f1904 = m_oDate1904->GetValue(); else From 1017b30776322241a92ecafda1e61e7d5ac23842 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 10 Jan 2024 14:14:09 +0600 Subject: [PATCH 230/794] Add numeric value cache for cell value --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index e0b55497aa1..25ab5a99305 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1797,6 +1797,8 @@ namespace OOX BiffRecord* pSource = nullptr; XLSB::Cell* oCell; bool isReal = false; + _INT32 intCache = 0; + double realCache = 0; if(!m_oType.IsInit()) { @@ -1810,13 +1812,17 @@ namespace OOX { if(m_oValue->m_sText.size() < 10) { + intCache = std::stoi(m_oValue->m_sText); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); } else if(m_oValue->m_sText.size() == 10) { _INT64 tempVal = std::stoll(m_oValue->m_sText); if(tempVal < MAXINT32 && tempVal > MININT32) + { + intCache = tempVal; m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + } } } @@ -1831,6 +1837,7 @@ namespace OOX { m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); isReal = true; + realCache = tempVal; } } else @@ -1838,9 +1845,10 @@ namespace OOX wchar_t *tail; long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); if(*tail == L'\0') - if(tempVal <= DBL_MAX) + if(tempVal <= DBL_MAX && tempVal >= DBL_MIN) { m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + realCache = tempVal; isReal = true; } } @@ -1853,6 +1861,7 @@ namespace OOX if(tempVal <= DBL_MAX) { m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); + realCache = tempVal; isReal = true; } } @@ -1868,7 +1877,7 @@ namespace OOX auto pCellRk = new(XLSB::CellRk); pCellRk->value.fInt = 1; pCellRk->value.fX100 = 0; - pCellRk->value.num = std::stoi(m_oValue->m_sText); + pCellRk->value.num = intCache; oCell = &pCellRk->cell; @@ -1878,7 +1887,7 @@ namespace OOX { auto pCellReal = new(XLSB::CellReal); - pCellReal->value.data.value = std::stod(m_oValue->m_sText); + pCellReal->value.data.value = realCache; oCell = &pCellReal->cell; pSource = pCellReal; From 508167f0f9eb62502e07df90a6e9d431735a1a53 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 11 Jan 2024 18:08:00 +0600 Subject: [PATCH 231/794] Fix conditional formating conversion --- .../Worksheets/ConditionalFormatting.cpp | 89 ++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index b7a9d7a948c..4a3a96d123c 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1741,30 +1741,61 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() { ptr->dxfId = m_oDxfId->GetValue(); } - ptr->iPri = m_oPriority->GetValue(); - ptr->fStopTrue = m_oStopIfTrue->GetValue(); - ptr->fAbove = m_oAboveAverage->GetValue(); - ptr->fBottom = m_oBottom->GetValue(); - ptr->fPercent = m_oPercent->GetValue(); - ptr->strParam = m_oText.get(); + if(m_oPriority.IsInit()) + ptr->iPri = m_oPriority->GetValue(); + if(m_oStopIfTrue.IsInit()) + ptr->fStopTrue = m_oStopIfTrue->GetValue(); + else + ptr->fStopTrue = false; + if(m_oAboveAverage.IsInit()) + ptr->fAbove = m_oAboveAverage->GetValue(); + else + ptr->fAbove = false; + if(m_oBottom.IsInit()) + ptr->fBottom = m_oBottom->GetValue(); + else + ptr->fBottom = false; + if(m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + else + ptr->fPercent = false; + if(m_oText.IsInit()) + ptr->strParam = m_oText.get(); + else + ptr->strParam = L""; if(!m_arrFormula.empty()) { ptr->rgce1 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); } + else + { + ptr->cbFmla1 = 0; + } if(!m_arrFormula.empty()) { ptr->rgce2 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); } + else + { + ptr->cbFmla2 = 0; + } if(!m_arrFormula.empty()) { ptr->rgce3 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); } + else + { + ptr->cbFmla3 = 0; + } + +ptr->iType = XLSB::CFType::CF_TYPE_EXPRIS; +ptr->iParam =0; - if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) +if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) { if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_between) ptr->iParam = XLSB::CFOper::CF_OPER_BN; @@ -1782,6 +1813,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() ptr->iParam = XLSB::CFOper::CF_OPER_GE; else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThanOrEqual) ptr->iParam = XLSB::CFOper::CF_OPER_LE; + ptr->iType = XLSB::CFType::CF_TYPE_CELLIS; } if (m_oType == SimpleTypes::Spreadsheet::ECfType::expression) @@ -1832,25 +1864,55 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::notContainsErrors) else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) { if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::today) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TODAY; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::tomorrow) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TOMORROW; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::yesterday) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_YESTERDAY; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::last7Days) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LAST7DAYS; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastMonth) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTMONTH; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextMonth) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTMONTH; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisWeek) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISWEEK; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextWeek) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTWEEK; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastWeek) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTWEEK; + } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisMonth) + { ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; + ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISMONTH; + } } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) @@ -2557,23 +2619,26 @@ XLS::BaseObjectPtr CConditionalFormatting::toBin() { return objectPtr; } - if(m_arrItems.back()->m_oExtId.IsInit()) - { + auto ptr(new XLSB::CONDITIONALFORMATTING); objectPtr = XLS::BaseObjectPtr{ptr}; if(m_oSqRef.IsInit()) { auto conditionPtr(new XLSB::BeginConditionalFormatting); ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; - + conditionPtr->ccf = m_arrItems.size(); conditionPtr->sqrfx.strValue = m_oSqRef.get(); - conditionPtr->fPivot = m_oPivot->GetValue(); + if(m_oPivot.IsInit()) + conditionPtr->fPivot = m_oPivot->GetValue(); + else + conditionPtr->fPivot = false; + } for(auto i: m_arrItems) { ptr->m_arCFRULE.push_back(i->toBin()); } - } + return objectPtr; } bool CConditionalFormatting::IsUsage() From 7af7b50f663ae14a3e7d6578fd9741f034a868d6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 12 Jan 2024 20:12:33 +0600 Subject: [PATCH 232/794] Fix autofilter conversion --- OOXML/XlsxFormat/Table/Autofilter.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index 990559617f2..e9fba5c921e 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -130,7 +130,11 @@ namespace OOX { ptr->sortOn = 3; } - + else + { + ptr->sortOn = 0; + } + ptr->stSslist = L""; return objectPtr; } EElementType CSortCondition::getType () const @@ -295,8 +299,12 @@ namespace OOX beginSortState->rfx = m_oRef->GetValue(); if(m_oCaseSensitive.IsInit()) beginSortState->fCaseSensitive = m_oCaseSensitive->GetValue(); + else + beginSortState->fCaseSensitive = false; if(m_oColumnSort.IsInit()) beginSortState->fCol = m_oColumnSort->GetValue(); + else + beginSortState->fCol = false; if(m_oSortMethod == SimpleTypes::Spreadsheet::ESortMethod::sortmethodStroke) beginSortState->fAltMethod = true; else @@ -308,6 +316,7 @@ namespace OOX { sortConds->m_arSORTCOND.push_back(i->toBin()); } + beginSortState->cconditions = sortConds->m_arSORTCOND.size(); return objectPtr; } From 5c1882722449cb851a18395d2a4c1ae6ca0c7be8 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 12 Jan 2024 17:26:47 +0300 Subject: [PATCH 233/794] fix chartEx --- .../Binary/Sheets/Reader/ChartFromToBinary.cpp | 14 ++++++++------ OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp | 18 ++++++++---------- OOXML/XlsxFormat/Chart/ChartSerializeEx.h | 5 +++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp index 67eb2a92172..d3c8a75654b 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp @@ -7033,11 +7033,13 @@ namespace BinXlsxRW if (c_oserct_chartExBinningBINSIZE == type) { - pBinning->m_binSize = m_oBufferedStream.GetDoubleReal(); + pBinning->m_binSize.Init(); + pBinning->m_binSize->m_oVal = m_oBufferedStream.GetDoubleReal(); } else if (c_oserct_chartExBinningBINCOUNT == type) { - pBinning->m_binCount = m_oBufferedStream.GetLong(); + pBinning->m_binCount.Init(); + pBinning->m_binCount->m_oVal = m_oBufferedStream.GetLong(); } else if (c_oserct_chartExBinningINTERVAL == type) { @@ -12604,16 +12606,16 @@ namespace BinXlsxRW } void BinaryChartWriter::WriteCT_ChartExBinning(OOX::Spreadsheet::ChartEx::CBinning *pVal) { - if (pVal->m_binSize.IsInit()) + if ((pVal->m_binSize.IsInit()) && (pVal->m_binSize->m_oVal.IsInit())) { int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartExBinningBINSIZE); - m_oBcw.m_oStream.WriteDoubleReal(*pVal->m_binSize); + m_oBcw.m_oStream.WriteDoubleReal(pVal->m_binSize->m_oVal->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pVal->m_binCount.IsInit()) + if ((pVal->m_binCount.IsInit()) && (pVal->m_binCount->m_oVal.IsInit())) { int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartExBinningBINCOUNT); - m_oBcw.m_oStream.WriteLONG(*pVal->m_binCount); + m_oBcw.m_oStream.WriteLONG(*pVal->m_binCount->m_oVal); m_oBcw.WriteItemEnd(nCurPos); } if (pVal->m_intervalClosed.IsInit()) diff --git a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp index 38f50909c2f..ce140704c10 100644 --- a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp +++ b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp @@ -1405,13 +1405,11 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); if( L"binSize" == sName) { - std::wstring s = oReader.GetText3(); - m_binSize = XmlUtils::GetDouble(s); + m_binSize = oReader; } else if( L"binCount" == sName) { - std::wstring s = oReader.GetText3(); - m_binCount = XmlUtils::GetInteger(s); + m_binCount = oReader; } } } @@ -1432,15 +1430,15 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" writer.WriteString(L">"); if (m_binCount.IsInit()) { - writer.WriteString(L""); - writer.WriteString(XmlUtils::ToString(*m_binCount)); - writer.WriteString(L""); + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); } else if (m_binSize.IsInit()) { - writer.WriteString(L""); - writer.WriteString(std::to_wstring(*m_binSize)); - writer.WriteString(L""); + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); } writer.WriteString(L""); } diff --git a/OOXML/XlsxFormat/Chart/ChartSerializeEx.h b/OOXML/XlsxFormat/Chart/ChartSerializeEx.h index 668fae7962b..01a7b5401a0 100644 --- a/OOXML/XlsxFormat/Chart/ChartSerializeEx.h +++ b/OOXML/XlsxFormat/Chart/ChartSerializeEx.h @@ -60,6 +60,7 @@ namespace ComplexTypes { class CParentLabelLayout; class CRegionLabelLayout; + class CDouble; } } @@ -294,8 +295,8 @@ namespace ChartEx void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - nullable_double m_binSize; - nullable_int m_binCount; + nullable m_binSize; + nullable m_binCount; nullable m_intervalClosed; nullable> m_underflow; From fe2779824bea6ab40590960218c0809d53ddda76 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 12 Jan 2024 21:37:42 +0600 Subject: [PATCH 234/794] Fix comment conversion error --- OOXML/XlsbFormat/Biff12_records/BeginComment.cpp | 8 ++++++++ OOXML/XlsxFormat/Comments/XlsxComments.cpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp b/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp index 0d3f298110e..9999b924d19 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp @@ -59,10 +59,18 @@ namespace XLSB void BeginComment::writeFields(XLS::CFRecord& record) { + if(!guid.empty()) + { _GUID_ guid_; STR::bstr2guid(guid, guid_); record << iauthor << rfx << guid_; + } + else + { + record << iauthor << rfx; + record.reserveNunBytes(16); + } } } // namespace XLSB diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index 9a3682e79c7..77ac492f44d 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -219,8 +219,12 @@ namespace OOX ptr1->rfx = m_oRef->GetValue(); if(m_oAuthorId.IsInit()) ptr1->iauthor = m_oAuthorId->GetValue(); + else + ptr1->iauthor = 0; if(m_oUid.IsInit()) ptr1->guid = m_oUid->ToString(); + else + ptr1->guid = L""; if(m_oText.IsInit()) { auto type = m_oText->getType(); From 01ac03f24b32b4ff636031cd7a8dd294b8ab3e5a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 15 Jan 2024 13:44:52 +0600 Subject: [PATCH 235/794] Fix comment convert condition --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 996fb65a23e..8aa1070b25a 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -385,7 +385,7 @@ namespace OOX void CWorksheet::PrepareAfterRead() { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); - if (!xlsb || ((xlsb) && (xlsb->m_bWriteToXlsb))) + if (!xlsb || !xlsb->m_bWriteToXlsb) { PrepareComments(m_pComments, m_pThreadedComments, m_oLegacyDrawing.GetPointer()); } From fb27d004907cca8a9f605329faae8557f8c3a0ef Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 15 Jan 2024 15:49:20 +0600 Subject: [PATCH 236/794] Fix hyperlinks conversion --- OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 19479f6c121..3b4bd4a027d 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -82,14 +82,22 @@ namespace OOX if(m_oDisplay.IsInit()) castedPtr->display = m_oDisplay.get(); + else + castedPtr->display = L""; if(m_oRid.IsInit()) castedPtr->relId.value = m_oRid->GetValue(); + else + castedPtr->relId.value = L""; if(m_oLocation.IsInit()) castedPtr->location = m_oLocation.get(); + else + castedPtr->location = L""; if(m_oRef.IsInit()) castedPtr->rfx = m_oRef.get(); if(m_oTooltip.IsInit()) castedPtr->tooltip = m_oTooltip.get(); + else + castedPtr->tooltip = L""; return ptr; } From 7d82d4a8b7befc936b5a5a42c9a484da61c97936 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 17 Jan 2024 22:01:51 +0600 Subject: [PATCH 237/794] Fix conditional formating conversion --- OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 4a3a96d123c..f0cd4e2671c 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1713,7 +1713,6 @@ XLS::BaseObjectPtr CConditionalFormattingRule::toBin() auto ptr(new XLSB::CFRULE(cellRef)); XLS::BaseObjectPtr objPtr(ptr); - auto beginRule(new XLSB::BeginCFRule(cellRef)); ptr->m_BrtBeginCFRule = WriteAttributes(); if(m_oColorScale.IsInit()) @@ -1768,6 +1767,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() { ptr->rgce1 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla1 = 1; } else { @@ -1777,6 +1777,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() { ptr->rgce2 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla2 = 1; } else { @@ -1786,6 +1787,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() { ptr->rgce3 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); + ptr->cbFmla3 = 1; } else { @@ -1814,6 +1816,7 @@ if (m_oType == SimpleTypes::Spreadsheet::ECfType::cellIs) else if (m_oOperator == SimpleTypes::Spreadsheet::ECfOperator::Operator_lessThanOrEqual) ptr->iParam = XLSB::CFOper::CF_OPER_LE; ptr->iType = XLSB::CFType::CF_TYPE_CELLIS; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_EXPR; } if (m_oType == SimpleTypes::Spreadsheet::ECfType::expression) @@ -1927,19 +1930,23 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) else if (m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale) { ptr->iType = XLSB::CFType::CF_TYPE_GRADIENT; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_GRADIENT; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar) { ptr->iType = XLSB::CFType::CF_TYPE_DATABAR; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DATABAR; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) { ptr->iType = XLSB::CFType::CF_TYPE_MULTISTATE; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_MULTISTATE; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::top10) { ptr->iType = XLSB::CFType::CF_TYPE_FILTER; ptr->iParam = m_oRank->GetValue(); + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FILTER; } return objectPtr; From 6e0a28f8c80d37667bf5bdb5f8aaf7bc0e9aa2e4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 17 Jan 2024 22:02:15 +0600 Subject: [PATCH 238/794] Fix merged cellc conversion --- OOXML/XlsxFormat/Worksheets/MergeCells.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index c6ff8045278..b677a0291aa 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -34,6 +34,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_records/MergeCell.h" +#include "../../XlsbFormat/Biff12_records/BeginMergeCells.h" #include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" namespace OOX @@ -163,11 +164,14 @@ namespace OOX XLS::BaseObjectPtr CMergeCells::toBin() { auto castedPtr(new XLSB::MERGECELLS); + auto beginCells(new XLSB::BeginMergeCells); + castedPtr->m_BrtBeginMergeCells = XLS::BaseObjectPtr{beginCells}; XLS::BaseObjectPtr ptr(castedPtr); for(auto i:m_arrItems) { castedPtr->m_arBrtMergeCell.push_back(i->toBin()); } + beginCells->cmcs = castedPtr->m_arBrtMergeCell.size(); return ptr; } EElementType CMergeCells::getType () const From ec89b34514822c207b8f3ebd99804a7978a5ad6a Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Thu, 18 Jan 2024 13:05:41 +0300 Subject: [PATCH 239/794] editing diacritics, unary marks. bug fixing. --- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 15 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 3 +- .../StarMath2OOXML/cstarmathpars.cpp | 294 +++++++++++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 10 +- .../Converter/StarMath2OOXML/typeselements.h | 10 +- 5 files changed, 244 insertions(+), 88 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 4173b638d76..cbf89627945 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -158,10 +158,11 @@ namespace StarMath { WriteCtrlPrNode(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } - void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *CValueBlock,XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) { pXmlWrite->WriteNodeBegin(wsNameBlock,false); - CValueBlock->ConversionToOOXML(pXmlWrite); + if(pValueBlock != nullptr) + pValueBlock->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeEnd(wsNameBlock,false,false); } std::wstring CConversionSMtoOOXML::GetOOXML() @@ -324,5 +325,15 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsAttributeNode); pXmlWrite->WriteNodeEnd(L"w",true,true); } + void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + StandartProperties(pXmlWrite,pAttribute); + pXmlWrite->WriteNodeBegin(L"m:t",true); + pXmlWrite->WriteAttribute(L"xml:space",L"preserve"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 692a6722917..7656f54f255 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -16,7 +16,7 @@ namespace StarMath { static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void BlockRecording(const std::wstring& wsNameBlock,CElement* CValueBlock,XmlUtils::CXmlWriter* pXmlWrite); + static void BlockRecording(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute); static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute); static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); @@ -25,6 +25,7 @@ namespace StarMath { static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); + static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute); void EndConversion(); std::wstring GetOOXML(); private: diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 12584ca4a34..d35669edb3b 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -11,11 +11,11 @@ namespace StarMath { CElement* pTempElement = ParseElement(pReader); if(nullptr == pTempElement) - break; + continue; if(!m_arEquation.empty() && CheckForLeftArgument(pTempElement->GetBaseType()) ) { - AddLeftArgument(m_arEquation.back(),pTempElement); - m_arEquation.pop_back(); + if(AddLeftArgument(m_arEquation.back(),pTempElement)) + m_arEquation.pop_back(); } m_arEquation.push_back(pTempElement); } @@ -52,24 +52,32 @@ namespace StarMath pElement->SetAttribute(pElement->GetAttribute()); return pElement; } - else return pElement; + else + { + pReader->ClearReader(); + return pElement; + } } template - void SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) + bool SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) { T* pTempElement = dynamic_cast(pElementWhichAdd); - pTempElement->SetLeftArg(pLeftArg); - pElementWhichAdd = pTempElement; + if(pTempElement->GetLeftArg() == nullptr) + { + pTempElement->SetLeftArg(pLeftArg); + pElementWhichAdd = pTempElement; + return true; + } + else return false; } - void CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) + bool CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) { switch(pElementWhichAdd->GetBaseType()) { case TypeElement::BinOperator: { - SetLeft(pLeftArg, pElementWhichAdd); - break; + return SetLeft(pLeftArg, pElementWhichAdd); } case TypeElement::SetOperations: { @@ -78,31 +86,27 @@ namespace StarMath } case TypeElement::Connection: { - SetLeft(pLeftArg,pElementWhichAdd); - break; + return SetLeft(pLeftArg,pElementWhichAdd); } case TypeElement::BracketWithIndex: { - SetLeft(pLeftArg,pElementWhichAdd); - break; + return SetLeft(pLeftArg,pElementWhichAdd); } case TypeElement::Index: { - SetLeft(pLeftArg,pElementWhichAdd); - break; + return SetLeft(pLeftArg,pElementWhichAdd); } default: break; } } - CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader,CAttribute* pAttribute) + CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - while(CheckForLeftArgument(pReader->GetGlobalType())) + while(CheckForLeftArgument(pReader->GetGlobalType()) && (pReader->GetLocalType() != TypeElement::frac || pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt)) { -// pReader->SetAttributeTemp(pAttribute); CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); if(pFirstTempElement != nullptr) { @@ -115,7 +119,6 @@ namespace StarMath pReader->SetTypesToken(); } } -// pReader->ClearAttributeTemp(); return pFirstTempElement; } bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType) @@ -553,15 +556,19 @@ namespace StarMath { if(m_enTypeBinOp == TypeElement::frac) { - SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); - SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); + } + else if(m_enTypeBinOp == TypeElement::And || m_enTypeBinOp == TypeElement::neg) + { + SetRightArg(CParserStarMathString::ParseElement(pReader)); } else { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) + if((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); @@ -569,8 +576,6 @@ namespace StarMath } else SetRightArg(pTempElement); -// if(TypeElement::plus == m_enTypeBinOp || TypeElement::minus == m_enTypeBinOp) -// m_pRightArgument->SetAttribute(GetAttribute()); } } void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) @@ -584,9 +589,10 @@ namespace StarMath CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); oXmlWrite->WriteNodeEnd(L"m:f",false,false); } - else if(m_enTypeBinOp == TypeElement::plus ||m_enTypeBinOp == TypeElement::minus || m_enTypeBinOp == TypeElement::multipl || m_enTypeBinOp == TypeElement::cdot || m_enTypeBinOp == TypeElement::times || m_enTypeBinOp == TypeElement::div || m_enTypeBinOp == TypeElement::odivide || m_enTypeBinOp == TypeElement::oplus || m_enTypeBinOp == TypeElement::ominus || m_enTypeBinOp == TypeElement::odot || m_enTypeBinOp == TypeElement::otimes) + else //if(m_enTypeBinOp == TypeElement::plus ||m_enTypeBinOp == TypeElement::minus || m_enTypeBinOp == TypeElement::multipl || m_enTypeBinOp == TypeElement::cdot || m_enTypeBinOp == TypeElement::times || m_enTypeBinOp == TypeElement::div || m_enTypeBinOp == TypeElement::odivide || m_enTypeBinOp == TypeElement::oplus || m_enTypeBinOp == TypeElement::ominus || m_enTypeBinOp == TypeElement::odot || m_enTypeBinOp == TypeElement::otimes) { - m_pLeftArgument->ConversionToOOXML(oXmlWrite); + if(m_pLeftArgument!=nullptr) + m_pLeftArgument->ConversionToOOXML(oXmlWrite); oXmlWrite->WriteNodeBegin(L"m:r",false); CConversionSMtoOOXML::StandartProperties(oXmlWrite,GetAttribute()); oXmlWrite->WriteNodeBegin(L"m:t",false); @@ -625,10 +631,22 @@ namespace StarMath case TypeElement::otimes: oXmlWrite->WriteString(L"\u2297"); break; + case TypeElement::plus_minus: + oXmlWrite->WriteString(L"\u00B1"); + break; + case TypeElement::minus_plus: + oXmlWrite->WriteString(L"\u2213"); + break; + case TypeElement::Or: + oXmlWrite->WriteString(L"\u2228"); + break; + case TypeElement::And: + oXmlWrite->WriteString(L"\u2227"); + break; default: break; } - if(m_pRightArgument->GetBaseType() == TypeElement::String && GetAttribute() == m_pRightArgument->GetAttribute()) + if(m_pRightArgument!=nullptr && m_pRightArgument->GetBaseType() == TypeElement::String && GetAttribute() == m_pRightArgument->GetAttribute()) { CElementString* oNumber = dynamic_cast (m_pRightArgument); oXmlWrite->WriteString(oNumber->GetString()); @@ -639,7 +657,8 @@ namespace StarMath { oXmlWrite->WriteNodeEnd(L"m:t",false,false); oXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_pRightArgument->ConversionToOOXML(oXmlWrite); + if(m_pRightArgument!= nullptr) + m_pRightArgument->ConversionToOOXML(oXmlWrite); } } @@ -667,6 +686,11 @@ namespace StarMath else if(L"odivide" == wsToken) return TypeElement::odivide; else if(L"wideslash" == wsToken) return TypeElement::wideslash; else if(L"widebslash" == wsToken) return TypeElement::widebslash; + else if(L"+-" == wsToken) return TypeElement::plus_minus; + else if(L"-+" == wsToken) return TypeElement::minus_plus; + else if(L"neg" == wsToken) return TypeElement::neg; + else if(L"or" == wsToken) return TypeElement::Or; + else if(L"and" == wsToken) return TypeElement::And; else return TypeElement::undefine; } bool CElementBinOperator::IsBinOperatorLowPrior() @@ -682,6 +706,8 @@ namespace StarMath return true; case TypeElement::circ: return true; + case TypeElement::Or: + return true; default: return false; } @@ -694,6 +720,14 @@ namespace StarMath if(m_pRightArgument!=nullptr) m_pRightArgument->SetAttribute(pAttribute); } + CElement* CElementBinOperator::GetLeftArg() + { + return m_pLeftArgument; + } + CElement* CElementBinOperator::GetRightArg() + { + return m_pRightArgument; + } //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) { @@ -754,8 +788,8 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) { - CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement); - m_arBrecketValue.pop_back(); + if(CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement)) + m_arBrecketValue.pop_back(); } m_arBrecketValue.push_back(pTempElement); if(pReader->EmptyString()) @@ -846,10 +880,26 @@ namespace StarMath else if(L"infinity" == wsToken) return TypeElement::infinity; else if(L"fact" == wsToken) return TypeElement::fact; else if(L"abs" == wsToken) return TypeElement::abs; + else if(L"`" == wsToken) return TypeElement::interval; + else if(L"~" == wsToken) return TypeElement::emptiness; + else if(L"partial" == wsToken) return TypeElement::partial; + else if(L"nabla" == wsToken) return TypeElement::nabla; + else if(L"exists" == wsToken) return TypeElement::exists; + else if(L"notexists" == wsToken) return TypeElement::notexists; + else if(L"forall" == wsToken) return TypeElement::forall; + else if(L"hbar" == wsToken) return TypeElement::hbar; + else if(L"lambdabar" == wsToken) return TypeElement::lambdabar; + else if(L"Re" == wsToken) return TypeElement::Re; + else if(L"Im" == wsToken) return TypeElement::Im; + else if(L"wp" == wsToken) return TypeElement::wp; + else if(L"laplace" == wsToken) return TypeElement::laplace; + else if(L"fourier" == wsToken) return TypeElement::fourier; + else if(L"backepsilon" == wsToken) return TypeElement::backepsilon; else return TypeElement::undefine; } void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { + SetWsTypeSymbol(); switch(m_enTypeSpecial) { case TypeElement::transition: @@ -858,16 +908,6 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:mr",false); break; } - case TypeElement::infinity: - { - pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeBegin(L"m:t",false); - pXmlWrite->WriteString(L"\u221E"); - pXmlWrite->WriteNodeEnd(L"m:t",false,false); - pXmlWrite->WriteNodeEnd(L"m:r",false,false); - break; - } case TypeElement::fact: { if(m_pValue!= nullptr) @@ -878,6 +918,33 @@ namespace StarMath pXmlWrite->WriteString(L"\u0021"); pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); + break; + } + case TypeElement::interval: + { + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + break; + } + case TypeElement::emptiness: + { + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + break; + } + default: + { + if(!m_wsType.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(m_wsType); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } + break; } } } @@ -885,6 +952,56 @@ namespace StarMath { SetBaseAttribute(pAttribute); } + void CElementSpecialSymbol::SetWsTypeSymbol() + { + switch(m_enTypeSpecial) + { + case TypeElement::infinity: + m_wsType = L"\u221E"; + break; + case TypeElement::partial: + m_wsType = L"\u2202"; + break; + case TypeElement::nabla: + m_wsType = L"\u2207"; + break; + case TypeElement::exists: + m_wsType = L"\u2203"; + break; + case TypeElement::notexists: + m_wsType = L"\u2204"; + break; + case TypeElement::forall: + m_wsType = L"\u2200"; + break; + case TypeElement::hbar: + m_wsType = L"\u"; + break; + case TypeElement::lambdabar: + m_wsType = L"\u"; + break; + case TypeElement::Re: + m_wsType = L"\u211C"; + break; + case TypeElement::Im: + m_wsType = L"\u2111"; + break; + case TypeElement::wp: + m_wsType = L"\u"; + break; + case TypeElement::laplace: + m_wsType = L"\u"; + break; + case TypeElement::fourier: + m_wsType = L"\u0192"; + break; + case TypeElement::backepsilon: + m_wsType = L"\u03F6"; + break; + default: + break; + } + } //class methods CElementSetOperations CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) { @@ -917,11 +1034,11 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) + if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { - CElement* pBinOpElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pBinOpElement); - SetRightArg(pBinOpElement); + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pElement); + SetRightArg(pElement); } else SetRightArg(pTempElement); } @@ -1045,7 +1162,7 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->GetToken(); pReader->SetTypesToken(); - if(pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetGlobalType() == TypeElement::BracketWithIndex || pReader->GetGlobalType() == TypeElement::Index) + if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) { pReader->SetAttribute(GetAttribute()); CElement* pBinOp = CParserStarMathString::ParseElement(pReader); @@ -1213,7 +1330,7 @@ namespace StarMath m_pRightArgument->SetAttribute(pAttribute); } //class methods CIndex - CElementIndex::CElementIndex(const TypeElement& enType): m_pValueIndex(nullptr),m_pValue(nullptr) + CElementIndex::CElementIndex(const TypeElement& enType): m_pValueIndex(nullptr),m_pLeftArg(nullptr) { m_enTypeIndex = enType; SetBaseType(TypeElement::Index); @@ -1221,7 +1338,7 @@ namespace StarMath CElementIndex::~CElementIndex() { delete m_pValueIndex; - delete m_pValue; + delete m_pLeftArg; } void CElementIndex::SetValueIndex(CElement *pElement) { @@ -1229,13 +1346,17 @@ namespace StarMath } void CElementIndex::SetLeftArg(CElement *pElement) { - if(m_pValue == nullptr) - m_pValue = pElement; + if(m_pLeftArg == nullptr) + m_pLeftArg = pElement; } CElement* CElementIndex::GetValueIndex() { return m_pValueIndex; } + CElement* CElementIndex::GetLeftArg() + { + return m_pLeftArg; + } TypeElement CElementIndex::GetIndex(const std::wstring &wsCheckToken) { if(L"^" == wsCheckToken) return TypeElement::upper; @@ -1257,6 +1378,8 @@ namespace StarMath } else SetValueIndex(CParserStarMathString::ParseElement(pReader)); + if(m_enTypeIndex == TypeElement::sqrt) + SetLeftArg(GetValueIndex()); } void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1278,7 +1401,7 @@ namespace StarMath CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pLeftArg,pXmlWrite); switch(m_enTypeIndex) { case TypeElement::upper: @@ -1306,7 +1429,7 @@ namespace StarMath { CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueIndex,pXmlWrite); } - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValue,pXmlWrite); + CConversionSMtoOOXML::BlockRecording(L"m:e",m_pLeftArg,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); } else if(m_enTypeIndex == TypeElement::nroot || TypeElement::sqrt == m_enTypeIndex) @@ -1315,10 +1438,10 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:radPr",false); CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); - if(m_pValue != nullptr) + if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) { pXmlWrite->WriteNodeBegin(L"m:deg",false); - m_pValue->ConversionToOOXML(pXmlWrite); + m_pLeftArg->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:deg",false,false); } else @@ -1342,8 +1465,8 @@ namespace StarMath void CElementIndex::SetAttribute(CAttribute *pAttribute) { SetBaseAttribute(pAttribute); - if(m_pValue != nullptr) - m_pValue->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr) + m_pLeftArg->SetAttribute(pAttribute); if(m_pValueIndex != nullptr) m_pValueIndex->SetAttribute(pAttribute); } @@ -1557,12 +1680,12 @@ namespace StarMath if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); - SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + SetFromValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } if(pReader->GetLocalType() == TypeElement::to) { pReader->ClearReader(); - SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } // pReader->SetAttributeTemp(GetAttribute()); SetValueOperator(CParserStarMathString::ParseElement(pReader)); @@ -1793,7 +1916,7 @@ namespace StarMath } bool CStarMathReader::CheckIteratorPosition() { - if(m_itStart !=m_itEnd) return false; + if(m_itStart != m_itEnd) return false; else return true; } void CStarMathReader::SetAttribute(CAttribute *pAttribute) @@ -1815,11 +1938,11 @@ namespace StarMath m_itStart++; break; } - else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart ||(L'#' == *m_itStart && L'#' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart ||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) { return m_wsElement; } - else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) + else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || (L'+' == *m_itStart && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) { m_wsElement.push_back(*m_itStart); m_itStart++; @@ -1843,8 +1966,10 @@ namespace StarMath else if(L'^' == cToken) return true; else if(L'*' == cToken) return true; else if(L'/' == cToken) return true; - else if(L'-' == cToken) return true; - else if(L'+' == cToken) return true; +// else if(L'-' == cToken) return true; +// else if(L'+' == cToken) return true; + else if(L'`' == cToken) return true; + else if(L'~' == cToken) return true; else return false; } //class methods CElementBracketWithIndex @@ -1866,6 +1991,10 @@ namespace StarMath { m_pValue = pElement; } + CElement* CElementBracketWithIndex::GetLeftArg() + { + return m_pLeftArg; + } void CElementBracketWithIndex::Parse(CStarMathReader *pReader) { SetBracketValue(CParserStarMathString::ParseElement(pReader)); @@ -2081,8 +2210,8 @@ namespace StarMath { if(m_enTypeMatrix == TypeElement::binom) { - SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); - SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader,GetAttribute())); + SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); } else { @@ -2206,7 +2335,7 @@ namespace StarMath wsTypeMark = L"\u0305"; break; case TypeElement::vec: - wsTypeMark = L"\u279E"; + wsTypeMark = L"\u20D7"; break; case TypeElement::acute: wsTypeMark = L"\u0301"; @@ -2227,10 +2356,10 @@ namespace StarMath wsTypeMark = L"\u0304"; break; case TypeElement::dddot: - wsTypeMark = L"\u0309"; + wsTypeMark = L"\u20DB"; break; case TypeElement::harpoon: - wsTypeMark = L"\u21C0"; + wsTypeMark = L"\u20D1"; break; case TypeElement::tilde: wsTypeMark = L"\u0342"; @@ -2242,31 +2371,34 @@ namespace StarMath wsTypeMark = L"\u030C"; break; case TypeElement::widevec: - wsTypeMark = L"\u27F6"; + wsTypeMark = L"\u20D7"; break; case TypeElement::widetilde: wsTypeMark = L"\u0360"; break; -// case TypeElement::wideharpoon: -// wsTypeMark = L"\u"; -// break; -// case TypeElement::widehat: -// wsTypeMark = L"\u"; -// break; + case TypeElement::wideharpoon: + wsTypeMark = L"\u20D1"; + break; case TypeElement::underline: wsTypeMark = L"\u0332"; break; -// case TypeElement::: -// wsTypeMark = L"\u"; -// break; default: break; } pXmlWrite->WriteNodeBegin(L"m:acc",false); pXmlWrite->WriteNodeBegin(L"m:accPr",false); - pXmlWrite->WriteNodeBegin(L"m:chr",true); - pXmlWrite->WriteAttribute(L"m:val",wsTypeMark); - pXmlWrite->WriteNodeEnd(L"w",true,true); + switch(m_enTypeMark) + { + case TypeElement::widehat: + break; + default: + { + pXmlWrite->WriteNodeBegin(L"m:chr",true); + pXmlWrite->WriteAttribute(L"m:val",wsTypeMark); + pXmlWrite->WriteNodeEnd(L"w",true,true); + break; + } + } CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 915c2f646a4..2304e4a77ea 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -101,13 +101,14 @@ namespace StarMath void SetValueIndex(CElement* pElement); void SetLeftArg(CElement* pElement); CElement* GetValueIndex(); + CElement* GetLeftArg(); static TypeElement GetIndex(const std::wstring& wsCheckToken); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValueIndex; - CElement* m_pValue; + CElement* m_pLeftArg; TypeElement m_enTypeIndex; }; @@ -213,6 +214,7 @@ namespace StarMath virtual ~CElementBracketWithIndex(); void SetLeftArg(CElement* pElement); void SetBracketValue(CElement* pElement); + CElement* GetLeftArg(); static TypeElement GetBracketWithIndex(const std::wstring& wsToken); private: void SetAttribute(CAttribute* pAttribute) override; @@ -285,11 +287,13 @@ namespace StarMath static TypeElement GetSpecialSymbol(const std::wstring& wsToken); void SetValue(CElement* pValue); private: + void SetWsTypeSymbol(); void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValue; TypeElement m_enTypeSpecial; + std::wstring m_wsType; }; class CElementMatrix: public CElement @@ -330,9 +334,9 @@ namespace StarMath std::vector Parse(std::wstring& wsParseString); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). - static void AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); + static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); static bool CheckForLeftArgument(const TypeElement& enType); - static CElement* ReadingWithoutBracket(CStarMathReader* pReader,CAttribute* pAttribute); + static CElement* ReadingWithoutBracket(CStarMathReader* pReader); private: std::vector m_arEquation; }; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index bff250cba00..b59de249314 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -41,6 +41,13 @@ enum class TypeElement{ circ, wideslash, widebslash, + //logic + And, + Or, + neg, + //unary + plus_minus, + minus_plus, //op lim, sum, @@ -184,7 +191,8 @@ enum class TypeElement{ setC, grid, transition, - // + emptiness, + interval, infinity, partial, nabla, From 0bbd2d6d35f9695feacfb0d09c8d424b198324b9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 18 Jan 2024 20:03:38 +0600 Subject: [PATCH 240/794] Fix xfs conversion --- OOXML/XlsxFormat/Styles/Xfs.cpp | 38 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index b12160f9f79..9002b31d8d8 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -391,34 +391,50 @@ namespace OOX ptr->fsxButton = m_oPivotButton->GetValue(); if(m_oQuotePrefix.IsInit()) ptr->f123Prefix = m_oQuotePrefix->GetValue(); - ptr->ind_xf = 0; if (m_oXfId.IsInit()) ptr->ixfParent = m_oXfId->GetValue(); else ptr->ixfParent = 65535; - if(m_oApplyAlignment.IsInit()) + + if(m_oAligment.IsInit()) + { + m_oAligment->toBin(objectPtr); + } + else + { + ptr->alc = 0; + ptr->alcV = 2; + } + if(m_oProtection.IsInit()) + m_oProtection->toBin(objectPtr); + + + + if(m_oApplyAlignment.IsInit()) ptr->fAtrAlc = m_oApplyAlignment->GetValue(); + else + ptr->fAtrAlc = false; if(m_oApplyBorder.IsInit()) ptr->fAtrBdr = m_oApplyBorder->GetValue(); + else + ptr->fAtrBdr = false; if(m_oApplyFill.IsInit()) ptr->fAtrPat = m_oApplyFill->GetValue(); + else + ptr->fAtrPat = false; if(m_oApplyFont.IsInit()) ptr->fAtrFnt = m_oApplyFont->GetValue(); + else + ptr->fAtrFnt = false; if(m_oApplyNumberFormat.IsInit()) ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); + else + ptr->fAtrNum = false; if(m_oApplyProtection.IsInit()) ptr->fAtrProt = m_oApplyProtection->GetValue(); - - if(m_oAligment.IsInit()) - m_oAligment->toBin(objectPtr); else - { - ptr->alc = 0; - ptr->alcV = 2; - } - if(m_oProtection.IsInit()) - m_oProtection->toBin(objectPtr); + ptr->fAtrProt = false; return objectPtr; } From bc4449f7a754ca8863ef402296d3b7eedfec379a Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 21 Jan 2024 23:11:32 +0300 Subject: [PATCH 241/794] Fix bug 62427 CFileBinary::GetTime, CFileBinary::SetTime was updated Fix bugs with time in Zip/Unzip --- DesktopEditor/common/File.cpp | 167 ++++++++++++++++++++++++++++----- DesktopEditor/common/File.h | 13 ++- OfficeUtils/src/OfficeUtils.h | 2 +- OfficeUtils/src/ZipUtilsCP.cpp | 78 ++++++++------- 4 files changed, 203 insertions(+), 57 deletions(-) diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index b0a4415998a..9349e5dfa26 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #endif #ifdef _MAC @@ -1688,38 +1690,161 @@ namespace NSFile g_overrideTmpPath = strTempPath; } - unsigned long CFileBinary::GetDateTime(const std::wstring & inputFile) + bool CFileBinary::GetTime(const std::wstring& sFilename, struct tm* ptmLastWrite, struct tm* ptmLastAccess) { - unsigned long result = 0; -#if defined(_WIN32) || defined (_WIN64) + bool result = true; + + if (ptmLastWrite) memset(ptmLastWrite, 0, sizeof(struct tm)); + if (ptmLastAccess) memset(ptmLastAccess, 0, sizeof(struct tm)); + +#if defined(_WIN32) || defined (_WIN64) // windows + HANDLE hFile; - hFile = ::CreateFileW(inputFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hFile = ::CreateFileW(sFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile) { - FILETIME ft; ft.dwLowDateTime = ft.dwHighDateTime = 0; - if (GetFileTime(hFile, NULL, NULL, &ft)) + FILETIME ftLastWrite{}, ftLastAccess{}; + if (::GetFileTime(hFile, NULL, &ftLastAccess, &ftLastWrite)) { - WORD fatDate = 0, fatTime = 0; - if (FileTimeToDosDateTime(&ft, &fatDate, &fatTime)) + FILETIME ftLastWriteLocal{}, ftLastAccessLocal{}; + result = result && ::FileTimeToLocalFileTime(&ftLastWrite, &ftLastWriteLocal); + result = result && ::FileTimeToLocalFileTime(&ftLastAccess, &ftLastAccessLocal); + + SYSTEMTIME stLastWrite{}, stLastAccess{}; + result = result && ::FileTimeToSystemTime(&ftLastWriteLocal, &stLastWrite); + result = result && ::FileTimeToSystemTime(&ftLastAccessLocal, &stLastAccess); + + auto set_tm_by_st = [] (struct tm* time_tm, SYSTEMTIME* time_st) { + time_tm->tm_sec = static_cast(time_st->wSecond); + time_tm->tm_min = static_cast(time_st->wMinute); + time_tm->tm_hour = static_cast(time_st->wHour); + time_tm->tm_mday = static_cast(time_st->wDay); + time_tm->tm_mon = static_cast(time_st->wMonth); + time_tm->tm_year = static_cast(time_st->wYear); + }; + + if (result) { - result = (fatDate << 16) + fatTime; + if (ptmLastWrite) set_tm_by_st(ptmLastWrite, &stLastWrite); + if (ptmLastAccess) set_tm_by_st(ptmLastAccess, &stLastAccess); } } + else + result = false; + CloseHandle(hFile); } -#else - std::string inputFileA = U_TO_UTF8(inputFile); -#if defined(__linux__) && !defined(_MAC) - struct stat attrib; - stat(inputFileA.c_str(), &attrib); - result = attrib.st_mtim.tv_nsec; -#else - struct stat attrib; - stat(inputFileA.c_str(), &attrib); - result = (unsigned long)attrib.st_mtimespec.tv_nsec; -#endif -#endif + else + result = false; + + +#else // linux or macOS + struct stat attr; + result = (0 == stat(U_TO_UTF8(sFilename).c_str(), &attr)); + + if (result) + { + auto set_tm_by_secs = [] (struct tm* time_tm, time_t time_secs) { + struct tm* ltime = localtime(&time_secs); + *time_tm = *ltime; + time_tm->tm_year += 1900; + time_tm->tm_mon += 1; + }; + + time_t m_secs = attr.st_mtim.tv_sec; // edit + time_t a_secs = attr.st_atim.tv_sec; // access + + if (ptmLastWrite) set_tm_by_secs(ptmLastWrite, m_secs); + if (ptmLastAccess) set_tm_by_secs(ptmLastAccess, a_secs); + } + +#endif // defined(_WIN32) || defined (_WIN64) + return result; + } + + bool CFileBinary::SetTime(const std::wstring& sFilename, struct tm* ptmLastWrite, struct tm* ptmLastAccess) + { + bool result = true; + +#if defined(_WIN32) || defined (_WIN64) // windows + + auto set_st_by_tm = [] (SYSTEMTIME* time_st, struct tm* time_tm) { + time_st->wSecond = static_cast(time_tm->tm_sec); + time_st->wMinute = static_cast(time_tm->tm_min); + time_st->wHour = static_cast(time_tm->tm_hour); + time_st->wDay = static_cast(time_tm->tm_mday); + time_st->wMonth = static_cast(time_tm->tm_mon); + time_st->wYear = static_cast(time_tm->tm_year); + }; + + SYSTEMTIME stLastWrite{}, stLastAccess{}; + if (ptmLastWrite) set_st_by_tm(&stLastWrite, ptmLastWrite); + if (ptmLastAccess) set_st_by_tm(&stLastAccess, ptmLastAccess); + + FILETIME ftLastWriteLocal{}, ftLastAccessLocal{}; + if (ptmLastWrite) result = result && ::SystemTimeToFileTime(&stLastWrite, &ftLastWriteLocal); + if (ptmLastAccess) result = result && ::SystemTimeToFileTime(&stLastAccess, &ftLastAccessLocal); + + FILETIME ftLastWrite{}, ftLastAccess{}; + if (ptmLastWrite) result = result && ::LocalFileTimeToFileTime(&ftLastWriteLocal, &ftLastWrite); + if (ptmLastAccess) result = result && ::LocalFileTimeToFileTime(&ftLastAccessLocal, &ftLastAccess); + + if (result) + { + HANDLE hFile; + hFile = ::CreateFileW(sFilename.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile) + { + FILETIME* pftLastWrite = NULL; + FILETIME* pftLastAccess = NULL; + + if (ptmLastWrite) pftLastWrite = &ftLastWrite; + if (ptmLastAccess) pftLastAccess = &ftLastAccess; + + result = SetFileTime(hFile, NULL, pftLastAccess, pftLastWrite); + } + else + result = false; + + CloseHandle(hFile); + } + + +#else // linux or macOS + struct stat attr; + std::string sFilenameA = U_TO_UTF8(sFilename); + result = (0 == stat(sFilenameA.c_str(), &attr)); + + if (result) + { + time_t m_secs = attr.st_mtim.tv_sec; // edit + time_t a_secs = attr.st_atim.tv_sec; // access + + time_t new_m_secs = m_secs; + time_t new_a_secs = a_secs; + + if (ptmLastWrite) + { + struct tm tmLastWriteUnix = *ptmLastWrite; + tmLastWriteUnix.tm_year -= 1900; + tmLastWriteUnix.tm_mon -= 1; + new_m_secs = mktime(&tmLastWriteUnix); + } + if (ptmLastAccess) + { + struct tm tmLastAccessUnix = *ptmLastAccess; + tmLastAccessUnix.tm_year -= 1900; + tmLastAccessUnix.tm_mon -= 1; + new_a_secs = mktime(&tmLastAccessUnix); + } + + utimbuf new_time{}; + new_time.actime = new_a_secs; + new_time.modtime = new_m_secs; + utime(sFilenameA.c_str(), &new_time); + } +#endif // defined(_WIN32) || defined (_WIN64) return result; } } diff --git a/DesktopEditor/common/File.h b/DesktopEditor/common/File.h index dfe3ac4170b..b8ce97b3f8a 100644 --- a/DesktopEditor/common/File.h +++ b/DesktopEditor/common/File.h @@ -194,7 +194,18 @@ namespace NSFile static bool OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName = NULL); static FILE* OpenFileNative(const std::wstring& sFileName, const std::wstring& sMode); - static unsigned long GetDateTime(const std::wstring & strFileName); + // returns true if everything is OK; + // you can set ptmLastWrite / ptmLastAccess to nullptr if you are not going to use them; + // tm_wday && tm_yday && tm_isdst is unused on windows + static bool GetTime(const std::wstring& sFilename, + struct tm* ptmLastWrite = nullptr, + struct tm* ptmLastAccess = nullptr); + + // returns true if everything is OK; + // you can set ptmLastWrite / ptmLastAccess to nullptr if you are not going to change them + static bool SetTime(const std::wstring& sFilename, + struct tm* ptmLastWrite = nullptr, + struct tm* ptmLastAccess = nullptr); }; class KERNEL_DECL CBase64Converter diff --git a/OfficeUtils/src/OfficeUtils.h b/OfficeUtils/src/OfficeUtils.h index 7e9d1a081cc..827352118f2 100644 --- a/OfficeUtils/src/OfficeUtils.h +++ b/OfficeUtils/src/OfficeUtils.h @@ -53,7 +53,7 @@ class KERNEL_DECL COfficeUtils HRESULT ExtractToDirectory (const std::wstring& zipFile, const std::wstring& unzipDir, wchar_t* password, short extract_without_path); HRESULT ExtractToDirectory (BYTE* data, size_t len, const std::wstring& unzipDir, wchar_t* password, short extract_without_path); - HRESULT CompressFileOrDirectory (const std::wstring& name, const std::wstring& outputFile, bool bSorted = false, int method = Z_DEFLATED, short level = -1, bool bDateTime = false); + HRESULT CompressFileOrDirectory (const std::wstring& name, const std::wstring& outputFile, bool bSorted = false, int method = Z_DEFLATED, short level = -1, bool bDateTime = true); HRESULT Uncompress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize); HRESULT Compress (BYTE* destBuf, ULONG* destSize, BYTE* sourceBuf, ULONG sourceSize, short level = -1); diff --git a/OfficeUtils/src/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index 1e8bcf3f7c5..3d0dbff1f9d 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -217,28 +217,6 @@ namespace ZLibZipUtils /*========================================================================================================*/ - /* change_file_date : change the date/time of a file - filename : the filename of the file where date/time must be modified - dosdate : the new date at the MSDos format (4 bytes) - tmu_date : the SAME new date at the tm_unz format */ - static void change_file_date( const wchar_t *filename, uLong dosdate, tm_unz tmu_date ) - { -#if defined(_WIN32) || defined (_WIN64) - HANDLE hFile; - FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; - - hFile = CreateFileW(filename,GENERIC_READ | GENERIC_WRITE, - 0,NULL,OPEN_EXISTING,0,NULL); - GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); - DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); - LocalFileTimeToFileTime(&ftLocal,&ftm); - SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); - CloseHandle(hFile); -#endif - } - - /*========================================================================================================*/ - static void replace_all(std::string& subject, const std::string& search, const std::string& replace) { size_t pos = 0; @@ -380,13 +358,22 @@ namespace ZLibZipUtils break; } } + // ? while (err>0); - - //close вызовется в oFile - if (err==0) { - change_file_date(write_filename, file_info.dosDate, file_info.tmu_date); + oFile.CloseFile(); + + struct tm time; + memset(&time, 0, sizeof(struct tm)); + time.tm_sec = file_info.tmu_date.tm_sec; + time.tm_min = file_info.tmu_date.tm_min; + time.tm_hour = file_info.tmu_date.tm_hour; + time.tm_mday = file_info.tmu_date.tm_mday; + time.tm_mon = file_info.tmu_date.tm_mon + 1; + time.tm_year = file_info.tmu_date.tm_year; + + NSFile::CFileBinary::SetTime(write_filename, &time); } } @@ -568,16 +555,24 @@ namespace ZLibZipUtils zip_fileinfo zinfo; zinfo.dosDate = zinfo.external_fa = zinfo.internal_fa = 0; - zinfo.tmz_date.tm_sec = zinfo.tmz_date.tm_min = zinfo.tmz_date.tm_hour = 0; - zinfo.tmz_date.tm_mday = 1; - zinfo.tmz_date.tm_mon = 0; - zinfo.tmz_date.tm_year = 1980; zip_fileinfo* zi_new = zi ? zi : &zinfo; - if (bDateTime ) + + if (bDateTime) { - zi_new->dosDate = oFile.GetDateTime(file_name); + struct tm edited; + bool ok = NSFile::CFileBinary::GetTime(file_name, &edited); + if (ok) + { + zi_new->tmz_date.tm_sec = edited.tm_sec; + zi_new->tmz_date.tm_min = edited.tm_min; + zi_new->tmz_date.tm_hour = edited.tm_hour; + zi_new->tmz_date.tm_mday = edited.tm_mday; + zi_new->tmz_date.tm_mon = edited.tm_mon - 1; + zi_new->tmz_date.tm_year = edited.tm_year; + } } + if(oFile.OpenFile(file_name)) { DWORD dwSizeRead; @@ -726,9 +721,24 @@ namespace ZLibZipUtils zip_fileinfo zinfo; zinfo.external_fa = zinfo.internal_fa = 0; - zinfo.dosDate = bDateTime ? oFile.GetDateTime(inputFile) : 0; + zinfo.dosDate = 0; + + if (bDateTime) + { + struct tm edited; + bool ok = NSFile::CFileBinary::GetTime(inputFile, &edited); + if (ok) + { + zinfo.tmz_date.tm_sec = edited.tm_sec; + zinfo.tmz_date.tm_min = edited.tm_min; + zinfo.tmz_date.tm_hour = edited.tm_hour; + zinfo.tmz_date.tm_mday = edited.tm_mday; + zinfo.tmz_date.tm_mon = edited.tm_mon - 1; + zinfo.tmz_date.tm_year = edited.tm_year; + } + } - if(oFile.OpenFile(inputFile)) + if (oFile.OpenFile(inputFile)) { DWORD dwSizeRead; BYTE* pData = new BYTE[oFile.GetFileSize()]; From d1a35c2e9cdfc3a0af05af7703e0ae6f5a3bd18a Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Mon, 22 Jan 2024 18:39:00 +0300 Subject: [PATCH 242/794] Refactoring in HtmlFile2 --- .../html/css/src/xhtml/CDocumentStyle.cpp | 114 ++++++++++-------- .../html/css/src/xhtml/CDocumentStyle.h | 4 + .../html/css/src/xhtml/CXmlElement.cpp | 8 +- Common/3dParty/html/htmltoxhtml.h | 105 +++++++--------- HtmlFile2/htmlfile2.cpp | 47 +++----- HtmlFile2/src/StringFinder.h | 42 +++++-- 6 files changed, 171 insertions(+), 149 deletions(-) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 6f4330d24a4..d6751df57a0 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -355,69 +355,87 @@ namespace NSCSS { if (oStyle.m_oBorder.EqualSides()) { - const std::wstring sBorderColor = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); - - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"0\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; - - oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, sBorder); - oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, sBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_TopBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_BottomBorder); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_RightBorder); } else { if (!oStyle.m_oBorder.GetTopBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetTopBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetTopBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetTopBorder().GetWidth().ToWString(); - - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; - - oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, sBorder); - } + SetBorderStyle(oStyle, oXmlElement, PProperties::P_TopBorder); if (!oStyle.m_oBorder.GetRightBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetRightBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetRightBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetRightBorder().GetWidth().ToWString(); - - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; - - oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, sBorder); - } + SetBorderStyle(oStyle, oXmlElement, PProperties::P_RightBorder); if (!oStyle.m_oBorder.GetBottomBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetBottomBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); + SetBorderStyle(oStyle, oXmlElement, PProperties::P_BottomBorder); - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + if (!oStyle.m_oBorder.GetLeftBorder().Empty()) + SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder); + } + } + } - oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, sBorder); - } + void CDocumentStyle::SetAllBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement) + { + const std::wstring wsBorder = CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - if (!oStyle.m_oBorder.GetLeftBorder().Empty()) - { - const std::wstring sBorderColor = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - const std::wstring sBorderStyle = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - const std::wstring sBorderWidth = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); + oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, wsBorder); + oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, wsBorder); + oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, wsBorder); + oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, wsBorder); + } - const std::wstring sBorder = L" w:color=\"" + sBorderColor + L"\" w:space=\"4\" w:sz=\"" + - sBorderWidth + L"\" w:val=\"" + sBorderStyle + L"\""; + void CDocumentStyle::SetBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement, const PProperties &enBorderProperty) + { + const NSCSS::NSProperties::CBorderSide* pBorder = NULL; - oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, sBorder); - } + switch(enBorderProperty) + { + case PProperties::P_BottomBorder: + { + pBorder = &oStyle.m_oBorder.GetBottomBorder(); + break; + } + case PProperties::P_LeftBorder: + { + pBorder = &oStyle.m_oBorder.GetLeftBorder(); + break; + } + case PProperties::P_RightBorder: + { + pBorder = &oStyle.m_oBorder.GetRightBorder(); + break; + } + case PProperties::P_TopBorder: + { + pBorder = &oStyle.m_oBorder.GetTopBorder(); + break; } + default: + return; } + + oXmlElement.AddPropertiesInP(enBorderProperty, CalculateBorderStyle(*pBorder)); + } + + std::wstring CDocumentStyle::CalculateBorderStyle(const NSProperties::CBorderSide &oBorder) + { + std::wstring wsColor = oBorder.GetColor().ToWString(); + std::wstring wsStyle = oBorder.GetStyle().ToWString(); + std::wstring wsWidth = oBorder.GetWidth().ToWString(); + + if (wsColor.empty()) + wsColor = L"auto"; + + if (wsStyle.empty()) + wsStyle = L"single"; + + if (wsWidth.empty()) + wsWidth = L"1"; + + return L"w:color=\"" + wsColor + L"\" w:space=\"0\" w:sz=\"" + wsWidth + L"\" w:val=\"" + wsStyle + L"\""; } void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 886abc8c62d..487c30418cc 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -43,6 +43,8 @@ namespace NSCSS void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); + void SetAllBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); + void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty); public: CDocumentStyle(); ~CDocumentStyle(); @@ -59,6 +61,8 @@ namespace NSCSS std::wstring GetIdAndClear(); void Clear(); + + static std::wstring CalculateBorderStyle(const NSCSS::NSProperties::CBorderSide& oBorder); }; } #endif // CDOCUMENTSTYLE_H diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index a3cb37abe29..451b4f0358c 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -364,22 +364,22 @@ std::wstring CXmlElement::ConvertPStyle(bool bIsLite) const case CSSProperties::ParagraphProperties::P_TopBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_LeftBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_BottomBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_RightBorder: { - sPBdr += L""; + sPBdr += L""; break; } case CSSProperties::ParagraphProperties::P_KeepLines: diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 1bc7737a5ae..6076fa60042 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -40,29 +40,15 @@ static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) // Распознование кодировки if (bNeedConvert) { - size_t posEncoding = sFileContent.find("charset="); - if (posEncoding == std::string::npos) - posEncoding = sFileContent.find("encoding="); - if (posEncoding != std::string::npos) - { - posEncoding = sFileContent.find("=", posEncoding) + 1; - char quoteSymbol = '\"'; - if(sFileContent[posEncoding] == '\"' || sFileContent[posEncoding] == '\'') - { - quoteSymbol = sFileContent[posEncoding]; - posEncoding += 1; - } + std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", "\"", "\""); - size_t posEnd = sFileContent.find(quoteSymbol, posEncoding); - if (std::string::npos != posEnd) - { - std::string sEncoding = sFileContent.substr(posEncoding, posEnd - posEncoding); - if (sEncoding != "utf-8" && sEncoding != "UTF-8") - { - NSUnicodeConverter::CUnicodeConverter oConverter; - sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); - } - } + if (sEncoding.empty()) + sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", "\"", "\""); + + if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding)) + { + NSUnicodeConverter::CUnicodeConverter oConverter; + sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); } } @@ -121,7 +107,7 @@ static std::string Base64ToString(const std::string& sContent, const std::string if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen)) { std::wstring sConvert; - if(!sCharset.empty() && sCharset != "utf-8" && sCharset != "UTF-8") + if(!sCharset.empty() && NSStringFinder::Equals("utf-8", sCharset)) { NSUnicodeConverter::CUnicodeConverter oConverter; sConvert = oConverter.toUnicode(reinterpret_cast(pData), (unsigned)nDecodeLen, sCharset.data()); @@ -209,8 +195,8 @@ static std::string QuotedPrintableDecode(const std::string& sContent, std::strin return sRes.GetData(); } -static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFound, const std::string& sBoundary, - std::map& sRes, NSStringUtils::CStringBuilderA& oRes) +static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFound, + std::map& sRes, NSStringUtils::CStringBuilderA& oRes) { // Content size_t nContentTag = sFileContent.find("\n\n", nFound); @@ -253,7 +239,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun // charset std::string sCharset = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r"}, nFound); - NSStringFinder::CutInside(sCharset, std::string("\"")); + NSStringFinder::CutInside(sCharset, "\""); // Content-Location std::string sContentLocation = NSStringFinder::FindPropety(sFileContent, "content-location", {":"}, {";", "\\n", "\\r"}, nFound); @@ -262,7 +248,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun { // Content-ID std::string sContentID = NSStringFinder::FindPropety(sFileContent, "content-id", {":"}, {";", "\\n", "\\r"}, nFound); - NSStringFinder::CutInside(sCharset, std::string("<"), std::string(">")); + NSStringFinder::CutInside(sCharset, "<", ">"); if (!sContentID.empty()) sContentLocation = "cid:" + sContentID; @@ -289,53 +275,52 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun } std::string sContent = sFileContent.substr(nContentTag, nTagEnd - nContentTag); - // Удаляем лишнее - sFileContent.erase(0, nNextFound); - nFound = sFileContent.find(sBoundary); - std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); - std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); +// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); // Основной документ - if (NSStringFinder::Equals(sContentType, std::string("multipart/alternative"))) + if (NSStringFinder::Equals(sContentType, "multipart/alternative")) oRes.WriteString(mhtTohtml(sContent)); - else if((sContentType.find("text") != std::string::npos && (sExtention.empty() || sExtention == L"htm" || sExtention == L"html" || sExtention - == L"xhtml" || sExtention == L"css")) || (sContentType == "application/octet-stream" && (sContentLocation.find("css") != - std::string::npos))) + else if ((NSStringFinder::Find(sContentType, "text") && (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))) + || (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css"))) { // Стили заключаются в тэг "); } // Картинки - else if((sContentType.find("image") != std::string::npos || sExtention == L"gif" || sContentType == "application/octet-stream") && - (sContentEncoding == "Base64" || sContentEncoding == "base64")) + else if ((NSStringFinder::Find(sContentType, "image") || NSStringFinder::Equals(sExtention, L"gif") || NSStringFinder::Equals(sContentType, "application/octet-stream")) && + NSStringFinder::Equals(sContentEncoding, "base64")) { - if(sExtention == L"ico" || sContentType.find("ico") != std::string::npos) + if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico")) sContentType = "image/jpg"; - else if(sExtention == L"gif") + else if(NSStringFinder::Equals(sExtention, L"gif")) sContentType = "image/gif"; int nSrcLen = (int)sContent.length(); int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); @@ -351,39 +336,39 @@ static std::string mhtTohtml(std::string& sFileContent) std::map sRes; NSStringUtils::CStringBuilderA oRes; + size_t nFound = 0; // Поиск boundary - std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r","\\n"}, 0); + std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""}, 0, nFound); - size_t nFound = 0; if (sBoundary.empty()) { size_t nFoundEnd = sFileContent.length(); nFound = 0; - ReadMht(sFileContent, nFound, nFoundEnd, "no", sRes, oRes); + ReadMht(sFileContent, nFound, nFoundEnd, sRes, oRes); return oRes.GetData(); } NSStringFinder::CutInside(sBoundary, "\""); - size_t nFoundEnd = 0; + size_t nFoundEnd{nFound}; + + sBoundary = "--" + sBoundary; size_t nBoundaryLength = sBoundary.length(); - // Удаляем лишнее - nFound = sFileContent.find(sBoundary, nFoundEnd); - sFileContent.erase(0, nFound); + nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength; // Цикл по boundary - nFound = 0; while(nFound != std::string::npos) { - // Выход по --boundary-- - if(sFileContent[nFound + nBoundaryLength + 1] == '-') - break; - nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength); + nFoundEnd = sFileContent.find(sBoundary + "--", nFound + nBoundaryLength); if(nFoundEnd == std::string::npos) break; - ReadMht(sFileContent, nFound, nFoundEnd, sBoundary, sRes, oRes); + + ReadMht(sFileContent, nFound, nFoundEnd, sRes, oRes); + + nFound = sFileContent.find(sBoundary, nFoundEnd + nBoundaryLength);; } + std::string sFile = oRes.GetData(); for(const std::pair& item : sRes) { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index c2d829732bf..522426dc7fb 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -490,7 +490,7 @@ class CHtmlFile2_Private const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); bool bRes = false; - if(NSStringFinder::Equals(sContentType, std::string("multipart/related"))) + if(NSStringFinder::Equals(sContentType, "multipart/related")) { BYTE* pData; DWORD nLength; @@ -1377,37 +1377,26 @@ class CHtmlFile2_Private { if (oStyle.m_oBorder.EqualSides()) { - std::wstring sColor = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - std::wstring sSz = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); - std::wstring sStyle = oStyle.m_oBorder.GetBottomBorder().GetStyle().ToWString(); - - sBorders = L"" + - L"" + - L"" + - L"" + - L"" + - L""; + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); + + sBorders = L"" + + L"" + + L"" + + L"" + + L"" + + L""; } else { - std::wstring sColorLeftSide = oStyle.m_oBorder.GetLeftBorder().GetColor().ToWString(); - std::wstring sSzLeftSide = oStyle.m_oBorder.GetLeftBorder().GetWidth().ToWString(); - std::wstring sStyleLeftSide = oStyle.m_oBorder.GetLeftBorder().GetStyle().ToWString(); - std::wstring sColorTopSide = oStyle.m_oBorder.GetTopBorder().GetColor().ToWString(); - std::wstring sSzTopSide = oStyle.m_oBorder.GetTopBorder().GetWidth().ToWString(); - std::wstring sStyleTopSide = oStyle.m_oBorder.GetTopBorder().GetStyle().ToWString(); - std::wstring sColorRightSide = oStyle.m_oBorder.GetRightBorder().GetColor().ToWString(); - std::wstring sSzRightSide = oStyle.m_oBorder.GetRightBorder().GetWidth().ToWString(); - std::wstring sStyleRightSide = oStyle.m_oBorder.GetRightBorder().GetStyle().ToWString(); - std::wstring sColorBottomSide = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - std::wstring sSzBottomSide = oStyle.m_oBorder.GetBottomBorder().GetWidth().ToWString(); - std::wstring sStyleBottomSide = oStyle.m_oBorder.GetBottomBorder().GetColor().ToWString(); - - sBorders = L"" + - L"" + - L"" + - L""; - + const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetTopBorder()); + const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); + const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetBottomBorder()); + const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetRightBorder()); + + sBorders = L"" + + L"" + + L"" + + L""; } } diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index 280736069a2..9f7a326ff04 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -43,7 +43,7 @@ namespace NSStringFinder boost::algorithm::trim(sValue); return sValue; } - + template StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) { @@ -90,14 +90,14 @@ namespace NSStringFinder } template - StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting) + StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) { size_t unTempEnding = 0; return FindPropety(sString, sProperty, arDelimiters, arEndings, unStarting, unTempEnding); } - template - void CutInside(StringType& sString, const StringType& sLeftEdge, const StringType& sRightEdge) + template + void CutInside(StringType& sString, const StringEndgeType& sLeftEdge, const StringEndgeType& sRightEdge) { typedef const boost::iterator_range StringRange; @@ -117,17 +117,43 @@ namespace NSStringFinder sString = StringType{itFoundBegin.end(), itFoundEnd.begin()}; } - template - void CutInside(StringType& sString, const StringType& sEdge) + template + void CutInside(StringType& sString, const StringEdgeType& sEdge) { CutInside(sString, sEdge, sEdge); } - template - bool Equals(const StringType& sFirstString, const StringType& sSecondString) + template + bool Equals(const StringFirstType& sFirstString, const StringSecondType& sSecondString) { return boost::iequals(sFirstString, sSecondString); } + + template + bool EqualOf(const StringFirstType& sFirstString, const std::vector& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template + bool EqualOf(const StringFirstType& sFirstString, const std::initializer_list& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template + bool Find(const StringType& sString, const StringValueType& sValue) + { + return !boost::algorithm::ifind_first(sString, sValue).empty(); + } } #endif // STRINGFINDER_H From daaeaee4df6821374b25a01cc3c140710ba74301 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 23 Jan 2024 13:27:47 +0300 Subject: [PATCH 243/794] Add tests for time --- OfficeUtils/tests/.gitignore | 3 +- OfficeUtils/tests/main.cpp | 116 +++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/OfficeUtils/tests/.gitignore b/OfficeUtils/tests/.gitignore index 07fb5b83ca6..3390380ff38 100644 --- a/OfficeUtils/tests/.gitignore +++ b/OfficeUtils/tests/.gitignore @@ -1 +1,2 @@ -unzip \ No newline at end of file +unzip +temp \ No newline at end of file diff --git a/OfficeUtils/tests/main.cpp b/OfficeUtils/tests/main.cpp index 22bfc763624..4f6364f6035 100644 --- a/OfficeUtils/tests/main.cpp +++ b/OfficeUtils/tests/main.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "gtest/gtest.h" @@ -53,6 +55,7 @@ class COfficeUtilsTest : public testing::Test std::wstring zipDirectory; std::wstring unzipDirectory; std::wstring wsep; + std::wstring tempDirectory; std::vector expected_general; std::vector expected_general_no_folder; @@ -70,10 +73,14 @@ class COfficeUtilsTest : public testing::Test workDirectory = NSFile::GetProcessDirectory(); unzipDirectory = workDirectory + wsep + L".." + wsep + L"unzip"; zipDirectory = workDirectory + wsep + L".." + wsep + L"zip"; + tempDirectory = workDirectory + wsep + L".." + wsep + L"temp"; if(!NSDirectory::Exists(unzipDirectory)) NSDirectory::CreateDirectories(unzipDirectory); + if(!NSDirectory::Exists(tempDirectory)) + NSDirectory::CreateDirectories(tempDirectory); + // general expected_general.push_back(L"1.txt"); expected_general.push_back(L"2.txt"); @@ -380,3 +387,112 @@ TEST_F(COfficeUtilsTest, other_win) ASSERT_EQ(error_code, S_OK); EXPECT_EQ(wstr, L"123 321"); } + +TEST_F(COfficeUtilsTest, time_file) +{ + // creating file + std::wstring filename = L"time_file_test.txt"; + std::wstring file_path = tempDirectory + wsep + filename; + + std::wstring zip_filename = L"time_file_test.zip"; + std::wstring zip_path = tempDirectory + wsep + zip_filename; + + std::wstring unzip_folder = tempDirectory + wsep + L"time_file_test"; + std::wstring unzip_path = unzip_folder + wsep + filename; + + // folder for unzip files + if (NSDirectory::Exists(unzip_folder)) + NSDirectory::DeleteDirectory(unzip_folder); + + NSDirectory::CreateDirectories(unzip_folder); + + // create file to zip, then unzip it + if (NSFile::CFileBinary::Exists(file_path)) + NSFile::CFileBinary::Remove(file_path); + + NSFile::CFileBinary file; + file.CreateFileW(file_path); + file.WriteStringUTF8(L"some text"); + file.CloseFile(); + + struct tm edit_time_before{}; + bool result_get_time_before = NSFile::CFileBinary::GetTime(file_path, &edit_time_before); + ASSERT_EQ(result_get_time_before, true); + + HRESULT error_code = utils.CompressFileOrDirectory(file_path, zip_path); + ASSERT_EQ(error_code, S_OK); + + error_code = utils.ExtractToDirectory(zip_path, unzip_folder, NULL, false); + ASSERT_EQ(error_code, S_OK); + + struct tm edit_time_after{}; + bool result_get_time_after = NSFile::CFileBinary::GetTime(unzip_path, &edit_time_after); + ASSERT_EQ(result_get_time_after, true); + + EXPECT_EQ(edit_time_before.tm_sec, edit_time_after.tm_sec); + EXPECT_EQ(edit_time_before.tm_min, edit_time_after.tm_min); + EXPECT_EQ(edit_time_before.tm_hour, edit_time_after.tm_hour); + EXPECT_EQ(edit_time_before.tm_mday, edit_time_after.tm_mday); + EXPECT_EQ(edit_time_before.tm_mon, edit_time_after.tm_mon); + EXPECT_EQ(edit_time_before.tm_year, edit_time_after.tm_year); +} + +TEST_F(COfficeUtilsTest, time_folder) +{ + std::wstring file_folder = tempDirectory + wsep + L"time_file_test_folder"; + + // creating file + std::wstring filename = L"time_file_test.txt"; + std::wstring file_path = file_folder + wsep + filename; + + std::wstring zip_filename = L"time_file_test.zip"; + std::wstring zip_path = tempDirectory + wsep + zip_filename; + + std::wstring unzip_folder = tempDirectory + wsep + L"time_file_test"; + std::wstring unzip_path = unzip_folder + wsep + filename; + + // folder for unzip files + if (NSDirectory::Exists(unzip_folder)) + NSDirectory::DeleteDirectory(unzip_folder); + + NSDirectory::CreateDirectories(unzip_folder); + + // folder for zip files + if (NSDirectory::Exists(file_folder)) + NSDirectory::DeleteDirectory(file_folder); + + NSDirectory::CreateDirectories(file_folder); + + // create file to zip, then unzip it + if (NSFile::CFileBinary::Exists(file_path)) + NSFile::CFileBinary::Remove(file_path); + + NSFile::CFileBinary file; + file.CreateFileW(file_path); + file.WriteStringUTF8(L"some text"); + file.CloseFile(); + + struct tm edit_time_before{}; + bool result_get_time_before = NSFile::CFileBinary::GetTime(file_path, &edit_time_before); + ASSERT_EQ(result_get_time_before, true); + + HRESULT error_code = utils.CompressFileOrDirectory(file_folder, zip_path); + ASSERT_EQ(error_code, S_OK); + + error_code = utils.ExtractToDirectory(zip_path, unzip_folder, NULL, false); + ASSERT_EQ(error_code, S_OK); + + struct tm edit_time_after{}; + bool result_get_time_after = NSFile::CFileBinary::GetTime(unzip_path, &edit_time_after); + ASSERT_EQ(result_get_time_after, true); + + // the 2-second precision + EXPECT_LE(std::abs(edit_time_before.tm_sec - edit_time_after.tm_sec), 1); + + EXPECT_EQ(edit_time_before.tm_min, edit_time_after.tm_min); + EXPECT_EQ(edit_time_before.tm_hour, edit_time_after.tm_hour); + EXPECT_EQ(edit_time_before.tm_mday, edit_time_after.tm_mday); + EXPECT_EQ(edit_time_before.tm_mon, edit_time_after.tm_mon); + EXPECT_EQ(edit_time_before.tm_year, edit_time_after.tm_year); +} + From 6537a1998a3d38a2da2677038089a43f4d1658e0 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 23 Jan 2024 19:36:48 +0300 Subject: [PATCH 244/794] add starmath convert --- OdfFile/Projects/Linux/OdfFormatLib.pro | 2 + OdfFile/Projects/Windows/cpodf.vcxproj | 5 +++ .../Projects/Windows/cpodf.vcxproj.filters | 18 ++++++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 38 ++++++++++++++-- .../StarMath2OOXML/cconversionsmtoooxml.h | 34 +++++++++++++- .../StarMath2OOXML/cstarmathpars.cpp | 32 +++++++++++++ .../Converter/StarMath2OOXML/cstarmathpars.h | 32 +++++++++++++ .../Converter/StarMath2OOXML/typeselements.h | 33 ++++++++++++++ OdfFile/Reader/Format/math_elements.cpp | 45 ++++++++++++++----- OdfFile/Reader/Format/math_elements.h | 12 ++--- 10 files changed, 227 insertions(+), 24 deletions(-) diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 45e696350e0..d3e81ad1de7 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -19,6 +19,8 @@ include(../../../Common/base.pri) #BOOST include($$PWD/../../../Common/3dParty/boost/boost.pri) +include($$PWD/../../Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri) + DEFINES += UNICODE \ _UNICODE \ DONT_WRITE_EMBEDDED_FONTS diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index 9261997573f..05f9ae9ddda 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -282,6 +282,8 @@ /bigobj %(AdditionalOptions) + + /bigobj %(AdditionalOptions) @@ -675,6 +677,9 @@ + + + diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index 7ab9701d637..9fca4cac955 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -25,6 +25,9 @@ {67b2bf43-5673-4a6f-82cb-fe4be01aee5f} + + {7d3e34d2-a224-4d68-9144-4889bbcc3698} + @@ -481,6 +484,12 @@ oox\pptx + + starmath + + + starmath + @@ -934,5 +943,14 @@ oox\pptx + + starmath + + + starmath + + + starmath + \ No newline at end of file diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index cbf89627945..e7bd859a2cd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -1,3 +1,34 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ #include "cconversionsmtoooxml.h" #include "../../../../DesktopEditor/common/File.h" #include @@ -16,15 +47,13 @@ namespace StarMath { oTempElement->ConversionToOOXML(m_pXmlWrite); } EndConversion(); - NSFile::CFileBinary oFile; - oFile.CreateFileW(L"Test.txt"); - oFile.WriteStringUTF8(m_pXmlWrite->GetXmlString()); - oFile.CloseFile(); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { if(pAttribute == nullptr) { + //тут должны быть базовые свойства шрифта, задаваемые выше + pXmlWrite->WriteNodeBegin(L"w:rPr",false); pXmlWrite->WriteNodeBegin(L"w:rFonts",true); pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); @@ -47,6 +76,7 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w",true,true); if(pAttribute->GetSize() == 0) { + //тут должны быть базовые свойства шрифта, задаваемые выше - далее везде где не задано - аналогично pXmlWrite->WriteNodeBegin(L"w:sz",true); pXmlWrite->WriteAttribute(L"w:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 7656f54f255..5581cc4742a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -1,10 +1,40 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + #ifndef CCONVERSIONSMTOOOXML_H #define CCONVERSIONSMTOOOXML_H #include "cstarmathpars.h" #include "../../../../DesktopEditor/xml/include/xmlwriter.h" - - namespace StarMath { //delete XmlWrite class CConversionSMtoOOXML diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index d35669edb3b..46fad8c5079 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1,3 +1,35 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + #include "cstarmathpars.h" #include "cconversionsmtoooxml.h" namespace StarMath diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 2304e4a77ea..30afb326a2a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -1,3 +1,35 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + #ifndef CSTARMATHPARS_H #define CSTARMATHPARS_H #include "typeselements.h" diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index b59de249314..3ed61afb426 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -1,5 +1,38 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + #ifndef TYPESELEMENTS_H #define TYPESELEMENTS_H + namespace StarMath { enum class TypeElement{ diff --git a/OdfFile/Reader/Format/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index 7e68a62abf0..aa46882f156 100644 --- a/OdfFile/Reader/Format/math_elements.cpp +++ b/OdfFile/Reader/Format/math_elements.cpp @@ -31,6 +31,7 @@ */ #include "math_elements.h" +#include "../Converter/StarMath2OOXML/cconversionsmtoooxml.h" namespace cpdoccore { @@ -93,10 +94,39 @@ void math_semantics::add_child_element( xml::sax * Reader, const std::wstring & void math_semantics::oox_convert(oox::math_context & Context) { - for (size_t i = 0 ; i < content_.size(); i++) + math_annotation* annotation = dynamic_cast(annotation_.get()); + math_annotation_xml* annotation_xml = dynamic_cast(annotation_.get()); + + std::wstring annotation_text; + if ((annotation) && (annotation->text_)) annotation_text = *annotation->text_; + else if ((annotation_xml) && (annotation_xml->text_)) annotation_text = *annotation_xml->text_; + + bool result = false; + if (!annotation_text.empty()) { - office_math_element* math_element = dynamic_cast(content_[i].get()); - math_element->oox_convert(Context); + result = true; + StarMath::CParserStarMathString parser; + StarMath::CConversionSMtoOOXML converter; + + // базовые свойства шрифта для математики + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_name_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_size_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_alignment_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_italic_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_bold_; + + /*result = */converter.StartConversion(parser.Parse(annotation_text)); + + Context.output_stream() << converter.GetOOXML(); + } + + if (!result) + { + for (size_t i = 0; i < content_.size(); i++) + { + office_math_element* math_element = dynamic_cast(content_[i].get()); + math_element->oox_convert(Context); + } } } @@ -126,11 +156,6 @@ void math_annotation::add_text(const std::wstring & Text) text_ = Text; } -void math_annotation::oox_convert(oox::math_context & Context) -{ - -} - //---------------------------------------------------------------------------------------------------- const wchar_t * math_annotation_xml::ns = L"math"; const wchar_t * math_annotation_xml::name = L"annotation-xml"; @@ -157,10 +182,6 @@ void math_annotation_xml::add_text(const std::wstring & Text) text_ = Text; } -void math_annotation_xml::oox_convert(oox::math_context & Context) -{ - -} //---------------------------------------------------------------------------------------------------- } diff --git a/OdfFile/Reader/Format/math_elements.h b/OdfFile/Reader/Format/math_elements.h index e7691fa0d5a..0c8e49dbec3 100644 --- a/OdfFile/Reader/Format/math_elements.h +++ b/OdfFile/Reader/Format/math_elements.h @@ -119,16 +119,16 @@ class math_annotation : public office_math_element static const xml::NodeType xml_type = xml::typeElement; static const ElementType type = typeMathAnnotation; - virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context& Context) {} + _CP_OPT(std::wstring) text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_text(const std::wstring & Text); - office_element_ptr_array content_; - _CP_OPT(std::wstring) text_; - _CP_OPT(std::wstring) encoding_; + office_element_ptr_array content_; + _CP_OPT(std::wstring) encoding_; }; CP_REGISTER_OFFICE_ELEMENT2(math_annotation); @@ -142,15 +142,15 @@ class math_annotation_xml : public office_math_element static const xml::NodeType xml_type = xml::typeElement; static const ElementType type = typeMathAnnotationXml; - virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context& Context) {} + _CP_OPT(std::wstring) text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_text(const std::wstring & Text); office_element_ptr_array content_; - _CP_OPT(std::wstring) text_; _CP_OPT(std::wstring) encoding_; }; From ae7854d23f9d9e4bfbf74c593e3d4bc88a260f8e Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 24 Jan 2024 01:34:57 +0500 Subject: [PATCH 245/794] For bug #65838 Convert text href pptx to odp --- OdfFile/Writer/Converter/ConvertDrawing.cpp | 27 ++++++++++-- OdfFile/Writer/Converter/PptxConverter.cpp | 41 +++++++++++++++---- OdfFile/Writer/Format/odf_text_context.cpp | 11 +++-- .../Writer/Format/odp_conversion_context.h | 2 +- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 88f06face0d..4dd8e045000 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -2499,10 +2499,6 @@ void OoxConverter::convert(PPTX::Logic::RunProperties *oox_run_pr, odf_writer::t { text_properties->fo_text_transform_ = odf_types::text_transform(odf_types::text_transform::Capitalize); } - if (oox_run_pr->hlinkClick.IsInit()) - { - convert(oox_run_pr->hlinkClick.GetPointer()); - } } static std::vector split_tabs(const std::wstring& text) { @@ -2577,6 +2573,29 @@ void OoxConverter::convert(PPTX::Logic::Run *oox_run) bool bExternal = false; std::wstring hlink = find_link_by_id(oox_run->rPr->hlinkClick->id.get(), 2, bExternal); std::wstring location; + + smart_ptr file = find_file_by_id(oox_run->rPr->hlinkClick->id.get()); + OOX::HyperLink* hyperlink = dynamic_cast(file.GetPointer()); + + if (hyperlink) + location = hyperlink->Uri().GetBasename(); + + if (oox_run->rPr->hlinkClick->action.IsInit() && location.empty()) + { + const std::wstring& action = *oox_run->rPr->hlinkClick->action; + + if (std::wstring::npos != action.find(L"previousslide")) + location = L"previous-page"; + else if (std::wstring::npos != action.find(L"nextslide")) + location = L"next-page"; + else if (std::wstring::npos != action.find(L"firstslide")) + location = L"first-page"; + else if (std::wstring::npos != action.find(L"lastslide")) + location = L"last-page"; + else if (std::wstring::npos != action.find(L"endshow")) + location = L"end"; + } + text_context->add_hyperlink(hlink, oox_run->GetText(), location); } else diff --git a/OdfFile/Writer/Converter/PptxConverter.cpp b/OdfFile/Writer/Converter/PptxConverter.cpp index 0275f165706..df562327db2 100644 --- a/OdfFile/Writer/Converter/PptxConverter.cpp +++ b/OdfFile/Writer/Converter/PptxConverter.cpp @@ -84,6 +84,7 @@ #include "../Format/odf_text_context.h" #include "../Format/odf_drawing_context.h" #include "../Format/office_event_listeners.h" +#include "../Format/paragraph_elements.h" #include "../Format/styles.h" #include "../Format/style_presentation.h" @@ -1280,22 +1281,44 @@ std::wstring PptxConverter::get_page_name(PPTX::Logic::CSld* oox_slide, _typePag void PptxConverter::fill_in_deferred_hyperlinks() { - for (auto hyperlink : odp_context->get_deferred_hyperlinks()) + auto links = odp_context->get_deferred_hyperlinks(); + auto slidenames_vec = std::vector>(odp_context->map_slidenames_.begin(), odp_context->map_slidenames_.end()); + + for (size_t i = 0; i < links.size(); i++) { + const auto& hyperlink = links[i]; + cpdoccore::odf_writer::presentation_event_listener* event_listener = dynamic_cast(hyperlink.first.get()); + cpdoccore::odf_writer::text_a* text = dynamic_cast(hyperlink.first.get()); const std::wstring& slidename = hyperlink.second; - if (!event_listener) - continue; - + std::wstring href; auto hrefIt = odp_context->map_slidenames_.find(slidename); - if (hrefIt == odp_context->map_slidenames_.end()) + if (slidename == L"previous-page" && i > 0) + href = slidenames_vec[i - 1].second; + else if (slidename == L"next-page" && i < slidenames_vec.size() - 2) + href = slidenames_vec[i + 1].second; + else if (slidename == L"first-page") + href = slidenames_vec[0].second; + else if (slidename == L"last-page") + href = slidenames_vec[slidenames_vec.size() - 1].second; + else if (hrefIt == odp_context->map_slidenames_.end()) continue; + else + href = hrefIt->second; - event_listener->attlist_.common_xlink_attlist_.href_ = std::wstring(L"#") + hrefIt->second; - event_listener->attlist_.common_xlink_attlist_.type_ = xlink_type::Simple; - event_listener->attlist_.common_xlink_attlist_.show_ = xlink_show::Embed; - event_listener->attlist_.common_xlink_attlist_.actuate_ = xlink_actuate::OnRequest; + if (event_listener) + { + event_listener->attlist_.common_xlink_attlist_.href_ = std::wstring(L"#") + href; + event_listener->attlist_.common_xlink_attlist_.type_ = xlink_type::Simple; + event_listener->attlist_.common_xlink_attlist_.show_ = xlink_show::Embed; + event_listener->attlist_.common_xlink_attlist_.actuate_ = xlink_actuate::OnRequest; + } + else if (text) + { + text->common_xlink_attlist_.href_ = std::wstring(L"#") + href; + text->common_xlink_attlist_.type_ = xlink_type::Simple; + } } } diff --git a/OdfFile/Writer/Format/odf_text_context.cpp b/OdfFile/Writer/Format/odf_text_context.cpp index 468f7ff0e59..771b4347ee0 100644 --- a/OdfFile/Writer/Format/odf_text_context.cpp +++ b/OdfFile/Writer/Format/odf_text_context.cpp @@ -669,9 +669,14 @@ void odf_text_context::add_hyperlink (const std::wstring & link, const std::wstr if (!display.empty()) hyperlink->add_text(display); //////////////////////////// - - hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); - hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; + + if (!link.empty()) + { + hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); + hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; + } + else + odf_context_->add_hyperlink(elm, location); if (false == current_level_.empty()) current_level_.back().elm->add_child_element(elm); diff --git a/OdfFile/Writer/Format/odp_conversion_context.h b/OdfFile/Writer/Format/odp_conversion_context.h index 4068241e004..76b32462166 100644 --- a/OdfFile/Writer/Format/odp_conversion_context.h +++ b/OdfFile/Writer/Format/odp_conversion_context.h @@ -103,7 +103,7 @@ class odp_conversion_context : public odf_conversion_context std::vector map_identifiers_; // NOTE(Kamil Kerimov): Key - slide name in pptx (e.g. slide1.xml), Value - slide name in odp (e.g. "This is a title") - using SlidenameMap = std::unordered_map; + using SlidenameMap = std::map; SlidenameMap map_slidenames_; private: odp_slide_context slide_context_; From 6f3dae7d5d4a5f72e2ccb5a0ef813d54e56ded6d Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 24 Jan 2024 01:35:26 +0500 Subject: [PATCH 246/794] Fix bug #65838 Convert text href odp to pptx --- OdfFile/Reader/Converter/oox_rels.cpp | 2 +- OdfFile/Reader/Converter/pptx_drawings.cpp | 10 ++++- .../Reader/Converter/pptx_text_context.cpp | 45 ++++++++++++++++--- OdfFile/Reader/Converter/pptx_text_context.h | 11 ++++- OdfFile/Reader/Format/paragraph_elements.cpp | 36 ++++++++++++++- .../Reader/Format/style_text_properties.cpp | 15 ++++--- OdfFile/Reader/Format/style_text_properties.h | 2 +- 7 files changed, 103 insertions(+), 18 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_rels.cpp b/OdfFile/Reader/Converter/oox_rels.cpp index f51ca1710dc..d6fca2e5c46 100644 --- a/OdfFile/Reader/Converter/oox_rels.cpp +++ b/OdfFile/Reader/Converter/oox_rels.cpp @@ -52,7 +52,7 @@ std::wostream & relationship::xml_to_stream(std::wostream & _Wostream) const CP_XML_ATTR(L"Type", type()); CP_XML_ATTR(L"Target", target()); - if (!target_mode().empty()) + if (!target_mode().empty() && type() != L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide") CP_XML_ATTR(L"TargetMode", target_mode()); } } diff --git a/OdfFile/Reader/Converter/pptx_drawings.cpp b/OdfFile/Reader/Converter/pptx_drawings.cpp index 516633bbf6a..b60312ccc25 100644 --- a/OdfFile/Reader/Converter/pptx_drawings.cpp +++ b/OdfFile/Reader/Converter/pptx_drawings.cpp @@ -31,6 +31,7 @@ */ #include +#include #include "oox_rels.h" @@ -74,8 +75,13 @@ class pptx_drawings::Impl } } - if(!found) - pptx_drawing_rels_.push_back(_rel(false, d.hlinks[i].hId, d.hlinks[i].hRef, typeHyperlink)); + if (!found) + { + oox::_rels_type type = boost::algorithm::starts_with(d.hlinks[i].hRef, L"slide") && + boost::algorithm::ends_with(d.hlinks[i].hRef, L".xml") ? typeSlide : typeHyperlink; + pptx_drawing_rels_.push_back(_rel(false, d.hlinks[i].hId, d.hlinks[i].hRef, type)); + } + } if (!d.action.hId.empty()) { diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index 0bfc224aeaf..78574034bfe 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -80,8 +80,12 @@ class pptx_text_context::Impl: boost::noncopyable void set_local_styles_container(odf_reader::styles_container* local_styles_);//это если стили объектов содержатся в другом документе - void end_hyperlink (std::wstring hId); + hyperlink_data get_hyperlink(); void start_hyperlink(); + void set_rel_id(const std::wstring& rId); + void set_action(const std::wstring& action); + void end_hyperlink (); + void start_list (const std::wstring & StyleName, bool Continue = false); void end_list (); @@ -102,6 +106,7 @@ class pptx_text_context::Impl: boost::noncopyable odf_reader::odf_read_context & odf_context_ ; std::wstring hyperlink_hId; + hyperlink_data hyperlink_; bool in_span; bool in_paragraph; @@ -240,11 +245,10 @@ void pptx_text_context::Impl::start_hyperlink() dump_run();//проверить } -void pptx_text_context::Impl::end_hyperlink(std::wstring hId) +void pptx_text_context::Impl::end_hyperlink() { - hyperlink_hId = hId; dump_run(); - hyperlink_hId = L""; + hyperlink_ = { L"", L"" }; } void pptx_text_context::Impl::ApplyTextProperties(std::wstring style_name, std::wstring para_style_name, odf_reader::text_format_properties & propertiesOut, bool inStyle) { @@ -780,6 +784,21 @@ void pptx_text_context::Impl::write_list_styles(std::wostream & strm)//defaults list_style_stack_.clear(); } +void pptx_text_context::Impl::set_rel_id(const std::wstring& rId) +{ + hyperlink_.rId = rId; +} + +void pptx_text_context::Impl::set_action(const std::wstring& action) +{ + hyperlink_.action = action; +} + +hyperlink_data pptx_text_context::Impl::get_hyperlink() +{ + return hyperlink_; +} + ///////////////////////////////////////////////////////////////////////////////////////////////////// pptx_text_context::pptx_text_context(odf_reader::odf_read_context & odf_context_, pptx_conversion_context & pptx_context_): @@ -865,14 +884,28 @@ void pptx_text_context::start_hyperlink() { return impl_->start_hyperlink(); } -void pptx_text_context::end_hyperlink(std::wstring hId) +void pptx_text_context::set_rel_id(const std::wstring& rId) +{ + impl_->set_rel_id(rId); +} +void pptx_text_context::set_action(const std::wstring& action) +{ + impl_->set_action(action); +} +void pptx_text_context::end_hyperlink() { - return impl_->end_hyperlink(hId); + return impl_->end_hyperlink(); } std::wstring pptx_text_context::end_object() { return impl_->end_object(); } + +hyperlink_data pptx_text_context::get_hyperlink() +{ + return impl_->get_hyperlink(); +} + styles_context & pptx_text_context::get_styles_context() { return impl_->get_styles_context() ; diff --git a/OdfFile/Reader/Converter/pptx_text_context.h b/OdfFile/Reader/Converter/pptx_text_context.h index a0aa4dc68ae..fcc55f63722 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.h +++ b/OdfFile/Reader/Converter/pptx_text_context.h @@ -58,6 +58,12 @@ enum field_type datetime }; +struct hyperlink_data +{ + std::wstring rId; + std::wstring action; +}; + class pptx_text_context: boost::noncopyable { public: @@ -85,8 +91,11 @@ class pptx_text_context: boost::noncopyable void start_object(); std::wstring end_object(); + hyperlink_data get_hyperlink(); void start_hyperlink(); - void end_hyperlink(std::wstring hId); + void set_rel_id(const std::wstring& rId); + void set_action(const std::wstring& action); + void end_hyperlink(); void start_field(field_type type, const std::wstring & styleName);//1 - datetime, 2 -pagecount, 3 - pagenumber - void end_field(); diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 6931d03870c..cadfe5e0489 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -778,6 +778,27 @@ void a::xlsx_convert(oox::xlsx_conversion_context & Context) } Context.end_hyperlink(xlink_attlist_.href_.get_value_or(L"")); } + +static std::wstring convert_href(oox::pptx_conversion_context& Context, const std::wstring& href) +{ + std::wstring result = href; + + if (boost::algorithm::starts_with(href, L"#")) + result = href.substr(1); + + const auto& page_names = Context.get_page_names(); + for (size_t i = 0; i < page_names.size(); i++) + { + if (result == page_names[i]) + { + result = std::wstring(L"slide") + std::to_wstring(i + 1) + std::wstring(L".xml"); + break; + } + } + + return result; +} + void a::pptx_convert(oox::pptx_conversion_context & Context) { Context.get_text_context().start_hyperlink(); @@ -786,9 +807,20 @@ void a::pptx_convert(oox::pptx_conversion_context & Context) content_[i]->pptx_convert(Context); } - std::wstring hId = Context.get_slide_context().add_hyperlink(xlink_attlist_.href_.get_value_or(L"")); - Context.get_text_context().end_hyperlink(hId); + std::wstring href = xlink_attlist_.href_.get_value_or(L""); + + if (boost::algorithm::starts_with(href, L"#")) + { + Context.get_text_context().set_action(L"ppaction://hlinksldjump"); + + href = convert_href(Context, href); + } + + std::wstring hId = Context.get_slide_context().add_hyperlink(href); + + Context.get_text_context().set_rel_id(hId); + Context.get_text_context().end_hyperlink(); } //------------------------------------------------------------------------------------------------------------ const wchar_t * endnote::ns = L"text"; diff --git a/OdfFile/Reader/Format/style_text_properties.cpp b/OdfFile/Reader/Format/style_text_properties.cpp index 1ed28cf320e..3ffccee4232 100644 --- a/OdfFile/Reader/Format/style_text_properties.cpp +++ b/OdfFile/Reader/Format/style_text_properties.cpp @@ -311,7 +311,7 @@ void text_format_properties::pptx_convert_as_list(oox::pptx_conversion_context & } } } -void text_format_properties::drawing_serialize(std::wostream & strm, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style, std::wstring hlink) +void text_format_properties::drawing_serialize(std::wostream & strm, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style, const oox::hyperlink_data link) { CP_XML_WRITER(strm) { @@ -541,12 +541,15 @@ void text_format_properties::drawing_serialize(std::wostream & strm, std::wstrin } } - if (!hlink.empty()) + if (!link.rId.empty()) { CP_XML_NODE(L"a:hlinkClick") { - CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); - CP_XML_ATTR(L"r:id", hlink); + if (link.action == L"ppaction://hlinksldjump") + CP_XML_ATTR(L"action", link.action); + else + CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + CP_XML_ATTR(L"r:id", link.rId); } } } @@ -1031,7 +1034,9 @@ void text_format_properties::pptx_convert(oox::pptx_conversion_context & Context oox::styles_context & styles_context_ = Context.get_text_context().get_styles_context(); fonts_container & fonts_ = Context.root()->odf_context().fontContainer(); - drawing_serialize(styles_context_.text_style(), styles_context_.extern_node(), fonts_, styles_context_.get_current_processed_style(), styles_context_.hlinkClick()); + oox::hyperlink_data link = Context.get_text_context().get_hyperlink(); + + drawing_serialize(styles_context_.text_style(), styles_context_.extern_node(), fonts_, styles_context_.get_current_processed_style(), link); // styles_context_.hlinkClick() } void text_format_properties::docx_convert(oox::docx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/style_text_properties.h b/OdfFile/Reader/Format/style_text_properties.h index 5953eccc9ef..59e1b2ef7d3 100644 --- a/OdfFile/Reader/Format/style_text_properties.h +++ b/OdfFile/Reader/Format/style_text_properties.h @@ -78,7 +78,7 @@ class text_format_properties : public oox::conversion_element void oox_serialize (std::wostream & stream, bool graphic, fonts_container & fonts, bool default_ = false); void docx_serialize (std::wostream & stream, fonts_container & fonts); - void drawing_serialize (std::wostream & stream, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style = NULL, std::wstring hlink = L""); + void drawing_serialize (std::wostream & stream, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style = NULL, const oox::hyperlink_data link = {L"", L""}); void xlsx_serialize (std::wostream & strm, oox::xlsx_conversion_context & Context); From 755ea7761c46d6c6216f3ff1d9ac507ccc4583a8 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Wed, 24 Jan 2024 10:36:31 +0300 Subject: [PATCH 247/794] Conversion of Greek characters, universal input of functions and operators. Writing tests. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 100 ++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 8 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 525 +++++++++++++++--- .../Converter/StarMath2OOXML/cstarmathpars.h | 24 +- .../Converter/StarMath2OOXML/typeselements.h | 67 +++ 6 files changed, 640 insertions(+), 86 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 3b970281042..bb314a39353 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -974,6 +974,106 @@ TEST(SMConvectorTest,AttributeGrade) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,Example2) +{ + std::wstring wsString = L"C = %pi cdot d = 2 cdot %pi cdot r"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example3) +{ + std::wstring wsString = L"c = sqrt{ a^2 + b^2 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"c=a2+b2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example4) +{ + std::wstring wsString = L"vec F = m times vec a"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"F=m\u00D7a"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example5) +{ + std::wstring wsString = L"E = m c^2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"E=mc2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example6) +{ + std::wstring wsString = L"G_{%mu %nu} + %LAMBDA g_{%mu %nu}= frac{8 %pi G}{c^4} T_{%mu %nu}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example8) +{ + std::wstring wsString = L"d over dt left( {partial L}over{partial dot q} right) = {partial L}over{partial q}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example9) +{ + std::wstring wsString = L"int from a to b f'(x) dx = f(b) - f(a)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"abf'xdx=fb-fa"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example10) +{ + std::wstring wsString = L"ldline %delta bold{r}(t) rdline approx e^{%lambda t} ldline %delta { bold{r} }_0 rdline"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +//TEST(SMConvectorTest,Example13) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString =L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + +//TEST(SMConvectorTest,Example13) +//{ +// std::wstring wsString = L""; +// StarMath::CParserStarMathString oTemp; +// StarMath::CConversionSMtoOOXML oTest; +// oTest.StartConversion(oTemp.Parse(wsString)); +// std::wstring wsXmlString =L""; +// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +//} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index cbf89627945..74e2af689cf 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -13,7 +13,8 @@ namespace StarMath { m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); for(CElement* oTempElement:arPars) { - oTempElement->ConversionToOOXML(m_pXmlWrite); + if(oTempElement != nullptr) + oTempElement->ConversionToOOXML(m_pXmlWrite); } EndConversion(); NSFile::CFileBinary oFile; @@ -292,7 +293,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp) { pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -313,6 +314,9 @@ namespace StarMath { case TypeElement::limsup: pXmlWrite->WriteString(L"lim sup"); break; + case TypeElement::oper: + pXmlWrite->WriteString(wsNameOp); + break; default: break; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 7656f54f255..986c18d1963 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -23,7 +23,7 @@ namespace StarMath { static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); - static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute); void EndConversion(); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index d35669edb3b..498ed730b64 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -415,6 +415,9 @@ namespace StarMath } CElement::CElement(): m_pAttribute(nullptr) {} + CElement::CElement(const TypeElement &enTypeBase): m_pAttribute(nullptr),m_enBaseType(enTypeBase) + { + } CElement* CElement::CreateElement(CStarMathReader* pReader) { switch (pReader->GetGlobalType()) { @@ -427,11 +430,27 @@ namespace StarMath case TypeElement::Connection: return new CElementConnection(pReader->GetLocalType()); case TypeElement::Function: - return new CElementFunction(pReader->GetLocalType()); + { + if(pReader->GetLocalType() == TypeElement::func) + { + pReader->GetToken(); + return new CElementFunction(pReader->GetLocalType(),pReader->GetString()); + } + else + return new CElementFunction(pReader->GetLocalType()); + } case TypeElement::Bracket: return new CElementBracket(pReader->GetLocalType()); case TypeElement::Operation: - return new CElementOperator(pReader->GetLocalType()); + { + if(pReader->GetLocalType() == TypeElement::oper) + { + pReader->GetToken(); + return new CElementOperator(pReader->GetLocalType(),pReader->GetString()); + } + else + return new CElementOperator(pReader->GetLocalType()); + } case TypeElement::BracketWithIndex: return new CElementBracketWithIndex(pReader->GetLocalType()); case TypeElement::Grade: @@ -580,11 +599,13 @@ namespace StarMath } void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) { - if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division) + if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division || TypeElement::frac == m_enTypeBinOp) { oXmlWrite->WriteNodeBegin(L"m:f",false); - if(m_enTypeBinOp == TypeElement::division) CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite,GetAttribute()); - else CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite,GetAttribute()); + if(m_enTypeBinOp == TypeElement::division) + CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite,GetAttribute()); + else + CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite,GetAttribute()); CConversionSMtoOOXML::BlockRecording(L"m:num",m_pLeftArgument,oXmlWrite); CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); oXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -816,7 +837,8 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* oTemp:m_arBrecketValue) { - oTemp->ConversionToOOXML(pXmlWrite); + if(oTemp != nullptr) + oTemp->ConversionToOOXML(pXmlWrite); } pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:d",false,false); @@ -825,7 +847,8 @@ namespace StarMath { for(CElement* oTemp:m_arBrecketValue) { - oTemp->ConversionToOOXML(pXmlWrite); + if(oTemp != nullptr) + oTemp->ConversionToOOXML(pXmlWrite); } } @@ -866,48 +889,127 @@ namespace StarMath { m_pValue = pValue; } - TypeElement CElementSpecialSymbol::GetSpecialSymbol(const std::wstring &wsToken) - { - if(L"#" == wsToken) return TypeElement::grid; - else if(L"##" == wsToken) return TypeElement::transition; - else if(L"emptyset" == wsToken) return TypeElement::emptyset; - else if(L"aleph" == wsToken) return TypeElement::aleph; - else if(L"setN" == wsToken) return TypeElement::setN; - else if(L"setZ" == wsToken) return TypeElement::setZ; - else if(L"setQ" == wsToken) return TypeElement::setQ; - else if(L"setR" == wsToken) return TypeElement::setR; - else if(L"setc" == wsToken) return TypeElement::setC; - else if(L"infinity" == wsToken) return TypeElement::infinity; - else if(L"fact" == wsToken) return TypeElement::fact; - else if(L"abs" == wsToken) return TypeElement::abs; - else if(L"`" == wsToken) return TypeElement::interval; - else if(L"~" == wsToken) return TypeElement::emptiness; - else if(L"partial" == wsToken) return TypeElement::partial; - else if(L"nabla" == wsToken) return TypeElement::nabla; - else if(L"exists" == wsToken) return TypeElement::exists; - else if(L"notexists" == wsToken) return TypeElement::notexists; - else if(L"forall" == wsToken) return TypeElement::forall; - else if(L"hbar" == wsToken) return TypeElement::hbar; - else if(L"lambdabar" == wsToken) return TypeElement::lambdabar; - else if(L"Re" == wsToken) return TypeElement::Re; - else if(L"Im" == wsToken) return TypeElement::Im; - else if(L"wp" == wsToken) return TypeElement::wp; - else if(L"laplace" == wsToken) return TypeElement::laplace; - else if(L"fourier" == wsToken) return TypeElement::fourier; - else if(L"backepsilon" == wsToken) return TypeElement::backepsilon; - else return TypeElement::undefine; + const TypeElement CElementSpecialSymbol::GetType() + { + return m_enTypeSpecial; + } + TypeElement CElementSpecialSymbol::GetSpecialSymbol(std::wstring &wsToken) + { + if(wsToken[0] != L'%') + { + if(L"#" == wsToken) return TypeElement::grid; + else if(L"##" == wsToken) return TypeElement::transition; + else if(L"emptyset" == wsToken) return TypeElement::emptyset; + else if(L"aleph" == wsToken) return TypeElement::aleph; + else if(L"setN" == wsToken) return TypeElement::setN; + else if(L"setZ" == wsToken) return TypeElement::setZ; + else if(L"setQ" == wsToken) return TypeElement::setQ; + else if(L"setR" == wsToken) return TypeElement::setR; + else if(L"setc" == wsToken) return TypeElement::setC; + else if(L"infinity" == wsToken) return TypeElement::infinity; + else if(L"fact" == wsToken) return TypeElement::fact; + else if(L"abs" == wsToken) return TypeElement::abs; + else if(L"`" == wsToken) return TypeElement::interval; + else if(L"~" == wsToken) return TypeElement::emptiness; + else if(L"partial" == wsToken) return TypeElement::partial; + else if(L"nabla" == wsToken) return TypeElement::nabla; + else if(L"exists" == wsToken) return TypeElement::exists; + else if(L"notexists" == wsToken) return TypeElement::notexists; + else if(L"forall" == wsToken) return TypeElement::forall; + else if(L"hbar" == wsToken) return TypeElement::hbar; + else if(L"lambdabar" == wsToken) return TypeElement::lambdabar; + else if(L"Re" == wsToken) return TypeElement::Re; + else if(L"Im" == wsToken) return TypeElement::Im; + else if(L"wp" == wsToken) return TypeElement::wp; + else if(L"laplace" == wsToken) return TypeElement::laplace; + else if(L"fourier" == wsToken) return TypeElement::fourier; + else if(L"backepsilon" == wsToken) return TypeElement::backepsilon; + else if(L"leftarrow" == wsToken) return TypeElement::leftarrow; + else if(L"rightarrow" == wsToken) return TypeElement::rightarrow; + else if(L"uparrow" == wsToken) return TypeElement::uparrow; + else if(L"downarrow" == wsToken) return TypeElement::downarrow; + else if(L"dotslow" == wsToken) return TypeElement::dotslow; + else if(L"dotsaxis" == wsToken) return TypeElement::dotsaxis; + else if(L"dotsvert" == wsToken) return TypeElement::dotsvert; + else if(L"dotsup" == wsToken) return TypeElement::dotsup; + else if(L"dotsdown" == wsToken) return TypeElement::dotsdown; + } + else if(wsToken[0] == L'%') + { + wsToken = wsToken.substr(1,wsToken.size()-1); + if(L"ALPHA" == wsToken) return TypeElement::alpha; + else if(L"ZETA" == wsToken) return TypeElement::zeta; + else if(L"LAMBDA" == wsToken) return TypeElement::lambda; + else if(L"PI" == wsToken) return TypeElement::pi; + else if(L"PHI" == wsToken) return TypeElement::phi; + else if(L"alpha" == wsToken) return TypeElement::alpha_small; + else if(L"varepsilon" == wsToken) return TypeElement::varepsilon; + else if(L"iota" == wsToken) return TypeElement::iota_small; + else if(L"xi" == wsToken) return TypeElement::xi_small; + else if(L"varrho" == wsToken) return TypeElement::varrho; + else if(L"phi" == wsToken) return TypeElement::phi_small; + else if(L"BETA" == wsToken) return TypeElement::beta; + else if(L"ETA" == wsToken) return TypeElement::eta; + else if(L"MU" == wsToken) return TypeElement::mu; + else if(L"RHO" == wsToken) return TypeElement::rho; + else if(L"CHI" == wsToken) return TypeElement::chi; + else if(L"beta" == wsToken) return TypeElement::beta_small; + else if(L"zeta" == wsToken) return TypeElement::zeta_small; + else if(L"kappa" == wsToken) return TypeElement::kappa_small; + else if(L"omicron" == wsToken) return TypeElement::omicron_small; + else if(L"sigma" == wsToken) return TypeElement::sigma_small; + else if(L"varphi" == wsToken) return TypeElement::varphi; + else if(L"GAMMA" == wsToken) return TypeElement::gamma; + else if(L"THETA" == wsToken) return TypeElement::theta; + else if(L"NU" == wsToken) return TypeElement::nu; + else if(L"SIGMA" == wsToken) return TypeElement::sigma; + else if(L"PSI" == wsToken) return TypeElement::psi; + else if(L"gamma" == wsToken) return TypeElement::gamma_small; + else if(L"eta" == wsToken) return TypeElement::eta_small; + else if(L"lambda" == wsToken) return TypeElement::lambda_small; + else if(L"pi" == wsToken) return TypeElement::pi_small; + else if(L"varsigma" == wsToken) return TypeElement::varsigma; + else if(L"chi" == wsToken) return TypeElement::chi_small; + else if(L"DELTA" == wsToken) return TypeElement::delta; + else if(L"IOTA" == wsToken) return TypeElement::iota; + else if(L"XI" == wsToken) return TypeElement::xi; + else if(L"TAU" == wsToken) return TypeElement::tau; + else if(L"OMEGA" == wsToken) return TypeElement::omega; + else if(L"delta" == wsToken) return TypeElement::delta_small; + else if(L"theta" == wsToken) return TypeElement::theta_small; + else if(L"mu" == wsToken) return TypeElement::mu_small; + else if(L"varpi" == wsToken) return TypeElement::varpi; + else if(L"tau" == wsToken) return TypeElement::tau_small; + else if(L"psi" == wsToken) return TypeElement::psi_small; + else if(L"EPSILON" == wsToken) return TypeElement::epsilon; + else if(L"KAPPA" == wsToken) return TypeElement::kappa; + else if(L"OMICRON" == wsToken) return TypeElement::omicron; + else if(L"UPSILON" == wsToken) return TypeElement::upsilon; + else if(L"epsilon" == wsToken) return TypeElement::epsilon_small; + else if(L"vartheta" == wsToken) return TypeElement::vartheta; + else if(L"nu" == wsToken) return TypeElement::nu_small; + else if(L"rho" == wsToken) return TypeElement::rho_small; + else if(L"upsilon" == wsToken) return TypeElement::upsilon_small; + else if(L"omega" == wsToken) return TypeElement::omega_small; + else if(L"and" == wsToken) return TypeElement::And; + else if(L"infinite" == wsToken) return TypeElement::infinity; + else if(L"perthousand" == wsToken) return TypeElement::perthousand; + else if(L"angle" == wsToken) return TypeElement::notin; + else if(L"strictlygreaterthan" == wsToken) return TypeElement::dlriarrow; + else if(L"element" == wsToken) return TypeElement::in; + else if(L"notequal" == wsToken) return TypeElement::notequals; + else if(L"strictlylessthan" == wsToken) return TypeElement::dllearrow; + else if(L"identical" == wsToken) return TypeElement::equiv; + else if(L"or" == wsToken) return TypeElement::Or; + else if(L"tendto" == wsToken) return TypeElement::rightarrow; + } + return TypeElement::undefine; } void CElementSpecialSymbol::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - SetWsTypeSymbol(); + SetTypeSymbol(); switch(m_enTypeSpecial) { - case TypeElement::transition: - { - pXmlWrite->WriteNodeEnd(L"m:mr",false,false); - pXmlWrite->WriteNodeBegin(L"m:mr",false); - break; - } case TypeElement::fact: { if(m_pValue!= nullptr) @@ -952,7 +1054,7 @@ namespace StarMath { SetBaseAttribute(pAttribute); } - void CElementSpecialSymbol::SetWsTypeSymbol() + void CElementSpecialSymbol::SetTypeSymbol() { switch(m_enTypeSpecial) { @@ -998,6 +1100,225 @@ namespace StarMath case TypeElement::backepsilon: m_wsType = L"\u03F6"; break; + case TypeElement::alpha: + m_wsType = L"\u0391"; + break; + case TypeElement::alpha_small: + m_wsType = L"\u03B1"; + break; + case TypeElement::zeta: + m_wsType = L"\u0396"; + break; + case TypeElement::zeta_small: + m_wsType = L"\u03B6"; + break; + case TypeElement::lambda: + m_wsType = L"\u039B"; + break; + case TypeElement::lambda_small: + m_wsType = L"\u03BB"; + break; + case TypeElement::pi: + m_wsType = L"\u03A0"; + break; + case TypeElement::pi_small: + m_wsType = L"\u03C0"; + break; + case TypeElement::phi: + m_wsType = L"\u03A6"; + break; + case TypeElement::phi_small: + m_wsType = L"\u03C6"; + break; + case TypeElement::varepsilon: + m_wsType = L"\u03B5"; + break; + case TypeElement::iota_small: + m_wsType = L"\u03B9"; + break; + case TypeElement::iota: + m_wsType = L"\u0399"; + break; + case TypeElement::xi_small: + m_wsType = L"\u03BE"; + break; + case TypeElement::xi: + m_wsType = L"\u039E"; + break; + case TypeElement::varrho: + m_wsType = L"\u03F1"; + break; + case TypeElement::beta: + m_wsType = L"\u0392"; + break; + case TypeElement::beta_small: + m_wsType = L"\u03B2"; + break; + case TypeElement::eta: + m_wsType = L"\u0397"; + break; + case TypeElement::eta_small: + m_wsType = L"\u03B7"; + break; + case TypeElement::mu: + m_wsType = L"\u039C"; + break; + case TypeElement::mu_small: + m_wsType = L"\u03BC"; + break; + case TypeElement::rho: + m_wsType = L"\u03A1"; + break; + case TypeElement::rho_small: + m_wsType = L"\u03C1"; + break; + case TypeElement::chi: + m_wsType = L"\u03A7"; + break; + case TypeElement::chi_small: + m_wsType = L"\u03C7"; + break; + case TypeElement::kappa_small: + m_wsType = L"\u03BA"; + break; + case TypeElement::kappa: + m_wsType = L"\u039A"; + break; + case TypeElement::omicron: + m_wsType = L"\u039F"; + break; + case TypeElement::omicron_small: + m_wsType = L"\u03BF"; + break; + case TypeElement::sigma: + m_wsType = L"\u03A3"; + break; + case TypeElement::sigma_small: + m_wsType = L"\u03C3"; + break; + case TypeElement::varphi: + m_wsType = L"\u03C6"; + break; + case TypeElement::gamma: + m_wsType = L"\u0393"; + break; + case TypeElement::gamma_small: + m_wsType = L"\u03B3"; + break; + case TypeElement::theta: + m_wsType = L"\u0398"; + break; + case TypeElement::theta_small: + m_wsType = L"\u03B8"; + break; + case TypeElement::nu: + m_wsType = L"\u039D"; + break; + case TypeElement::nu_small: + m_wsType = L"\u03BD"; + break; + case TypeElement::psi: + m_wsType = L"\u03A8"; + break; + case TypeElement::psi_small: + m_wsType = L"\u03C8"; + break; + case TypeElement::varsigma: + m_wsType = L"\u03DB"; + break; + case TypeElement::delta: + m_wsType = L"\u0394"; + break; + case TypeElement::delta_small: + m_wsType = L"\u03B4"; + break; + case TypeElement::tau: + m_wsType = L"\u03A4"; + break; + case TypeElement::tau_small: + m_wsType = L"\u03C4"; + break; + case TypeElement::omega: + m_wsType = L"\u03A9"; + break; + case TypeElement::omega_small: + m_wsType = L"\u03C9"; + break; + case TypeElement::varpi: + m_wsType = L"\u03D6"; + break; + case TypeElement::epsilon: + m_wsType = L"\u0395"; + break; + case TypeElement::epsilon_small: + m_wsType = L"\u03B5"; + break; + case TypeElement::upsilon: + m_wsType = L"\u03A5"; + break; + case TypeElement::upsilon_small: + m_wsType = L"\u03C5"; + break; + case TypeElement::vartheta: + m_wsType = L"\u03D1"; + break; + case TypeElement::And: + m_wsType = L"\u2227"; + break; + case TypeElement::Or: + m_wsType = L"\u2228"; + break; + case TypeElement::perthousand: + m_wsType = L"\u2030"; + break; + case TypeElement::angle: + m_wsType = L"\u2222"; + break; + case TypeElement::notin: + m_wsType = L"\u2209"; + break; + case TypeElement::dlriarrow: + m_wsType = L"\u\u226B"; + break; + case TypeElement::dllearrow: + m_wsType = L"\u226A"; + break; + case TypeElement::in: + m_wsType = L"\u2208"; + break; + case TypeElement::notequals: + m_wsType = L"\u2260"; + break; + case TypeElement::equiv: + m_wsType = L"\u2261"; + break; + case TypeElement::rightarrow: + m_wsType = L"\u1F872"; + break; + case TypeElement::leftarrow: + m_wsType = L"\u1F870"; + break; + case TypeElement::uparrow: + m_wsType = L"\u1F871"; + break; + case TypeElement::downarrow: + m_wsType = L"\u1F873"; + break; + case TypeElement::dotsaxis: + m_wsType = L"\u22EF"; + break; + case TypeElement::dotsup: + m_wsType = L"\u22F0"; + break; + case TypeElement::dotsdown: + m_wsType = L"\u22F1"; + break; + case TypeElement::dotsvert: + m_wsType = L"\u22EE"; + break; + case TypeElement::dotslow: + m_wsType = L"\u2026"; + break; default: break; } @@ -1032,8 +1353,11 @@ namespace StarMath void CElementSetOperations::Parse(CStarMathReader* pReader) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); + if(pReader->EmptyString()) + { + pReader->GetToken(); + pReader->SetTypesToken(); + } if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { CElement* pElement = CParserStarMathString::ParseElement(pReader); @@ -1160,8 +1484,11 @@ namespace StarMath { pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); + if(pReader->EmptyString()) + { + pReader->GetToken(); + pReader->SetTypesToken(); + } if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) { pReader->SetAttribute(GetAttribute()); @@ -1471,10 +1798,9 @@ namespace StarMath m_pValueIndex->SetAttribute(pAttribute); } //class methods CElementFunction - CElementFunction::CElementFunction(const TypeElement &enType): m_pValue(nullptr) + CElementFunction::CElementFunction(const TypeElement &enType, const std::wstring &wsNameFunc) + :CElement(TypeElement::Function), m_pValue(nullptr),m_wsNameFunc(wsNameFunc),m_enTypeFunction(enType) { - m_enTypeFunction = enType; - SetBaseType(TypeElement::Function); } CElementFunction::~CElementFunction() { @@ -1488,7 +1814,14 @@ namespace StarMath { return m_pValue; } - + void CElementFunction::SetNameFunc(const std::wstring &wsNameFunc) + { + m_wsNameFunc = wsNameFunc; + } + std::wstring CElementFunction::GetNameFuncInString() + { + return m_wsNameFunc; + } void CElementFunction::Parse(CStarMathReader* pReader) { CElement* pTemp = CParserStarMathString::ParseElement(pReader); @@ -1574,6 +1907,12 @@ namespace StarMath case TypeElement::exp: pXmlWrite->WriteString(L"exp"); break; + case TypeElement::func: + { + if(!m_wsNameFunc.empty()) + pXmlWrite->WriteString(GetNameFuncInString()); + break; + } default: break; } @@ -1606,6 +1945,7 @@ namespace StarMath else if(L"ln" == wsToken) return TypeElement::ln; else if(L"exp" == wsToken) return TypeElement::exp; else if(L"log" == wsToken) return TypeElement::log; + else if(L"func" == wsToken) return TypeElement::func; else return TypeElement::undefine; } void CElementFunction::SetAttribute(CAttribute *pAttribute) @@ -1615,10 +1955,9 @@ namespace StarMath m_pValue->SetAttribute(pAttribute); } //class methods CElementOperation - CElementOperator::CElementOperator(const TypeElement &enType): m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr) + CElementOperator::CElementOperator(const TypeElement &enType, const std::wstring& wsNameOp) + :CElement(TypeElement::Operator), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) { - m_enTypeOperator = enType; - SetBaseType(TypeElement::Operation); } CElementOperator::~CElementOperator() { @@ -1650,6 +1989,14 @@ namespace StarMath { return m_pValueTo; } + void CElementOperator::SetName(const std::wstring &wsNameOp) + { + m_wsName = wsNameOp; + } + std::wstring CElementOperator::GetName() + { + return m_wsName; + } TypeElement CElementOperator::GetFromOrTo(const std::wstring &wsToken) { if(L"from" == wsToken) return TypeElement::from; @@ -1659,17 +2006,18 @@ namespace StarMath TypeElement CElementOperator::GetOperator(const std::wstring &wsToken) { if(L"lim" == wsToken) return TypeElement::lim; - if(L"sum" == wsToken) return TypeElement::sum; - if(L"liminf" == wsToken) return TypeElement::liminf; - if(L"limsup" == wsToken) return TypeElement::limsup; - if(L"prod" == wsToken) return TypeElement::prod; - if(L"coprod" == wsToken) return TypeElement::coprod; - if(L"int" == wsToken) return TypeElement::Int; - if(L"iint" == wsToken) return TypeElement::iint; - if(L"iiint" == wsToken) return TypeElement::iiint; - if(L"lint" == wsToken) return TypeElement::lint; - if(L"llint" == wsToken) return TypeElement::llint; - if(L"lllint" == wsToken) return TypeElement::lllint; + else if(L"sum" == wsToken) return TypeElement::sum; + else if(L"liminf" == wsToken) return TypeElement::liminf; + else if(L"limsup" == wsToken) return TypeElement::limsup; + else if(L"prod" == wsToken) return TypeElement::prod; + else if(L"coprod" == wsToken) return TypeElement::coprod; + else if(L"int" == wsToken) return TypeElement::Int; + else if(L"iint" == wsToken) return TypeElement::iint; + else if(L"iiint" == wsToken) return TypeElement::iiint; + else if(L"lint" == wsToken) return TypeElement::lint; + else if(L"llint" == wsToken) return TypeElement::llint; + else if(L"lllint" == wsToken) return TypeElement::lllint; + else if(L"oper" == wsToken) return TypeElement::oper; else return TypeElement::undefine; } void CElementOperator::Parse(CStarMathReader* pReader) @@ -1693,7 +2041,7 @@ namespace StarMath } void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { - if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator) + if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator || TypeElement::oper == m_enTypeOperator) { std::wstring wsTempNameNode; if(m_pValueFrom != nullptr) @@ -1704,7 +2052,7 @@ namespace StarMath CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:fName",false); if(m_pValueFrom == nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); else { pXmlWrite->WriteNodeBegin(wsTempNameNode,false); @@ -1712,7 +2060,7 @@ namespace StarMath CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); pXmlWrite->WriteNodeEnd(wsTempNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeBegin(L"m:lim",false); if(wsTempNameNode == L"m:limLow") @@ -1887,7 +2235,7 @@ namespace StarMath } if(m_enUnderType == TypeElement::undefine) { - m_enGlobalType = TypeElement::Empty; + m_enGlobalType = TypeElement::String; return; } } @@ -1938,7 +2286,7 @@ namespace StarMath m_itStart++; break; } - else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart ||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (iswalpha(*m_itStart) && !iswalpha(m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) { return m_wsElement; } @@ -1956,7 +2304,11 @@ namespace StarMath if(!m_wsElement.empty()) return m_wsElement; else return {}; } - bool CStarMathReader::CheckTokenForGetElement(const char &cToken) + void CStarMathReader::FindingTheEndOfParentheses() + { + + } + bool CStarMathReader::CheckTokenForGetElement(const wchar_t &cToken) { if(L'[' == cToken) return true; else if(L']' == cToken) return true; @@ -1972,6 +2324,19 @@ namespace StarMath else if(L'~' == cToken) return true; else return false; } + bool CStarMathReader::CheckIsalhpaForGetElement(const wchar_t &cToken, const wchar_t &cLastToken) + { + if(isalpha(cToken)) + { + if(L'%' == cLastToken) + return false; + if(isalpha(cLastToken)) + return false; + } + else + return false; + return true; + } //class methods CElementBracketWithIndex CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType): m_pLeftArg(nullptr), m_pValue(nullptr) { @@ -2181,10 +2546,9 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } //class methods CElementMatrix - CElementMatrix::CElementMatrix(const TypeElement &enType): m_pFirstArgument(nullptr), m_pSecondArgument(nullptr) + CElementMatrix::CElementMatrix(const TypeElement &enType) + :CElement(TypeElement::Matrix), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) { - m_enTypeMatrix = enType; - SetBaseType(TypeElement::Matrix); } CElementMatrix::~CElementMatrix() { @@ -2239,6 +2603,15 @@ namespace StarMath pOneElement->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:e",false,false); } + else if(pOneElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pTempSpecial = dynamic_cast(pOneElement); + if(pTempSpecial->GetType() == TypeElement::transition) + { + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + } else if(pOneElement->GetBaseType() != TypeElement::undefine) pOneElement->ConversionToOOXML(pXmlWrite); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 2304e4a77ea..b728a1be701 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -65,9 +65,11 @@ namespace StarMath CAttribute* GetAttribute(); //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); + void FindingTheEndOfParentheses(); private: - bool CheckTokenForGetElement(const char& cToken); - std::wstring::iterator m_itStart,m_itEnd; + bool CheckTokenForGetElement(const wchar_t& cToken); + bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); + std::wstring::iterator m_itStart,m_itEnd,m_itEndBracket; TypeElement m_enGlobalType; TypeElement m_enUnderType; std::wstring m_wsToken; @@ -78,6 +80,7 @@ namespace StarMath { public: CElement(); + CElement(const TypeElement& enTypeBase); virtual ~CElement(); virtual void Parse(CStarMathReader* pReader) = 0; //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) @@ -152,7 +155,7 @@ namespace StarMath class CElementOperator: public CElement { public: - CElementOperator(const TypeElement& enType); + CElementOperator(const TypeElement& enType,const std::wstring& wsNameOp = L""); virtual ~CElementOperator(); void SetValueOperator(CElement* pElement); CElement* GetValueOperator(); @@ -160,6 +163,8 @@ namespace StarMath CElement* GetFromValue(); void SetToValue(CElement* pElement); CElement* GetToValue(); + void SetName(const std::wstring& wsNameOp); + std::wstring GetName(); static TypeElement GetOperator(const std::wstring& wsToken); static TypeElement GetFromOrTo(const std::wstring& wsToken); private: @@ -170,6 +175,7 @@ namespace StarMath CElement* m_pValueFrom; CElement* m_pValueTo; TypeElement m_enTypeOperator; + std::wstring m_wsName; }; class CElementGrade: public CElement @@ -199,10 +205,10 @@ namespace StarMath static TypeElement GetBracketOpen(const std::wstring& wsToken); std::vector GetBracketValue(); private: + TypeElement GetBracketClose(const std::wstring& wsToken); void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override;// - TypeElement GetBracketClose(const std::wstring& wsToken); TypeElement m_enTypeBracket; std::vector m_arBrecketValue; }; @@ -266,16 +272,19 @@ namespace StarMath class CElementFunction: public CElement { public: - CElementFunction(const TypeElement& enType); + CElementFunction(const TypeElement& enType, const std::wstring& wsNameFunc = L""); virtual ~CElementFunction(); void SetValueFunction(CElement* pElement); CElement* GetValueFunction(); + void SetNameFunc(const std::wstring& wsNameFunc); + std::wstring GetNameFuncInString(); static TypeElement GetFunction(const std::wstring& wsToken); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValue; + std::wstring m_wsNameFunc; TypeElement m_enTypeFunction; }; @@ -284,10 +293,11 @@ namespace StarMath public: CElementSpecialSymbol(const TypeElement& enType); virtual ~CElementSpecialSymbol(); - static TypeElement GetSpecialSymbol(const std::wstring& wsToken); + static TypeElement GetSpecialSymbol(std::wstring& wsToken); void SetValue(CElement* pValue); + const TypeElement GetType(); private: - void SetWsTypeSymbol(); + void SetTypeSymbol(); void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index b59de249314..d766c8a753d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -61,6 +61,7 @@ enum class TypeElement{ lint, llint, lllint, + oper, //brace brace, round, @@ -207,6 +208,71 @@ enum class TypeElement{ laplace, fourier, backepsilon, + alpha, + zeta, + lambda, + pi, + phi, + alpha_small, + varepsilon, + iota_small, + xi, + varrho, + phi_small, + beta, + eta, + mu, + rho, + chi, + beta_small, + zeta_small, + kappa, + omicron, + sigma, + varphi, + gamma, + theta, + nu, + sigma_small, + psi, + gamma_small, + eta_small, + lambda_small, + pi_small, + varsigma, + chi_small, + delta, + iota, + xi_small, + tau, + omega, + delta_small, + theta_small, + mu_small, + varpi, + tau_small, + psi_small, + epsilon, + kappa_small, + omicron_small, + upsilon, + epsilon_small, + vartheta, + nu_small, + rho_small, + upsilon_small, + omega_small, + perthousand, + angle, + rightarrow, + leftarrow, + uparrow, + downarrow, + dotsaxis, + dotsvert, + dotsup, + dotsdown, + dotslow, //function abs, fact, @@ -231,6 +297,7 @@ enum class TypeElement{ ln, exp, log, + func, //index upper, lower, From 5b6735e3bf95868eed59cd7ada7e555d0fc38466 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 24 Jan 2024 15:36:14 +0600 Subject: [PATCH 248/794] Fix formula conversion --- OOXML/XlsxFormat/Workbook/Workbook.cpp | 44 +++++++- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 120 +++++++++++----------- OOXML/XlsxFormat/Worksheets/SheetData.h | 2 +- 3 files changed, 104 insertions(+), 62 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 0a5fbee6cb3..365b9b8ed5e 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -43,6 +43,11 @@ #include "../../XlsbFormat/Biff12_unions/PIVOTCACHEID.h" #include "../../XlsbFormat/Biff12_records/FileVersion.h" #include "../../XlsbFormat/Biff12_records/BeginPivotCacheID.h" +#include "../../XlsbFormat/Biff12_unions/SUP.h" +#include "../../XlsbFormat/Biff12_records/SupSelf.h" +#include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../XlsbFormat/Biff12_records/BundleSh.h" + #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" #include "../../Common/SimpleTypes_Shared.h" @@ -296,6 +301,36 @@ namespace OOX auto ptr(new XLSB::BUNDLESHS); ptr->m_arBrtBundleSh = m_oSheets->toBin(); workBookStream->m_BUNDLESHS = XLS::BaseObjectPtr{ptr}; + + auto ptr1(new XLSB::EXTERNALS); + workBookStream->m_EXTERNALS = XLS::BaseObjectPtr{ptr1}; + auto externSheet(new XLSB::ExternSheet); + ptr1->m_BrtExternSheet = XLS::BaseObjectPtr{externSheet}; + externSheet->cXTI = ptr->m_arBrtBundleSh.size(); + for(auto i = 0; i < ptr->m_arBrtBundleSh.size(); i++) + { + auto sup(new XLSB::SUP); + auto supSelf(new XLSB::SupSelf); + sup->m_source = XLS::BaseObjectPtr{supSelf}; + ptr1->m_arSUP.push_back(XLS::BaseObjectPtr{sup}); + auto xti(new XLS::XTI); + xti->iSupBook = i; + xti->itabFirst = i; + xti->itabLast = i; + + auto biffStructPtr = XLS::BiffStructurePtr(xti); + externSheet->rgXTI.push_back(biffStructPtr); + + XLS::GlobalWorkbookInfo::_xti val_1; + val_1.iSup = xti->iSupBook; + val_1.itabFirst = i; + val_1.itabLast = i; + auto sheet = static_cast(ptr->m_arBrtBundleSh[i].get()); + val_1.link = sheet->strName; + + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(val_1); + + } } if (m_oWorkbookPr.IsInit()) workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); @@ -307,11 +342,14 @@ namespace OOX if (m_oExternalReferences.IsInit()) { - auto ptr(new XLSB::EXTERNALS); - ptr->m_arSUP = m_oExternalReferences->toBin(); - workBookStream->m_EXTERNALS = XLS::BaseObjectPtr{ptr}; + auto ptr = static_cast(workBookStream->m_EXTERNALS.get()); + auto sups = m_oExternalReferences->toBin(); + if(!sups.empty()) + ptr->m_arSUP.insert(ptr->m_arSUP.end(), sups.begin(), sups.end()); + } + /* if (m_oAppName.IsInit()) { diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 25ab5a99305..306c10285ef 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1085,47 +1085,43 @@ namespace OOX } } - XLS::BaseObjectPtr CFormula::toBin() + void CFormula::toBin(XLS::BaseObjectPtr& obj) { - XLS::BaseObjectPtr objectPtr; switch(m_oT->GetValue()) { case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal: { - auto formula(new XLSB::FmlaBase(false)); + auto formula = dynamic_cast(obj.get()); formula->formula = m_sText; - objectPtr = XLS::BaseObjectPtr{dynamic_cast(formula)}; + } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared: { + auto formula = dynamic_cast(obj.get()); + formula->formula = m_sText; if(m_oRef.IsInit()) - { - auto formula(new XLSB::ShrFmla(m_oRef.get())); - formula->formula = m_sText; - objectPtr = XLS::BaseObjectPtr{formula}; - } + formula->rfx = m_oRef.get(); + } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: { - if(m_oRef.IsInit()) + auto formula = dynamic_cast(obj.get()); + formula->formula = m_sText; + if(m_oAca.IsInit()) { - auto formula(new XLSB::ArrFmla(m_oRef.get())); - - formula->formula = m_sText; - if(m_oAca.IsInit()) - { - formula->fAlwaysCalc = m_oAca->GetValue(); - } - objectPtr = XLS::BaseObjectPtr{formula}; + formula->fAlwaysCalc = m_oAca->GetValue(); } + if(m_oRef.IsInit()) + formula->rfx = m_oRef.get(); + + } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: { - - auto dataTable(new XLSB::Table); + auto dataTable = dynamic_cast(obj.get()); if(m_oCa.IsInit()) { @@ -1169,7 +1165,6 @@ namespace OOX } break; } - return objectPtr; } EElementType CFormula::getType () const { @@ -1804,7 +1799,7 @@ namespace OOX { m_oType.Init(); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); - if(m_oValue.IsInit()) + if(m_oValue.IsInit() && !m_oFormula.IsInit()) { if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); @@ -2083,55 +2078,64 @@ namespace OOX ptr->m_source = XLS::BaseObjectPtr{pDATACELL}; pDATACELL->m_source = XLS::BaseObjectPtr{pSource}; } - else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeDataTable) - { - pTABLECELL = new(XLSB::TABLECELL); - ptr->m_source = XLS::BaseObjectPtr{pTABLECELL}; - pFMLACELL->m_source = m_oFormula->toBin(); - pTABLECELL->m_source = XLS::BaseObjectPtr{pSource}; - } else { - std::vector ref; - pFMLACELL = new XLSB::FMLACELL(0, ref); - - if(m_oRef.IsInit()) + if(!m_oFormula->m_oT.IsInit()) + { + m_oFormula->m_oT.Init(); + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; + } + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeDataTable) { - pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, ref); - pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; - ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; + pTABLECELL = new(XLSB::TABLECELL); + ptr->m_source = XLS::BaseObjectPtr{pTABLECELL}; + pTABLECELL->m_source = XLS::BaseObjectPtr{pSource}; + auto table(new XLSB::Table); + pTABLECELL->m_BrtTable = XLS::BaseObjectPtr{table}; + m_oFormula->toBin(pTABLECELL->m_BrtTable); + } - if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeShared) + else { + std::vector ref; + pFMLACELL = new XLSB::FMLACELL(0, ref); - if(!m_oRef.IsInit()) + if(m_oFormula->m_oRef.IsInit()) { - pFMLACELL->m_source = m_oFormula->toBin(); - if(m_oFormula->m_oSi.IsInit()) - pFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); - pFMLACELL->isShared = true; - ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + ref.push_back(m_oFormula->m_oRef.get()); } - else + /*if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeShared) { - if(m_oFormula->m_oSi.IsInit()) + + pSHRFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + if(m_oFormula->m_oSi.IsInit()) + pFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); + pFMLACELL->isShared = true; + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + + else { - pSHRFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); - pSHRFMLACELL->m_source = m_oFormula->toBin(); + if(m_oFormula->m_oSi.IsInit()) + { + pSHRFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); + pSHRFMLACELL->m_source = m_oFormula->toBin(); + } } + }*/ + else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeNormal) + { + + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + m_oFormula->toBin(pFMLACELL->m_source); } - } - else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeNormal) - { - std::vector ref; - pFMLACELL = new XLSB::FMLACELL(0, ref); - ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; - pFMLACELL->m_source = m_oFormula->toBin(); - } - else if(m_oFormula->getType() == SimpleTypes::Spreadsheet::cellformulatypeArray) - { - pSHRFMLACELL->m_source = m_oFormula->toBin(); + /*else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) + { + pSHRFMLACELL->m_source = m_oFormula->toBin(pSHRFMLACELL); + }*/ } } if(m_oCol.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 57dece8a776..976d88ca4a7 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -141,7 +141,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream); void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nFlags); void fromBin(XLS::BaseObjectPtr& obj, SimpleTypes::Spreadsheet::ECellFormulaType eType); - XLS::BaseObjectPtr toBin(); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; From 71afe4a0d52240f9919077c10b2402d9803a748e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 24 Jan 2024 16:41:41 +0600 Subject: [PATCH 249/794] Add relative reference saving --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h index ba503160405..e5d13bf7ab6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h @@ -180,10 +180,12 @@ class CellRef_T : public CellRef void save(CFRecord& record) override { RwType rw; - ColType col; + ColType col = 0; rw = row; - col = column; + SETBITS(col, 0, 13, column); + SETBIT(col, 14, colRelative); + SETBIT(col, 15, rowRelative); record << rw << col; } From 9947e80e6c468005cb74773d8ea4b97e93de4c0a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 24 Jan 2024 17:50:21 +0600 Subject: [PATCH 250/794] Fix XLUnicodeString_T operator= --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h | 1 + 1 file changed, 1 insertion(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h index 50786da3a4a..03443bef33f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h @@ -118,6 +118,7 @@ class XLUnicodeString_T : public BiffString } XLUnicodeString_T operator=(const bool& boolVal) { + cch_ = 0; return *this; } const size_t getStructSizeWouldWritten() const // Number of unsigned chars that would be written From d5de6a710d139441f4e6f73ee99ab50ea92876fa Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 25 Jan 2024 00:07:00 +0300 Subject: [PATCH 251/794] Fix ZipFile func for linux --- OfficeUtils/src/ZipUtilsCP.cpp | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/OfficeUtils/src/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index 3d0dbff1f9d..7c5db7baa1a 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -746,24 +746,8 @@ namespace ZLibZipUtils { zipFile zf = zipOpenHelp(outputFile); if (zf) - { - wstring inputFileName( inputFile ); - - wstring::size_type pos = 0; - static const wstring::size_type npos = -1; - - pos = inputFileName.find_last_of( L'\\' ); - - wstring zipFileName; - - if ( pos != npos ) - { - zipFileName = wstring( ( inputFileName.begin() + pos + 1 ), inputFileName.end() ); - } - else - { - zipFileName = wstring( inputFileName.begin(), inputFileName.end() ); - } + { + wstring zipFileName = NSFile::GetFileName(inputFile); std::string zipFileNameA = codepage_issue_fixToOEM(zipFileName); err = zipOpenNewFileInZip( zf, zipFileNameA.c_str(), &zinfo, NULL, 0, NULL, 0, NULL, method, compressionLevel ); From bccdeedc4e3f2bfbe3dd085688103094c811346f Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 25 Jan 2024 15:55:14 +0600 Subject: [PATCH 252/794] Fix cell refs conversion --- .../Logic/Biff_structures/CellRangeRef.h | 43 ++++++++++++++----- .../Format/Logic/Biff_structures/CellRef.h | 16 +++++-- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h index 9d9605b83ff..31e1652c5b3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h @@ -189,20 +189,43 @@ class CellRangeRef_T : public CellRangeRef RwType rwLast; ColType colFirst; ColType colLast; - + + auto version = record.getGlobalWorkbookInfo()->Version; + rwFirst = rowFirst; rwLast = rowLast; - switch (rel_info) + if (version < 0x0800) + { + switch (rel_info) + { + case rel_Present: + colFirst = (columnFirst >> 2) << 2; + colLast = (columnLast >> 2) << 2; + break; + case rel_Absent: + colFirst = columnFirst; + colLast = columnLast; + break; + } + } + else { - case rel_Present: - colFirst = (columnFirst >> 2) << 2; - colLast = (columnLast >> 2) << 2; - break; - case rel_Absent: - colFirst = columnFirst; - colLast = columnLast; - break; + if(rel_info == rel_Present) + { + SETBITS(colFirst, 0, 13, columnFirst); + SETBIT(colFirst, 14, columnFirstRelative); + SETBIT(colFirst, 15, rowFirstRelative); + + SETBITS(colLast, 0, 13, columnLast); + SETBIT(colLast, 14, columnLastRelative); + SETBIT(colLast, 15, rowLastRelative); + } + else if(rel_info == rel_Absent) + { + colFirst = columnFirst; + colLast = columnLast; + } } record << rwFirst << rwLast << colFirst << colLast; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h index e5d13bf7ab6..f2d617a035b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h @@ -181,11 +181,19 @@ class CellRef_T : public CellRef { RwType rw; ColType col = 0; - rw = row; - SETBITS(col, 0, 13, column); - SETBIT(col, 14, colRelative); - SETBIT(col, 15, rowRelative); + auto version = record.getGlobalWorkbookInfo()->Version; + + if (version < 0x0800) + { + col = column; + } + else + { + SETBITS(col, 0, 13, column); + SETBIT(col, 14, colRelative); + SETBIT(col, 15, rowRelative); + } record << rw << col; } From afdc28dbe44248d8e71fde9456cdd48d211a78da Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 25 Jan 2024 18:44:32 +0600 Subject: [PATCH 253/794] Fix page setup --- .../Worksheets/WorksheetChildOther.cpp | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index e96a8970bfb..705b931460d 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -444,22 +444,22 @@ namespace OOX XLS::BaseObjectPtr objPtr(ptr); if(m_oLeft.IsInit()) - ptr->xnumLeft.data.value = std::round(m_oLeft->GetValue() * 100) / 100; + ptr->xnumLeft.data.value = std::round(m_oLeft->GetValue()) / 100; if(m_oTop.IsInit()) - ptr->xnumTop.data.value = std::round(m_oTop->GetValue() * 100) / 100; + ptr->xnumTop.data.value = std::round(m_oTop->GetValue()) / 100; if(m_oRight.IsInit()) - ptr->xnumRight.data.value = std::round(m_oRight->GetValue() * 100) / 100; + ptr->xnumRight.data.value = std::round(m_oRight->GetValue()) / 100; if(m_oBottom.IsInit()) - ptr->xnumBottom.data.value = std::round(m_oBottom->GetValue() * 100) / 100; + ptr->xnumBottom.data.value = std::round(m_oBottom->GetValue()) / 100; if(m_oHeader.IsInit()) - ptr->xnumHeader.data.value = std::round(m_oHeader->GetValue() * 100) / 100; + ptr->xnumHeader.data.value = std::round(m_oHeader->GetValue()) / 100; if(m_oFooter.IsInit()) - ptr->xnumFooter.data.value = std::round(m_oFooter->GetValue() * 100) / 100; + ptr->xnumFooter.data.value = std::round(m_oFooter->GetValue()) / 100; return objPtr; } @@ -571,6 +571,8 @@ namespace OOX if (m_oCopies.IsInit()) ptr->iCopies = m_oCopies->m_eValue; + else + ptr->iCopies = 1; if (m_oDraft.IsInit()) ptr->fDraft = m_oDraft->m_eValue; @@ -580,37 +582,63 @@ namespace OOX if (m_oFirstPageNumber.IsInit()) ptr->iPageStart = m_oFirstPageNumber->m_eValue; + else + ptr->iPageStart = 1; if (m_oFitToHeight.IsInit()) ptr->iFitHeight = m_oFitToHeight->m_eValue; + else + ptr->iFitHeight = 1; if (m_oFitToWidth.IsInit()) ptr->iFitWidth = m_oFitToWidth->m_eValue; + else + ptr->iFitWidth = 1; if (m_oHorizontalDpi.IsInit()) ptr->iRes = m_oHorizontalDpi->m_eValue; + else + ptr->iRes = 600; if (m_oRId.IsInit()) ptr->szRelID = m_oRId->GetValue(); - if (m_oOrientation == SimpleTypes::EPageOrientation::pageorientLandscape) + if (m_oOrientation.IsInit() && m_oOrientation->GetValue() == SimpleTypes::EPageOrientation::pageorientLandscape) + { + ptr->fPortrait = false; ptr->fLandscape = true; - else + } + else if(m_oOrientation.IsInit()) + { ptr->fLandscape = false; + ptr->fPortrait = true; + } + else + { + ptr->fPortrait = false; + ptr->fLandscape = false; + ptr->fNoOrient = true; + } - if ( m_oPageOrder == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) + if (m_oPageOrder.IsInit() && m_oPageOrder->GetValue() == SimpleTypes::Spreadsheet::EPageOrder::pageorderOverThenDown) ptr->fLeftToRight = true; else ptr->fLeftToRight = false; if (m_oPaperSize.IsInit()) ptr->iPaperSize = m_oPaperSize->m_eValue; + else + ptr->iPaperSize = 9; if (m_oScale.IsInit()) ptr->iScale = m_oScale->m_eValue; + else + ptr->iScale = 100; if (m_oUseFirstPageNumber.IsInit()) ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + else + ptr->fUsePage = true; if (m_oVerticalDpi.IsInit()) ptr->iVRes = m_oVerticalDpi->m_eValue; From 3fbbf754a2d4535bf5a135113462415f2630ed1c Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 26 Jan 2024 12:22:13 +0300 Subject: [PATCH 254/794] Fixed a bug in reading a function without an element. Adding a base attribute read. Code refactoring. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 10 - .../StarMath2OOXML/cconversionsmtoooxml.cpp | 4 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 220 ++++++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 21 +- 5 files changed, 166 insertions(+), 91 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index bb314a39353..b20ec93d2cd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1064,16 +1064,6 @@ TEST(SMConvectorTest,Example10) // EXPECT_EQ(oTest.GetOOXML(),wsXmlString); //} -//TEST(SMConvectorTest,Example13) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString =L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} - //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 74e2af689cf..4524e27160f 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -97,13 +97,13 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); } } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) { pXmlWrite->WriteNodeBegin(L"m:type",true); - pXmlWrite->WriteAttribute(L"m:val",wsType); + pXmlWrite->WriteAttribute(L"m:val",L"lin"); pXmlWrite->WriteNodeEnd(L"w",true,true); } WriteCtrlPrNode(pXmlWrite,pAttribute); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 986c18d1963..4509453546e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -13,7 +13,7 @@ namespace StarMath { CConversionSMtoOOXML(); void StartConversion(std::vector arPars); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void PropertiesMFPR(bool bType,const std::wstring& wsType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void BlockRecording(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 498ed730b64..4d6c9a4ad73 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -3,11 +3,12 @@ namespace StarMath { //class methods CParsStarMath - std::vector CParserStarMathString::Parse(std::wstring& wsParseString) + std::vector CParserStarMathString::Parse(std::wstring& wsParseString,const TBaseAttribute* pBaseAttribute) { std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); CStarMathReader* pReader = new CStarMathReader(itStart,itEnd); - while(!pReader->CheckIteratorPosition()) + pReader->SetBaseAttribute(pBaseAttribute); + while(pReader->CheckIteratorPosition()) { CElement* pTempElement = ParseElement(pReader); if(nullptr == pTempElement) @@ -42,6 +43,8 @@ namespace StarMath if(pElement != nullptr) { + if(pReader->GetBaseAttribute()!=nullptr) + pElement->SetBaseAttribute(pReader->GetBaseAttribute()); if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType())) @@ -501,9 +504,8 @@ namespace StarMath } //class methods CElementString CElementString::CElementString(const std::wstring& wsTokenString) + :CElement(TypeElement::String),m_wsString(wsTokenString) { - m_wsString = wsTokenString; - SetBaseType(TypeElement::String); } CElementString::~CElementString() {} @@ -553,10 +555,9 @@ namespace StarMath SetBaseAttribute(pAttribute); } //class methods CElementBinOperator - CElementBinOperator::CElementBinOperator(const TypeElement& enType): m_pLeftArgument(nullptr) , m_pRightArgument(nullptr) + CElementBinOperator::CElementBinOperator(const TypeElement& enType) + :CElement(TypeElement::BinOperator),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) { - m_enTypeBinOp = enType; - SetBaseType(TypeElement::BinOperator); } CElementBinOperator::~CElementBinOperator() { @@ -603,9 +604,9 @@ namespace StarMath { oXmlWrite->WriteNodeBegin(L"m:f",false); if(m_enTypeBinOp == TypeElement::division) - CConversionSMtoOOXML::PropertiesMFPR(true,L"lin",oXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesMFPR(true,oXmlWrite,GetAttribute()); else - CConversionSMtoOOXML::PropertiesMFPR(false,L"",oXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesMFPR(false,oXmlWrite,GetAttribute()); CConversionSMtoOOXML::BlockRecording(L"m:num",m_pLeftArgument,oXmlWrite); CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); oXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -751,9 +752,8 @@ namespace StarMath } //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) + :CElement(TypeElement::Bracket),m_enTypeBracket(enType) { - m_enTypeBracket = enType; - SetBaseType(TypeElement::Bracket); } CElementBracket::~CElementBracket() { @@ -798,13 +798,15 @@ namespace StarMath } void CElementBracket::Parse(CStarMathReader* pReader) { - pReader->GetToken(); - TypeElement enBracketClose = GetBracketClose(pReader->GetString()); - if(enBracketClose == TypeElement::undefine) - { - pReader->SetTypesToken(); - } - while(enBracketClose == TypeElement::undefine) + pReader->FindingTheEndOfParentheses(); +// pReader->EndingBrackets(); +// pReader->GetToken(); +// TypeElement enBracketClose = GetBracketClose(pReader->GetString()); +// if(enBracketClose == TypeElement::undefine) +// { +// pReader->SetTypesToken(); +// } + while(pReader->CheckIteratorPosition()) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) @@ -813,20 +815,20 @@ namespace StarMath m_arBrecketValue.pop_back(); } m_arBrecketValue.push_back(pTempElement); - if(pReader->EmptyString()) - { - pReader->GetToken(); - enBracketClose = GetBracketClose(pReader->GetString()); - if(enBracketClose == TypeElement::undefine) - { - pReader->SetTypesToken(); - } - } - else enBracketClose = GetBracketClose(pReader->GetString()); +// if(pReader->EmptyString()) +// { +// pReader->GetToken(); +// enBracketClose = GetBracketClose(pReader->GetString()); +// if(enBracketClose == TypeElement::undefine) +// { +// pReader->SetTypesToken(); +// } +// } +// else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() SetAttribute(GetAttribute()); - pReader->ClearReader(); + pReader->IteratorNullification(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -863,10 +865,9 @@ namespace StarMath } } //class methods CElementSpecialSymbol - CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType):m_pValue(nullptr) + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) + :CElement(TypeElement::SpecialSymbol),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") { - m_enTypeSpecial = enType; - SetBaseType(TypeElement::SpecialSymbol); } CElementSpecialSymbol::~CElementSpecialSymbol() { @@ -1324,10 +1325,9 @@ namespace StarMath } } //class methods CElementSetOperations - CElementSetOperations::CElementSetOperations(const TypeElement &enType): m_pRightArgument(nullptr), m_pLeftArgument(nullptr) + CElementSetOperations::CElementSetOperations(const TypeElement &enType) + :CElement(TypeElement::SetOperations),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) { - m_enTypeSet = enType; - SetBaseType(TypeElement::SetOperations); } CElementSetOperations::~CElementSetOperations() { @@ -1454,10 +1454,9 @@ namespace StarMath m_pRightArgument->SetAttribute(pAttribute); } //class methods CElementConnection - CElementConnection::CElementConnection(const TypeElement& enType): m_pLeftArgument(nullptr), m_pRightArgument(nullptr) + CElementConnection::CElementConnection(const TypeElement& enType) + :CElement(TypeElement::Connection),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) { - m_enTypeCon = enType; - SetBaseType(TypeElement::Connection); } CElementConnection::~CElementConnection() { @@ -1657,10 +1656,9 @@ namespace StarMath m_pRightArgument->SetAttribute(pAttribute); } //class methods CIndex - CElementIndex::CElementIndex(const TypeElement& enType): m_pValueIndex(nullptr),m_pLeftArg(nullptr) + CElementIndex::CElementIndex(const TypeElement& enType) + : CElement(TypeElement::Index),m_pValueIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) { - m_enTypeIndex = enType; - SetBaseType(TypeElement::Index); } CElementIndex::~CElementIndex() { @@ -1824,16 +1822,21 @@ namespace StarMath } void CElementFunction::Parse(CStarMathReader* pReader) { - CElement* pTemp = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); - if(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + if(pReader->CheckIteratorPosition()) { - CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTemp,pTempElement); - pTemp = pTempElement; + CElement* pTemp = CParserStarMathString::ParseElement(pReader); + pReader->GetToken(); + pReader->SetTypesToken(); + if(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + { + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTemp,pTempElement); + pTemp = pTempElement; + } + SetValueFunction(pTemp); } - SetValueFunction(pTemp); + else + SetValueFunction(nullptr); //pReader->ClearReader(); } void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -1919,9 +1922,17 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + if(m_pValue!=nullptr) + { pXmlWrite->WriteNodeBegin(L"m:e",false); m_pValue->ConversionToOOXML(pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:e",false,false); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:e",true); + pXmlWrite->WriteNodeEnd(L"",true,true); + } pXmlWrite->WriteNodeEnd(L"m:func",false,false); } TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) @@ -2105,7 +2116,8 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } // class methods CStarMathReader - CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd): m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr) + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr) { m_itStart = itStart; m_itEnd = itEnd; @@ -2118,7 +2130,7 @@ namespace StarMath //TODO :: ParseColor and ParseFont void CStarMathReader::GetToken() { - if(m_itStart != m_itEnd) + if(CheckIteratorPosition()) { m_wsToken = GetElement(); TypeElement enTypeFont =CAttribute::GetTypeFontAttribute(m_wsToken),enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); @@ -2264,8 +2276,7 @@ namespace StarMath } bool CStarMathReader::CheckIteratorPosition() { - if(m_itStart != m_itEnd) return false; - else return true; + return (m_itStart != m_itEnd); } void CStarMathReader::SetAttribute(CAttribute *pAttribute) { @@ -2275,6 +2286,29 @@ namespace StarMath { return m_pAttribute; } + void CStarMathReader::SetBaseAttribute(const TBaseAttribute* pAttribute) + { + if(pAttribute!=nullptr) + { + m_pBaseAttribute = new CAttribute; + if(pAttribute->base_font_italic) + m_pBaseAttribute->SetItal(); + if(pAttribute->base_font_bold) + m_pBaseAttribute->SetBold(); + // if(!pAttribute.base_font_name.empty()) + // m_pBaseAttribute->SetFont(); + if(pAttribute->base_font_size != 0) + m_pBaseAttribute->SetSize(pAttribute->base_font_size); + // if(pAttribute.base_alignment != 0) + // m_pBaseAttribute-> + } + else + m_pBaseAttribute = nullptr; + } + CAttribute* CStarMathReader::GetBaseAttribute() + { + return m_pBaseAttribute; + } std::wstring CStarMathReader::GetElement() { std::wstring m_wsElement{}; @@ -2306,23 +2340,61 @@ namespace StarMath } void CStarMathReader::FindingTheEndOfParentheses() { - + std::wstring::iterator itStart = m_itStart,itStartBracketClose; + int inBracketInside = 0; + while(CheckIteratorPosition()) + { + itStartBracketClose = m_itStart; + GetToken(); + if(CElementBracket::GetBracketOpen(m_wsToken) != TypeElement::undefine) + { + inBracketInside +=1; + } + else if(CElementBracket::GetBracketClose(m_wsToken) != TypeElement::undefine && inBracketInside == 0) + { + m_stBracket.push(m_itEnd); + m_itEnd = itStartBracketClose; + break; + } + else if(CElementBracket::GetBracketClose(m_wsToken) != TypeElement::undefine && inBracketInside != 0) + { + inBracketInside -=1; + } + } + ClearReader(); + m_itStart = itStart; + } + void CStarMathReader::IteratorNullification() + { + if(!m_stBracket.empty()) + { + m_itEnd = m_stBracket.top(); + m_stBracket.pop(); + } + while(TypeElement::undefine == CElementBracket::GetBracketClose(GetString()) && CheckIteratorPosition()) + { + GetToken(); + } + ClearReader(); } bool CStarMathReader::CheckTokenForGetElement(const wchar_t &cToken) { - if(L'[' == cToken) return true; - else if(L']' == cToken) return true; - else if(L'{' == cToken) return true; - else if(L'}' == cToken) return true; - else if(L'_' == cToken) return true; - else if(L'^' == cToken) return true; - else if(L'*' == cToken) return true; - else if(L'/' == cToken) return true; -// else if(L'-' == cToken) return true; -// else if(L'+' == cToken) return true; - else if(L'`' == cToken) return true; - else if(L'~' == cToken) return true; - else return false; + switch(cToken) + { + case L'[': + case L']': + case L'{': + case L'}': + case L'_': + case L'^': + case L'*': + case L'/': + case L'`': + case L'~': + return true; + default: + return false; + } } bool CStarMathReader::CheckIsalhpaForGetElement(const wchar_t &cToken, const wchar_t &cLastToken) { @@ -2338,10 +2410,9 @@ namespace StarMath return true; } //class methods CElementBracketWithIndex - CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType): m_pLeftArg(nullptr), m_pValue(nullptr) + CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType) + :CElement(TypeElement::BracketWithIndex),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) { - m_enTypeBracketWithIndex = enType; - SetBaseType(TypeElement::BracketWithIndex); } CElementBracketWithIndex::~CElementBracketWithIndex() { @@ -2443,9 +2514,9 @@ namespace StarMath m_pLeftArg->SetAttribute(pAttribute); } //class methods CElementGrade - CElementGrade::CElementGrade(): m_pValueFrom(nullptr), m_pValueGrade(nullptr), m_pValueTo(nullptr) + CElementGrade::CElementGrade() + :CElement(TypeElement::Grade),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) { - SetBaseType(TypeElement::Grade); } CElementGrade::~CElementGrade() { @@ -2655,10 +2726,9 @@ namespace StarMath m_pSecondArgument->SetAttribute(pAttribute); } //class CElementDiacriticalMark - CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType):m_pValueMark(nullptr) + CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType) + :CElement(TypeElement::Mark),m_pValueMark(nullptr),m_enTypeMark(enType) { - m_enTypeMark = enType; - SetBaseType(TypeElement::Mark); } CElementDiacriticalMark::~CElementDiacriticalMark() { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index b728a1be701..215a5e2e0a4 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -5,12 +5,22 @@ #include #include #include +#include #include "../../../../DesktopEditor/xml/include/xmlwriter.h" namespace StarMath { class CStarMathReader; + struct TBaseAttribute + { + int base_font_size = 12; + std::wstring base_font_name; + int base_alignment = 1; + bool base_font_bold = false; + bool base_font_italic = false; + }; + class CAttribute { public: @@ -63,17 +73,22 @@ namespace StarMath bool EmptyString(); void SetAttribute(CAttribute* pAttribute); CAttribute* GetAttribute(); + void SetBaseAttribute(const TBaseAttribute* pAttribute); + CAttribute* GetBaseAttribute(); //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); void FindingTheEndOfParentheses(); + void IteratorNullification(); private: bool CheckTokenForGetElement(const wchar_t& cToken); bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); - std::wstring::iterator m_itStart,m_itEnd,m_itEndBracket; + std::wstring::iterator m_itStart,m_itEnd; TypeElement m_enGlobalType; TypeElement m_enUnderType; std::wstring m_wsToken; CAttribute* m_pAttribute; + CAttribute* m_pBaseAttribute; + std::stack m_stBracket; }; class CElement @@ -203,9 +218,9 @@ namespace StarMath virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); static TypeElement GetBracketOpen(const std::wstring& wsToken); + static TypeElement GetBracketClose(const std::wstring& wsToken); std::vector GetBracketValue(); private: - TypeElement GetBracketClose(const std::wstring& wsToken); void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override;// @@ -341,7 +356,7 @@ namespace StarMath class CParserStarMathString { public: - std::vector Parse(std::wstring& wsParseString); + std::vector Parse(std::wstring& wsParseString, const TBaseAttribute* pBaseAttribute = nullptr); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); From 7333e6943bb02eceab285501ef2a28c071d95136 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 26 Jan 2024 19:18:28 +0500 Subject: [PATCH 255/794] Fix bug #65611 --- OdfFile/Reader/Converter/pptx_slide_context.cpp | 13 +++++++++++-- OdfFile/Reader/Format/draw_shapes_pptx.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_slide_context.cpp b/OdfFile/Reader/Converter/pptx_slide_context.cpp index 3a9d5f1845e..cc9248c690c 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.cpp +++ b/OdfFile/Reader/Converter/pptx_slide_context.cpp @@ -170,6 +170,7 @@ class pptx_slide_context::Impl private: void process_common_properties(drawing_object_description& obj, _pptx_drawing & drawing); + void process_crop(const drawing_object_description& obj, _pptx_drawing& drawing, const std::wstring& filename); void process_shape (drawing_object_description& obj, _pptx_drawing & drawing); void process_image (drawing_object_description& obj, _pptx_drawing & drawing); @@ -688,8 +689,7 @@ void pptx_slide_context::Impl::process_image(drawing_object_description& obj, _p } std::wstring fileName = odfPacket_ + FILE_SEPARATOR_STR + obj.xlink_href_; - drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, fileName, drawing.fill.bitmap->cropRect, get_mediaitems()->applicationFonts()); - drawing.fill.bitmap->bStretch = true; + process_crop(obj, drawing, fileName); if ((sColorMode) && (*sColorMode == L"greyscale")) drawing.fill.bitmap->luminance = true; @@ -748,6 +748,9 @@ void pptx_slide_context::Impl::process_shape(drawing_object_description & obj, _ drawing.fill.bitmap->rId = get_mediaitems()->add_or_find(drawing.fill.bitmap->xlink_href_, typeImage, isMediaInternal, ref, oox::document_place); add_additional_rels(isMediaInternal, drawing.fill.bitmap->rId, ref, typeImage); + + std::wstring fileName = odfPacket_ + FILE_SEPARATOR_STR + drawing.fill.bitmap->xlink_href_; + process_crop(obj, drawing, fileName); } std::wstring rId = get_mediaitems()->add_or_find(L"", typeShape, isMediaInternal, ref, oox::document_place); @@ -845,6 +848,12 @@ void pptx_slide_context::Impl::process_common_properties(drawing_object_descript drawing.fill = pic.fill_; } +void pptx_slide_context::Impl::process_crop(const drawing_object_description& obj, _pptx_drawing& drawing, const std::wstring& filename) +{ + drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, filename, drawing.fill.bitmap->cropRect, get_mediaitems()->applicationFonts()); + drawing.fill.bitmap->bStretch = true; +} + void pptx_slide_context::dump_rels(rels & Rels) { impl_->get_drawings()->dump_rels(Rels); diff --git a/OdfFile/Reader/Format/draw_shapes_pptx.cpp b/OdfFile/Reader/Format/draw_shapes_pptx.cpp index 5a289712598..e3e2cd70bad 100644 --- a/OdfFile/Reader/Format/draw_shapes_pptx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_pptx.cpp @@ -139,6 +139,12 @@ void draw_shape::common_pptx_convert(oox::pptx_conversion_context & Context) { properties->apply_to(Context.get_slide_context().get_properties()); Compute_GraphicFill(properties->common_draw_fill_attlist_, properties->style_background_image_, Context.root(), fill); + + if (properties->fo_clip_) + { + std::wstring strRectClip = properties->fo_clip_.get(); + Context.get_slide_context().set_clipping(strRectClip.substr(5, strRectClip.length() - 6)); + } } for (size_t i = 0; i < additional_.size(); i++) { From 7d3940a3828a250eb9fcbc6e4e39cb24099991eb Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 29 Jan 2024 15:04:03 +0600 Subject: [PATCH 256/794] Fix area ptg conversion --- .../Format/Logic/Biff_structures/CellRangeRef.h | 11 ++++------- .../Format/Logic/Biff_structures/StringPtgParser.cpp | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h index 31e1652c5b3..a1ecbcab552 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h @@ -185,15 +185,12 @@ class CellRangeRef_T : public CellRangeRef void save(CFRecord& record) override { - RwType rwFirst; - RwType rwLast; - ColType colFirst; - ColType colLast; + RwType rwFirst = rowFirst; + RwType rwLast = rowLast; + ColType colFirst = 0; + ColType colLast = 0; auto version = record.getGlobalWorkbookInfo()->Version; - - rwFirst = rowFirst; - rwLast = rowLast; if (version < 0x0800) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 08f56fb64e4..55d5a2c65a8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -301,7 +301,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(SyntaxPtg::extract_PtgArea(it, itEnd, operand_str)) { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgArea3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgArea3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRef(it, itEnd, operand_str)) { @@ -340,7 +340,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else { - found_operand = OperandPtgPtr(new PtgArea(operand_str, OperandPtg::ptg_VALUE)); + found_operand = OperandPtgPtr(new PtgArea(operand_str, OperandPtg::ptg_REFERENCE)); } rgce.addPtg(found_operand); } From 71fc5323c72a4671eb47c43e16ed5ecef74ab678 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 29 Jan 2024 15:04:34 +0600 Subject: [PATCH 257/794] Fix formula value conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 37 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 306c10285ef..f11b816b973 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1799,7 +1799,7 @@ namespace OOX { m_oType.Init(); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); - if(m_oValue.IsInit() && !m_oFormula.IsInit()) + if(m_oValue.IsInit()) { if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); @@ -1869,23 +1869,46 @@ namespace OOX { if(!isReal) { - auto pCellRk = new(XLSB::CellRk); - pCellRk->value.fInt = 1; - pCellRk->value.fX100 = 0; - pCellRk->value.num = intCache; + if(!m_oFormula.IsInit()) + { + auto pCellRk = new(XLSB::CellRk); + pCellRk->value.fInt = 1; + pCellRk->value.fX100 = 0; + pCellRk->value.num = intCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + } + else + { + auto pCellRk = new(XLSB::FmlaNum); + + pCellRk->value.data.value = intCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + } + - oCell = &pCellRk->cell; - pSource = pCellRk; } else if(isReal) { + if(!m_oFormula.IsInit()) + { auto pCellReal = new(XLSB::CellReal); pCellReal->value.data.value = realCache; oCell = &pCellReal->cell; pSource = pCellReal; + } + else + { + auto pCellRk = new(XLSB::FmlaNum); + + pCellRk->value.data.value = realCache; + oCell = &pCellRk->cell; + pSource = pCellRk; + } } } break; From efbb6f38a0cf14246f30009dbbd88ce0776b8872 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 29 Jan 2024 20:05:20 +0600 Subject: [PATCH 258/794] Fix cell protection --- OOXML/XlsxFormat/Styles/Xfs.cpp | 11 +++--- .../Worksheets/WorksheetChildOther.cpp | 36 ++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 9002b31d8d8..f771a556c5c 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -281,8 +281,12 @@ namespace OOX auto ptr = static_cast(obj.get()); if(m_oHidden.IsInit()) ptr->fHidden = m_oHidden->GetValue(); + else + ptr->fHidden = false; if(m_oLocked.IsInit()) ptr->fLocked = m_oLocked->GetValue(); + else + ptr->fLocked = true; } EElementType CProtection::getType () const { @@ -406,10 +410,9 @@ namespace OOX ptr->alc = 0; ptr->alcV = 2; } - if(m_oProtection.IsInit()) - m_oProtection->toBin(objectPtr); - - + if(!m_oProtection.IsInit()) + m_oProtection.Init(); + m_oProtection->toBin(objectPtr); if(m_oApplyAlignment.IsInit()) ptr->fAtrAlc = m_oApplyAlignment->GetValue(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 705b931460d..74f7f549ef9 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1414,7 +1414,7 @@ namespace OOX if (m_oShowZeros.IsInit()) pWsView->fDspZerosRt = m_oShowZeros->m_eValue; else - pWsView->fDspZerosRt = false; + pWsView->fDspZerosRt = true; if (m_oTabSelected.IsInit()) pWsView->fSelected = m_oTabSelected->m_eValue; else @@ -2595,54 +2595,88 @@ namespace OOX if (m_oPassword.IsInit()) ptr->protpwd = std::stoul(m_oPassword.get()); + else + ptr->protpwd = 0; if (m_oAutoFilter.IsInit()) ptr->fAutoFilter = m_oAutoFilter->GetValue(); + else + ptr->fAutoFilter = false; if (m_oDeleteColumns.IsInit()) ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + else + ptr->fDeleteColumns= false; if (m_oDeleteRows.IsInit()) ptr->fDeleteRows = m_oDeleteRows->GetValue(); + else + ptr->fDeleteRows = false; if (m_oFormatCells.IsInit()) ptr->fFormatCells = m_oFormatCells->GetValue(); + else + ptr->fFormatCells = false; if (m_oFormatColumns.IsInit()) ptr->fFormatColumns = m_oFormatColumns->GetValue(); + else + ptr->fFormatColumns = false; if (m_oFormatRows.IsInit()) ptr->fFormatRows = m_oFormatRows->GetValue(); + else + ptr->fFormatRows = false; if (m_oInsertColumns.IsInit()) ptr->fInsertColumns = m_oInsertColumns->GetValue(); + else + ptr->fInsertColumns = false; if (m_oInsertHyperlinks.IsInit()) ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + else + ptr->fInsertHyperlinks = false; if (m_oInsertRows.IsInit()) ptr->fInsertRows = m_oInsertRows->GetValue(); + else + ptr->fInsertRows = false; if (m_oObjects.IsInit()) ptr->fObjects = m_oObjects->GetValue(); + else + ptr->fObjects = false; if (m_oPivotTables.IsInit()) ptr->fPivotTables = m_oPivotTables->GetValue(); + else + ptr->fPivotTables = false; if (m_oScenarios.IsInit()) ptr->fScenarios = m_oScenarios->GetValue(); + else + ptr->fScenarios = false; if (m_oSelectLockedCells.IsInit()) ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + else + ptr->fSelLockedCells = true; if (m_oSelectUnlockedCells.IsInit()) ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + else + ptr->fSelUnlockedCells = true; if (m_oSheet.IsInit()) ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fLocked = false; if (m_oSort.IsInit()) ptr->fSort = m_oSort->GetValue(); + else + ptr->fSort = false; return castedPtr; } From 278d6294188f819794b287648f5304c4add6582c Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 30 Jan 2024 11:54:32 +0300 Subject: [PATCH 259/794] . --- MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp | 10 ++++++++-- OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp | 10 +++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp index 07b74b285db..9c0b90f0936 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_sheet_context.cpp @@ -47,8 +47,14 @@ table_state::table_state(xlsx_conversion_context & Context) : drawing_context_(C table_state_ptr & xlsx_sheet_context::state() { - if (tables_state_.empty()) return table_state_ptr(); - return tables_state_.back(); + if (false == tables_state_.empty()) + { + return tables_state_.back(); + } + else + { + throw; + } } xlsx_sheet_context::xlsx_sheet_context(xlsx_conversion_context & Context) : context_(Context) diff --git a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp index ce140704c10..e02622249f0 100644 --- a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp +++ b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp @@ -657,11 +657,11 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" { m_title = oReader; } - //else if(_T("numFmt") == sName) - //{ - // m_numFmt = new CT_NumFmt; - // m_numFmt->fromXML(oReader); - //} + else if(_T("numFmt") == sName) + { + m_numFmt = new CNumberFormat; + m_numFmt->fromXML(oReader); + } else if(_T("majorTickMark") == sName) { m_majorTickMarks = new CTickMarks; From d4f4f4d500c09a2502a747b7adca8ed8cf245840 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 30 Jan 2024 15:00:13 +0600 Subject: [PATCH 260/794] Fix whitespace showing in worksheet --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 74f7f549ef9..3e40ff86fd4 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1408,7 +1408,7 @@ namespace OOX else pWsView->fDspRuler = false; if (m_oShowWhiteSpace.IsInit()) - pWsView->fWhitespaceHidden = m_oShowWhiteSpace->m_eValue; + pWsView->fWhitespaceHidden = !m_oShowWhiteSpace->m_eValue; else pWsView->fWhitespaceHidden = false; if (m_oShowZeros.IsInit()) From 79bb09f2c23e28c2e4115e0b7f4f26e802ded7af Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 31 Jan 2024 19:06:37 +0500 Subject: [PATCH 261/794] Fix odf tests --- .../Converter/pptx_conversion_context.cpp | 1 + OdfFile/Reader/Format/draw_page.cpp | 1 - OdfFile/Test/audio.cpp | 32 ++++++----- OdfFile/Test/common.cpp | 9 ++- OdfFile/Test/entrance.cpp | 12 ++-- OdfFile/Test/interactions.cpp | 56 +++++++++++++------ 6 files changed, 68 insertions(+), 43 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_conversion_context.cpp b/OdfFile/Reader/Converter/pptx_conversion_context.cpp index cd06a9bd623..f857f0e1d08 100644 --- a/OdfFile/Reader/Converter/pptx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/pptx_conversion_context.cpp @@ -461,6 +461,7 @@ const std::vector& pptx_conversion_context::get_page_names() const { create_new_slide(pageName); get_slide_context().start_slide();//pageName, pageStyleName); + get_slide_context().get_animation_context().clear(); current_master_page_name_ = pageMasterName; current_layout_page_name_ = pageLayoutName; diff --git a/OdfFile/Reader/Format/draw_page.cpp b/OdfFile/Reader/Format/draw_page.cpp index 12fe1fecaba..ac0ab285074 100644 --- a/OdfFile/Reader/Format/draw_page.cpp +++ b/OdfFile/Reader/Format/draw_page.cpp @@ -207,7 +207,6 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) } Context.end_page(); - Context.get_slide_context().get_animation_context().clear(); if (presentation_notes_) { diff --git a/OdfFile/Test/audio.cpp b/OdfFile/Test/audio.cpp index 0152443eeb2..b7df1b30d12 100644 --- a/OdfFile/Test/audio.cpp +++ b/OdfFile/Test/audio.cpp @@ -104,36 +104,40 @@ const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& OD return actions; } -TEST_F(ODP2OOX_AnimationAudioTest, r_embed_id) +TEST_F(ODP2OOX_AnimationAudioTest, set) { using namespace cpdoccore::oox; const auto& mainArray = GetMainSequenceArray(); ASSERT_GE(mainArray.size(), 1); const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; - ASSERT_EQ(actions.size(), 4); - const auto audio = dynamic_cast(actions[3].get()); ; - ASSERT_NE(audio, nullptr); - - const std::wstring rIdExp = L"aId1"; - - EXPECT_EQ(audio->RId.value(), rIdExp); + ASSERT_EQ(actions.size(), 3); + const auto set = dynamic_cast(actions[0].get()); + ASSERT_NE(set, nullptr); } -TEST_F(ODP2OOX_AnimationAudioTest, name) +TEST_F(ODP2OOX_AnimationAudioTest, anim_1) { using namespace cpdoccore::oox; const auto& mainArray = GetMainSequenceArray(); ASSERT_GE(mainArray.size(), 1); const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; - ASSERT_EQ(actions.size(), 4); - const auto audio = dynamic_cast(actions[3].get()); ; - ASSERT_NE(audio, nullptr); + ASSERT_EQ(actions.size(), 3); + const auto anim = dynamic_cast(actions[1].get()); + ASSERT_NE(anim, nullptr); +} - const std::wstring nameExp = L"apert.wav"; +TEST_F(ODP2OOX_AnimationAudioTest, anim_2) +{ + using namespace cpdoccore::oox; - EXPECT_EQ(audio->Name.value(), nameExp); + const auto& mainArray = GetMainSequenceArray(); + ASSERT_GE(mainArray.size(), 1); + const auto& actions = GetInnermostPar(mainArray[0])->AnimationActionArray; + ASSERT_EQ(actions.size(), 3); + const auto anim = dynamic_cast(actions[2].get()); + ASSERT_NE(anim, nullptr); } ////////////////////////////////////////////////////////////////////////// diff --git a/OdfFile/Test/common.cpp b/OdfFile/Test/common.cpp index 42da3e35e8d..c62de29df65 100644 --- a/OdfFile/Test/common.cpp +++ b/OdfFile/Test/common.cpp @@ -191,7 +191,10 @@ const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnerPar(const if (!par) return nullptr; - const anim_par* inner_par = dynamic_cast(par->anim_par_.get()); + if (par->anim_par_.size() == 0) + return nullptr; + + const anim_par* inner_par = dynamic_cast(par->anim_par_[0].get()); if (!inner_par) return nullptr; @@ -208,9 +211,9 @@ const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnermostPar(co const anim_par* innermost = GetInnerPar(par); - while (innermost->anim_par_) + while (innermost->anim_par_.size()) { - innermost = dynamic_cast(innermost->anim_par_.get()); + innermost = dynamic_cast(innermost->anim_par_[0].get()); if (!innermost) return nullptr; } diff --git a/OdfFile/Test/entrance.cpp b/OdfFile/Test/entrance.cpp index ac0dd1cbf48..75001e91cb3 100644 --- a/OdfFile/Test/entrance.cpp +++ b/OdfFile/Test/entrance.cpp @@ -432,8 +432,8 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_key_point const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast(actions[1].get()); std::vector keypointsExp; - keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"#ppt_x", boost::none)); - keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"#ppt_x", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"ppt_x", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"ppt_x", boost::none)); EXPECT_EQ(animate1->KeypointArray->size(), keypointsExp.size()); for (size_t i = 0; i < animate1->KeypointArray->size(); i++) @@ -513,8 +513,8 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_key_point const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast(actions[2].get()); std::vector keypointsExp; - keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"1+#ppt_h/2", boost::none)); - keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"#ppt_y", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(0, L"1+ppt_h/2", boost::none)); + keypointsExp.push_back(pptx_animation_context::Impl::_anim::_keypoint(100000, L"ppt_y", boost::none)); EXPECT_EQ(animate2->KeypointArray->size(), keypointsExp.size()); for (size_t i = 0; i < animate2->KeypointArray->size(); i++) @@ -576,9 +576,7 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_trans const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast(actions[1].get()); - const std::wstring transitionExp = L"in"; - - EXPECT_EQ(animEffect->Transition.value(), transitionExp); + EXPECT_FALSE(animEffect->Transition.has_value()); } TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_duration) diff --git a/OdfFile/Test/interactions.cpp b/OdfFile/Test/interactions.cpp index 16860f0de95..8247f9b8569 100644 --- a/OdfFile/Test/interactions.cpp +++ b/OdfFile/Test/interactions.cpp @@ -197,49 +197,69 @@ TEST_F(ODP2OOX_AnimationPlayAudioTest, rels_size) ASSERT_NE(mConversionContext, nullptr); auto rels_ = mConversionContext->current_slide().Rels().relationships(); - const size_t relsSizeExp = 3; + const size_t relsSizeExp = 2; - EXPECT_EQ(rels_.size(), 3); + EXPECT_EQ(rels_.size(), relsSizeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_id) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_type) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring idExp = L"hId1"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"; - EXPECT_EQ(audioRel.id(), idExp); + EXPECT_EQ(slideRel.type(), typeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_type) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetExp = L"../slideLayouts/slideLayout1.xml"; - EXPECT_EQ(audioRel.type(), typeExp); + EXPECT_EQ(slideRel.target(), targetExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_target) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target_mode) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring targetExp = L"../../../../X2tConverter/test/win32Test/Res/media_example.wav"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetModeExp = L""; - EXPECT_EQ(audioRel.target(), targetExp); + EXPECT_EQ(slideRel.target_mode(), targetModeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_target_mode) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_type) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring targetModeExp = L"External"; + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"; + + EXPECT_EQ(notesRel.type(), typeExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_target) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetExp = L"../notesSlides/notesSlide1.xml"; + + EXPECT_EQ(notesRel.target(), targetExp); +} + +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_target_mode) +{ + ASSERT_NE(mConversionContext, nullptr); + + auto notesRel = mConversionContext->current_slide().Rels().relationships()[1]; + const std::wstring targetModeExp = L""; - EXPECT_EQ(audioRel.target_mode(), targetModeExp); + EXPECT_EQ(notesRel.target_mode(), targetModeExp); } ////////////////////////////////////////////////////////////////////////// From 00671ffdd65865ca989246fa94a523b7dcc4d2ac Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 2 Feb 2024 14:47:45 +0600 Subject: [PATCH 262/794] Fix shared formulas conversion --- .../Format/Logic/Biff_structures/PtgRef.h | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 94 +++++++++++++------ OOXML/XlsxFormat/Worksheets/SheetData.h | 9 +- 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h index a10b730b563..fae265d3640 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h @@ -56,7 +56,7 @@ class PtgRef: public OperandPtg static const unsigned short fixed_id = 0x04; -private: + RgceLoc loc; XLSB::RgceLoc loc_xlsb; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index f11b816b973..468fd8c6cca 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -62,6 +62,8 @@ #include "../../XlsbFormat/Biff12_records/Cell.h" #include "../../XlsbFormat/Biff12_records/Fmla.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" #include #include @@ -1757,7 +1759,7 @@ namespace OOX oStream.Seek(nEnd); } - XLS::BaseObjectPtr CCell::toBin() + XLS::BaseObjectPtr CCell::toBin(sharedFormula &sharedFormulas) { std::vector shared_formulas_locations_ref; auto ptr(new XLSB::CELL(0, shared_formulas_locations_ref)); @@ -2120,45 +2122,76 @@ namespace OOX } else { - std::vector ref; - pFMLACELL = new XLSB::FMLACELL(0, ref); - - if(m_oFormula->m_oRef.IsInit()) + std::vector refs; + pFMLACELL = new XLSB::FMLACELL(0, refs); + + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeNormal) { - ref.push_back(m_oFormula->m_oRef.get()); + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + m_oFormula->toBin(pFMLACELL->m_source); } - /*if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeShared) + if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeShared) { - - pSHRFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; - pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; - pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; - if(m_oFormula->m_oSi.IsInit()) - pFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); - pFMLACELL->isShared = true; - ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; - else + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; + ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + + if(!m_oFormula->m_sText.empty()) + { + m_oFormula->toBin(pFMLACELL->m_source); + std::wstring wstrRef(m_oRef.get().begin(), m_oRef.get().end()); + XLS::CellRef ref(wstrRef); + sharedFormulas.shrFmla.push_back(std::make_pair(ref, m_oFormula->m_sText)); + + } + else if(m_oFormula->m_oSi.IsInit() && sharedFormulas.shrFmla.size() > m_oFormula->m_oSi->GetValue() ) { - if(m_oFormula->m_oSi.IsInit()) + + auto fmla = dynamic_cast(pSource); + std::wstring wstrRef(m_oRef.get().begin(), m_oRef.get().end()); + XLS::CellRef ref(wstrRef); + auto dataPair = sharedFormulas.shrFmla[m_oFormula->m_oSi->GetValue()]; + auto ref1 = dataPair.first; + int coldiff = 0; + if(ref1.colRelative) + coldiff = ref.column - dataPair.first.column; + int rowdiff = 0; + if(ref1.rowRelative) + rowdiff = ref.row - dataPair.first.row; + fmla->formula = dataPair.second; + if(rowdiff || coldiff) { - pSHRFMLACELL->m_sharedIndex = m_oFormula->m_oSi->GetValue(); - pSHRFMLACELL->m_source = m_oFormula->toBin(); + for(auto i:fmla->formula.rgce.sequence) + { + if(i->ptg_id.is_initialized() && i->ptg_id.get() == 37) + { + auto area(static_cast(i.get())); + area->areaXlsb.columnFirst += coldiff; + area->areaXlsb.columnLast += coldiff; + area->areaXlsb.rowFirst += rowdiff; + area->areaXlsb.rowLast += rowdiff; + } + else if(i->ptg_id.is_initialized() && i->ptg_id.get() == 36) + { + auto area(static_cast(i.get())); + area->loc_xlsb.column += coldiff; + area->loc_xlsb.row += rowdiff; + } + } } + } - }*/ - else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeNormal) + } + else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) { - + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; m_oFormula->toBin(pFMLACELL->m_source); } - /*else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) - { - pSHRFMLACELL->m_source = m_oFormula->toBin(pSHRFMLACELL); - }*/ } } if(m_oCol.IsInit()) @@ -2801,7 +2834,7 @@ namespace OOX m_arrItems.push_back(pCell); }*/ } - XLS::BaseObjectPtr CRow::toBin() + XLS::BaseObjectPtr CRow::toBin(sharedFormula &sharedFormulas) { std::vector shared_formulas_locations_ref; auto ptr(new XLSB::Parenthesis_CELLTABLE(shared_formulas_locations_ref)); @@ -2809,7 +2842,7 @@ namespace OOX for(auto it = m_arrItems.begin(); it != m_arrItems.end();) { - ptr->m_arCELL.push_back((*it)->toBin()); + ptr->m_arCELL.push_back((*it)->toBin(sharedFormulas)); it = m_arrItems.erase(it); } @@ -3422,10 +3455,11 @@ namespace OOX { auto ptr(new XLSB::CELLTABLE); XLS::BaseObjectPtr objectPtr(ptr); - + sharedFormula fmlaStruct; + for(auto it = m_arrItems.begin(); it != m_arrItems.end();) { - ptr->m_arParenthesis_CELLTABLE.push_back((*it)->toBin()); + ptr->m_arParenthesis_CELLTABLE.push_back((*it)->toBin(fmlaStruct)); it = m_arrItems.erase(it); } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 976d88ca4a7..441c4b9766e 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -33,6 +33,7 @@ #include "../SharedStrings/Si.h" #include "../../Common/SimpleTypes_Shared.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h" namespace NSBinPptxRW { @@ -125,6 +126,10 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; + struct sharedFormula + { + std::vector> shrFmla; + }; class CFormula : public WritingElement { public: @@ -216,7 +221,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, _UINT32 nRow); void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; @@ -285,7 +290,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType); void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const; void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; From aa8a0cfbc24539196f8fb43c7e346e9eca734653 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 2 Feb 2024 23:18:05 +0600 Subject: [PATCH 263/794] FIx array formula conversion --- .../Format/Logic/Biff_structures/PtgExp.h | 1 - .../Logic/Biff_structures/PtgExtraCol.h | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 110 ++++++++++++++---- OOXML/XlsxFormat/Worksheets/SheetData.h | 2 + 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h index ef52ce58607..affb820df73 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h @@ -53,7 +53,6 @@ class PtgExp : public Ptg static const unsigned short fixed_id = 0x01; -private: unsigned short row; unsigned short col; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h index 7f9325f4a56..64cce73f710 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h @@ -52,7 +52,7 @@ class PtgExtraCol : public Ptg // No type info const std::wstring toString() const; -private: + _INT32 col; }; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 468fd8c6cca..19b63e487ce 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -64,6 +64,8 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h" #include #include @@ -1111,6 +1113,17 @@ namespace OOX { auto formula = dynamic_cast(obj.get()); formula->formula = m_sText; + for(auto i:formula->formula.rgce.sequence) + { + if(i->ptg_id.get() == 37) + { + i->ptg_id = 101; + } + if(i->ptg_id.get() == 36) + { + i->ptg_id = 100; + } + } if(m_oAca.IsInit()) { formula->fAlwaysCalc = m_oAca->GetValue(); @@ -1376,6 +1389,18 @@ namespace OOX } } } + bool CCell::checkArrayCell(XLS::CellRef &cellref, const sharedFormula& ArrFmlas) + { + for(auto i:ArrFmlas.arrfmla) + { + if(i.first.inRange(cellref)) + { + cellref = i.second; + return true; + } + } + return false; + } void CCell::After2003Read() { CXlsxFlat* xlsx_flat = dynamic_cast(m_pMainDocument); @@ -1797,6 +1822,21 @@ namespace OOX _INT32 intCache = 0; double realCache = 0; + XLS::CellRef cellref(m_oRow.get() -1, m_oCol.get(), 0, 0); + auto sourceCellRef = cellref; + + if(!sharedFormulas.arrfmla.empty()) + { + if(checkArrayCell(sourceCellRef, sharedFormulas)) + { + if(!m_oFormula.IsInit()) + { + m_oFormula.Init(); + m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeArray; + } + } + } + if(!m_oType.IsInit()) { m_oType.Init(); @@ -2141,25 +2181,23 @@ namespace OOX if(!m_oFormula->m_sText.empty()) { m_oFormula->toBin(pFMLACELL->m_source); - std::wstring wstrRef(m_oRef.get().begin(), m_oRef.get().end()); - XLS::CellRef ref(wstrRef); - sharedFormulas.shrFmla.push_back(std::make_pair(ref, m_oFormula->m_sText)); + + sharedFormulas.shrFmla.push_back(std::make_pair(cellref, m_oFormula->m_sText)); } else if(m_oFormula->m_oSi.IsInit() && sharedFormulas.shrFmla.size() > m_oFormula->m_oSi->GetValue() ) { auto fmla = dynamic_cast(pSource); - std::wstring wstrRef(m_oRef.get().begin(), m_oRef.get().end()); - XLS::CellRef ref(wstrRef); + auto dataPair = sharedFormulas.shrFmla[m_oFormula->m_oSi->GetValue()]; - auto ref1 = dataPair.first; + sourceCellRef = dataPair.first; int coldiff = 0; - if(ref1.colRelative) - coldiff = ref.column - dataPair.first.column; + if(sourceCellRef.colRelative) + coldiff = cellref.column - dataPair.first.column; int rowdiff = 0; - if(ref1.rowRelative) - rowdiff = ref.row - dataPair.first.row; + if(sourceCellRef.rowRelative) + rowdiff = cellref.row - dataPair.first.row; fmla->formula = dataPair.second; if(rowdiff || coldiff) { @@ -2186,10 +2224,40 @@ namespace OOX } else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) { - m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; - ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, refs); + ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; - m_oFormula->toBin(pFMLACELL->m_source); + if(!m_oFormula->m_sText.empty()) + { + auto arrfmla(new XLSB::ArrFmla(XLS::CellRef())); + pSHRFMLACELL->m_source = XLS::BaseObjectPtr{arrfmla}; + m_oFormula->toBin(pSHRFMLACELL->m_source); + + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = cellref.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = cellref.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + if(m_oFormula->m_oRef.IsInit()) + { + XLS::CellRangeRef arrRange(m_oFormula->m_oRef.get()); + sharedFormulas.arrfmla.push_back(std::make_pair(arrRange, cellref)); + } + } + else + { + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = sourceCellRef.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = sourceCellRef.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + } + } } @@ -2888,14 +2956,14 @@ namespace OOX hdrPtr->fExAsc = m_oThickTop->GetValue(); } - if(m_oDyDescent.IsInit()) - { - auto ptrAccel(new XLSB::ACCELLTABLE); - ptr->m_ACCELLTABLE = XLS::BaseObjectPtr{ptrAccel}; - auto ptrdescent(new XLSB::RwDescent); - ptrAccel->m_BrtRwDescent = XLS::BaseObjectPtr{ptrdescent}; - ptrdescent->dyDescent = m_oDyDescent->GetValue(); - } + //if(m_oDyDescent.IsInit()) + //{ + //auto ptrAccel(new XLSB::ACCELLTABLE); + //ptr->m_ACCELLTABLE = XLS::BaseObjectPtr{ptrAccel}; + //auto ptrdescent(new XLSB::RwDescent); + // ptrAccel->m_BrtRwDescent = XLS::BaseObjectPtr{ptrdescent}; + // ptrdescent->dyDescent = m_oDyDescent->GetValue(); + //} return objectPtr; } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 441c4b9766e..1b18f455f17 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -129,6 +129,7 @@ namespace OOX struct sharedFormula { std::vector> shrFmla; + std::vector> arrfmla; }; class CFormula : public WritingElement { @@ -241,6 +242,7 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadComment(XmlUtils::CXmlLiteReader& oReader, CCommentItem* pComment); + bool checkArrayCell(XLS::CellRef &cellref, const sharedFormula& ArrFmlas); void AfterRead(); //----------- 2003 From 84f58b7b08a968be543a695902ff67d33fad0e45 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 5 Feb 2024 15:41:14 +0600 Subject: [PATCH 264/794] Add row col initialization check --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 19b63e487ce..7d79964207a 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1822,7 +1822,16 @@ namespace OOX _INT32 intCache = 0; double realCache = 0; - XLS::CellRef cellref(m_oRow.get() -1, m_oCol.get(), 0, 0); + XLS::CellRef cellref; + if(m_oRow.IsInit() && m_oCol.IsInit()) + cellref = XLS::CellRef(m_oRow.get() -1, m_oCol.get(), 0, 0); + else if(m_oRef.IsInit()) + { + std::wstring wstringRef(m_oRef.get().begin(), m_oRef.get().end()); + cellref = XLS::CellRef(wstringRef); + } + else + cellref = XLS::CellRef(0, 0, 0, 0); auto sourceCellRef = cellref; if(!sharedFormulas.arrfmla.empty()) @@ -2262,16 +2271,8 @@ namespace OOX } } - if(m_oCol.IsInit()) - oCell->column = m_oCol.get(); - else if(m_oRef.IsInit()) - { - std::wstring strRef(m_oRef.get().begin(), m_oRef.get().end()); - XLS::CellRef reference(strRef); - oCell->column = reference.getColumn(); - } - else - oCell->column = 0; + + oCell->column = cellref.column; if(m_oShowPhonetic.IsInit()) oCell->fPhShow = m_oShowPhonetic->GetValue(); else From b36c1ae9e70b5bc076b6800b3fcdbf2bf70a490e Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Mon, 5 Feb 2024 18:05:55 +0300 Subject: [PATCH 265/794] Fix bug #59451 --- Common/3dParty/html/htmltoxhtml.h | 4 ++-- HtmlFile2/HtmlFile2.pro | 3 +-- HtmlFile2/htmlfile2.cpp | 16 +++++++++++----- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 6076fa60042..04cb2713f4f 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -40,7 +40,7 @@ static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) // Распознование кодировки if (bNeedConvert) { - std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", "\"", "\""); + std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"\"", "="}, {"\"", " "}, 0); if (sEncoding.empty()) sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", "\"", "\""); @@ -360,7 +360,7 @@ static std::string mhtTohtml(std::string& sFileContent) // Цикл по boundary while(nFound != std::string::npos) { - nFoundEnd = sFileContent.find(sBoundary + "--", nFound + nBoundaryLength); + nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength); if(nFoundEnd == std::string::npos) break; diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index 96ea48deafd..a246410bc21 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -27,8 +27,7 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network) -SOURCES += htmlfile2.cpp \ - ./src/StringFinder.cpp +SOURCES += htmlfile2.cpp HEADERS += htmlfile2.h \ ./src/StringFinder.h diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 522426dc7fb..81b5df6b1d5 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -960,11 +960,11 @@ class CHtmlFile2_Private readStream(oXml, sSelectors, oTSR); } // Векторная картинка - else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) - { - wrP(oXml, sSelectors, oTS); - readSVG(oXml); - } +// else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) +// { +// wrP(oXml, sSelectors, oTS); +// readSVG(oXml); +// } else if(sName == L"input") readInput(oXml, sSelectors, oTS); // Игнорируются тэги выполняющие скрипт @@ -1100,9 +1100,15 @@ class CHtmlFile2_Private oTSP.sPStyle += L""; readStream(oXml, sSelectors, oTSP); } + else if (sName == L"xml") + { + sSelectors.pop_back(); + return; + } // Неизвестный тэг. Выделять ли его абзацем? else readStream(oXml, sSelectors, oTS); + readNote(oXml, sSelectors, sNote); sNote = L""; From 0d1e5198c45cf600f96bd3abf9b6765c5fcf5ece Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 5 Feb 2024 21:01:58 +0300 Subject: [PATCH 266/794] Converting lim families with upper and lower indexes. Converting csub and csup. Bug fixing.Code refactoring. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 50 ++- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 51 ++- .../StarMath2OOXML/cconversionsmtoooxml.h | 4 +- .../StarMath2OOXML/cstarmathpars.cpp | 383 +++++++++--------- .../Converter/StarMath2OOXML/cstarmathpars.h | 5 +- .../Converter/StarMath2OOXML/typeselements.h | 2 +- 6 files changed, 292 insertions(+), 203 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index b20ec93d2cd..5914ccfd953 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -990,7 +990,7 @@ TEST(SMConvectorTest,Example3) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"c=a2+b2"; + std::wstring wsXmlString =L"c=a2+b2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1054,15 +1054,45 @@ TEST(SMConvectorTest,Example10) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } -//TEST(SMConvectorTest,Example13) -//{ -// std::wstring wsString = L""; -// StarMath::CParserStarMathString oTemp; -// StarMath::CConversionSMtoOOXML oTest; -// oTest.StartConversion(oTemp.Parse(wsString)); -// std::wstring wsXmlString =L""; -// EXPECT_EQ(oTest.GetOOXML(),wsXmlString); -//} +TEST(SMConvectorTest,LimAndCsub) +{ + std::wstring wsString = L"{lim from 2 over 10 to 1 5} csub 244"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"lim21015244"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,LimSupAndCsup) +{ + std::wstring wsString = L"limsup from 10 to 2 csup 10 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"lim sup10210100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OverWithoutLeft) +{ + std::wstring wsString = L"over +- 2_10 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString =L"\u00B12105"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Newline) +{ + std::wstring wsString = L"2 over 3 newline 10 csup 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2323102"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} //TEST(SMConvectorTest,AttributeMatrix) //{ diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 627b7048c54..4c16e63b6c9 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -48,6 +48,10 @@ namespace StarMath { oTempElement->ConversionToOOXML(m_pXmlWrite); } EndConversion(); + NSFile::CFileBinary oFile; + oFile.CreateFileW(L"Test.txt"); + oFile.WriteStringUTF8(m_pXmlWrite->GetXmlString()); + oFile.CloseFile(); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { @@ -70,10 +74,19 @@ namespace StarMath { } else { + std::wstring wsNameFont = pAttribute->GetFontName(); pXmlWrite->WriteNodeBegin(L"w:rPr",false); pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + if(!wsNameFont.empty()) + { + pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); + pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); + } + else + { + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + } pXmlWrite->WriteNodeEnd(L"w",true,true); if(pAttribute->GetSize() == 0) { @@ -189,12 +202,23 @@ namespace StarMath { WriteCtrlPrNode(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } - void CConversionSMtoOOXML::BlockRecording(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) + void CConversionSMtoOOXML::WriteNodeConversion(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) { - pXmlWrite->WriteNodeBegin(wsNameBlock,false); if(pValueBlock != nullptr) + { + pXmlWrite->WriteNodeBegin(wsNameBlock,false); pValueBlock->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(wsNameBlock,false,false); + pXmlWrite->WriteNodeEnd(wsNameBlock,false,false); + } + else + { + pXmlWrite->WriteNodeBegin(wsNameBlock,true); + pXmlWrite->WriteNodeEnd(L"",true,true); + } +/* pXmlWrite->WriteNodeBegin(wsNameBlock,false); + if(pValueBlock != nullptr) + pValueBlock->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameBlock,false,false)*/; } std::wstring CConversionSMtoOOXML::GetOOXML() { @@ -369,5 +393,22 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); } + void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite,const std::wstring& wsNameNode,CElement* pValue, const TypeElement& enType,CAttribute* pAttribute,const std::wstring& wsName) + { + pXmlWrite->WriteNodeBegin(wsNameNode,false); + pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); + pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + WriteNodeConversion(L"m:lim",pValue,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameNode,false,false); + } + void CConversionSMtoOOXML::ElementConversion(XmlUtils::CXmlWriter *pXmlWrite, CElement *pElement) + { + if(pElement!= nullptr) + pElement->ConversionToOOXML(pXmlWrite); + } } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index b83ec64ab6d..75615850397 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -46,7 +46,7 @@ namespace StarMath { static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void BlockRecording(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); + static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute); static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute); static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); @@ -56,6 +56,8 @@ namespace StarMath { static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute); + static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper"); + static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); void EndConversion(); std::wstring GetOOXML(); private: diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index c2344dfe08a..786a4639a28 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -42,7 +42,14 @@ namespace StarMath pReader->SetBaseAttribute(pBaseAttribute); while(pReader->CheckIteratorPosition()) { - CElement* pTempElement = ParseElement(pReader); + CElement* pTempElement; + if(pReader->GetLocalType() == TypeElement::newline) + { + m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + pReader->ClearReader(); + } + else + pTempElement = ParseElement(pReader); if(nullptr == pTempElement) continue; if(!m_arEquation.empty() && CheckForLeftArgument(pTempElement->GetBaseType()) ) @@ -54,7 +61,14 @@ namespace StarMath } if(!pReader->EmptyString()) { - CElement* pTempElement = ParseElement(pReader); + CElement* pTempElement; + if(pReader->GetLocalType() == TypeElement::newline) + { + m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + pReader->ClearReader(); + } + else + pTempElement = ParseElement(pReader); if(nullptr != pTempElement) m_arEquation.push_back(pTempElement); } @@ -65,24 +79,23 @@ namespace StarMath { CElement* pElement; - if(pReader->EmptyString()) - { - pReader->GetToken(); - pReader->SetTypesToken(); - } + pReader->ReadingTheNextToken(); + + if(TypeElement::newline == pReader->GetLocalType()) + return nullptr; pElement = CElement::CreateElement(pReader); if(pElement != nullptr) { - if(pReader->GetBaseAttribute()!=nullptr) - pElement->SetBaseAttribute(pReader->GetBaseAttribute()); if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); pReader->ClearReader(); pElement->Parse(pReader); + if(pReader->GetBaseAttribute()!=nullptr) + pElement->SetBaseAttribute(pReader->GetBaseAttribute()); if(pElement->GetAttribute() != nullptr && TypeElement::Function != pElement->GetBaseType()) pElement->SetAttribute(pElement->GetAttribute()); return pElement; @@ -308,6 +321,10 @@ namespace StarMath break; } } + void CAttribute::SetFontName(const std::wstring &wsNameFont) + { + m_wsNameFont = wsNameFont; + } bool CAttribute::GetBold() { return m_bBold; @@ -328,6 +345,10 @@ namespace StarMath { return m_wsColor; } + const std::wstring& CAttribute::GetFontName() + { + return m_wsNameFont; + } unsigned int CAttribute::GetSize() { return m_iSize; @@ -392,6 +413,15 @@ namespace StarMath } case TypeElement::font: { + pReader->GetToken(); + if(pReader->GetString() == L"sans") + m_wsNameFont = L"Arial"; + else if(pReader->GetString() == L"serif") + m_wsNameFont = L"Times New Roman"; + else if(pReader->GetString() == L"fixed") + m_wsNameFont = L"Times New Roman"; + else + m_wsNameFont = pReader->GetString(); break; } default: @@ -618,8 +648,7 @@ namespace StarMath else { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); if((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { CElement* pBinOp = CParserStarMathString::ParseElement(pReader); @@ -630,72 +659,71 @@ namespace StarMath SetRightArg(pTempElement); } } - void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* oXmlWrite) + void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division || TypeElement::frac == m_enTypeBinOp) { - oXmlWrite->WriteNodeBegin(L"m:f",false); + pXmlWrite->WriteNodeBegin(L"m:f",false); if(m_enTypeBinOp == TypeElement::division) - CConversionSMtoOOXML::PropertiesMFPR(true,oXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute()); else - CConversionSMtoOOXML::PropertiesMFPR(false,oXmlWrite,GetAttribute()); - CConversionSMtoOOXML::BlockRecording(L"m:num",m_pLeftArgument,oXmlWrite); - CConversionSMtoOOXML::BlockRecording(L"m:den",m_pRightArgument,oXmlWrite); - oXmlWrite->WriteNodeEnd(L"m:f",false,false); - } - else //if(m_enTypeBinOp == TypeElement::plus ||m_enTypeBinOp == TypeElement::minus || m_enTypeBinOp == TypeElement::multipl || m_enTypeBinOp == TypeElement::cdot || m_enTypeBinOp == TypeElement::times || m_enTypeBinOp == TypeElement::div || m_enTypeBinOp == TypeElement::odivide || m_enTypeBinOp == TypeElement::oplus || m_enTypeBinOp == TypeElement::ominus || m_enTypeBinOp == TypeElement::odot || m_enTypeBinOp == TypeElement::otimes) - { - if(m_pLeftArgument!=nullptr) - m_pLeftArgument->ConversionToOOXML(oXmlWrite); - oXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(oXmlWrite,GetAttribute()); - oXmlWrite->WriteNodeBegin(L"m:t",false); + CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteNodeConversion(L"m:num",m_pLeftArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:den",m_pRightArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:f",false,false); + } + else + { + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeBinOp) { case TypeElement::plus: - oXmlWrite->WriteString(L"+"); + pXmlWrite->WriteString(L"+"); break; case TypeElement::minus: - oXmlWrite->WriteString(L"-"); + pXmlWrite->WriteString(L"-"); break; case TypeElement::multipl: - oXmlWrite->WriteString(L"*"); + pXmlWrite->WriteString(L"*"); break; case TypeElement::cdot: - oXmlWrite->WriteString(L"\u00B7"); + pXmlWrite->WriteString(L"\u00B7"); break; case TypeElement::times: - oXmlWrite->WriteString(L"\u00D7"); + pXmlWrite->WriteString(L"\u00D7"); break; case TypeElement::div: - oXmlWrite->WriteString(L"\u00F7"); + pXmlWrite->WriteString(L"\u00F7"); break; case TypeElement::odivide: - oXmlWrite->WriteString(L"\u2298"); + pXmlWrite->WriteString(L"\u2298"); break; case TypeElement::oplus: - oXmlWrite->WriteString(L"\u2295"); + pXmlWrite->WriteString(L"\u2295"); break; case TypeElement::ominus: - oXmlWrite->WriteString(L"\u2296"); + pXmlWrite->WriteString(L"\u2296"); break; case TypeElement::odot: - oXmlWrite->WriteString(L"\u2299"); + pXmlWrite->WriteString(L"\u2299"); break; case TypeElement::otimes: - oXmlWrite->WriteString(L"\u2297"); + pXmlWrite->WriteString(L"\u2297"); break; case TypeElement::plus_minus: - oXmlWrite->WriteString(L"\u00B1"); + pXmlWrite->WriteString(L"\u00B1"); break; case TypeElement::minus_plus: - oXmlWrite->WriteString(L"\u2213"); + pXmlWrite->WriteString(L"\u2213"); break; case TypeElement::Or: - oXmlWrite->WriteString(L"\u2228"); + pXmlWrite->WriteString(L"\u2228"); break; case TypeElement::And: - oXmlWrite->WriteString(L"\u2227"); + pXmlWrite->WriteString(L"\u2227"); break; default: break; @@ -703,16 +731,15 @@ namespace StarMath if(m_pRightArgument!=nullptr && m_pRightArgument->GetBaseType() == TypeElement::String && GetAttribute() == m_pRightArgument->GetAttribute()) { CElementString* oNumber = dynamic_cast (m_pRightArgument); - oXmlWrite->WriteString(oNumber->GetString()); - oXmlWrite->WriteNodeEnd(L"m:t",false,false); - oXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteString(oNumber->GetString()); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); } else { - oXmlWrite->WriteNodeEnd(L"m:t",false,false); - oXmlWrite->WriteNodeEnd(L"m:r",false,false); - if(m_pRightArgument!= nullptr) - m_pRightArgument->ConversionToOOXML(oXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); } } @@ -831,13 +858,6 @@ namespace StarMath void CElementBracket::Parse(CStarMathReader* pReader) { pReader->FindingTheEndOfParentheses(); -// pReader->EndingBrackets(); -// pReader->GetToken(); -// TypeElement enBracketClose = GetBracketClose(pReader->GetString()); -// if(enBracketClose == TypeElement::undefine) -// { -// pReader->SetTypesToken(); -// } while(pReader->CheckIteratorPosition()) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -847,19 +867,8 @@ namespace StarMath m_arBrecketValue.pop_back(); } m_arBrecketValue.push_back(pTempElement); -// if(pReader->EmptyString()) -// { -// pReader->GetToken(); -// enBracketClose = GetBracketClose(pReader->GetString()); -// if(enBracketClose == TypeElement::undefine) -// { -// pReader->SetTypesToken(); -// } -// } -// else enBracketClose = GetBracketClose(pReader->GetString()); } //доработать() - SetAttribute(GetAttribute()); pReader->IteratorNullification(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -869,20 +878,18 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:d",false); CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:e",false); - for(CElement* oTemp:m_arBrecketValue) + for(CElement* pTemp:m_arBrecketValue) { - if(oTemp != nullptr) - oTemp->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:d",false,false); } else { - for(CElement* oTemp:m_arBrecketValue) + for(CElement* pTemp:m_arBrecketValue) { - if(oTemp != nullptr) - oTemp->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } } @@ -966,6 +973,7 @@ namespace StarMath else if(L"dotsvert" == wsToken) return TypeElement::dotsvert; else if(L"dotsup" == wsToken) return TypeElement::dotsup; else if(L"dotsdown" == wsToken) return TypeElement::dotsdown; + else if(L"newline" == wsToken) return TypeElement::newline; } else if(wsToken[0] == L'%') { @@ -1045,8 +1053,7 @@ namespace StarMath { case TypeElement::fact: { - if(m_pValue!= nullptr) - m_pValue->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); pXmlWrite->WriteNodeBegin(L"m:r",false); CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); @@ -1068,6 +1075,16 @@ namespace StarMath CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); break; } + case TypeElement::newline: + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"w:br",true); + pXmlWrite->WriteNodeEnd(L"",true,true); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + pXmlWrite->WriteNodeBegin(L"m:oMath",false); + break; + } default: { if(!m_wsType.empty()) @@ -1385,11 +1402,7 @@ namespace StarMath void CElementSetOperations::Parse(CStarMathReader* pReader) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(pReader->EmptyString()) - { - pReader->GetToken(); - pReader->SetTypesToken(); - } + pReader->ReadingTheNextToken(); if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { CElement* pElement = CParserStarMathString::ParseElement(pReader); @@ -1400,7 +1413,7 @@ namespace StarMath } void CElementSetOperations::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - m_pLeftArgument->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r", false); CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); @@ -1456,7 +1469,7 @@ namespace StarMath } pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_pRightArgument->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); } TypeElement CElementSetOperations::GetSetOperation(const std::wstring &wsToken) { @@ -1513,26 +1526,21 @@ namespace StarMath } void CElementConnection::Parse(CStarMathReader *pReader) { - pReader->SetAttribute(GetAttribute()); +// pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(pReader->EmptyString()) - { - pReader->GetToken(); - pReader->SetTypesToken(); - } + pReader->ReadingTheNextToken(); if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) { - pReader->SetAttribute(GetAttribute()); +// pReader->SetAttribute(GetAttribute()); CElement* pBinOp = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); SetRightArg(pBinOp); } else SetRightArg(pTempElement); } - //absent leslant,geslant and toward void CElementConnection::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - m_pLeftArgument->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r",false); CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); @@ -1639,7 +1647,7 @@ namespace StarMath } pXmlWrite->WriteNodeEnd(L"m:t", false, false); pXmlWrite->WriteNodeEnd(L"m:r",false ,false); - m_pRightArgument->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pRightArgument); } TypeElement CElementConnection::GetConnection(const std::wstring& wsToken) { @@ -1740,7 +1748,10 @@ namespace StarMath } void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { - if(m_enTypeIndex == TypeElement::upper || m_enTypeIndex == TypeElement::lower) + switch(m_enTypeIndex) + { + case TypeElement::upper: + case TypeElement::lower: { std::wstring wsNameNodeIndex; switch(m_enTypeIndex) @@ -1754,45 +1765,52 @@ namespace StarMath } pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); - pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pLeftArg,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); switch(m_enTypeIndex) { case TypeElement::upper: - CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); break; case TypeElement::lower: - CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); break; } pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); + break; } - else if(m_enTypeIndex == TypeElement::lsub || TypeElement::lsup == m_enTypeIndex) + case TypeElement::lsub: + case TypeElement::lsup: { pXmlWrite->WriteNodeBegin(L"m:sPre",false); pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); - pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); - if(m_enTypeIndex==TypeElement::lsup) - { - CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueIndex,pXmlWrite); - } - else if(m_enTypeIndex == TypeElement::lsub) + switch(m_enTypeIndex) { - CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueIndex,pXmlWrite); + case TypeElement::lsup: + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); + break; + case TypeElement::lsub: + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); + break; } - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pLeftArg,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); + break; } - else if(m_enTypeIndex == TypeElement::nroot || TypeElement::sqrt == m_enTypeIndex) + case TypeElement::nroot: + case TypeElement::sqrt: { pXmlWrite->WriteNodeBegin(L"m:rad",false); pXmlWrite->WriteNodeBegin(L"m:radPr",false); + if(TypeElement::sqrt == m_enTypeIndex) + { + pXmlWrite->WriteNodeBegin(L"m:degHide",true); + pXmlWrite->WriteAttribute(L"m:val",1); + pXmlWrite->WriteNodeEnd(L"",true,true); + } CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) @@ -1806,18 +1824,33 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:deg",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueIndex,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:rad",false,false); + break; + } + case TypeElement::csub: + case TypeElement::csup: + { + std::wstring wsNameLim; + switch(m_enTypeIndex) + { + case TypeElement::csub: + wsNameLim = L"m:limLow"; + break; + case TypeElement::csup: + wsNameLim = L"m:limUpp"; + break; + } + pXmlWrite->WriteNodeBegin(wsNameLim,false); + pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameLim,false,false); + break; + } } -// else if(m_enTypeIndex == TypeElement::csup || TypeElement::csub == m_enTypeIndex) -// { -// pXmlWrite->WriteNodeBegin(L"m:acc",false); -// pXmlWrite->WriteNodeBegin(L"m:accPr",false); -// pXmlWrite->WriteNodeBegin(L"m:chr",true); -// pXmlWrite->WriteAttribute(L"m:val",L""); -// pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); -// pXmlWrite->WriteNodeEnd(L"m:acc",false,false); -// } } void CElementIndex::SetAttribute(CAttribute *pAttribute) { @@ -1857,8 +1890,7 @@ namespace StarMath if(pReader->CheckIteratorPosition()) { CElement* pTemp = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); if(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -1956,9 +1988,7 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:fName",false,false); if(m_pValue!=nullptr) { - pXmlWrite->WriteNodeBegin(L"m:e",false); - m_pValue->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); } else { @@ -2065,9 +2095,7 @@ namespace StarMath } void CElementOperator::Parse(CStarMathReader* pReader) { -// pReader->SetAttributeTemp(GetAttribute()); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); @@ -2078,45 +2106,35 @@ namespace StarMath pReader->ClearReader(); SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } -// pReader->SetAttributeTemp(GetAttribute()); SetValueOperator(CParserStarMathString::ParseElement(pReader)); -// pReader->ClearAttributeTemp(); } void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator || TypeElement::oper == m_enTypeOperator) { - std::wstring wsTempNameNode; - if(m_pValueFrom != nullptr) - wsTempNameNode = L"m:limLow"; - else if(m_pValueTo != nullptr) - wsTempNameNode = L"m:limUpp"; pXmlWrite->WriteNodeBegin(L"m:func",false); CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:fName",false); - if(m_pValueFrom == nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); - else + if(m_pValueFrom != nullptr && m_pValueTo == nullptr) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName); + else if(m_pValueTo != nullptr && m_pValueFrom == nullptr) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),m_wsName); + else if(m_pValueFrom != nullptr && m_pValueTo != nullptr) { - pXmlWrite->WriteNodeBegin(wsTempNameNode,false); - pXmlWrite->WriteNodeBegin(wsTempNameNode+L"Pr",false); + pXmlWrite->WriteNodeBegin(L"m:limUpp",false); + pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); - pXmlWrite->WriteNodeEnd(wsTempNameNode+L"Pr",false,false); + pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName); pXmlWrite->WriteNodeEnd(L"m:e",false,false); - pXmlWrite->WriteNodeBegin(L"m:lim",false); - if(wsTempNameNode == L"m:limLow") - m_pValueFrom->ConversionToOOXML(pXmlWrite); - else if(wsTempNameNode == L"m:limUpp") - m_pValueTo->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:lim",false,false); - pXmlWrite->WriteNodeEnd(wsTempNameNode,false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueTo,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); } + else if(m_pValueFrom == nullptr && m_pValueTo == nullptr) + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); pXmlWrite->WriteNodeEnd(L"m:fName",false,false); - pXmlWrite->WriteNodeBegin(L"m:e",false); - m_pValueOperator->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:func",false,false); } else @@ -2126,14 +2144,14 @@ namespace StarMath if(m_pValueFrom == nullptr) pXmlWrite->WriteNode(L"m:sub",L""); else { - CConversionSMtoOOXML::BlockRecording(L"m:sub",m_pValueFrom,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); } if(m_pValueTo == nullptr) pXmlWrite->WriteNode(L"m:sup",L""); else { - CConversionSMtoOOXML::BlockRecording(L"m:sup",m_pValueTo,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); } - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pValueOperator,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:nary",false,false); } } @@ -2277,7 +2295,7 @@ namespace StarMath m_enGlobalType = TypeElement::String; return; } - if(m_enUnderType == TypeElement::undefine) + if(m_enUnderType == TypeElement::undefine && !m_wsToken.empty()) { m_enGlobalType = TypeElement::String; return; @@ -2327,8 +2345,8 @@ namespace StarMath m_pBaseAttribute->SetItal(); if(pAttribute->base_font_bold) m_pBaseAttribute->SetBold(); - // if(!pAttribute.base_font_name.empty()) - // m_pBaseAttribute->SetFont(); + if(!pAttribute->base_font_name.empty()) + m_pBaseAttribute->SetFontName(pAttribute->base_font_name); if(pAttribute->base_font_size != 0) m_pBaseAttribute->SetSize(pAttribute->base_font_size); // if(pAttribute.base_alignment != 0) @@ -2409,6 +2427,14 @@ namespace StarMath } ClearReader(); } + void CStarMathReader::ReadingTheNextToken() + { + if(m_wsToken.empty()) + { + GetToken(); + SetTypesToken(); + } + } bool CStarMathReader::CheckTokenForGetElement(const wchar_t &cToken) { switch(cToken) @@ -2505,10 +2531,10 @@ namespace StarMath switch(m_enTypeBracketWithIndex) { case TypeElement::overbrace: - m_pLeftArg->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); break; case TypeElement::underbrace: - m_pValue->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); break; default: break; @@ -2520,10 +2546,10 @@ namespace StarMath switch(m_enTypeBracketWithIndex) { case TypeElement::overbrace: - m_pValue->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); break; case TypeElement::underbrace: - m_pLeftArg->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); break; default: break; @@ -2571,14 +2597,12 @@ namespace StarMath void CElementGrade::Parse(CStarMathReader *pReader) { SetValueGrade(CParserStarMathString::ParseElement(pReader)); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); SetValueFrom(CParserStarMathString::ParseElement(pReader)); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); } if(pReader->GetLocalType() == TypeElement::to) { @@ -2620,15 +2644,11 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(m_pValueFrom != nullptr) { - pXmlWrite->WriteNodeBegin(L"m:sub",false); - m_pValueFrom->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:sub",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); } if(m_pValueTo != nullptr) { - pXmlWrite->WriteNodeBegin(L"m:sup",false); - m_pValueTo->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:sup",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); } pXmlWrite->WriteNodeEnd(wsNodeGrade,false,false); } @@ -2702,9 +2722,7 @@ namespace StarMath { if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol && pOneElement->GetBaseType()!= TypeElement::undefine) { - pXmlWrite->WriteNodeBegin(L"m:e",false); - pOneElement->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); } else if(pOneElement->GetBaseType() == TypeElement::SpecialSymbol) { @@ -2716,7 +2734,7 @@ namespace StarMath } } else if(pOneElement->GetBaseType() != TypeElement::undefine) - pOneElement->ConversionToOOXML(pXmlWrite); + CConversionSMtoOOXML::ElementConversion(pXmlWrite,pOneElement); } break; } @@ -2728,9 +2746,7 @@ namespace StarMath { if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol) { - pXmlWrite->WriteNodeBegin(L"m:e",false); - pOneElement->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeBegin(L"m:mr",false); } @@ -2739,10 +2755,10 @@ namespace StarMath } case TypeElement::binom: { - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pFirstArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeBegin(L"m:mr",false); - CConversionSMtoOOXML::BlockRecording(L"m:e",m_pSecondArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pSecondArgument,pXmlWrite); break; } } @@ -2795,7 +2811,6 @@ namespace StarMath } void CElementDiacriticalMark::Parse(CStarMathReader *pReader) { - //pReader->SetAttribute(GetAttribute()); SetValueMark(CParserStarMathString::ParseElement(pReader)); } void CElementDiacriticalMark::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -2876,9 +2891,7 @@ namespace StarMath } CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); - pXmlWrite->WriteNodeBegin(L"m:e",false); - m_pValueMark->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueMark,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:acc",false,false); } void CElementDiacriticalMark::SetAttribute(CAttribute *pAttribute) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 8ae4b0a98c2..1e5d2c77bff 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -47,7 +47,7 @@ namespace StarMath struct TBaseAttribute { int base_font_size = 12; - std::wstring base_font_name; + std::wstring base_font_name = L"Arial"; int base_alignment = 1; bool base_font_bold = false; bool base_font_italic = false; @@ -66,6 +66,7 @@ namespace StarMath bool GetStrike(); unsigned int GetSize(); std::wstring GetColor(); + const std::wstring& GetFontName(); bool EmptyColor(); void ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); void ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); @@ -77,6 +78,7 @@ namespace StarMath void SetColor(const TypeElement& enColor); void SetColor(const std::wstring& wsColor); void SetFont(const TypeElement& enFont); + void SetFontName(const std::wstring& wsNameFont); private: std::wstring m_wsColor; bool m_bBold; @@ -111,6 +113,7 @@ namespace StarMath std::wstring GetElement(); void FindingTheEndOfParentheses(); void IteratorNullification(); + void ReadingTheNextToken(); private: bool CheckTokenForGetElement(const wchar_t& cToken); bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 2de2182bc0e..7e24ced39f2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -46,7 +46,6 @@ enum class TypeElement{ BracketWithIndex, Grade, Mark, - //BracketEnd, UnarSign, Attribute, SpecialSymbol, @@ -306,6 +305,7 @@ enum class TypeElement{ dotsup, dotsdown, dotslow, + newline, //function abs, fact, From 0e114331debd5e6a962699bffc2df3c5053de51f Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Tue, 6 Feb 2024 02:35:06 +0500 Subject: [PATCH 267/794] Fix bug #58244 --- .../Reader/Converter/pptx_text_context.cpp | 22 ++++++++++--- OdfFile/Reader/Converter/pptx_text_context.h | 2 ++ .../style_paragraph_properties_pptx.cpp | 32 ++++++++++++++++--- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index 78574034bfe..ccc4b7a24e9 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -98,6 +98,8 @@ class pptx_text_context::Impl: boost::noncopyable void start_comment (); std::wstring end_comment(); + std::wstring get_last_paragraph_style_name(); + bool in_list_; bool process_layouts_; @@ -129,6 +131,7 @@ class pptx_text_context::Impl: boost::noncopyable std::wstringstream paragraph_; //перманенто скидываемые параграфы std::wstringstream run_; //перманенто скидываемые куски с быть может разными свойствами + std::wstring last_paragraph_style_name_; std::wstring paragraph_style_name_; std::wstring span_style_name_; @@ -200,9 +203,10 @@ void pptx_text_context::Impl::start_paragraph(const std::wstring & styleName) text_.str(std::wstring()); field_value_.str(std::wstring()); } - paragraph_style_name_ = styleName; - in_paragraph = true; - is_predump = false; + last_paragraph_style_name_ = paragraph_style_name_; + paragraph_style_name_ = styleName; + in_paragraph = true; + is_predump = false; } void pptx_text_context::Impl::end_paragraph() @@ -397,7 +401,7 @@ void pptx_text_context::Impl::write_pPr(std::wostream & strm) const std::wstring & paragraphNodes = get_styles_context().paragraph_nodes().str(); - if (level < 0 && paragraphAttr.length() < 1 && !paragraphNodes.empty()) return; + if (level < 0 && paragraphAttr.length() < 1 && paragraphNodes.empty()) return; strm << L"process_layouts_ = val; } +std::wstring pptx_text_context::get_last_paragraph_style_name() +{ + return impl_->get_last_paragraph_style_name(); +} + } } diff --git a/OdfFile/Reader/Converter/pptx_text_context.h b/OdfFile/Reader/Converter/pptx_text_context.h index fcc55f63722..ffb9d306a2d 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.h +++ b/OdfFile/Reader/Converter/pptx_text_context.h @@ -111,6 +111,8 @@ class pptx_text_context: boost::noncopyable styles_context & get_styles_context(); void set_process_layouts(bool val); + + std::wstring get_last_paragraph_style_name(); private: diff --git a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp index 12ca330a5bf..1735eb6972d 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp @@ -35,6 +35,8 @@ #include #include "../../Reader/Converter/pptx_conversion_context.h" +#include "../../Reader/Format/odf_document.h" +#include "../../Reader/Format/odfcontext.h" #include "../../DataTypes/borderstyle.h" namespace cpdoccore { @@ -452,13 +454,32 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } - if (fo_margin_top_/* || fo_margin_*/) + if (fo_margin_top_) { + style_instance* last_paragraph_style = Context.root()->odf_context().styleContainer().style_by_name( + Context.get_text_context().get_last_paragraph_style_name(), + style_family::Paragraph, + false + ); + CP_XML_NODE(L"a:spcBef") { if (fo_margin_top_->get_type() == length_or_percent::Length) { - std::wstring w_before = pptx_process_margin(fo_margin_top_, length::pt, 100.0); + _CP_OPT(length_or_percent) margin_top = fo_margin_top_; + if (last_paragraph_style) + { + const style_paragraph_properties* last_style_paragraph_props = last_paragraph_style->content()->get_style_paragraph_properties(); + const paragraph_format_properties& last_paragraph_props = last_paragraph_style->content()->get_style_paragraph_properties()->content_; + length_or_percent last_margin_bottom = last_paragraph_props.fo_margin_bottom_.get_value_or(length_or_percent(length(0.0, length::cm))); + + if (fo_margin_top_->get_length().get_value_unit(length::cm) > last_margin_bottom.get_length().get_value_unit(length::cm)) + margin_top = _CP_OPT(length_or_percent)(length(fo_margin_top_->get_length().get_value_unit(length::cm) - last_margin_bottom.get_length().get_value_unit(length::cm), length::cm)); + else + margin_top = _CP_OPT(length_or_percent)(length(0.0, length::cm)); + } + + std::wstring w_before = pptx_process_margin(margin_top, length::pt, 100.0); CP_XML_NODE(L"a:spcPts") { CP_XML_ATTR(L"val",w_before); @@ -475,16 +496,16 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } - if (fo_margin_bottom_/* || fo_margin_*/) + if (fo_margin_bottom_) { CP_XML_NODE(L"a:spcAft") { if (fo_margin_bottom_->get_type() == length_or_percent::Length) { - std::wstring w_after = pptx_process_margin(fo_margin_bottom_, length::pt, 100.0); + std::wstring w_after = pptx_process_margin(fo_margin_bottom_, length::pt, 100.0); CP_XML_NODE(L"a:spcPts") { - CP_XML_ATTR(L"val",w_after); + CP_XML_ATTR(L"val", w_after); } } else @@ -498,6 +519,7 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co } } } + //if (style_punctuation_wrap_) //{ // std::wstring w_val; From cce60166a413b3a7cac32f68c86918512becd461 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 6 Feb 2024 03:42:48 +0300 Subject: [PATCH 268/794] Add extract mode in x2ttester --- Test/Applications/x2tTester/README.md | 21 +- Test/Applications/x2tTester/x2tTester.cpp | 245 +++++++++++++++++++--- Test/Applications/x2tTester/x2tTester.h | 42 +++- 3 files changed, 271 insertions(+), 37 deletions(-) diff --git a/Test/Applications/x2tTester/README.md b/Test/Applications/x2tTester/README.md index f8a03581a4a..1b35855423f 100644 --- a/Test/Applications/x2tTester/README.md +++ b/Test/Applications/x2tTester/README.md @@ -1,7 +1,9 @@ CONFIGURATION ============= -You need to create an xml configuration file. It must contain: +## Default conversion + +You need to create an xml configuration file. It contains: # root of xml @@ -95,8 +97,23 @@ You need to create an xml configuration file. It must contain: docx txt pptx xlsx txt doc pdf +## Extraction +x2ttester can extract files with the required output extension instead of default x2t conversion. Set extraction mode: + + (non-required) sets extraction mode (default - "0") + + +When `extract` is "1", you can set the `output` parameter to determine which exts will be extracted. Default `output` is `emf wmf`. +Params `input`, `inputDirectory`, `outputDirectory`, `cores` works the same. + +Extract mode has additional options: + + (non-required) converts non-zip office files into docx (e.g. pdf) (default - "0"). + + +The conversion params in `convertBeforeExtract` are the same as the default conversion. -You can use the following templates: +## Templates # main xml config diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index b594a8ae4b9..cbbdc6a4519 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -119,22 +119,23 @@ std::vector CFormatsList::GetAllExts() const { std::vector all_formats; - for(auto& val : m_documents) + for (const auto& val : m_documents) all_formats.push_back(val); - for(auto& val : m_presentations) + for (const auto& val : m_presentations) all_formats.push_back(val); - for(auto& val : m_spreadsheets) + for (const auto& val : m_spreadsheets) all_formats.push_back(val); - for(auto& val : m_images) + for (const auto& val : m_images) all_formats.push_back(val); - for(auto& val : m_crossplatform) + for (const auto& val : m_crossplatform) all_formats.push_back(val); - all_formats.push_back(m_pdf); + if (!m_pdf.empty()) + all_formats.push_back(m_pdf); return all_formats; } @@ -259,6 +260,16 @@ CFormatsList CFormatsList::GetOutputExts() return list; } +CFormatsList CFormatsList::GetExtractExts() +{ + CFormatsList list; + + list.m_images.push_back(L"emf"); + list.m_images.push_back(L"wmf"); + + return list; +} + Cx2tTester::Cx2tTester(const std::wstring& configPath) { m_bIsUseSystemFonts = true; @@ -269,14 +280,22 @@ Cx2tTester::Cx2tTester(const std::wstring& configPath) m_bIsFilenamePassword = true; m_bTroughConversion = false; m_bSaveEnvironment = false; + + m_bExtract = false; + m_bConvertBeforeExtract = false; + m_defaultCsvDelimiter = L";"; m_defaultCsvTxtEndcoding = L"UTF-8"; m_inputFormatsList = CFormatsList::GetDefaultExts(); m_outputFormatsList = CFormatsList::GetOutputExts(); + m_extractFormatsList = CFormatsList::GetExtractExts(); m_timeout = 5 * 60; // 5 min + SetConfig(configPath); + m_errorsXmlDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_errors"; m_troughConversionDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_t"; + m_tempDirectory = m_outputDirectory + FILE_SEPARATOR_STR + L"_temp"; m_fontsDirectory = NSFile::GetProcessDirectory() + FILE_SEPARATOR_STR + L"fonts"; @@ -335,6 +354,12 @@ Cx2tTester::~Cx2tTester() m_reportCS.DeleteCriticalSection(); m_outputCS.DeleteCriticalSection(); m_reportStream.CloseFile(); + + for(auto&& val : m_deleteLaterFiles) + NSFile::CFileBinary::Remove(val); + + for(auto&& val : m_deleteLaterDirectories) + NSDirectory::DeleteDirectory(val); } void Cx2tTester::SetConfig(const std::wstring& configPath) @@ -366,6 +391,8 @@ void Cx2tTester::SetConfig(const std::wstring& configPath) else if(name == L"troughConversion" && !node.GetText().empty()) m_bTroughConversion = std::stoi(node.GetText()); else if(name == L"saveEnvironment" && !node.GetText().empty()) m_bSaveEnvironment = std::stoi(node.GetText()); else if(name == L"defaultCsvTxtEncoding" && !node.GetText().empty()) m_defaultCsvTxtEndcoding = node.GetText(); + else if(name == L"extract" && !node.GetText().empty()) m_bExtract = std::stoi(node.GetText()); + else if(name == L"convertBeforeExtract" && !node.GetText().empty()) m_bConvertBeforeExtract = std::stoi(node.GetText()); else if(name == L"defaultCsvDelimiter" && !node.GetText().empty()) m_defaultCsvDelimiter = (wchar_t)std::stoi(node.GetText(), nullptr, 16); else if(name == L"inputFilesList" && !node.GetText().empty()) { @@ -418,17 +445,39 @@ void Cx2tTester::SetConfig(const std::wstring& configPath) exit(-1); } - if(default_input_formats) + if (default_input_formats) m_inputExts = m_inputFormatsList.GetAllExts(); - if(default_output_formats) - m_outputExts = m_outputFormatsList.GetAllExts(); + if (default_output_formats) + { + if (m_bExtract) + m_outputExts = m_extractFormatsList.GetAllExts(); + else + m_outputExts = m_outputFormatsList.GetAllExts(); + } + } void Cx2tTester::Start() { // setup timer m_timeStart = NSTimers::GetTickCount(); + m_outputDirectory = CorrectPathW(m_outputDirectory); + m_errorsXmlDirectory = CorrectPathW(m_errorsXmlDirectory); + m_troughConversionDirectory = CorrectPathW(m_troughConversionDirectory); + + // setup & clear output folder + if(NSDirectory::Exists(m_outputDirectory)) + NSDirectory::DeleteDirectory(m_outputDirectory); + + NSDirectory::CreateDirectory(m_outputDirectory); + + // setup & clear errors folder + if(NSDirectory::Exists(m_errorsXmlDirectory)) + NSDirectory::DeleteDirectory(m_errorsXmlDirectory); + + NSDirectory::CreateDirectory(m_errorsXmlDirectory); + // check fonts CApplicationFontsWorker fonts_worker; fonts_worker.m_sDirectory = m_fontsDirectory; @@ -449,23 +498,6 @@ void Cx2tTester::Start() NSFonts::IApplicationFonts* pFonts = fonts_worker.Check(); RELEASEINTERFACE(pFonts); - m_outputDirectory = CorrectPathW(m_outputDirectory); - m_errorsXmlDirectory = CorrectPathW(m_errorsXmlDirectory); - m_troughConversionDirectory = CorrectPathW(m_troughConversionDirectory); - - // setup & clear output folder - if(NSDirectory::Exists(m_outputDirectory)) - NSDirectory::DeleteDirectory(m_outputDirectory); - - NSDirectory::CreateDirectory(m_outputDirectory); - - // setup & clear errors folder - if(NSDirectory::Exists(m_errorsXmlDirectory)) - NSDirectory::DeleteDirectory(m_errorsXmlDirectory); - - NSDirectory::CreateDirectory(m_errorsXmlDirectory); - - std::vector files = NSDirectory::GetFiles(m_inputDirectory, true); for(int i = 0; i < files.size(); i++) { @@ -486,6 +518,54 @@ void Cx2tTester::Start() if(files.size() < m_maxProc) m_maxProc = files.size(); + if (m_bExtract) + { + COfficeFileFormatChecker checker; + COfficeUtils utils; + std::vector files_to_convert; + + for (size_t i = 0; i < files.size(); i++) + if (utils.IsArchive(files[i]) == S_FALSE && checker.isOfficeFile(files[i])) + { + if (m_bConvertBeforeExtract) + files_to_convert.push_back(files[i]); + files.erase(files.begin() + i); + } + + if (!files_to_convert.empty()) + { + if(NSDirectory::Exists(m_tempDirectory)) + NSDirectory::DeleteDirectory(m_tempDirectory); + + NSDirectory::CreateDirectories(m_tempDirectory); + + auto copy_inputDirectory = m_inputDirectory; + auto copy_outputDirectory = m_outputDirectory; + auto copy_outputExts = m_outputExts; + + m_outputDirectory = m_tempDirectory; + m_outputExts = {L"docx"}; + + Convert(files_to_convert, true, true); + + m_outputDirectory = copy_outputDirectory; + m_outputExts = copy_outputExts; + + m_inputDirectory = m_tempDirectory; + std::vector temp_files = NSDirectory::GetFiles(m_tempDirectory, true); + Extract(temp_files); + + m_inputDirectory = copy_inputDirectory; + } + + Extract(files); + + if(NSDirectory::Exists(m_tempDirectory)) + NSDirectory::DeleteDirectory(m_tempDirectory); + + return; + } + // conversion in _t directory -> _t directory to output if(m_bTroughConversion) { @@ -512,12 +592,6 @@ void Cx2tTester::Start() Convert(files); WriteTime(); - - for(auto&& val : m_deleteLaterFiles) - NSFile::CFileBinary::Remove(val); - - for(auto&& val : m_deleteLaterDirectories) - NSDirectory::DeleteDirectory(val); } void Cx2tTester::Convert(const std::vector& files, bool bNoDirectory, bool bTrough) @@ -652,6 +726,47 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto while(!IsAllFree()) NSThreads::Sleep(150); } +void Cx2tTester::Extract(const std::vector& files) +{ + for (int i = 0; i < files.size(); i++) + { + const std::wstring& input_file = files[i]; + std::wstring input_filename = NSFile::GetFileName(input_file); + std::wstring input_file_directory = NSFile::GetDirectoryName(input_file); + std::wstring input_subfolders = input_file_directory.substr(m_inputDirectory.size(), + input_file_directory.size() - m_inputDirectory.size()); + std::wstring output_files_directory = m_outputDirectory + input_subfolders + FILE_SEPARATOR_STR + input_filename; + + if(!NSDirectory::Exists(output_files_directory)) + NSDirectory::CreateDirectories(output_files_directory); + + // waiting... + do + { + NSThreads::Sleep(50); + } while(IsAllBusy()); + + m_coresCS.Enter(); + + // setup & start new extractor + CExtractor *extractor = new CExtractor(this); + extractor->SetInputFile(input_file); + extractor->SetOutputFilesDirectory(output_files_directory); + extractor->SetExtractExts(m_outputExts); + extractor->SetFilesCount(files.size(), i + 1); + extractor->DestroyOnFinish(); + m_currentProc++; + + m_coresCS.Leave(); + + extractor->Start(0); + } + + // waiting all procs end + while(!IsAllFree()) + NSThreads::Sleep(150); +} + void Cx2tTester::WriteReportHeader() { CTemporaryCS CS(&m_reportCS); @@ -844,7 +959,7 @@ DWORD CConverter::ThreadProc() for(int i = 0; i < m_outputExts.size(); i++) { std::wstring output_ext = L"."+ m_outputExts[i]; - int output_format = checker.GetFormatByExtension(output_ext); + int output_format = m_checker.GetFormatByExtension(output_ext); std::wstring xml_params_filename = input_filename + L"_" + output_ext + L".xml"; std::wstring xml_params_file = m_outputFilesDirectory + FILE_SEPARATOR_STR + xml_params_filename; @@ -1077,4 +1192,68 @@ DWORD CConverter::ThreadProc() return 0; } +CExtractor::CExtractor(Cx2tTester* internal) : m_internal(internal) +{ +} +CExtractor::~CExtractor() +{ + Stop(); +} + +void CExtractor::SetInputFile(const std::wstring& inputFile) +{ + m_inputFile = inputFile; +} +void CExtractor::SetOutputFilesDirectory(const std::wstring& outputFilesDirectory) +{ + m_outputFilesDirectory = outputFilesDirectory; +} +void CExtractor::SetExtractExts(const std::vector& extractExts) +{ + m_extractExts = extractExts; +} +void CExtractor::SetFilesCount(int totalFiles, int currFile) +{ + m_totalFiles = totalFiles; + m_currFile = currFile; +} + +DWORD CExtractor::ThreadProc() +{ + std::wstring input_filename = NSFile::GetFileName(m_inputFile); + std::wstring input_ext = L'.' + NSFile::GetFileExtention(input_filename); + std::wstring input_filename_no_ext = input_filename.substr(0, input_filename.size() - input_ext.size()); + + for (size_t i = 0; i < m_extractExts.size(); i++) + { + const std::wstring& extract_ext = m_extractExts[i]; + std::wstring output_folder = m_outputFilesDirectory + FILE_SEPARATOR_STR + extract_ext; + + if (NSDirectory::Exists(output_folder)) + NSDirectory::DeleteDirectory(output_folder); + + NSDirectory::CreateDirectories(output_folder); + + std::wstring temp_folder = NSDirectory::CreateDirectoryWithUniqueName(output_folder); + m_utils.ExtractToDirectory(m_inputFile, temp_folder, nullptr, false); + + auto unzip_files = NSDirectory::GetFiles(temp_folder, true); + bool delete_empty = true; + for (const auto& file : unzip_files) + { + if (NSFile::GetFileExtention(file) == m_extractExts[i]) + { + delete_empty = false; + NSFile::CFileBinary::Move(file, output_folder + FILE_SEPARATOR_STR +NSFile::GetFileName(file)); + } + } + if (delete_empty) + NSDirectory::DeleteDirectory(output_folder); + NSDirectory::DeleteDirectory(temp_folder); + } + if (NSDirectory::GetFilesCount(m_outputFilesDirectory, true) == 0) + NSDirectory::DeleteDirectory(m_outputFilesDirectory); + m_internal->m_currentProc--; + return 0; +} diff --git a/Test/Applications/x2tTester/x2tTester.h b/Test/Applications/x2tTester/x2tTester.h index 47dfac86055..01ce96ada2a 100644 --- a/Test/Applications/x2tTester/x2tTester.h +++ b/Test/Applications/x2tTester/x2tTester.h @@ -55,7 +55,10 @@ class CFormatsList static CFormatsList GetDefaultExts(); // all writable exts - static CFormatsList GetOutputExts(); + static CFormatsList GetOutputExts(); + + // default exts to extract + static CFormatsList GetExtractExts(); private: std::vector m_documents; @@ -111,6 +114,7 @@ class Cx2tTester // parse string like "docx txt" into vector std::vector ParseExtensionsString(std::wstring extensions, const CFormatsList& fl); void Convert(const std::vector& files, bool bNoDirectory = false, bool bTrough = false); + void Extract(const std::vector& files); // takes from config std::wstring m_reportFile; @@ -121,6 +125,7 @@ class Cx2tTester std::wstring m_errorsXmlDirectory; std::wstring m_troughConversionDirectory; std::wstring m_fontsDirectory; + std::wstring m_tempDirectory; // fonts bool m_bIsUseSystemFonts; @@ -137,6 +142,7 @@ class Cx2tTester // lists CFormatsList m_inputFormatsList; CFormatsList m_outputFormatsList; + CFormatsList m_extractFormatsList; bool m_bIsErrorsOnly; bool m_bIsTimestamp; @@ -157,6 +163,12 @@ class Cx2tTester std::vector m_deleteLaterFiles; std::vector m_deleteLaterDirectories; + + // extract files with output_ext from input_files + bool m_bExtract; + + // convert to docx before extract + bool m_bConvertBeforeExtract; }; // generates temp xml, convert, calls m_internal->writeReport @@ -194,7 +206,7 @@ class CConverter : public NSThreads::CBaseThread std::wstring m_inputExt; std::wstring m_fontsDirectory; - COfficeFileFormatChecker checker; + COfficeFileFormatChecker m_checker; std::wstring m_x2tPath; std::wstring m_errorsXmlDirectory; @@ -214,4 +226,30 @@ class CConverter : public NSThreads::CBaseThread unsigned long m_timeout; }; +// extracts files from office files +class CExtractor : public NSThreads::CBaseThread +{ +public: + CExtractor(Cx2tTester* internal); + virtual ~CExtractor(); + + void SetInputFile(const std::wstring& inputFile); + void SetOutputFilesDirectory(const std::wstring& outputFilesDirectory); + void SetExtractExts(const std::vector& extractExts); + void SetFilesCount(int totalFiles, int currFile); + + virtual DWORD ThreadProc(); + +private: + Cx2tTester* m_internal; + std::wstring m_inputFile; + std::wstring m_outputFilesDirectory; + std::vector m_extractExts; + COfficeUtils m_utils; + + int m_totalFiles; + int m_currFile; + +}; + #endif // X2T_TESTER_H From eb8e7866aa195b63cf9bd9a7172cda3496c5c991 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 6 Feb 2024 07:57:47 +0300 Subject: [PATCH 269/794] Add diff-only arg in standardtester --- Test/Applications/StandardTester/main.cpp | 493 ++++++++++++---------- 1 file changed, 263 insertions(+), 230 deletions(-) diff --git a/Test/Applications/StandardTester/main.cpp b/Test/Applications/StandardTester/main.cpp index d68817925d8..fa29715f0fa 100644 --- a/Test/Applications/StandardTester/main.cpp +++ b/Test/Applications/StandardTester/main.cpp @@ -27,6 +27,19 @@ enum CheckResultCode bool g_save_x2t_xml = false; +int GetPagesCount(const std::wstring& dir) +{ + int nCount = 0; + std::vector files = NSDirectory::GetFiles(dir, false); + for (std::vector::iterator i = files.begin(); i != files.end(); i++) + { + std::wstring sExt = NSFile::GetFileExtention(*i); + if (sExt == L"png") + ++nCount; + } + return nCount; +} + class CConverter; class CInternalWorker { @@ -63,6 +76,7 @@ class CInternalWorker bool m_bIsStandard; bool m_bIsDiffAllInOne; + bool m_bDiffOnly{false}; NSCriticalSection::CRITICAL_SECTION m_oCS; NSCriticalSection::CRITICAL_SECTION m_oCS_OfficeUtils; @@ -121,6 +135,13 @@ class CInternalWorker void OpenDir(std::wstring sDir) { m_sInputFolder = sDir; + if (m_bDiffOnly) + { + m_files = NSDirectory::GetDirectories(m_sInputFolder); + m_nCount = (int)m_files.size(); + return; + } + std::vector arFiles = NSDirectory::GetFiles(sDir, true); for (std::vector::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++) { @@ -268,6 +289,224 @@ class CInternalWorker NSFile::CFileBinary::SaveToFile(sLogFile, sLogContent, true); } + + + int GenerateDiff(const std::wstring strDirIn, const std::wstring strDirOut, const std::wstring strDiffs) + { + int nCountInPages = GetPagesCount(strDirIn); + int nCountOutPages = GetPagesCount(strDirOut); + int checkCode = crcEqual; + + if (nCountInPages != nCountOutPages) + { + if (nCountInPages > nCountOutPages) + nCountInPages = nCountOutPages; + + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + std::wstring sFilePagesDiff = strDiffs + L"/pages_count"; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFilePagesDiff); + oFile.CloseFile(); + + checkCode |= crcPageCount; + } + + for (int nPage = 0; nPage < nCountInPages; ++nPage) + { + std::wstring sPageI = strDirIn + L"/image" + std::to_wstring(nPage + 1) + L".png"; + std::wstring sPageO = strDirOut + L"/image" + std::to_wstring(nPage + 1) + L".png"; + std::wstring sPageDiff = strDiffs + L"/image" + std::to_wstring(nPage + 1) + L".png"; + + CBgraFrame frameI; + frameI.OpenFile(sPageI); + + CBgraFrame frameO; + frameO.OpenFile(sPageO); + + int nW_I = frameI.get_Width(); + int nH_I = frameI.get_Height(); + + int nW_O = frameO.get_Width(); + int nH_O = frameO.get_Height(); + + if (nW_I != nW_O || nH_I != nH_O) + { + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + std::wstring sFilePagesDiff = sPageDiff; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sPageDiff); + oFile.WriteStringUTF8(L"sizes!"); + oFile.CloseFile(); + + checkCode |= crcPageSize; + continue; + } + + BYTE* pDataI = frameI.get_Data(); + BYTE* pDataO = frameO.get_Data(); + size_t sizeMemory = 4 * nW_I * nH_I; + + if (0 == memcmp(pDataI, pDataO, sizeMemory)) + continue; + + sizeMemory = nW_I * nH_I; + + int nEpsilonEps = 3; + int nEpsilonNatural = 5; + + int nDivExist = 0; + for (int indexPixH = 0; indexPixH < nH_I; indexPixH++) + { + for (int indexPixW = 0; indexPixW < nW_I; indexPixW++) + { + if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) + { + // test epsilon natural + if ((abs(pDataI[0] - pDataO[0]) < nEpsilonNatural) && + (abs(pDataI[1] - pDataO[1]) < nEpsilonNatural) && + (abs(pDataI[2] - pDataO[2]) < nEpsilonNatural)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + // test epsilon left, right, top, bottom + int nEpsUp = nEpsilonEps; + if (indexPixH > 0) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH - 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsUp = nEpsilonEps - 1; + } + } + + int nEpsDown = nEpsilonEps; + if (indexPixH < (nH_I - 1)) + { + BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH + 1) * nW_I + 4 * indexPixW; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsDown = nEpsilonEps - 1; + } + } + + int nEpsLeft = nEpsilonEps; + if (indexPixW > 0) + { + BYTE* pByteI = pDataI - 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsLeft = nEpsilonEps - 1; + } + } + + int nEpsRight = nEpsilonEps; + if (indexPixW < (nW_I - 1)) + { + BYTE* pByteI = pDataI + 4; + + if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && + (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && + (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) + { + nEpsRight = nEpsilonEps - 1; + } + } + + if ((nEpsLeft < nEpsilonEps) || + (nEpsRight < nEpsilonEps) || + (nEpsUp < nEpsilonEps) || + (nEpsDown < nEpsilonEps)) + { + pDataI += 4; + pDataO += 4; + continue; + } + + ++nDivExist; + + if (pDataO[0] == 0x00 && pDataO[1] == 0x00 && pDataO[2] == 0xFF) + { + pDataO[0] = 0xFF; + pDataO[1] = 0x00; + pDataO[2] = 0x00; + } + else + { + pDataO[0] = 0x00; + pDataO[1] = 0x00; + pDataO[2] = 0xFF; + } + } + pDataI += 4; + pDataO += 4; + } + } + + if (nDivExist > 7) + { + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectories(CorrectPathW(strDiffs)); + + if (!m_bIsDiffAllInOne) + { + frameO.SaveFile(sPageDiff, 4); + } + else + { + CBgraFrame frameOSrc; + frameOSrc.OpenFile(sPageO); + + BYTE* pData1 = frameI.get_Data(); + BYTE* pData2 = frameOSrc.get_Data(); + BYTE* pData3 = frameO.get_Data(); + + int nRowW = 4 * nW_I; + BYTE* pDataAll = new BYTE[3 * nRowW * nH_I]; + BYTE* pDataAllSrc = pDataAll; + for (int j = 0; j < nH_I; j++) + { + memcpy(pDataAll, pData1, nRowW); + pDataAll += nRowW; + pData1 += nRowW; + + memcpy(pDataAll, pData2, nRowW); + pDataAll += nRowW; + pData2 += nRowW; + + memcpy(pDataAll, pData3, nRowW); + pDataAll += nRowW; + pData3 += nRowW; + } + + CBgraFrame oFrameAll; + oFrameAll.put_Data(pDataAllSrc); + oFrameAll.put_Width(3 * nW_I); + oFrameAll.put_Height(nH_I); + oFrameAll.put_Stride(-3 * nRowW); + oFrameAll.SaveFile(sPageDiff, 4); + } + + checkCode |= crcPageDiffs; + } + } + return checkCode; + } }; class CConverter : public NSThreads::CBaseThread @@ -277,6 +516,7 @@ class CConverter : public NSThreads::CBaseThread std::wstring m_file; std::wstring m_folder_dst; int m_format; + bool m_bDiffOnly{false}; public: CConverter(CInternalWorker* pWorker) : NSThreads::CBaseThread() @@ -291,6 +531,21 @@ class CConverter : public NSThreads::CBaseThread virtual DWORD ThreadProc() { + if (m_bDiffOnly) + { + std::wstring strDirIn = m_file; + std::wstring strDirOut = m_folder_dst; + + std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF"; + std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file); + + int checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs); + + m_bRunThread = FALSE; + m_pInternal->OnConvertFile(this, 0, 0, checkCode); + + return 0; + } bool bIsOfficeFile = true; if (true) { @@ -393,223 +648,7 @@ class CConverter : public NSThreads::CBaseThread std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF"; std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file); - int nCountInPages = GetPagesCount(strDirIn); - int nCountOutPages = GetPagesCount(strDirOut); - - if (nCountInPages != nCountOutPages) - { - if (!NSDirectory::Exists(strDiffsMain)) - NSDirectory::CreateDirectory(strDiffsMain); - if (!NSDirectory::Exists(strDiffs)) - NSDirectory::CreateDirectory(strDiffs); - - if (nCountInPages > nCountOutPages) - nCountInPages = nCountOutPages; - - std::wstring sFilePagesDiff = strDiffs + L"/pages_count"; - NSFile::CFileBinary oFile; - oFile.CreateFileW(sFilePagesDiff); - oFile.CloseFile(); - - checkCode |= crcPageCount; - } - - for (int nPage = 0; nPage < nCountInPages; ++nPage) - { - std::wstring sPageI = strDirIn + L"/image" + std::to_wstring(nPage + 1) + L".png"; - std::wstring sPageO = strDirOut + L"/image" + std::to_wstring(nPage + 1) + L".png"; - std::wstring sPageDiff = strDiffs + L"/image" + std::to_wstring(nPage + 1) + L".png"; - - CBgraFrame frameI; - frameI.OpenFile(sPageI); - - CBgraFrame frameO; - frameO.OpenFile(sPageO); - - int nW_I = frameI.get_Width(); - int nH_I = frameI.get_Height(); - - int nW_O = frameO.get_Width(); - int nH_O = frameO.get_Height(); - - if (nW_I != nW_O || nH_I != nH_O) - { - if (!NSDirectory::Exists(strDiffsMain)) - NSDirectory::CreateDirectory(strDiffsMain); - if (!NSDirectory::Exists(strDiffs)) - NSDirectory::CreateDirectory(strDiffs); - - std::wstring sFilePagesDiff = sPageDiff; - NSFile::CFileBinary oFile; - oFile.CreateFileW(sPageDiff); - oFile.WriteStringUTF8(L"sizes!"); - oFile.CloseFile(); - - checkCode |= crcPageSize; - continue; - } - - BYTE* pDataI = frameI.get_Data(); - BYTE* pDataO = frameO.get_Data(); - size_t sizeMemory = 4 * nW_I * nH_I; - - if (0 == memcmp(pDataI, pDataO, sizeMemory)) - continue; - - sizeMemory = nW_I * nH_I; - - int nEpsilonEps = 3; - int nEpsilonNatural = 5; - - int nDivExist = 0; - for (int indexPixH = 0; indexPixH < nH_I; indexPixH++) - { - for (int indexPixW = 0; indexPixW < nW_I; indexPixW++) - { - if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) - { - // test epsilon natural - if ((abs(pDataI[0] - pDataO[0]) < nEpsilonNatural) && - (abs(pDataI[1] - pDataO[1]) < nEpsilonNatural) && - (abs(pDataI[2] - pDataO[2]) < nEpsilonNatural)) - { - pDataI += 4; - pDataO += 4; - continue; - } - - // test epsilon left, right, top, bottom - int nEpsUp = nEpsilonEps; - if (indexPixH > 0) - { - BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH - 1) * nW_I + 4 * indexPixW; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsUp = nEpsilonEps - 1; - } - } - - int nEpsDown = nEpsilonEps; - if (indexPixH < (nH_I - 1)) - { - BYTE* pByteI = frameI.get_Data() + 4 * (indexPixH + 1) * nW_I + 4 * indexPixW; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsDown = nEpsilonEps - 1; - } - } - - int nEpsLeft = nEpsilonEps; - if (indexPixW > 0) - { - BYTE* pByteI = pDataI - 4; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsLeft = nEpsilonEps - 1; - } - } - - int nEpsRight = nEpsilonEps; - if (indexPixW < (nW_I - 1)) - { - BYTE* pByteI = pDataI + 4; - - if ((abs(pByteI[0] - pDataO[0]) < nEpsilonEps) && - (abs(pByteI[1] - pDataO[1]) < nEpsilonEps) && - (abs(pByteI[2] - pDataO[2]) < nEpsilonEps)) - { - nEpsRight = nEpsilonEps - 1; - } - } - - if ((nEpsLeft < nEpsilonEps) || - (nEpsRight < nEpsilonEps) || - (nEpsUp < nEpsilonEps) || - (nEpsDown < nEpsilonEps)) - { - pDataI += 4; - pDataO += 4; - continue; - } - - ++nDivExist; - - if (pDataO[0] == 0x00 && pDataO[1] == 0x00 && pDataO[2] == 0xFF) - { - pDataO[0] = 0xFF; - pDataO[1] = 0x00; - pDataO[2] = 0x00; - } - else - { - pDataO[0] = 0x00; - pDataO[1] = 0x00; - pDataO[2] = 0xFF; - } - } - pDataI += 4; - pDataO += 4; - } - } - - if (nDivExist > 7) - { - if (!NSDirectory::Exists(strDiffsMain)) - NSDirectory::CreateDirectory(strDiffsMain); - if (!NSDirectory::Exists(strDiffs)) - NSDirectory::CreateDirectory(strDiffs); - - if (!m_pInternal->m_bIsDiffAllInOne) - { - frameO.SaveFile(sPageDiff, 4); - } - else - { - CBgraFrame frameOSrc; - frameOSrc.OpenFile(sPageO); - - BYTE* pData1 = frameI.get_Data(); - BYTE* pData2 = frameOSrc.get_Data(); - BYTE* pData3 = frameO.get_Data(); - - int nRowW = 4 * nW_I; - BYTE* pDataAll = new BYTE[3 * nRowW * nH_I]; - BYTE* pDataAllSrc = pDataAll; - for (int j = 0; j < nH_I; j++) - { - memcpy(pDataAll, pData1, nRowW); - pDataAll += nRowW; - pData1 += nRowW; - - memcpy(pDataAll, pData2, nRowW); - pDataAll += nRowW; - pData2 += nRowW; - - memcpy(pDataAll, pData3, nRowW); - pDataAll += nRowW; - pData3 += nRowW; - } - - CBgraFrame oFrameAll; - oFrameAll.put_Data(pDataAllSrc); - oFrameAll.put_Width(3 * nW_I); - oFrameAll.put_Height(nH_I); - oFrameAll.put_Stride(-3 * nRowW); - oFrameAll.SaveFile(sPageDiff, 4); - } - - checkCode |= crcPageDiffs; - } - } + checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs); } m_bRunThread = FALSE; @@ -617,19 +656,6 @@ class CConverter : public NSThreads::CBaseThread m_pInternal->OnConvertFile(this, nReturnCode, (int)(dwTime2 - dwTime1), checkCode); return 0; } - - int GetPagesCount(const std::wstring& dir) - { - int nCount = 0; - std::vector files = NSDirectory::GetFiles(dir, false); - for (std::vector::iterator i = files.begin(); i != files.end(); i++) - { - std::wstring sExt = NSFile::GetFileExtention(*i); - if (sExt == L"png") - ++nCount; - } - return nCount; - } }; CConverter* CInternalWorker::GetNextConverter() @@ -640,6 +666,7 @@ CConverter* CInternalWorker::GetNextConverter() CConverter* pConverter = new CConverter(this); pConverter->DestroyOnFinish(); pConverter->m_file = m_files[m_nCurrent]; + pConverter->m_bDiffOnly = m_bDiffOnly; ++m_nCurrent; std::wstring sName = NSFile::GetFileName(pConverter->m_file); @@ -737,6 +764,7 @@ int main(int argc, char** argv) { std::vector arFontsDirs; bool bIsStandard = false; + bool bDiffOnly = false; std::wstring strInputFolder = L""; std::wstring strOutputFolder = L""; bool bIsUseSystemFonts = true; @@ -780,6 +808,10 @@ int main(int argc, char** argv) { bIsStandard = true; } + else if (sKey == L"--diff-only") + { + bDiffOnly = true; + } else if (sKey == L"--use-system-fonts") { if (sValue == L"0" || sValue == L"false") @@ -853,6 +885,7 @@ int main(int argc, char** argv) #endif CInternalWorker oWorker; + oWorker.m_bDiffOnly = bDiffOnly; oWorker.OpenDir(strInputFolder); oWorker.m_sOutputFolder = strOutputFolder; oWorker.m_bIsStandard = bIsStandard; From 1089bb3226a78856ea8ffd03820f5fab842b7d3a Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 6 Feb 2024 09:30:17 +0300 Subject: [PATCH 270/794] Fix bug --- Test/Applications/x2tTester/x2tTester.cpp | 27 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index cbbdc6a4519..7ab3959110b 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -515,9 +515,6 @@ void Cx2tTester::Start() } } - if(files.size() < m_maxProc) - m_maxProc = files.size(); - if (m_bExtract) { COfficeFileFormatChecker checker; @@ -537,7 +534,7 @@ void Cx2tTester::Start() if(NSDirectory::Exists(m_tempDirectory)) NSDirectory::DeleteDirectory(m_tempDirectory); - NSDirectory::CreateDirectories(m_tempDirectory); + NSDirectory::CreateDirectories(CorrectPathW(m_tempDirectory)); auto copy_inputDirectory = m_inputDirectory; auto copy_outputDirectory = m_outputDirectory; @@ -596,6 +593,9 @@ void Cx2tTester::Start() void Cx2tTester::Convert(const std::vector& files, bool bNoDirectory, bool bTrough) { + if(files.size() < m_maxProc) + m_maxProc = files.size(); + for(int i = 0; i < files.size(); i++) { const std::wstring& input_file = files[i]; @@ -643,8 +643,8 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto continue; // setup & clear output subfolder - while(!NSDirectory::Exists(output_files_directory)) - NSDirectory::CreateDirectories(output_files_directory); + if (!NSDirectory::Exists(output_files_directory)) + NSDirectory::CreateDirectories(CorrectPathW(output_files_directory)); std::wstring csvTxtEncodingS = m_defaultCsvTxtEndcoding; std::wstring csvDelimiter = m_defaultCsvDelimiter; @@ -694,6 +694,8 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto NSThreads::Sleep(50); } while(IsAllBusy()); + + m_coresCS.Enter(); // setup & start new coverter @@ -728,6 +730,9 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto } void Cx2tTester::Extract(const std::vector& files) { + if(files.size() < m_maxProc) + m_maxProc = files.size(); + for (int i = 0; i < files.size(); i++) { const std::wstring& input_file = files[i]; @@ -1229,6 +1234,16 @@ DWORD CExtractor::ThreadProc() const std::wstring& extract_ext = m_extractExts[i]; std::wstring output_folder = m_outputFilesDirectory + FILE_SEPARATOR_STR + extract_ext; + // output_CS start + m_internal->m_outputCS.Enter(); + + std::cout << "[" << m_currFile << "/" << m_totalFiles << "](" << i + 1 << "/" << m_extractExts.size() << ") "; + std::cout << "(" << m_internal->m_currentProc << " processes now) "; + std::cout << U_TO_UTF8(m_inputFile) << " extract " << U_TO_UTF8(extract_ext) << " "; + + std::cout << std::endl; + m_internal->m_outputCS.Leave(); + if (NSDirectory::Exists(output_folder)) NSDirectory::DeleteDirectory(output_folder); From 7e5da0b22c250144d61d68862e47c292223cd6e2 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 6 Feb 2024 10:38:49 +0300 Subject: [PATCH 271/794] Fix bug #63701 --- HtmlFile2/htmlfile2.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 81b5df6b1d5..ec6a55148f6 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -34,6 +34,9 @@ #define VALUE2STR(x) VALUE_TO_STRING(x) #endif +#define MAXCOLUMNSINTABLE 63 +#define MAXROWSINTABLE 32767 + std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym "; //struct CTree @@ -1144,8 +1147,10 @@ class CHtmlFile2_Private std::vector mTable; int nDeath = m_oLightReader.GetDepth(); int i = 1; // Строка - - while(m_oLightReader.ReadNextSiblingNode(nDeath)) + + UINT unMaxColumns = 0; + + while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) { // tr - строки в таблице if(m_oLightReader.GetName() != L"tr") @@ -1164,7 +1169,7 @@ class CHtmlFile2_Private { if(m_oLightReader.GetName() == L"colspan") nColspan = stoi(m_oLightReader.GetText()); - else if(m_oLightReader.GetName() == L"rowspan") + if(m_oLightReader.GetName() == L"rowspan") nRowspan = stoi(m_oLightReader.GetText()); } m_oLightReader.MoveToElement(); @@ -1224,6 +1229,8 @@ class CHtmlFile2_Private if(nColspan != 1) { + nColspan = std::min((MAXCOLUMNSINTABLE - j), nColspan); + oXml->WriteString(L"WriteString(std::to_wstring(nColspan)); oXml->WriteString(L"\"/>"); @@ -1236,6 +1243,7 @@ class CHtmlFile2_Private oXml->WriteString(L""); if(nRowspan != 1) { + nRowspan = std::min((MAXROWSINTABLE - i), nRowspan); oXml->WriteString(L""); std::wstring sColspan = std::to_wstring(nColspan); if(nRowspan == 0) @@ -1294,7 +1302,16 @@ class CHtmlFile2_Private it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); } - } while(m_oLightReader.ReadNextSiblingNode(nTrDeath)); + } while(m_oLightReader.ReadNextSiblingNode(nTrDeath) && j < MAXCOLUMNSINTABLE); + + if (j > unMaxColumns) + unMaxColumns = j; + else + { + for (; j < unMaxColumns; ++j) + oXml->WriteString(L""); + } + oXml->WriteString(L""); i++; } From 8a655f860035789c87e00d995569f4031ec83508 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Tue, 6 Feb 2024 11:17:47 +0300 Subject: [PATCH 272/794] deleting a file entry --- .../Converter/StarMath2OOXML/cconversionsmtoooxml.cpp | 4 ---- OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 4c16e63b6c9..4257d358360 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -48,10 +48,6 @@ namespace StarMath { oTempElement->ConversionToOOXML(m_pXmlWrite); } EndConversion(); - NSFile::CFileBinary oFile; - oFile.CreateFileW(L"Test.txt"); - oFile.WriteStringUTF8(m_pXmlWrite->GetXmlString()); - oFile.CloseFile(); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 786a4639a28..24d8f132881 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -415,11 +415,11 @@ namespace StarMath { pReader->GetToken(); if(pReader->GetString() == L"sans") - m_wsNameFont = L"Arial"; + m_wsNameFont = L"Liberation Sans"; else if(pReader->GetString() == L"serif") - m_wsNameFont = L"Times New Roman"; + m_wsNameFont = L"Liberation Serif"; else if(pReader->GetString() == L"fixed") - m_wsNameFont = L"Times New Roman"; + m_wsNameFont = L"Liberation Mono"; else m_wsNameFont = pReader->GetString(); break; From 2e22646c34e7ba242ae97c25c08f7cdf05e7d1a3 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Sun, 12 Nov 2023 21:15:40 +0500 Subject: [PATCH 273/794] Convert table templates --- .../Reader/Converter/pptx_table_context.cpp | 37 +++- OdfFile/Reader/Converter/pptx_table_context.h | 188 +++++++++++++++++- OdfFile/Reader/Format/table.cpp | 11 +- OdfFile/Reader/Format/table.h | 2 + OdfFile/Reader/Format/table_pptx.cpp | 77 ++++++- 5 files changed, 301 insertions(+), 14 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_table_context.cpp b/OdfFile/Reader/Converter/pptx_table_context.cpp index 67202bf10e4..c835d04511f 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.cpp +++ b/OdfFile/Reader/Converter/pptx_table_context.cpp @@ -53,7 +53,10 @@ pptx_table_state::pptx_table_state(pptx_conversion_context & Context, const std::wstring & StyleName) : context_(Context), table_style_(StyleName), current_table_column_(-1), - columns_spanned_num_(0) + columns_spanned_num_(0), + rows_(0), + current_row_(0), + total_columns_(0) { } @@ -75,13 +78,13 @@ std::wstring pptx_table_state::get_default_cell_style_row() return default_row_cell_style_name_; } - void pptx_table_state::start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName) { current_table_column_ = -1; columns_spanned_style_ = L""; table_row_style_stack_.push_back(StyleName); default_row_cell_style_name_ = defaultCellStyleName; + current_row_++; } void pptx_table_state::end_row() @@ -225,6 +228,36 @@ unsigned int pptx_table_state::current_rows_spanned(unsigned int Column) const } } +void pptx_table_state::set_rows(int rows) +{ + rows_ = rows; +} + +int pptx_table_state::get_rows() const +{ + return rows_; +} + +int pptx_table_state::get_current_row() const +{ + return current_row_; +} + +void pptx_table_state::set_columns(int cols) +{ + total_columns_ = cols; +} + +int pptx_table_state::get_columns() const +{ + return total_columns_; +} + +void pptx_table_state::set_is_row_template(bool is_row_template) +{ + is_row_template_ = is_row_template; +} + struct pptx_border_edge { bool present = false; diff --git a/OdfFile/Reader/Converter/pptx_table_context.h b/OdfFile/Reader/Converter/pptx_table_context.h index 67e289dc2f6..113b5728a75 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.h +++ b/OdfFile/Reader/Converter/pptx_table_context.h @@ -74,9 +74,25 @@ class pptx_table_state void set_rows_spanned(unsigned int Column, unsigned int Val, unsigned int ColumnsSpanned, const std::wstring & Style); unsigned int current_rows_spanned(unsigned int Column) const; + + void set_rows(int rows); + int get_rows() const; + int get_current_row() const; + void set_columns(int cols); + int get_columns() const; + void set_is_row_template(bool is_row_template); std::wstring default_cell_style_name_; + + _CP_OPT(std::wstring) first_row_style_name_; + _CP_OPT(std::wstring) last_row_style_name_; + _CP_OPT(std::wstring) odd_rows_style_name_; + + _CP_OPT(std::wstring) first_column_style_name_; + _CP_OPT(std::wstring) last_column_style_name_; + _CP_OPT(std::wstring) odd_columns_style_name; + bool is_row_template_ = false; private: pptx_conversion_context & context_; @@ -94,7 +110,10 @@ class pptx_table_state std::vector columns_; std::vector columnsDefaultCellStyleName_; - + + unsigned int rows_; + unsigned int current_row_; + unsigned int total_columns_; }; class pptx_table_context : boost::noncopyable @@ -116,10 +135,10 @@ class pptx_table_context : boost::noncopyable table_states_.pop_back(); } - std::wstring current_style() const - { - return table_states_.back().current_style(); - } + std::wstring current_style() const + { + return table_states_.back().current_style(); + } size_t in_table() const { @@ -205,14 +224,173 @@ class pptx_table_context : boost::noncopyable { table_states_.back().default_cell_style_name_ = style_name; } + + void set_table_rows(int rows) + { + table_states_.back().set_rows(rows); + } + + int get_table_rows() const + { + return table_states_.back().get_rows(); + } + + void set_table_columns(int cols) + { + return table_states_.back().set_columns(cols); + } + + int get_table_columns() const + { + return table_states_.back().get_columns(); + } + + void set_first_row_style_name(std::wstring style_name) + { + table_states_.back().first_row_style_name_ = style_name; + } + + void set_last_row_style_name(std::wstring style_name) + { + table_states_.back().last_row_style_name_ = style_name; + } + + void set_odd_rows_style_name(std::wstring style_name) + { + table_states_.back().odd_rows_style_name_ = style_name; + } + + void set_first_column_style_name(std::wstring style_name) + { + table_states_.back().first_column_style_name_ = style_name; + } + + void set_last_column_style_name(std::wstring style_name) + { + table_states_.back().last_column_style_name_ = style_name; + } + + void set_odd_columns_style_name(std::wstring style_name) + { + table_states_.back().odd_columns_style_name = style_name; + } + + std::wstring get_first_row_style_name() + { + return table_states_.back().first_row_style_name_.get_value_or(L""); + } + + std::wstring get_last_row_style_name() + { + return table_states_.back().last_row_style_name_.get_value_or(L""); + } + + std::wstring get_odd_rows_style_name() + { + return table_states_.back().odd_rows_style_name_.get_value_or(L""); + } + + std::wstring get_first_column_style_name() + { + return table_states_.back().first_column_style_name_.get_value_or(L""); + } + + std::wstring get_last_column_style_name() + { + return table_states_.back().last_column_style_name_.get_value_or(L""); + } + + std::wstring get_odd_column_style_name() + { + return table_states_.back().odd_columns_style_name.get_value_or(L""); + } + std::wstring get_default_cell_style() { return table_states_.back().default_cell_style_name_; } + + void set_is_row_template(bool is_row_template) + { + table_states_.back().set_is_row_template(is_row_template); + } + + bool get_is_row_template() const + { + return table_states_.back().is_row_template_; + } + + void set_template_use_styles( + bool use_first_row_styles, + bool use_last_row_styles, + bool use_banding_rows_styles, + bool use_first_column_styles, + bool use_last_column_styles, + bool use_banding_columns_styles) + { + template_use_styles_.use_first_row_styles = use_first_row_styles; + template_use_styles_.use_last_row_styles = use_last_row_styles; + template_use_styles_.use_banding_rows_styles = use_banding_rows_styles; + + template_use_styles_.use_first_column_styles = use_first_column_styles; + template_use_styles_.use_last_column_styles = use_last_column_styles; + template_use_styles_.use_banding_columns_styles = use_banding_columns_styles; + } + + bool template_is_first_row() + { + return table_states_.back().get_current_row() == 0 && template_use_styles_.use_first_row_styles; + } + + bool template_is_last_row() + { + return + table_states_.back().get_current_row() == table_states_.back().get_rows() - 1 && + template_use_styles_.use_last_row_styles; + } + + bool template_is_odd_row() + { + return + table_states_.back().get_current_row() % 2 == 1 && + template_use_styles_.use_banding_rows_styles; + } + + bool template_is_first_column() + { + return table_states_.back().current_column() == 0 && + template_use_styles_.use_first_column_styles; + } + + bool template_is_last_column() + { + return + table_states_.back().current_column() == table_states_.back().get_columns() - 1 && + template_use_styles_.use_last_column_styles; + } + + bool template_is_odd_column() + { + return + table_states_.back().current_column() % 2 == 1 && + template_use_styles_.use_banding_columns_styles; + } + private: std::wstringstream output_stream_; pptx_conversion_context & context_; std::vector table_states_; + + struct template_use_styles + { + bool use_first_row_styles = false; + bool use_last_row_styles = false; + bool use_banding_rows_styles = false; + + bool use_first_column_styles = false; + bool use_last_column_styles = false; + bool use_banding_columns_styles = false; + } template_use_styles_; }; void oox_serialize_tcPr(std::wostream & strm, std::vector & style_inst, oox::pptx_conversion_context & Context); diff --git a/OdfFile/Reader/Format/table.cpp b/OdfFile/Reader/Format/table.cpp index b32801a2120..7155a077442 100644 --- a/OdfFile/Reader/Format/table.cpp +++ b/OdfFile/Reader/Format/table.cpp @@ -61,10 +61,13 @@ void table_table_attlist::add_attributes( const xml::attributes_wc_ptr & Attribu CP_APPLY_ATTR(L"table:print", table_print_, true); CP_APPLY_ATTR(L"table:print-ranges", table_print_ranges_); - CP_APPLY_ATTR(L"table:use-first-row-styles", table_use_first_row_styles_,false); - CP_APPLY_ATTR(L"table:use-banding-rows-styles", table_use_banding_rows_styles_,false); - CP_APPLY_ATTR(L"table:use-banding-columns-styles", table_use_banding_columns_styles_,false); - CP_APPLY_ATTR(L"table:use-first-column-styles", table_use_first_column_styles_,false); + + CP_APPLY_ATTR(L"table:use-first-row-styles", table_use_first_row_styles_, false); + CP_APPLY_ATTR(L"table:use-last-row-styles", table_use_last_row_styles_, false); + CP_APPLY_ATTR(L"table:use-banding-rows-styles", table_use_banding_rows_styles_, false); + CP_APPLY_ATTR(L"table:use-last-column-styles", table_use_last_column_styles_, false); + CP_APPLY_ATTR(L"table:use-banding-columns-styles", table_use_banding_columns_styles_, false); + CP_APPLY_ATTR(L"table:use-first-column-styles", table_use_first_column_styles_, false); CP_APPLY_ATTR(L"table:is-sub-table", table_is_sub_table_); } diff --git a/OdfFile/Reader/Format/table.h b/OdfFile/Reader/Format/table.h index 5987f7da4dd..783cb4707ab 100644 --- a/OdfFile/Reader/Format/table.h +++ b/OdfFile/Reader/Format/table.h @@ -67,7 +67,9 @@ class table_table_attlist _CP_OPT(std::wstring) table_print_ranges_; bool table_use_first_row_styles_; // default false; + bool table_use_last_row_styles_; // default false; bool table_use_banding_rows_styles_; // defualt false; + bool table_use_last_column_styles_; // default false; bool table_use_first_column_styles_; // defualt false; bool table_use_banding_columns_styles_; // defualt false; diff --git a/OdfFile/Reader/Format/table_pptx.cpp b/OdfFile/Reader/Format/table_pptx.cpp index b172bbac96a..9ee772b6d33 100644 --- a/OdfFile/Reader/Format/table_pptx.cpp +++ b/OdfFile/Reader/Format/table_pptx.cpp @@ -67,8 +67,28 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) { std::wostream & _Wostream = Context.get_table_context().tableData(); - const std::wstring styleName = attlist_.table_style_name_.get_value_or(L""); - const std::wstring defaultCellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); + const std::wstring styleName = attlist_.table_style_name_.get_value_or(L""); + const std::wstring defaultCellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); + std::wstring cellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); + + bool template_is_first_or_last_row = false; + + if (Context.get_table_context().template_is_first_row()) + { + cellStyle = Context.get_table_context().get_first_row_style_name(); + template_is_first_or_last_row = true; + } + else if (Context.get_table_context().template_is_last_row()) + { + cellStyle = Context.get_table_context().get_last_row_style_name(); + template_is_first_or_last_row = true; + } + else if (Context.get_table_context().template_is_odd_row()) + { + cellStyle = Context.get_table_context().get_odd_rows_style_name(); + } + + Context.get_table_context().set_is_row_template(template_is_first_or_last_row); for (unsigned int i = 0; i < attlist_.table_number_rows_repeated_; ++i) { @@ -92,8 +112,9 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) _Wostream << L""; - Context.get_table_context().start_row(styleName, defaultCellStyle); + Context.get_table_context().start_row(styleName, cellStyle); + Context.get_table_context().set_table_columns(content_.size()); for (size_t i = 0; i < content_.size(); i++) { content_[i]->pptx_convert(Context); @@ -127,6 +148,7 @@ void table_rows::pptx_convert(oox::pptx_conversion_context & Context) table_table_rows_->pptx_convert(Context); else { + Context.get_table_context().set_table_rows(table_table_row_.size()); for (size_t i = 0; i < table_table_row_.size(); i++) { table_table_row_[i]->pptx_convert(Context); @@ -174,6 +196,45 @@ void table_table::pptx_convert(oox::pptx_conversion_context & Context) table_body_template* body_ = dynamic_cast(template_->table_body_.get()); Context.get_table_context().set_default_cell_style(body_->table_style_name_); } + if (template_->table_first_row_) + { + table_first_row_template* first_row_ = dynamic_cast(template_->table_first_row_.get()); + Context.get_table_context().set_first_row_style_name(first_row_->table_style_name_); + } + if (template_->table_last_row_) + { + table_last_row_template* last_row_ = dynamic_cast(template_->table_last_row_.get()); + Context.get_table_context().set_last_row_style_name(last_row_->table_style_name_); + } + if (template_->table_odd_rows_) + { + table_odd_rows_template* odd_rows_ = dynamic_cast(template_->table_odd_rows_.get()); + Context.get_table_context().set_odd_rows_style_name(odd_rows_->table_style_name_); + } + if (template_->table_first_column_) + { + table_first_column_template* first_column_ = dynamic_cast(template_->table_first_column_.get()); + Context.get_table_context().set_first_column_style_name(first_column_->table_style_name_); + } + if (template_->table_last_column_) + { + table_last_column_template* last_column = dynamic_cast(template_->table_last_column_.get()); + Context.get_table_context().set_last_column_style_name(last_column->table_style_name_); + } + if (template_->table_odd_columns_) + { + table_odd_columns_template* odd_columns = dynamic_cast(template_->table_odd_columns_.get()); + Context.get_table_context().set_odd_columns_style_name(odd_columns->table_style_name_); + } + + Context.get_table_context().set_template_use_styles( + attlist_.table_use_first_row_styles_, + attlist_.table_use_last_row_styles_, + attlist_.table_use_banding_rows_styles_, + attlist_.table_use_first_column_styles_, + attlist_.table_use_last_column_styles_, + attlist_.table_use_banding_columns_styles_); + } } } @@ -348,7 +409,17 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); if (style_inst) style_instances.push_back(style_inst); } + + bool is_row_template = Context.get_table_context().get_is_row_template(); + style_name = attlist_.table_style_name_.get_value_or(L""); + if (Context.get_table_context().template_is_first_column() && !is_row_template) + style_name = Context.get_table_context().get_first_column_style_name(); + else if (Context.get_table_context().template_is_last_column() && !is_row_template) + style_name = Context.get_table_context().get_last_column_style_name(); + else if (Context.get_table_context().template_is_odd_column() && !is_row_template) + style_name = Context.get_table_context().get_odd_column_style_name(); + if (!style_name.empty()) { style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); From ee0ab7f0425b11fb87e687f972dad3a7d6f78286 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 13 Nov 2023 15:49:29 +0500 Subject: [PATCH 274/794] Fix gradient path conversion --- OdfFile/Reader/Format/draw_common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index 768bac78f91..d802fe754fa 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -381,7 +381,7 @@ void Compute_GradientFill(draw_gradient* gradient_style, oox::oox_gradient_fill_ } } - if (fill->style > 1) + if (fill->style >= 1) { fill->rect[0] = fill->rect[1] = 0; fill->rect[2] = fill->rect[3] = 100; From 92663a7ae39e175f64d408f5a9c6a7f429765b16 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Tue, 14 Nov 2023 02:34:31 +0500 Subject: [PATCH 275/794] Fix bug #62568 --- .../Reader/Converter/pptx_table_context.cpp | 22 ++++++- OdfFile/Reader/Converter/pptx_table_context.h | 23 +++++--- OdfFile/Reader/Format/draw_common.cpp | 4 +- OdfFile/Reader/Format/table_pptx.cpp | 57 ++++++++++--------- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_table_context.cpp b/OdfFile/Reader/Converter/pptx_table_context.cpp index c835d04511f..bee8535bdb6 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.cpp +++ b/OdfFile/Reader/Converter/pptx_table_context.cpp @@ -78,6 +78,19 @@ std::wstring pptx_table_state::get_default_cell_style_row() return default_row_cell_style_name_; } +void pptx_table_state::set_default_cell_style_row(const std::wstring& style_name) +{ + default_row_cell_style_name_ = style_name; +} + +void pptx_table_state::set_default_cell_style_col(unsigned int column, const std::wstring style_name) +{ + if (column >= columnsDefaultCellStyleName_.size()) + return; + + columnsDefaultCellStyleName_[column] = style_name; +} + void pptx_table_state::start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName) { current_table_column_ = -1; @@ -253,9 +266,14 @@ int pptx_table_state::get_columns() const return total_columns_; } -void pptx_table_state::set_is_row_template(bool is_row_template) +void pptx_table_state::set_template_row_style_name(const std::wstring style_name) +{ + template_row_style_name_ = style_name; +} + +std::wstring pptx_table_state::get_template_row_style_name() const { - is_row_template_ = is_row_template; + return template_row_style_name_; } struct pptx_border_edge diff --git a/OdfFile/Reader/Converter/pptx_table_context.h b/OdfFile/Reader/Converter/pptx_table_context.h index 113b5728a75..af6bff6ee91 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.h +++ b/OdfFile/Reader/Converter/pptx_table_context.h @@ -56,6 +56,8 @@ class pptx_table_state void start_column(unsigned int repeated, const std::wstring & defaultCellStyleName); std::wstring get_default_cell_style_col(unsigned int column); std::wstring get_default_cell_style_row(); + void set_default_cell_style_row(const std::wstring& style_name); + void set_default_cell_style_col(unsigned int column, const std::wstring style_name); void start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName); void end_row(); @@ -80,9 +82,11 @@ class pptx_table_state int get_current_row() const; void set_columns(int cols); int get_columns() const; - void set_is_row_template(bool is_row_template); - + void set_template_row_style_name(const std::wstring style_name); + std::wstring get_template_row_style_name() const; + std::wstring default_cell_style_name_; + std::wstring template_row_style_name_; _CP_OPT(std::wstring) first_row_style_name_; _CP_OPT(std::wstring) last_row_style_name_; @@ -91,8 +95,6 @@ class pptx_table_state _CP_OPT(std::wstring) first_column_style_name_; _CP_OPT(std::wstring) last_column_style_name_; _CP_OPT(std::wstring) odd_columns_style_name; - - bool is_row_template_ = false; private: pptx_conversion_context & context_; @@ -210,6 +212,11 @@ class pptx_table_context : boost::noncopyable return table_states_.back().current_rows_spanned(Column); } + void set_default_cell_style_col(unsigned int column, std::wstring style_name) + { + table_states_.back().set_default_cell_style_col(column, style_name); + } + std::wstring get_default_cell_style_col(unsigned int column) { return table_states_.back().get_default_cell_style_col(column); @@ -310,14 +317,14 @@ class pptx_table_context : boost::noncopyable return table_states_.back().default_cell_style_name_; } - void set_is_row_template(bool is_row_template) + void set_template_row_style_name(const std::wstring& style_name) { - table_states_.back().set_is_row_template(is_row_template); + table_states_.back().set_template_row_style_name(style_name); } - bool get_is_row_template() const + std::wstring get_template_row_style_name() { - return table_states_.back().is_row_template_; + return table_states_.back().get_template_row_style_name(); } void set_template_use_styles( diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index d802fe754fa..2f1eb619d77 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -592,7 +592,9 @@ void Compute_GraphicFill(const common_draw_fill_attlist & props, const office_el } if ((fill.hatch) && (props.draw_fill_color_)) { - fill.hatch->color_back_ref = props.draw_fill_color_->get_hex_value(); + // NOTE: Do not use draw:fill-color for hatch + // fill.hatch->color_back_ref = props.draw_fill_color_->get_hex_value(); + fill.hatch->color_back_ref = L"FFFFFF"; } } if (props.draw_fill_) diff --git a/OdfFile/Reader/Format/table_pptx.cpp b/OdfFile/Reader/Format/table_pptx.cpp index 9ee772b6d33..20df34a1d62 100644 --- a/OdfFile/Reader/Format/table_pptx.cpp +++ b/OdfFile/Reader/Format/table_pptx.cpp @@ -69,26 +69,17 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) const std::wstring styleName = attlist_.table_style_name_.get_value_or(L""); const std::wstring defaultCellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); - std::wstring cellStyle = attlist_.table_default_cell_style_name_.get_value_or(L""); - bool template_is_first_or_last_row = false; + std::wstring template_style_name = L""; if (Context.get_table_context().template_is_first_row()) - { - cellStyle = Context.get_table_context().get_first_row_style_name(); - template_is_first_or_last_row = true; - } + template_style_name = Context.get_table_context().get_first_row_style_name(); else if (Context.get_table_context().template_is_last_row()) - { - cellStyle = Context.get_table_context().get_last_row_style_name(); - template_is_first_or_last_row = true; - } + template_style_name = Context.get_table_context().get_last_row_style_name(); else if (Context.get_table_context().template_is_odd_row()) - { - cellStyle = Context.get_table_context().get_odd_rows_style_name(); - } - - Context.get_table_context().set_is_row_template(template_is_first_or_last_row); + template_style_name = Context.get_table_context().get_odd_rows_style_name(); + + Context.get_table_context().set_template_row_style_name(template_style_name); for (unsigned int i = 0; i < attlist_.table_number_rows_repeated_; ++i) { @@ -112,7 +103,7 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context) _Wostream << L""; - Context.get_table_context().start_row(styleName, cellStyle); + Context.get_table_context().start_row(styleName, defaultCellStyle); Context.get_table_context().set_table_columns(content_.size()); for (size_t i = 0; i < content_.size(); i++) @@ -383,6 +374,16 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r) { Context.get_table_context().start_cell(); + + unsigned int current_col = Context.get_table_context().current_column(); + + if (Context.get_table_context().template_is_first_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_first_column_style_name()); + else if(Context.get_table_context().template_is_last_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_last_column_style_name()); + else if (Context.get_table_context().template_is_odd_column()) + Context.get_table_context().set_default_cell_style_col(current_col, Context.get_table_context().get_odd_column_style_name()); + CP_XML_NODE(L"a:tc") { std::vector style_instances; @@ -397,29 +398,31 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); if (style_inst) style_instances.push_back(style_inst); } + style_name = Context.get_table_context().get_default_cell_style_col(Context.get_table_context().current_column()); if (!style_name.empty()) { style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); if (style_inst)style_instances.push_back(style_inst); } - style_name = Context.get_table_context().get_default_cell_style_row(); - if (!style_name.empty()) + style_name = Context.get_table_context().get_template_row_style_name(); + if (!style_name.empty() && !Context.get_table_context().template_is_first_column() && !Context.get_table_context().template_is_last_column()) { style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); - if (style_inst) style_instances.push_back(style_inst); + if (style_inst)style_instances.push_back(style_inst); } - bool is_row_template = Context.get_table_context().get_is_row_template(); + if (!attlist_.table_style_name_.has_value()) + { + style_name = Context.get_table_context().get_default_cell_style_row(); + if (!style_name.empty()) + { + style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); + if (style_inst) style_instances.push_back(style_inst); + } + } style_name = attlist_.table_style_name_.get_value_or(L""); - if (Context.get_table_context().template_is_first_column() && !is_row_template) - style_name = Context.get_table_context().get_first_column_style_name(); - else if (Context.get_table_context().template_is_last_column() && !is_row_template) - style_name = Context.get_table_context().get_last_column_style_name(); - else if (Context.get_table_context().template_is_odd_column() && !is_row_template) - style_name = Context.get_table_context().get_odd_column_style_name(); - if (!style_name.empty()) { style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false); From 3e39bd8d13eb9345bf70d1205d22fda3c9b2245d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 14:38:24 +0600 Subject: [PATCH 276/794] Fix xf prop --- .../Format/Logic/Biff_structures/XFProp.cpp | 74 ++++++++++++++++++- .../Logic/Biff_structures/XFPropColor.cpp | 4 +- OOXML/XlsxFormat/Styles/dxf.cpp | 8 +- 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp index 9a7f8e38cd2..4fa7de73c54 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp @@ -143,8 +143,77 @@ void XFProp::save(CFRecord& record) { if (xfPropDataBlob) { - cb = sizeof(cb) + sizeof(xfPropType) + sizeof(*xfPropDataBlob.get()); + cb = sizeof(cb) + sizeof(xfPropType); + auto blobSize = 0; + switch(xfPropType) + { + case 0x000D: + case 0x000E: + case 0x000F: + case 0x0010: + case 0x0011: // XFPropTextRotation + case 0x0012: // indent + case 0x0013: // ReadingOrder + case 0x0014: + case 0x0015: + case 0x0016: + case 0x0017: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x001F: + case 0x0020: + case 0x0021: + case 0x0022: + case 0x0023: + case 0x0025: + case 0x002B: + case 0x002C: + case 0x0000: + blobSize = 1; + break; + case 0x0001: + case 0x0002: + case 0x0005: + blobSize = 8; + break; + case 0x0003: + blobSize = 44; + break; + case 0x0004: + blobSize = 18; + break; + case 0x0006: + case 0x0007: + case 0x0008: + case 0x0009: + case 0x000A: + case 0x000B: + case 0x000C: + blobSize = 10; + break; + case 0x0026: + case 0x0018: + { + blobSize = sizeof(*xfPropDataBlob.get()); + } + break; + case 0x0019: + case 0x001A: + case 0x001B: + case 0x0029: + case 0x002A: + blobSize = 2; + break; + case 0x0024: + blobSize = 4; + break; + default: + // EXCEPT::RT::WrongBiffRecord("Unsupported type of XFProp.", record.getTypeString()); + break; + } + cb += blobSize; record << xfPropType << cb; if (xfPropType == 0x0026 || xfPropType == 0x0018) @@ -552,6 +621,9 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) xfPropDataBlob.reset(new BIFF_WORD(XmlUtils::GetInteger(oReader.GetText()))); break; case 0x0019: + xfPropDataBlob.reset(new BIFF_WORD(0x02BC1)); + deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); + break; case 0x001A: xfPropDataBlob.reset(new BIFF_WORD(1)); case 0x001B: diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp index d2630dc0c0c..2d4075c68f1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp @@ -99,6 +99,7 @@ int XFPropColor::deserialize(XmlUtils::CXmlLiteReader& oReader) { std::wstring wsPropName = oReader.GetName(); nTintShade = 0; + fValidRGBA = false; while (!wsPropName.empty()) { if (wsPropName == L"auto" && oReader.GetText() == L"1") @@ -117,10 +118,11 @@ int XFPropColor::deserialize(XmlUtils::CXmlLiteReader& oReader) { xclrType = 2; dwRgba.Parse(oReader.GetText()); + fValidRGBA = true; } else if (wsPropName == L"tint") { - nTintShade = XmlUtils::GetInteger(oReader.GetText()) * 32767.0; + nTintShade = XmlUtils::GetDouble(oReader.GetText()) * 32767.0; } if (!oReader.MoveToNextAttribute()) diff --git a/OOXML/XlsxFormat/Styles/dxf.cpp b/OOXML/XlsxFormat/Styles/dxf.cpp index 15dd9aee751..d34afbdcd02 100644 --- a/OOXML/XlsxFormat/Styles/dxf.cpp +++ b/OOXML/XlsxFormat/Styles/dxf.cpp @@ -202,7 +202,9 @@ namespace OOX XLS::BaseObjectPtr CDxf::toBin() { auto ptr(new XLSB::DXF); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::FRTDXF); + ptr1->m_BrtDXF = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); NSStringUtils::CStringBuilder writer; toXML(writer); XmlUtils::CXmlLiteReader oReader; @@ -326,7 +328,9 @@ namespace OOX ptr->m_BrtBeginDXFs = XLS::BaseObjectPtr{ptr1}; for(auto i:m_arrItems) { - ptr->m_aruDXF.push_back(i->toBin()); + auto udxf(new XLSB::uDXF); + udxf->m_BrtFRTDXF = i->toBin(); + ptr->m_aruDXF.push_back(XLS::BaseObjectPtr{udxf}); } ptr1->cdxfs = ptr->m_aruDXF.size(); return objectPtr; From ae61dc5db9c196fe0185a27d863e96780e73c8e2 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 14:39:30 +0600 Subject: [PATCH 277/794] Fix xml pattern fill writing --- OOXML/XlsxFormat/Styles/Fills.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index 75880f33815..1d8f16f5335 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -78,11 +78,9 @@ namespace OOX else if(m_oFgColor.IsInit()) { m_oFgColor->toXMLWithNS(writer, child_ns, L"fgColor", child_ns); - m_oFgColor->toXMLWithNS(writer, child_ns, L"bgColor", child_ns); } else if(m_oBgColor.IsInit()) { - m_oBgColor->toXMLWithNS(writer, child_ns, L"fgColor", child_ns); m_oBgColor->toXMLWithNS(writer, child_ns, L"bgColor", child_ns); } From 2160c86556584c07a662ad73c93477a260330730 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 14:39:57 +0600 Subject: [PATCH 278/794] Fix underline xml reading --- OOXML/XlsxFormat/Styles/rPr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 87ca7455671..6c99fa3e12e 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -827,6 +827,10 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); + if(!m_oUnderline.IsInit()) + { + m_oUnderline.Init(); + } } std::wstring CUnderline::toXML() const { From ce2044a223d863ee637538d6406fc661c9ee40d4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 14:42:40 +0600 Subject: [PATCH 279/794] Fix default values for some structs --- OOXML/XlsxFormat/Styles/CellStyles.cpp | 6 ++++-- OOXML/XlsxFormat/Worksheets/Cols.cpp | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index 1becfb48b46..505c043d453 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -79,7 +79,10 @@ namespace OOX auto ptr(new XLSB::Style); XLS::BaseObjectPtr objectPtr(ptr); if(m_oBuiltinId.IsInit()) - ptr->fBuiltIn = m_oBuiltinId->GetValue(); + { + ptr->fBuiltIn = true; + ptr->iStyBuiltIn = m_oBuiltinId->GetValue(); + } else ptr->fBuiltIn = false; if (m_oCustomBuiltin.IsInit()) @@ -98,7 +101,6 @@ namespace OOX ptr->stName = m_oName.get(); if (m_oXfId.IsInit()) ptr->ixf = m_oXfId->GetValue(); - ptr->iStyBuiltIn = 0; return objectPtr; } diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index 2d686f81d07..9434ba6cef2 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -87,12 +87,20 @@ namespace OOX XLS::BaseObjectPtr ptr(castedPtr); if(m_oBestFit.IsInit()) castedPtr->fBestFit = m_oBestFit->ToBool(); + else + castedPtr->fBestFit = false; if(m_oCollapsed.IsInit()) castedPtr->fCollapsed = m_oCollapsed->ToBool(); + else + castedPtr->fCollapsed = false; if(m_oCustomWidth.IsInit()) castedPtr->fUserSet = m_oCustomWidth->ToBool(); + else + castedPtr->fUserSet = false; if(m_oHidden.IsInit()) castedPtr->fHidden = m_oHidden->ToBool(); + else + castedPtr->fHidden = false; if(m_oMax.IsInit()) castedPtr->colLast = m_oMax->m_eValue - 1; if(m_oMin.IsInit()) From b81fc6b3c7f0b1f8bd57d808a7e651063d7e5487 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 7 Feb 2024 11:51:34 +0300 Subject: [PATCH 280/794] Fix bug --- DesktopEditor/common/Directory.cpp | 4 ---- Test/Applications/x2tTester/x2tTester.cpp | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/common/Directory.cpp b/DesktopEditor/common/Directory.cpp index 66442dbb01f..338a52f75a2 100644 --- a/DesktopEditor/common/Directory.cpp +++ b/DesktopEditor/common/Directory.cpp @@ -586,11 +586,7 @@ namespace NSDirectory int GetFilesCount(const std::wstring& path, const bool& recursive) { std::vector arrFiles = NSDirectory::GetFiles(path, recursive); -#if defined(_WIN32) || defined (_WIN64) return (int)arrFiles.size(); -#endif - return (int)arrFiles.size() + 1; - // ??? } bool PathIsDirectory(const std::wstring& pathName) { diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index 7ab3959110b..2a73a79329e 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -465,6 +465,7 @@ void Cx2tTester::Start() m_outputDirectory = CorrectPathW(m_outputDirectory); m_errorsXmlDirectory = CorrectPathW(m_errorsXmlDirectory); m_troughConversionDirectory = CorrectPathW(m_troughConversionDirectory); + m_tempDirectory = CorrectPathW(m_tempDirectory); // setup & clear output folder if(NSDirectory::Exists(m_outputDirectory)) @@ -534,7 +535,7 @@ void Cx2tTester::Start() if(NSDirectory::Exists(m_tempDirectory)) NSDirectory::DeleteDirectory(m_tempDirectory); - NSDirectory::CreateDirectories(CorrectPathW(m_tempDirectory)); + NSDirectory::CreateDirectories(m_tempDirectory); auto copy_inputDirectory = m_inputDirectory; auto copy_outputDirectory = m_outputDirectory; @@ -644,7 +645,7 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto // setup & clear output subfolder if (!NSDirectory::Exists(output_files_directory)) - NSDirectory::CreateDirectories(CorrectPathW(output_files_directory)); + NSDirectory::CreateDirectories(output_files_directory); std::wstring csvTxtEncodingS = m_defaultCsvTxtEndcoding; std::wstring csvDelimiter = m_defaultCsvDelimiter; From d3ea527e66f7a22b0d29330ced9781181def1905 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 7 Feb 2024 12:03:15 +0300 Subject: [PATCH 281/794] Fix output --- Test/Applications/x2tTester/x2tTester.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index 2a73a79329e..6a6a5ccdcc9 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -1240,7 +1240,7 @@ DWORD CExtractor::ThreadProc() std::cout << "[" << m_currFile << "/" << m_totalFiles << "](" << i + 1 << "/" << m_extractExts.size() << ") "; std::cout << "(" << m_internal->m_currentProc << " processes now) "; - std::cout << U_TO_UTF8(m_inputFile) << " extract " << U_TO_UTF8(extract_ext) << " "; + std::cout << U_TO_UTF8(input_filename) << " extract " << U_TO_UTF8(extract_ext) << " "; std::cout << std::endl; m_internal->m_outputCS.Leave(); From 127d70203cbf4e8aee33cfb6a94033965b27145a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 15:50:23 +0600 Subject: [PATCH 282/794] Fix worksheet writing sequence --- OOXML/XlsbFormat/WorkSheetStream.cpp | 136 +++++++++++++-------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/OOXML/XlsbFormat/WorkSheetStream.cpp b/OOXML/XlsbFormat/WorkSheetStream.cpp index b9d929134de..410b7de2cac 100644 --- a/OOXML/XlsbFormat/WorkSheetStream.cpp +++ b/OOXML/XlsbFormat/WorkSheetStream.cpp @@ -453,103 +453,103 @@ const bool WorkSheetStream::saveContent(XLS::BinProcessor & proc) { proc.mandatory(); + if (m_BrtWsProp != nullptr) + proc.mandatory(*m_BrtWsProp); + + if (m_BrtWsDim != nullptr) + proc.mandatory(*m_BrtWsDim); + + if (m_WSVIEWS2 != nullptr) + proc.mandatory(*m_WSVIEWS2); + + if (m_BrtWsFmtInfo != nullptr) + proc.mandatory(*m_BrtWsFmtInfo); + for (auto &item : m_arCOLINFOS) { proc.mandatory(*item); } - if (m_BrtWsDim != nullptr) - proc.mandatory(*m_BrtWsDim); - - if (m_BrtDrawing != nullptr) - proc.mandatory(*m_BrtDrawing); - - if (m_BrtLegacyDrawing != nullptr) - proc.mandatory(*m_BrtLegacyDrawing); - - if (m_BrtLegacyDrawingHF != nullptr) - proc.mandatory(*m_BrtLegacyDrawingHF); + if (m_CELLTABLE != nullptr) + proc.mandatory(*m_CELLTABLE); - if (m_HLINKS != nullptr) - proc.mandatory(*m_HLINKS); + if (m_BrtSheetProtectionIso != nullptr) + proc.mandatory(*m_BrtSheetProtectionIso); - if (m_MERGECELLS != nullptr) - proc.mandatory(*m_MERGECELLS); + if (m_BrtSheetProtection != nullptr) + proc.mandatory(*m_BrtSheetProtection); - if (m_CELLTABLE != nullptr) - proc.mandatory(*m_CELLTABLE); + for (auto &item : m_arBrtRangeProtectionIso) + { + proc.mandatory(*item); + } - if (m_BrtWsFmtInfo != nullptr) - proc.mandatory(*m_BrtWsFmtInfo); + for (auto &item : m_arBrtRangeProtection) + { + proc.mandatory(*item); + } - if (m_WSVIEWS2 != nullptr) - proc.mandatory(*m_WSVIEWS2); + if (m_AUTOFILTER != nullptr) + proc.mandatory(*m_AUTOFILTER); - if (m_BrtMargins != nullptr) - proc.mandatory(*m_BrtMargins); + if (m_SORTSTATE != nullptr) + proc.mandatory(*m_SORTSTATE); - if (m_BrtPageSetup != nullptr) - proc.mandatory(*m_BrtPageSetup); + if (m_DCON != nullptr) + proc.mandatory(*m_DCON); - if (m_BrtPrintOptions != nullptr) - proc.mandatory(*m_BrtPrintOptions); + if (m_MERGECELLS != nullptr) + proc.mandatory(*m_MERGECELLS); - if (m_HEADERFOOTER != nullptr) - proc.mandatory(*m_HEADERFOOTER); - - if (m_BrtSheetProtectionIso != nullptr) - proc.mandatory(*m_BrtSheetProtectionIso); + for (auto &item : m_arCONDITIONALFORMATTING) + { + proc.mandatory(*item); + } - if (m_BrtSheetProtection != nullptr) - proc.mandatory(*m_BrtSheetProtection); + if (m_DVALS != nullptr) + proc.mandatory(*m_DVALS); - if (m_LISTPARTS != nullptr) - proc.mandatory(*m_LISTPARTS); + if (m_HLINKS != nullptr) + proc.mandatory(*m_HLINKS); - if (m_AUTOFILTER != nullptr) - proc.mandatory(*m_AUTOFILTER); + if (m_BrtPrintOptions != nullptr) + proc.mandatory(*m_BrtPrintOptions); - if (m_SORTSTATE != nullptr) - proc.mandatory(*m_SORTSTATE); + if (m_BrtMargins != nullptr) + proc.mandatory(*m_BrtMargins); - for (auto &item : m_arCONDITIONALFORMATTING) - { - proc.mandatory(*item); - } + if (m_BrtPageSetup != nullptr) + proc.mandatory(*m_BrtPageSetup); - if (m_DVALS != nullptr) - proc.mandatory(*m_DVALS); + if (m_HEADERFOOTER != nullptr) + proc.mandatory(*m_HEADERFOOTER); - if (m_OLEOBJECTS != nullptr) - proc.mandatory(*m_OLEOBJECTS); + if (m_RWBRK != nullptr) + proc.mandatory(*m_RWBRK); - if (m_ACTIVEXCONTROLS != nullptr) - proc.mandatory(*m_ACTIVEXCONTROLS); + if (m_COLBRK != nullptr) + proc.mandatory(*m_COLBRK); - if (m_BrtWsProp != nullptr) - proc.mandatory(*m_BrtWsProp); + if (m_BrtDrawing != nullptr) + proc.mandatory(*m_BrtDrawing); - if (m_BrtBkHim != nullptr) - proc.mandatory(*m_BrtBkHim); + if (m_BrtLegacyDrawing != nullptr) + proc.mandatory(*m_BrtLegacyDrawing); - if (m_RWBRK != nullptr) - proc.mandatory(*m_RWBRK); + if (m_BrtLegacyDrawingHF != nullptr) + proc.mandatory(*m_BrtLegacyDrawingHF); - if (m_COLBRK != nullptr) - proc.mandatory(*m_COLBRK); + if (m_BrtBkHim != nullptr) + proc.mandatory(*m_BrtBkHim); - for (auto &item : m_arBrtRangeProtectionIso) - { - proc.mandatory(*item); - } + if (m_OLEOBJECTS != nullptr) + proc.mandatory(*m_OLEOBJECTS); - for (auto &item : m_arBrtRangeProtection) - { - proc.mandatory(*item); - } + if (m_ACTIVEXCONTROLS != nullptr) + proc.mandatory(*m_ACTIVEXCONTROLS); - if (m_DCON != nullptr) - proc.mandatory(*m_DCON); + if (m_LISTPARTS != nullptr) + proc.mandatory(*m_LISTPARTS); if (m_FRTWORKSHEET != nullptr) proc.mandatory(*m_FRTWORKSHEET); From 587bd78f2fc262d1d9689e6a2d01cef45e4f9d91 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 7 Feb 2024 12:56:55 +0300 Subject: [PATCH 283/794] Fix build on macos/ios --- DesktopEditor/common/File.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index 70a59d668b3..ce2ae13a8c2 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -51,6 +51,12 @@ #include #endif +#if defined(__APPLE__) || defined(__NetBSD__) +#define st_atim st_atimespec +#define st_ctim st_ctimespec +#define st_mtim st_mtimespec +#endif + #ifndef MAX_PATH #define MAX_PATH 1024 #endif From 33058fbbcefa7dd6c65c43d344754afd2e8c27cd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 7 Feb 2024 16:00:59 +0600 Subject: [PATCH 284/794] Fix worksheet parts conversion --- .../Worksheets/WorksheetChildOther.cpp | 167 +++++++++++++----- .../Worksheets/WorksheetChildOther.h | 2 + 2 files changed, 127 insertions(+), 42 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 3e40ff86fd4..76911ad75f9 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -55,6 +55,7 @@ #include "../../XlsbFormat/Biff12_unions/DCON.h" #include "../../XlsbFormat/Biff12_records/BeginDCon.h" #include "../../XlsbFormat/Biff12_unions/DREFS.h" +#include "../../XlsbFormat/Biff12_records/BeginDRefs.h" #include "../../XlsbFormat/Biff12_records/DRef.h" #include "../../XlsbFormat/Biff12_unions/CSVIEWS.h" #include "../../XlsbFormat/Biff12_unions/CSVIEW.h" @@ -1663,6 +1664,18 @@ namespace OOX { ReadAttributes(obj); } + void CPageSetUpPr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oAutoPageBreaks.IsInit()) + ptr->fShowAutoBreaks = m_oAutoPageBreaks->GetValue(); + else + ptr->fShowAutoBreaks = true; + if(m_oFitToPage.IsInit()) + ptr->fFitToPage = m_oFitToPage->GetValue(); + else + ptr->fFitToPage = false; + } EElementType CPageSetUpPr::getType() const { return et_x_PageSetUpPr; @@ -1673,7 +1686,7 @@ namespace OOX if (ptr != nullptr) { m_oAutoPageBreaks = ptr->fShowAutoBreaks; - m_oFitToPage = ptr->fFitToPage;; + m_oFitToPage = ptr->fFitToPage; } } void CPageSetUpPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) @@ -1717,6 +1730,26 @@ namespace OOX { ReadAttributes(obj); } + void COutlinePr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast(obj.get()); + if(m_oApplyStyles.IsInit()) + ptr->fApplyStyles = m_oApplyStyles->GetValue(); + else + ptr->fApplyStyles = false; + if(m_oShowOutlineSymbols.IsInit()) + ptr->fShowOutlineSymbols = m_oShowOutlineSymbols->GetValue(); + else + ptr->fShowOutlineSymbols = true; + if(m_oSummaryBelow.IsInit()) + ptr->fRowSumsBelow = m_oSummaryBelow->GetValue(); + else + ptr->fRowSumsBelow = true; + if(m_oSummaryRight.IsInit()) + ptr->fColSumsRight = m_oSummaryRight->GetValue(); + else + ptr->fColSumsRight = true; + } EElementType COutlinePr::getType() const { return et_x_OutlinePr; @@ -1806,33 +1839,65 @@ namespace OOX } XLS::BaseObjectPtr CSheetPr::toBin() { - XLS::BaseObjectPtr objectPtr; - - if(m_oEnableFormatConditionsCalculation.IsInit() || m_oSyncHorizontal.IsInit() || m_oSyncHorizontal.IsInit() || m_oTransitionEvaluation.IsInit()) - { - auto ptr(new XLSB::WsProp); - objectPtr = XLS::BaseObjectPtr{ptr}; - - if(m_oCodeName.IsInit()) - ptr->strName.value = m_oCodeName.get(); - else - ptr->strName.value = L""; - - ptr->fCondFmtCalc = m_oEnableFormatConditionsCalculation->GetValue(); - ptr->fFilterMode = m_oFilterMode->GetValue(); - ptr->fPublish = m_oPublished->GetValue(); - ptr->fSyncHoriz = m_oSyncHorizontal->GetValue(); - ptr->fSyncVert = m_oSyncVertical->GetValue(); - ptr->fAltFormulaEntry = m_oTransitionEntry->GetValue(); - ptr->fAltExprEval = m_oTransitionEvaluation->GetValue(); - - if (m_oSyncRef.IsInit()) - ptr->syncRef = m_oSyncRef.get(); - if(m_oTabColor.IsInit()) - ptr->brtcolorTab = m_oTabColor->toColor(); - } - - return objectPtr; + auto ptr(new XLSB::WsProp); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oCodeName.IsInit()) + ptr->strName.value = m_oCodeName.get(); + else + ptr->strName.value = L""; + if(m_oEnableFormatConditionsCalculation.IsInit()) + ptr->fCondFmtCalc = m_oEnableFormatConditionsCalculation->GetValue(); + if(m_oFilterMode.IsInit()) + ptr->fFilterMode = m_oFilterMode->GetValue(); + else + ptr->fFilterMode = false; + if(m_oPublished.IsInit()) + ptr->fPublish = m_oPublished->GetValue(); + else + ptr->fPublish = true; + if(m_oSyncHorizontal.IsInit()) + ptr->fSyncHoriz = m_oSyncHorizontal->GetValue(); + else + ptr->fSyncHoriz = false; + if(m_oSyncVertical.IsInit()) + ptr->fSyncVert = m_oSyncVertical->GetValue(); + else + ptr->fSyncVert = false; + if(m_oTransitionEntry.IsInit()) + ptr->fAltFormulaEntry = m_oTransitionEntry->GetValue(); + else + ptr->fAltFormulaEntry = false; + if(m_oTransitionEvaluation.IsInit()) + ptr->fAltExprEval = m_oTransitionEvaluation->GetValue(); + else + ptr->fAltExprEval = false; + if (m_oSyncRef.IsInit()) + ptr->syncRef = m_oSyncRef.get(); + else + ptr->syncRef = L""; + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); + else + ptr->brtcolorTab = m_oTabColor->GetDefaultColor(); + if(m_oPageSetUpPr.IsInit()) + m_oPageSetUpPr->toBin(objectPtr); + else + { + ptr->fFitToPage = false; + ptr->fShowAutoBreaks = true; + } + if(m_oOutlinePr.IsInit()) + m_oOutlinePr->toBin(objectPtr); + else + { + ptr->fApplyStyles = false; + ptr->fColSumsRight = true; + ptr->fRowSumsBelow = true; + ptr->fShowOutlineSymbols = true; + } + ptr->fDialog = false; + ptr->fCondFmtCalc = false; + return objectPtr; } XLS::BaseObjectPtr CSheetPr::toBinCs() { @@ -2601,62 +2666,62 @@ namespace OOX if (m_oAutoFilter.IsInit()) ptr->fAutoFilter = m_oAutoFilter->GetValue(); else - ptr->fAutoFilter = false; + ptr->fAutoFilter = true; if (m_oDeleteColumns.IsInit()) ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); else - ptr->fDeleteColumns= false; + ptr->fDeleteColumns= true; if (m_oDeleteRows.IsInit()) ptr->fDeleteRows = m_oDeleteRows->GetValue(); else - ptr->fDeleteRows = false; + ptr->fDeleteRows = true; if (m_oFormatCells.IsInit()) ptr->fFormatCells = m_oFormatCells->GetValue(); else - ptr->fFormatCells = false; + ptr->fFormatCells = true; if (m_oFormatColumns.IsInit()) ptr->fFormatColumns = m_oFormatColumns->GetValue(); else - ptr->fFormatColumns = false; + ptr->fFormatColumns = true; if (m_oFormatRows.IsInit()) ptr->fFormatRows = m_oFormatRows->GetValue(); else - ptr->fFormatRows = false; + ptr->fFormatRows = true; if (m_oInsertColumns.IsInit()) ptr->fInsertColumns = m_oInsertColumns->GetValue(); else - ptr->fInsertColumns = false; + ptr->fInsertColumns = true; if (m_oInsertHyperlinks.IsInit()) ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); else - ptr->fInsertHyperlinks = false; + ptr->fInsertHyperlinks = true; if (m_oInsertRows.IsInit()) ptr->fInsertRows = m_oInsertRows->GetValue(); else - ptr->fInsertRows = false; + ptr->fInsertRows = true; if (m_oObjects.IsInit()) ptr->fObjects = m_oObjects->GetValue(); else - ptr->fObjects = false; + ptr->fObjects = true; if (m_oPivotTables.IsInit()) ptr->fPivotTables = m_oPivotTables->GetValue(); else - ptr->fPivotTables = false; + ptr->fPivotTables = true; if (m_oScenarios.IsInit()) ptr->fScenarios = m_oScenarios->GetValue(); else - ptr->fScenarios = false; + ptr->fScenarios = true; if (m_oSelectLockedCells.IsInit()) ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); @@ -2676,7 +2741,7 @@ namespace OOX if (m_oSort.IsInit()) ptr->fSort = m_oSort->GetValue(); else - ptr->fSort = false; + ptr->fSort = true; return castedPtr; } @@ -2977,12 +3042,18 @@ namespace OOX if (m_oName.IsInit()) ptr->xstrName = m_oName.get(); - + else + { + ptr->fName = false; + ptr->fBuiltin = false; + } if (m_oRef.IsInit()) ptr->rfx = m_oRef.get(); if (m_oSheet.IsInit()) ptr->xstrSheet = m_oSheet.get(); + else + ptr->xstrSheet = L""; return objectPtr; } @@ -3081,10 +3152,14 @@ namespace OOX { auto ptr(new XLSB::DREFS); XLS::BaseObjectPtr objectPtr(ptr); + auto beginRefs(new XLSB::BeginDRefs); + ptr->m_BrtBeginDRefs = XLS::BaseObjectPtr{beginRefs}; + for(auto i:m_arrItems) { ptr->m_arBrtDRef.push_back(i->toBin()); } + beginRefs->cdref = ptr->m_arBrtDRef.size(); return objectPtr; } EElementType CDataRefs::getType() const @@ -3147,12 +3222,20 @@ namespace OOX if(m_oFunction.IsInit()) beginPtr->iiftab = m_oFunction->GetValue(); + else + beginPtr->iiftab = 0; if(m_oFunction.IsInit()) beginPtr->fLinkConsol = m_oLink->GetValue(); + else + beginPtr->fLinkConsol = false; if(m_oFunction.IsInit()) beginPtr->fLeftCat = m_oStartLabels->GetValue(); + else + beginPtr->fLeftCat = false; if(m_oFunction.IsInit()) beginPtr->fTopCat = m_oTopLabels->GetValue(); + else + beginPtr->fTopCat = false; if(m_oDataRefs.IsInit()) { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 4560a53ae8f..f6b7c54bcdf 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -465,6 +465,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; private: @@ -491,6 +492,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; private: From 0aa03275f45bc164759431a0e50a99aa2c207c89 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 8 Feb 2024 19:27:33 +0600 Subject: [PATCH 285/794] Fix worbook defined names conversion --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 10 +--------- OOXML/XlsxFormat/Workbook/Workbook.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index 4a373a35f73..e5e1ce607f3 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -143,15 +143,7 @@ namespace OOX else ptr->fFutureFunction = false; if (m_oRef.IsInit()) - { - auto ref = m_oRef.get(); - auto separatorPos = ref.find(L"!"); - if(separatorPos != std::string::npos && separatorPos != ref.size() -1) - ref = ref.substr(separatorPos + 1, ref.size() - separatorPos -1); - else if(separatorPos == ref.size() -1) - ref = L""; - ptr->rgce = ref; - } + ptr->rgce = m_oRef.get(); ptr->fCalcExp = true; ptr->fBuiltin = false; return objectPtr; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index fde3a4990f4..9342b0ac087 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -292,10 +292,6 @@ namespace OOX } if (m_oCalcPr.IsInit()) workBookStream->m_BrtCalcProp = m_oCalcPr->toBin(); - if (m_oDefinedNames.IsInit()) - { - workBookStream->m_arBrtName = m_oDefinedNames->toBin(); - } if (m_oSheets.IsInit()) { auto ptr(new XLSB::BUNDLESHS); @@ -336,7 +332,10 @@ namespace OOX workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); if (m_oPivotCaches.IsInit()) workBookStream->m_PIVOTCACHEIDS = m_oPivotCaches->toBin(); - + if (m_oDefinedNames.IsInit()) + { + workBookStream->m_arBrtName = m_oDefinedNames->toBin(); + } if (m_oWorkbookProtection.IsInit()) workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); From 593a7ba176eefd6394e25986d2b910f4f88ad70a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 8 Feb 2024 18:53:15 +0300 Subject: [PATCH 286/794] RC parser --- .../pro/js/wasm/js/drawingfile_base.js | 26 ++- .../pro/js/wasm/src/drawingfile_test.cpp | 62 ++++- PdfFile/SrcReader/PdfAnnot.cpp | 216 ++++++++++++++++-- PdfFile/SrcReader/PdfAnnot.h | 42 ++-- 4 files changed, 305 insertions(+), 41 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 838e3c515ed..fcfc1f32e05 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1125,7 +1125,31 @@ rec["CA"] = reader.readDouble(); // RC if (flags & (1 << 3)) - rec["RC"] = reader.readString(); + { + // 0 - left, 1 - centered, 2 - right, 3 - justify + rec["alignment"] = reader.readByte(); + let n = reader.readInt(); + rec["RC"] = []; + for (let i = 0; i < n; ++i) + { + let oFont = {}; + let nFontFlag = reader.readInt(); + oFont["bold"] = (nFontFlag >> 0) & 1; + oFont["italic"] = (nFontFlag >> 1) & 1; + oFont["strikethrough"] = (nFontFlag >> 3) & 1; + oFont["underlined"] = (nFontFlag >> 4) & 1; + if (nFontFlag & (1 << 5)) + oFont["vertical"] = reader.readDouble(); + oFont["size"] = reader.readDouble(); + oFont["color"] = []; + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["name"] = reader.readString(); + oFont["text"] = reader.readString(); + rec["RC"].push(oFont); + } + } // CreationDate if (flags & (1 << 4)) rec["CreationDate"] = reader.readString(); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 1a80dd548c8..192193b9d5e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1238,11 +1238,63 @@ int main(int argc, char* argv[]) std::cout << "CA " << (double)nPathLength / 100.0 << ", "; } if (nFlags & (1 << 3)) - { - nPathLength = READ_INT(pAnnots + i); + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; + std::cout << "RC { text-align: " << arrTextAlign[nPathLength] << "; "; + + int nFontLength = READ_INT(pAnnots + i); i += 4; - std::cout << "RC " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; + for (int j = 0; j < nFontLength; ++j) + { + std::cout << std::endl << "span" << j << " { "; + + std::cout << "font-style:"; + int nFontFlag = READ_INT(pAnnots + i); + i += 4; + if (nFontFlag & (1 << 0)) + std::cout << "Bold "; + if (nFontFlag & (1 << 1)) + std::cout << "Italic "; + if (nFontFlag & (1 << 3)) + std::cout << "Strike "; + if (nFontFlag & (1 << 4)) + std::cout << "Underline "; + if (nFontFlag & (1 << 5)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; vertical-align:" << (double)nPathLength / 100.0; + } + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-size:" << (double)nPathLength / 100.0; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-color:" << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << "; "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "font-family:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + i += nPathLength; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "text:" << std::string((char*)(pAnnots + i), nPathLength) << " "; + i += nPathLength; + + std::cout << "} "; + } + std::cout << "}, " << std::endl; } if (nFlags & (1 << 4)) { @@ -1697,7 +1749,7 @@ int main(int argc, char* argv[]) } } - std::cout << std::endl; + std::cout << std::endl << std::endl; } if (pAnnots) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9b1ebff9f08..cef461633ba 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -43,6 +43,7 @@ #include "../../DesktopEditor/common/Types.h" #include "../../DesktopEditor/common/StringExt.h" +#include "../../DesktopEditor/xml/include/xmlutils.h" namespace PdfReader { @@ -1250,7 +1251,7 @@ CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Text //------------------------------------------------------------------------ -CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); @@ -1316,7 +1317,7 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar // Ink //------------------------------------------------------------------------ -CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1352,7 +1353,7 @@ CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarku // Line //------------------------------------------------------------------------ -CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1460,7 +1461,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar // TextMarkup: Highlight, Underline, Squiggly, StrikeOut //------------------------------------------------------------------------ -CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1500,7 +1501,7 @@ CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageI // Square, Circle //------------------------------------------------------------------------ -CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1547,7 +1548,7 @@ CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nP // Polygon, PolyLine //------------------------------------------------------------------------ -CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1623,7 +1624,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag // FreeText //------------------------------------------------------------------------ -CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1731,7 +1732,7 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex // Caret //------------------------------------------------------------------------ -CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1767,7 +1768,7 @@ CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CM // FileAttachment //------------------------------------------------------------------------ -CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { m_pEF = NULL; @@ -2093,7 +2094,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) // Markup //------------------------------------------------------------------------ -CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) { m_unFlags = 0; @@ -2120,9 +2121,61 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : oObj.free(); // 3 - Форматированный текст - RC - m_sRC = DictLookupString(&oAnnot, "RC", 3); + std::string sRC = DictLookupString(&oAnnot, "RC", 3); // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock + XmlUtils::CXmlLiteReader oLightReader; + if (!sRC.empty() && oLightReader.FromStringA(sRC) && oLightReader.ReadNextNode() && oLightReader.GetNameA() == "body") + { + CFontData oFontBase; + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + m_nTextAlign = ReadFontData(oLightReader.GetTextA(), &oFontBase); + break; + } + } + oLightReader.MoveToElement(); + + int nDepthP = oLightReader.GetDepth(); + while (oLightReader.ReadNextSiblingNode2(nDepthP)) + { + if (oLightReader.GetNameA() != "p") + continue; + + int nDepthSpan = oLightReader.GetDepth(); + if (oLightReader.IsEmptyNode() || !oLightReader.ReadNextSiblingNode2(nDepthSpan)) + continue; + + do + { + if (oLightReader.GetNameA() != "span") + continue; + + CFontData* pFont = new CFontData(oFontBase); + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + BYTE nTextAlign = ReadFontData(oLightReader.GetTextA(), pFont); + if (nTextAlign != 3) + m_nTextAlign = nTextAlign; + break; + } + } + oLightReader.MoveToElement(); + + pFont->sText = oLightReader.GetText2A(); + m_arrRC.push_back(pFont); + } while (oLightReader.ReadNextSiblingNode2(nDepthSpan)); + } + } + oLightReader.Clear(); + if (m_arrRC.empty()) + m_unFlags &= ~(1 << 3); + else + m_unFlags |= (1 << 3); // 4 - Дата создания - CreationDate m_sCreationDate = DictLookupString(&oAnnot, "CreationDate", 4); @@ -2150,6 +2203,110 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : oAnnot.free(); } +CAnnotMarkup::~CAnnotMarkup() +{ + for (int i = 0; i < m_arrRC.size(); ++i) + RELEASEOBJECT(m_arrRC[i]); +} +BYTE CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) +{ + BYTE nTextAlign = 0; + size_t nSemicolon = 0; + size_t nColon = sData.find(':'); + while (nColon != std::string::npos && nColon > nSemicolon) + { + std::string sProperty = sData.substr(nSemicolon, nColon - nSemicolon); + nSemicolon = sData.find(';', nSemicolon); + nColon++; + std::string sValue = sData.substr(nColon, nSemicolon - nColon); + nSemicolon++; + nColon = sData.find(':', nColon); + + if (sProperty == "font-size") + pFont->dFontSise = std::stod(sValue); + else if (sProperty == "text-align") + { + // 0 start / left + if (sValue == "center" || sValue == "middle") + nTextAlign = 1; + else if (sValue == "right" || sValue == "end") + nTextAlign = 2; + else if (sValue == "justify") + nTextAlign = 3; + } + else if (sProperty == "color") + { + if (sValue[0] == '#') + { + sValue = sValue.substr(1); + BYTE nColor1 = 0, nColor2 = 0, nColor3 = 0; + if (sValue.length() == 6) + sscanf(sValue.c_str(), "%2hhx%2hhx%2hhx", &nColor1, &nColor2, &nColor3); + else if (sValue.length() == 3) + { + sscanf(sValue.c_str(), "%1hhx%1hhx%1hhx", &nColor1, &nColor2, &nColor3); + nColor1 *= 17; + nColor2 *= 17; + nColor3 *= 17; + } + + pFont->dColor[0] = (double)nColor1 / 255.0; + pFont->dColor[1] = (double)nColor2 / 255.0; + pFont->dColor[2] = (double)nColor3 / 255.0; + } + } + else if (sProperty == "font-weight") + { + // 0 normal / 300 / 400 / 500 + if (sValue == "normal" || sValue == "300" || sValue == "400" || sValue == "500") + pFont->unFontFlags &= ~(1 << 0); + else if (sValue == "bold" || sValue == "bolder" || sValue == "600" || sValue == "700" || sValue == "800" || sValue == "900") + pFont->unFontFlags |= (1 << 0); + } + else if (sProperty == "font-style") + { + // 0 normal + if (sValue == "normal") + pFont->unFontFlags &= ~(1 << 1); + else if (sValue == "italic" || sValue.find("oblique") != std::string::npos) + pFont->unFontFlags |= (1 << 1); + } + else if (sProperty == "font-family") + pFont->sFontFamily = sValue[0] == '\'' ? sValue.substr(1, sValue.length() - 2) : sValue; + else if (sProperty == "text-decoration") + { + if (sValue.find("line-through") != std::string::npos) + pFont->unFontFlags |= (1 << 3); + if (sValue.find("word") != std::string::npos || sValue.find("underline") != std::string::npos) + pFont->unFontFlags |= (1 << 4); + if (sValue.find("none") != std::string::npos) + { + pFont->unFontFlags &= ~(1 << 3); + pFont->unFontFlags &= ~(1 << 4); + } + } + else if (sProperty == "vertical-align") + { + pFont->unFontFlags |= (1 << 5); + pFont->dVerticalAlign = std::stod(sValue); + if (pFont->dVerticalAlign == 0 && sValue[0] == '-') + pFont->dVerticalAlign = -0.01; + } + // font-stretch + } + return nTextAlign; +} +CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) +{ + unFontFlags = oFont.unFontFlags; + dFontSise = oFont.dFontSise; + dVerticalAlign = oFont.dVerticalAlign; + dColor[0] = oFont.dColor[0]; + dColor[1] = oFont.dColor[1]; + dColor[2] = oFont.dColor[2]; + sFontFamily = oFont.sFontFamily; + sText = oFont.sText; +} //------------------------------------------------------------------------ // Annot @@ -3074,7 +3231,7 @@ void CAnnotWidgetSig::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); } -void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) +void CAnnotMarkup::ToWASM(NSWasm::CData& oRes) { CAnnot::ToWASM(oRes); @@ -3086,7 +3243,22 @@ void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) if (m_unFlags & (1 << 2)) oRes.AddDouble(m_dCA); if (m_unFlags & (1 << 3)) - oRes.WriteString(m_sRC); + { + oRes.WriteBYTE(m_nTextAlign); + oRes.AddInt(m_arrRC.size()); + for (int i = 0; i < m_arrRC.size(); ++i) + { + oRes.AddInt(m_arrRC[i]->unFontFlags); + if (m_arrRC[i]->unFontFlags & (1 << 5)) + oRes.AddDouble(m_arrRC[i]->dVerticalAlign); + oRes.AddDouble(m_arrRC[i]->dFontSise); + oRes.WriteDouble(m_arrRC[i]->dColor[0]); + oRes.WriteDouble(m_arrRC[i]->dColor[1]); + oRes.WriteDouble(m_arrRC[i]->dColor[2]); + oRes.WriteString(m_arrRC[i]->sFontFamily); + oRes.WriteString(m_arrRC[i]->sText); + } + } if (m_unFlags & (1 << 4)) oRes.WriteString(m_sCreationDate); if (m_unFlags & (1 << 5)) @@ -3100,7 +3272,7 @@ void CAnnotText::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(0); // Text - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 16)) oRes.WriteBYTE(m_nName); @@ -3123,7 +3295,7 @@ void CAnnotInk::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(14); // Ink - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt(m_arrInkList.size()); for (int i = 0; i < m_arrInkList.size(); ++i) @@ -3137,7 +3309,7 @@ void CAnnotLine::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(3); // Line - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); for (int i = 0; i < 4; ++i) oRes.AddDouble(m_pL[i]); @@ -3173,7 +3345,7 @@ void CAnnotTextMarkup::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Highlight, Underline, Squiggly, StrikeOut - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt((unsigned int)m_arrQuadPoints.size()); for (int i = 0; i < m_arrQuadPoints.size(); ++i) @@ -3183,7 +3355,7 @@ void CAnnotSquareCircle::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Square, Circle - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -3201,7 +3373,7 @@ void CAnnotPolygonLine::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Polygon, PolyLine - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.AddInt((unsigned int)m_arrVertices.size()); for (int i = 0; i < m_arrVertices.size(); ++i) @@ -3225,7 +3397,7 @@ void CAnnotFreeText::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(2); // FreeText - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); oRes.WriteBYTE(m_nQ); if (m_unFlags & (1 << 15)) @@ -3256,7 +3428,7 @@ void CAnnotCaret::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(13); // Caret - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -3270,7 +3442,7 @@ void CAnnotFileAttachment::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(16); // FileAttachment - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) oRes.WriteString(m_sName); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 4d053291696..9175b266698 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -321,32 +321,48 @@ class CAnnotPopup final : public CAnnot }; //------------------------------------------------------------------------ -// PdfReader::CMarkupAnnot +// PdfReader::CAnnotMarkup //------------------------------------------------------------------------ -class CMarkupAnnot : public CAnnot +class CAnnotMarkup : public CAnnot { protected: - CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + virtual ~CAnnotMarkup(); virtual void ToWASM(NSWasm::CData& oRes) override; private: + struct CFontData final + { + unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 зачеркнутый, 4 подчеркнутый, 5 vertical-align + double dFontSise; + double dVerticalAlign; + double dColor[3]; + std::string sFontFamily; + std::string sText; + + CFontData() : unFontFlags(4), dFontSise(10), dVerticalAlign(0), dColor{0, 0, 0} {} + CFontData(const CFontData& oFont); + }; + BYTE ReadFontData(const std::string& sData, CFontData* pFont); + BYTE m_nRT; // Тип аннотации-ответа + BYTE m_nTextAlign; // Выравнивание текста в RC unsigned int m_unRefNumPopup; // Номер ссылки на всплывающую аннотацию unsigned int m_unRefNumIRT; // Номер ссылки на аннотацию-ответ double m_dCA; // Значение непрозрачности std::string m_sT; // Текстовая метка, пользователь добавивший аннотацию - std::string m_sRC; // Форматированный текст для отображения во всплывающем окне std::string m_sCreationDate; // Дата создания std::string m_sSubj; // Краткое описание + std::vector m_arrRC; // Форматированный текст }; //------------------------------------------------------------------------ // PdfReader::CAnnotText //------------------------------------------------------------------------ -class CAnnotText final : public CMarkupAnnot +class CAnnotText final : public CAnnotMarkup { public: CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -362,7 +378,7 @@ class CAnnotText final : public CMarkupAnnot // PdfReader::CAnnotInk //------------------------------------------------------------------------ -class CAnnotInk final : public CMarkupAnnot +class CAnnotInk final : public CAnnotMarkup { public: CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -377,7 +393,7 @@ class CAnnotInk final : public CMarkupAnnot // PdfReader::CAnnotLine //------------------------------------------------------------------------ -class CAnnotLine final : public CMarkupAnnot +class CAnnotLine final : public CAnnotMarkup { public: CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -401,7 +417,7 @@ class CAnnotLine final : public CMarkupAnnot // PdfReader::CAnnotTextMarkup //------------------------------------------------------------------------ -class CAnnotTextMarkup final : public CMarkupAnnot +class CAnnotTextMarkup final : public CAnnotMarkup { public: CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -417,7 +433,7 @@ class CAnnotTextMarkup final : public CMarkupAnnot // PdfReader::CAnnotSquareCircle //------------------------------------------------------------------------ -class CAnnotSquareCircle final : public CMarkupAnnot +class CAnnotSquareCircle final : public CAnnotMarkup { public: CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -434,7 +450,7 @@ class CAnnotSquareCircle final : public CMarkupAnnot // PdfReader::CAnnotPolygonPolyline //------------------------------------------------------------------------ -class CAnnotPolygonLine final : public CMarkupAnnot +class CAnnotPolygonLine final : public CAnnotMarkup { public: CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -454,7 +470,7 @@ class CAnnotPolygonLine final : public CMarkupAnnot // PdfReader::CAnnotFreeText //------------------------------------------------------------------------ -class CAnnotFreeText final : public CMarkupAnnot +class CAnnotFreeText final : public CAnnotMarkup { public: CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -475,7 +491,7 @@ class CAnnotFreeText final : public CMarkupAnnot // PdfReader::CAnnotCaret //------------------------------------------------------------------------ -class CAnnotCaret final : public CMarkupAnnot +class CAnnotCaret final : public CAnnotMarkup { public: CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -491,7 +507,7 @@ class CAnnotCaret final : public CMarkupAnnot // PdfReader::CAnnotFileAttachment //------------------------------------------------------------------------ -class CAnnotFileAttachment final : public CMarkupAnnot +class CAnnotFileAttachment final : public CAnnotMarkup { public: CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); From a7a80cb92eb1abcfea449a48869a5e2d3f221494 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 8 Feb 2024 18:55:17 +0300 Subject: [PATCH 287/794] Fixed some inaccuracies in the conversion of html tables --- .../3dParty/html/css/src/StyleProperties.cpp | 65 ++++++--- Common/3dParty/html/css/src/StyleProperties.h | 3 + .../html/css/src/xhtml/CDocumentStyle.cpp | 8 +- HtmlFile2/htmlfile2.cpp | 131 ++++++++++-------- HtmlFile2/src/StringFinder.h | 28 ++++ 5 files changed, 153 insertions(+), 82 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 732f05bfa46..3d81d7d703d 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -252,6 +252,16 @@ namespace NSCSS return (std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON); } + bool CDigit::operator!=(const double &oValue) const + { + return (std::abs(oValue - m_oValue) > DBL_EPSILON); + } + + bool CDigit::operator!=(const CDigit &oDigit) const + { + return (std::abs(oDigit.m_oValue - m_oValue) > DBL_EPSILON); + } + CDigit CDigit::operator+(const CDigit &oDigit) const { CDigit oTemp; @@ -1343,7 +1353,12 @@ namespace NSCSS wsNewValue.replace(unFoundPos, oAbsValue.first.length(), oAbsValue.second); } - return m_oWidth.SetValue(wsNewValue, unLevel, bHardMode); + const bool bResult = m_oWidth.SetValue(wsNewValue, unLevel, bHardMode); + + if (m_oWidth != 1.) + m_oWidth += 1.; + + return bResult; } bool CBorderSide::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1434,34 +1449,50 @@ namespace NSCSS bool CBorder::SetSides(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetValue(wsValue, unLevel, bHardMode) || - m_oTop .SetValue(wsValue, unLevel, bHardMode) || - m_oRight .SetValue(wsValue, unLevel, bHardMode) || - m_oBottom.SetValue(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetValue(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetValue(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetWidth(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetWidth(wsValue, unLevel, bHardMode) || - m_oTop .SetWidth(wsValue, unLevel, bHardMode) || - m_oRight .SetWidth(wsValue, unLevel, bHardMode) || - m_oBottom.SetWidth(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetWidth(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetStyle(wsValue, unLevel, bHardMode) || - m_oTop .SetStyle(wsValue, unLevel, bHardMode) || - m_oRight .SetStyle(wsValue, unLevel, bHardMode) || - m_oBottom.SetStyle(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetStyle(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetColor(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oLeft .SetColor(wsValue, unLevel, bHardMode) || - m_oTop .SetColor(wsValue, unLevel, bHardMode) || - m_oRight .SetColor(wsValue, unLevel, bHardMode) || - m_oBottom.SetColor(wsValue, unLevel, bHardMode); + bool bResult = false; + + if (m_oLeft .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oTop .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oRight .SetColor(wsValue, unLevel, bHardMode)) bResult = true; + if (m_oBottom.SetColor(wsValue, unLevel, bHardMode)) bResult = true; + + return bResult; } bool CBorder::SetLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 179156bbc02..6bf38c7878b 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -144,6 +144,9 @@ namespace NSCSS bool operator==(const double& oValue) const; bool operator==(const CDigit& oDigit) const; + bool operator!=(const double& oValue) const; + bool operator!=(const CDigit& oDigit) const; + CDigit operator+(const CDigit& oDigit) const; CDigit operator-(const CDigit& oDigit) const; CDigit operator*(const CDigit& oDigit) const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index d6751df57a0..580326f5945 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -424,7 +424,7 @@ namespace NSCSS { std::wstring wsColor = oBorder.GetColor().ToWString(); std::wstring wsStyle = oBorder.GetStyle().ToWString(); - std::wstring wsWidth = oBorder.GetWidth().ToWString(); + double dWidth = oBorder.GetWidth().ToDouble(Point) * 8; // Так как значение указано в восьмых долях точки if (wsColor.empty()) wsColor = L"auto"; @@ -432,10 +432,10 @@ namespace NSCSS if (wsStyle.empty()) wsStyle = L"single"; - if (wsWidth.empty()) - wsWidth = L"1"; + if (1 > dWidth) + dWidth = 1; - return L"w:color=\"" + wsColor + L"\" w:space=\"0\" w:sz=\"" + wsWidth + L"\" w:val=\"" + wsStyle + L"\""; + return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(static_cast(dWidth)) + + L"\" w:space=\"0\" w:color=\"" + wsColor + L"\""; } void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index ec6a55148f6..5ffbd267555 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -963,11 +963,11 @@ class CHtmlFile2_Private readStream(oXml, sSelectors, oTSR); } // Векторная картинка -// else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) -// { -// wrP(oXml, sSelectors, oTS); -// readSVG(oXml); -// } + else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) + { + wrP(oXml, sSelectors, oTS); + readSVG(oXml); + } else if(sName == L"input") readInput(oXml, sSelectors, oTS); // Игнорируются тэги выполняющие скрипт @@ -1142,7 +1142,7 @@ class CHtmlFile2_Private return true; } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sBorders) + void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { std::vector mTable; int nDeath = m_oLightReader.GetDepth(); @@ -1168,9 +1168,9 @@ class CHtmlFile2_Private while(m_oLightReader.MoveToNextAttribute()) { if(m_oLightReader.GetName() == L"colspan") - nColspan = stoi(m_oLightReader.GetText()); - if(m_oLightReader.GetName() == L"rowspan") - nRowspan = stoi(m_oLightReader.GetText()); + nColspan = std::min((MAXCOLUMNSINTABLE - j), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + else if(m_oLightReader.GetName() == L"rowspan") + nRowspan = std::min((MAXROWSINTABLE - i), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); } m_oLightReader.MoveToElement(); @@ -1180,7 +1180,7 @@ class CHtmlFile2_Private while(it1 != mTable.end() || it2 != mTable.end()) { oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); +// oXml->WriteString(!sBorders.empty() ? sBorders : L""); oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); @@ -1229,21 +1229,17 @@ class CHtmlFile2_Private if(nColspan != 1) { - nColspan = std::min((MAXCOLUMNSINTABLE - j), nColspan); - oXml->WriteString(L"WriteString(std::to_wstring(nColspan)); oXml->WriteString(L"\"/>"); - - j += nColspan - 1; } - oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L""); +// oXml->WriteString(L""); +// oXml->WriteString(!sBorders.empty() ? sBorders : L""); +// oXml->WriteString(L""); + if(nRowspan != 1) { - nRowspan = std::min((MAXROWSINTABLE - i), nRowspan); oXml->WriteString(L""); std::wstring sColspan = std::to_wstring(nColspan); if(nRowspan == 0) @@ -1253,24 +1249,41 @@ class CHtmlFile2_Private mTable.push_back({k, j, sColspan}); } + if(nColspan != 1) + j += nColspan - 1; + std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); - if (!wsVerticalAlign.empty()) + if (wsVerticalAlign.empty()) + oXml->WriteString(L""); + else oXml->WriteString(L""); oXml->WriteString(L""); m_bWasPStyle = false; + //Оставляем только всё что не относится к таблице + std::vector arSelectors; + for (const NSCSS::CNode& oItem : sSelectors) + { + if (oItem.m_wsName == L"table" || oItem.m_wsName == L"tbody" || oItem.m_wsName == L"th" || + oItem.m_wsName == L"td" || oItem.m_wsName == L"tr" || oItem.m_wsName == L"thead" || + oItem.m_wsName == L"tfoot") + continue; + arSelectors.push_back(oItem); + } // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") { CTextSettings oTSR(oTS); oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + readStream(oXml, arSelectors, oTSR); } // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") - readStream(oXml, sSelectors, oTS); + { + readStream(oXml, arSelectors, oTS); + } sSelectors.pop_back(); if (m_bInP) { @@ -1293,7 +1306,7 @@ class CHtmlFile2_Private while(it1 != mTable.end() || it2 != mTable.end()) { oXml->WriteString(L""); - oXml->WriteString(!sBorders.empty() ? sBorders : L""); +// oXml->WriteString(!sBorders.empty() ? sBorders : L""); oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); @@ -1340,8 +1353,8 @@ class CHtmlFile2_Private if (0 < nWidth) wsTable += L""; - else if (m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth != 0) - wsTable += L""; +// else if (m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth != 0) +// wsTable += L""; else wsTable += L""; @@ -1363,6 +1376,36 @@ class CHtmlFile2_Private sSelectors.push_back(oLastNode); } + + // borders + if (!oStyle.m_oBorder.Empty()) + { + wsTable += L""; + + if (oStyle.m_oBorder.EqualSides()) + { + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); + + wsTable += L"" + + L"" + + L"" + + L""; + } + else + { + const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetTopBorder()); + const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); + const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetBottomBorder()); + const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetRightBorder()); + + wsTable += L"" + + L"" + + L"" + + L""; + } + + wsTable += L""; + } if (!oStyle.m_oMargin.Empty() && (0 < oStyle.m_oMargin.GetTop().ToInt() || 0 < oStyle.m_oMargin.GetBottom().ToInt())) { @@ -1389,40 +1432,6 @@ class CHtmlFile2_Private wsTable += L""; wsTable += L""; - // borders - std::wstring sBorders; - oStyle.m_oBorder.Unblock(); - if (oStyle.m_oBorder.Empty()) - { - sBorders = L""; - } - else - { - if (oStyle.m_oBorder.EqualSides()) - { - const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - - sBorders = L"" + - L"" + - L"" + - L"" + - L"" + - L""; - } - else - { - const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetTopBorder()); - const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetBottomBorder()); - const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetRightBorder()); - - sBorders = L"" + - L"" + - L"" + - L""; - } - } - oXml->WriteString(wsTable); /* @@ -1489,11 +1498,11 @@ class CHtmlFile2_Private m_bWasSpace = false; } if(sName == L"thead") - readTr(&oHead, sSelectors, oTS, sBorders); + readTr(&oHead, sSelectors, oTS); else if(sName == L"tbody") - readTr(&oBody, sSelectors, oTS, sBorders); + readTr(&oBody, sSelectors, oTS); else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS, sBorders); + readTr(&oFoot, sSelectors, oTS); sSelectors.pop_back(); } diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index 9f7a326ff04..6ac8ef4d3e9 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -154,6 +154,34 @@ namespace NSStringFinder { return !boost::algorithm::ifind_first(sString, sValue).empty(); } + + int ToInt(const std::wstring& oValue, int nMinValue = 0) + { + boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); + + boost::match_results oResult; + + if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) + return nMinValue; + + const int nValue = std::stoi(*oResult.begin()); + + return (nValue >= nMinValue) ? nValue : nMinValue; + } + + int ToDouble(const std::wstring& oValue, double dMinValue = 0.) + { + boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); + + boost::match_results oResult; + + if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) + return dMinValue; + + const double dValue = std::stod(*oResult.begin()); + + return (dValue >= dMinValue) ? dValue : dMinValue; + } } #endif // STRINGFINDER_H From 835f4ba89db4bf52993519a88948923821db17be Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 9 Feb 2024 11:20:24 +0300 Subject: [PATCH 288/794] bug fixing --- .../Converter/StarMath2OOXML/.gitignore | 74 ++++++++++++ .../StarMath2OOXML/cstarmathpars.cpp | 107 ++++++++++-------- .../Converter/StarMath2OOXML/cstarmathpars.h | 2 +- 3 files changed, 133 insertions(+), 50 deletions(-) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/.gitignore diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore b/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore new file mode 100644 index 00000000000..4a0b530afd2 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/.gitignore @@ -0,0 +1,74 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* +CMakeLists.txt.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 24d8f132881..c256c4e2386 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -112,6 +112,12 @@ namespace StarMath T* pTempElement = dynamic_cast(pElementWhichAdd); if(pTempElement->GetLeftArg() == nullptr) { + if(pLeftArg->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pLeftArg); + if(pSpecial->GetType() == TypeElement::newline) + return false; + } pTempElement->SetLeftArg(pLeftArg); pElementWhichAdd = pTempElement; return true; @@ -121,38 +127,41 @@ namespace StarMath bool CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) { - switch(pElementWhichAdd->GetBaseType()) + if(pElementWhichAdd!=nullptr) { - case TypeElement::BinOperator: - { - return SetLeft(pLeftArg, pElementWhichAdd); - } - case TypeElement::SetOperations: - { - SetLeft(pLeftArg, pElementWhichAdd); - break; - } - case TypeElement::Connection: - { - return SetLeft(pLeftArg,pElementWhichAdd); - } - case TypeElement::BracketWithIndex: - { - return SetLeft(pLeftArg,pElementWhichAdd); - } - case TypeElement::Index: + switch(pElementWhichAdd->GetBaseType()) { - return SetLeft(pLeftArg,pElementWhichAdd); + case TypeElement::BinOperator: + { + return SetLeft(pLeftArg, pElementWhichAdd); + } + case TypeElement::SetOperations: + { + SetLeft(pLeftArg, pElementWhichAdd); + break; + } + case TypeElement::Connection: + { + return SetLeft(pLeftArg,pElementWhichAdd); + } + case TypeElement::BracketWithIndex: + { + return SetLeft(pLeftArg,pElementWhichAdd); + } + case TypeElement::Index: + { + return SetLeft(pLeftArg,pElementWhichAdd); + } + default: + return false; } - default: - break; } + else return false; } CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); - pReader->GetToken(); - pReader->SetTypesToken(); + pReader->ReadingTheNextToken(); while(CheckForLeftArgument(pReader->GetGlobalType()) && (pReader->GetLocalType() != TypeElement::frac || pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt)) { CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); @@ -161,11 +170,7 @@ namespace StarMath CParserStarMathString::AddLeftArgument(pFirstTempElement,pSecondTempElement); } pFirstTempElement = pSecondTempElement; - if(pReader->EmptyString()) - { - pReader->GetToken(); - pReader->SetTypesToken(); - } + pReader->ReadingTheNextToken(); } return pFirstTempElement; } @@ -430,7 +435,6 @@ namespace StarMath } } -//нет phantom, rgb, 16 , гарнитуры и кегля TypeElement CAttribute::GetTypeColorAttribute(const std::wstring &wsToken) { if(L"color" == wsToken) return TypeElement::color; @@ -649,14 +653,14 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - if((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) + while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { - CElement* pBinOp = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); - SetRightArg(pBinOp); + CElement* pElementWithRightArgument = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pElementWithRightArgument); + pTempElement = pElementWithRightArgument; + pReader->ReadingTheNextToken(); } - else - SetRightArg(pTempElement); + SetRightArg(pTempElement); } } void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) @@ -860,8 +864,13 @@ namespace StarMath pReader->FindingTheEndOfParentheses(); while(pReader->CheckIteratorPosition()) { + if(pReader->GetLocalType() == TypeElement::newline) + { + m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + pReader->ClearReader(); + } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType())) + if(pTempElement!= nullptr &&( !m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType()))) { if(CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement)) m_arBrecketValue.pop_back(); @@ -1403,13 +1412,14 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { CElement* pElement = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTempElement,pElement); - SetRightArg(pElement); + pTempElement = pElement; + pReader->ReadingTheNextToken(); } - else SetRightArg(pTempElement); + SetRightArg(pTempElement); } void CElementSetOperations::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1526,17 +1536,16 @@ namespace StarMath } void CElementConnection::Parse(CStarMathReader *pReader) { -// pReader->SetAttribute(GetAttribute()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - if((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) { -// pReader->SetAttribute(GetAttribute()); - CElement* pBinOp = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pBinOp); - SetRightArg(pBinOp); + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pElement); + pTempElement = pElement; + pReader->ReadingTheNextToken(); } - else SetRightArg(pTempElement); + SetRightArg(pTempElement); } void CElementConnection::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -1891,17 +1900,17 @@ namespace StarMath { CElement* pTemp = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - if(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + while(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddLeftArgument(pTemp,pTempElement); pTemp = pTempElement; + pReader->ReadingTheNextToken(); } SetValueFunction(pTemp); } else SetValueFunction(nullptr); - //pReader->ClearReader(); } void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 1e5d2c77bff..954c7e6c490 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -395,7 +395,7 @@ namespace StarMath static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); - static bool CheckForLeftArgument(const TypeElement& enType); + static bool CheckForLeftArgument(const TypeElement& enType ); static CElement* ReadingWithoutBracket(CStarMathReader* pReader); private: std::vector m_arEquation; From c43536c61858f75810caa0f9b9f1dbfddd2429b6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 9 Feb 2024 15:00:55 +0600 Subject: [PATCH 289/794] Fix strings to shared strings conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 7d79964207a..6289c616c49 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1633,7 +1633,7 @@ namespace OOX m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeSharedString); } } - else if (SimpleTypes::Spreadsheet::celltypeStr == m_oType->GetValue() || SimpleTypes::Spreadsheet::celltypeError == m_oType->GetValue()) + else if ((SimpleTypes::Spreadsheet::celltypeStr == m_oType->GetValue() || SimpleTypes::Spreadsheet::celltypeError == m_oType->GetValue()) && !m_oFormula.IsInit()) { if (m_oValue.IsInit()) { From 80782f371c68c9b3a39c376bd340ede093ecfcba Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 9 Feb 2024 15:01:14 +0600 Subject: [PATCH 290/794] Fix pcdi conversion --- OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 2 - OOXML/XlsxFormat/Pivot/Pivots.cpp | 145 ++++++++++-------- 2 files changed, 85 insertions(+), 62 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 9111c189735..114093b2c8f 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -92,8 +92,6 @@ namespace OOX nullable m_oMinDate; nullable m_oMaxDate; nullable m_oCount; - private: - XLS::BaseObjectPtr parsePCDI(XLS::BaseObjectPtr object); }; class COLAPGroupItems : public WritingElementWithChilds { diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 921b4c06d24..684274ac5bd 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -1849,7 +1849,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } - XLS::BaseObjectPtr CFieldItem::toBin() + XLS::BaseObjectPtr CFieldItem::toBin()// fix name init { auto ptr1(new XLSB::SXVI); XLS::BaseObjectPtr objectPtr(ptr1); @@ -1870,7 +1870,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oMissing.IsInit()) ptr->fMissing = m_oMissing.get(); if(m_oUserCaption.IsInit()) + { ptr->displayName = m_oUserCaption.get(); + ptr->fDisplayName = true; + } + else + { + ptr->fDisplayName = false; + } if(m_oCharacter.IsInit()) ptr->fOlapFilterSelected = m_oCharacter.get(); if(m_oHideDetails.IsInit()) @@ -4184,66 +4191,53 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_BrtBeginPCDFAtbl = writeAttributes(); for(auto i:m_arrItems) { - auto valueBool = static_cast(i); - if(valueBool) + + if(i->getType() == et_x_PivotBooleanValue) { - XLS::BaseObjectPtr element= valueBool->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + auto valueBool = static_cast(i); + XLS::BaseObjectPtr element = valueBool->toBin(); + ptr->m_arSource.push_back(element); continue; } - auto noVal = static_cast(i); - if(noVal) + else if(i->getType() == et_x_PivotNoValue) { + auto noVal = static_cast(i); XLS::BaseObjectPtr element = noVal->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + ptr->m_arSource.push_back(element); continue; } - auto numVal = static_cast(i); - if(numVal) + else if(i->getType() == et_x_PivotNumericValue) { + auto numVal = static_cast(i); XLS::BaseObjectPtr element = numVal->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + ptr->m_arSource.push_back(element); continue; } - auto charVal = static_cast(i); - if(charVal) + else if(i->getType() == et_x_PivotCharacterValue) { + auto charVal = static_cast(i); XLS::BaseObjectPtr element = charVal->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + ptr->m_arSource.push_back(element); continue; } - auto dateValue = static_cast(i); - if(dateValue) + else if(i->getType() == et_x_PivotDateTimeValue) { + auto dateValue = static_cast(i); XLS::BaseObjectPtr element = dateValue->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + ptr->m_arSource.push_back(element); continue; } - auto errorVal = static_cast(i); - if(errorVal) + else if(i->getType() == et_x_PivotErrorValue) { + auto errorVal = static_cast(i); XLS::BaseObjectPtr element = errorVal->toBin(); - ptr->m_arSource.push_back(parsePCDI(element)); + ptr->m_arSource.push_back(element); continue; } } return objectPtr; } - XLS::BaseObjectPtr CSharedItems::parsePCDI(XLS::BaseObjectPtr object) - { - if(object->get_type() == XLS::typePCDI) - { - auto ptr1(new XLSB::PCDI); - ptr1->m_source = object; - return XLS::BaseObjectPtr{ptr1}; - } - else if(object->get_type() == XLS::typePCDIA) - { - auto ptr1(new XLSB::PCDIA); - ptr1->m_source = object; - return XLS::BaseObjectPtr{ptr1}; - } - } + XLS::BaseObjectPtr CSharedItems::writeAttributes() { auto ptr(new XLSB::BeginPCDFAtbl); @@ -4960,6 +4954,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) { auto ptr(new XLSB::PCDIAString); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); @@ -4976,7 +4972,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDIString); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->st = m_oValue.get(); if(m_oBold.IsInit()) @@ -5128,7 +5126,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) { auto ptr(new XLSB::PCDIAError); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) { if (m_oValue == L"#NULL!") ptr->err = 0x00; @@ -5155,7 +5155,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDIError); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) { if (m_oValue == L"#NULL!") ptr->err = 0x00; @@ -5338,7 +5340,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) { auto ptr(new XLSB::PCDIANumber); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); if(m_oCalculated.IsInit()) @@ -5354,7 +5358,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDINumber); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->xnum.data.value = m_oValue.get(); if(m_oBold.IsInit()) @@ -5488,7 +5494,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) { auto ptr(new XLSB::PCDIADatetime); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); if(m_oCalculated.IsInit()) @@ -5504,7 +5512,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDIDatetime); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->datetime.fromString(m_oValue->GetValue()); @@ -5604,7 +5614,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCalculated.IsInit() || m_oUnused.IsInit() || m_oCount.IsInit() || !m_arrItems.empty() || m_oCaption.IsInit()) { auto ptr(new XLSB::PCDIABoolean); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->f = m_oValue.get(); if(m_oCalculated.IsInit()) @@ -5622,7 +5634,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDIBoolean); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->f = m_oValue.get(); return objectPtr; @@ -5738,7 +5752,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" || m_oBackColor.IsInit() || m_oForeColor.IsInit()) { auto ptr(new XLSB::PCDIMissing); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDI); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oBold.IsInit()) ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); if(m_oItalic.IsInit()) @@ -5758,7 +5774,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else { auto ptr(new XLSB::PCDIAMissing); - XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::PCDIA); + ptr1->m_source = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr(ptr1); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); if(m_oCalculated.IsInit()) @@ -6822,51 +6840,58 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptrPCDIDT(new XLSB::PCDIDT); - auto boolValue = static_cast(i); - if(boolValue) + + if(i->getType() == et_x_PivotBooleanValue) { + auto boolValue = static_cast(i); ptrPCDIDT->m_source = boolValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto dataValue = static_cast(i); - if(dataValue) + + else if(i->getType() == et_x_PivotDateTimeValue) { + auto dataValue = static_cast(i); ptrPCDIDT->m_source = dataValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto errorValue = static_cast(i); - if(errorValue) + + else if(i->getType() == et_x_PivotErrorValue) { + auto errorValue = static_cast(i); ptrPCDIDT->m_source = errorValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto noValue = static_cast(i); - if(noValue) + + else if(i->getType() == et_x_PivotNoValue) { + auto noValue = static_cast(i); ptrPCDIDT->m_source = noValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto numValue = static_cast(i); - if(numValue) + + else if(i->getType() == et_x_PivotNumericValue) { + auto numValue = static_cast(i); ptrPCDIDT->m_source = numValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto charValue = static_cast(i); - if(charValue) + + else if(i->getType() == et_x_PivotCharacterValue) { + auto charValue = static_cast(i); ptrPCDIDT->m_source = charValue->toBin(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; } - auto itemIndex = static_cast(i); - if(charValue) + + else if(i->getType() == et_x_SharedItemsIndex) { + auto itemIndex = static_cast(i); ptrPCDIDT->m_source = itemIndex->toBinItemIndex(); ptr1->m_arPCDIDT.push_back(XLS::BaseObjectPtr{ptrPCDIDT}); continue; From 479943f5e28a55282eafd5f4f6c6fd76f351328f Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 9 Feb 2024 16:36:54 +0300 Subject: [PATCH 291/794] Improved conversion of html tables to ooxml --- .../3dParty/html/css/src/CCompiledStyle.cpp | 5 + .../3dParty/html/css/src/StyleProperties.cpp | 41 ++++-- Common/3dParty/html/css/src/StyleProperties.h | 13 +- HtmlFile2/htmlfile2.cpp | 123 ++++++++++-------- 4 files changed, 115 insertions(+), 67 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 7de99f83d2a..9e6b4ef38f6 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -305,6 +305,11 @@ namespace NSCSS m_oBorder.SetColor(pPropertie.second, unLevel, bHardMode); break; } + CASE(L"border-collapse"): + { + m_oBorder.SetCollapse(pPropertie.second, unLevel, bHardMode); + break; + } //BORDER TOP CASE(L"border-top"): { diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 3d81d7d703d..d1100d08659 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1353,12 +1353,7 @@ namespace NSCSS wsNewValue.replace(unFoundPos, oAbsValue.first.length(), oAbsValue.second); } - const bool bResult = m_oWidth.SetValue(wsNewValue, unLevel, bHardMode); - - if (m_oWidth != 1.) - m_oWidth += 1.; - - return bResult; + return m_oWidth.SetValue(wsNewValue, unLevel, bHardMode); } bool CBorderSide::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1437,7 +1432,9 @@ namespace NSCSS // BORDER CBorder::CBorder() - {} + { + m_enCollapse.SetMapping({{L"collapse", BorderCollapse::Collapse}, {L"separate", BorderCollapse::Separate}}, BorderCollapse::Separate); + } void CBorder::Equation(CBorder &oFirstBorder, CBorder &oSecondBorder) { @@ -1495,6 +1492,11 @@ namespace NSCSS return bResult; } + bool CBorder::SetCollapse(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_enCollapse.SetValue(wsValue, unLevel, bHardMode); + } + bool CBorder::SetLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { return m_oLeft.SetValue(wsValue, unLevel, bHardMode); @@ -1602,6 +1604,11 @@ namespace NSCSS return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; } + const CEnum &CBorder::GetCollapse() const + { + return m_enCollapse; + } + const CBorderSide& CBorder::GetLeftBorder() const { return m_oLeft; @@ -2304,7 +2311,16 @@ namespace NSCSS { Clear(); - m_pColor = new std::wstring(wsValue); + if (6 != wsValue.length() && 3 != wsValue.length()) + { + m_enType = ColorEmpty; + return; + } + + if (6 == wsValue.length()) + m_pColor = new std::wstring(wsValue); + else + m_pColor = new std::wstring({wsValue[0], wsValue[0], wsValue[1], wsValue[1], wsValue[2], wsValue[2]}); if (NULL == m_pColor) { @@ -2399,8 +2415,10 @@ namespace NSCSS RELEASEOBJECT(pValue); break; } + default: + break; } - + m_enType = ColorEmpty; } @@ -2433,9 +2451,12 @@ namespace NSCSS return true; } - void CEnum::SetMapping(const std::map &mMap) + void CEnum::SetMapping(const std::map &mMap, int nDefaulvalue) { m_mMap = mMap; + + if (-1 != nDefaulvalue) + m_oValue = nDefaulvalue; } bool CEnum::Empty() const diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 6bf38c7878b..cbfc5711ad7 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -280,7 +280,7 @@ namespace NSCSS CEnum(); bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode) override; - void SetMapping(const std::map& mMap); + void SetMapping(const std::map& mMap, int nDefaulvalue = -1); bool Empty() const override; void Clear() override; @@ -443,6 +443,12 @@ namespace NSCSS bool m_bBlock; }; + typedef enum + { + Collapse, + Separate + } BorderCollapse; + class CBorder { public: @@ -454,6 +460,7 @@ namespace NSCSS bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetCollapse(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); //Left Side bool SetLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); @@ -485,6 +492,8 @@ namespace NSCSS bool Empty() const; bool EqualSides() const; + const CEnum& GetCollapse() const; + const CBorderSide& GetLeftBorder() const; const CBorderSide& GetTopBorder() const; const CBorderSide& GetRightBorder() const; @@ -497,6 +506,8 @@ namespace NSCSS CBorderSide m_oTop; CBorderSide m_oRight; CBorderSide m_oBottom; + + CEnum m_enCollapse; }; class CTextDecorationLine diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 5ffbd267555..ac01f9985ea 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -51,8 +51,10 @@ struct CTc int i; int j; std::wstring sGridSpan = L"1"; + std::wstring sPr = L""; - CTc(int _i, int _j, const std::wstring& sColspan) : i(_i), j(_j), sGridSpan(sColspan) {} + CTc(int _i, int _j, const std::wstring& sColspan, const std::wstring& sTcPr = L"") + : i(_i), j(_j), sGridSpan(sColspan), sPr(sTcPr) {} bool operator==(const CTc& c2) { @@ -1142,8 +1144,35 @@ class CHtmlFile2_Private return true; } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) { + if (oBorder.EqualSides()) + { + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); + + return L"" + + L"" + + L"" + + L""; + } + else + { + const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetTopBorder()); + const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); + const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetBottomBorder()); + const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetRightBorder()); + + return L"" + + L"" + + L"" + + L""; + } + + return L""; + } + + void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const NSCSS::CCompiledStyle& oTableStyle) + { std::vector mTable; int nDeath = m_oLightReader.GetDepth(); int i = 1; // Строка @@ -1161,6 +1190,10 @@ class CHtmlFile2_Private int j = 1; // Столбец oXml->WriteString(L""); + + if (oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + oXml->WriteString(L""); + do { int nColspan = 1; @@ -1179,9 +1212,9 @@ class CHtmlFile2_Private std::vector::iterator it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); while(it1 != mTable.end() || it2 != mTable.end()) { - oXml->WriteString(L""); -// oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L"WriteString(L""); + oXml->WriteString(it1->sPr); + oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); oXml->WriteString(L"\"/>"); @@ -1222,42 +1255,44 @@ class CHtmlFile2_Private } //------------------------- + std::wstring wsTcPr; + if (nWidth > 0) - oXml->WriteString(L""); + wsTcPr += L""; else - oXml->WriteString(L""); + wsTcPr += L""; if(nColspan != 1) - { - oXml->WriteString(L"WriteString(std::to_wstring(nColspan)); - oXml->WriteString(L"\"/>"); - } + wsTcPr += L""; + + if (!oStyle.m_oBorder.Empty()) + wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; + + if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) + wsTcPr += L""; + + std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); -// oXml->WriteString(L""); -// oXml->WriteString(!sBorders.empty() ? sBorders : L""); -// oXml->WriteString(L""); + if (wsVerticalAlign.empty()) + wsTcPr += L""; + else + wsTcPr += L""; if(nRowspan != 1) { oXml->WriteString(L""); std::wstring sColspan = std::to_wstring(nColspan); if(nRowspan == 0) - mTable.push_back({0, j, sColspan}); + mTable.push_back({0, j, sColspan, wsTcPr}); else for(int k = i + 1; k < i + nRowspan; k++) - mTable.push_back({k, j, sColspan}); + mTable.push_back({k, j, sColspan, wsTcPr}); } if(nColspan != 1) j += nColspan - 1; - std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); - - if (wsVerticalAlign.empty()) - oXml->WriteString(L""); - else - oXml->WriteString(L""); + oXml->WriteString(wsTcPr); oXml->WriteString(L""); m_bWasPStyle = false; @@ -1305,9 +1340,9 @@ class CHtmlFile2_Private it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); while(it1 != mTable.end() || it2 != mTable.end()) { - oXml->WriteString(L""); -// oXml->WriteString(!sBorders.empty() ? sBorders : L""); - oXml->WriteString(L"WriteString(L""); + oXml->WriteString(it1->sPr); + oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); oXml->WriteString(L"\"/>"); @@ -1379,33 +1414,7 @@ class CHtmlFile2_Private // borders if (!oStyle.m_oBorder.Empty()) - { - wsTable += L""; - - if (oStyle.m_oBorder.EqualSides()) - { - const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - - wsTable += L"" + - L"" + - L"" + - L""; - } - else - { - const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetTopBorder()); - const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetBottomBorder()); - const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oStyle.m_oBorder.GetRightBorder()); - - wsTable += L"" + - L"" + - L"" + - L""; - } - - wsTable += L""; - } + wsTable += L"" + CreateBorders(oStyle.m_oBorder) + L""; if (!oStyle.m_oMargin.Empty() && (0 < oStyle.m_oMargin.GetTop().ToInt() || 0 < oStyle.m_oMargin.GetBottom().ToInt())) { @@ -1425,6 +1434,8 @@ class CHtmlFile2_Private wsTable += L""; } + else + wsTable += L""; if (!wsAlign.empty()) wsTable += L""; @@ -1498,11 +1509,11 @@ class CHtmlFile2_Private m_bWasSpace = false; } if(sName == L"thead") - readTr(&oHead, sSelectors, oTS); + readTr(&oHead, sSelectors, oTS, oStyle); else if(sName == L"tbody") - readTr(&oBody, sSelectors, oTS); + readTr(&oBody, sSelectors, oTS, oStyle); else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS); + readTr(&oFoot, sSelectors, oTS, oStyle); sSelectors.pop_back(); } From 6f0af189e1343a2b4cea9b2c3fe7dc0ac9585aa2 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 12 Feb 2024 16:05:06 +0500 Subject: [PATCH 292/794] Fix bug #61378 --- OdfFile/Writer/Converter/ConvertDrawing.cpp | 34 ++++++++++++++------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 02306d43b34..8b071518dae 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -1993,6 +1993,26 @@ void OoxConverter::convert_list_level(PPTX::Logic::TextParagraphPr *oox_para_pro odf_context()->styles_context()->lists_styles().end_style_level(); } +static bool is_empty_run_elems(const std::vector& runElems) +{ + using namespace PPTX::Logic; + + auto runIt = std::find_if_not(runElems.begin(), runElems.end(), + [](const RunElem& r) { + return !r.is(); + }); + if (runIt != runElems.end()) + { + const Run& run = runIt->as(); + if (!run.HasText()) + return true; + } + else + return true; + + return false; +} + void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::TextListStyle *oox_list_style) { if (!oox_paragraph)return; @@ -2036,6 +2056,8 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T if (paraPr->ParagraphBullet.is()) list_present = false; } + else + list_present = false; //свойства могут быть приписаны не только к параграфу, но и к самому объекту odf_writer::paragraph_format_properties* paragraph_properties = odf_context()->text_context()->get_paragraph_properties(); odf_writer::text_format_properties* text_properties = odf_context()->text_context()->get_text_properties(); @@ -2061,17 +2083,7 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T } } - std::vector::iterator runIt = std::find_if_not(oox_paragraph->RunElems.begin(), oox_paragraph->RunElems.end(), - [](const PPTX::Logic::RunElem& r) { - return !r.is(); - }); - if (runIt != oox_paragraph->RunElems.end()) - { - const PPTX::Logic::Run& run = runIt->as(); - if (!run.HasText()) - list_present = false; - } - else + if (is_empty_run_elems(oox_paragraph->RunElems)) list_present = false; //if (oox_paragraph->RunElems.empty() && list_present) list_present = false; // ms не обозначает присутствие списка, libra - показывает значек From d65cbf194ad514177874c16fee83a77cf5ab728c Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 13 Feb 2024 10:21:49 +0300 Subject: [PATCH 293/794] Added TextAssociationTypes --- DocxRenderer/src/logic/Page.cpp | 311 +++++++++--------- DocxRenderer/src/logic/Page.h | 4 +- DocxRenderer/src/resources/VectorGraphics.cpp | 1 + 3 files changed, 156 insertions(+), 160 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index cd4d3ccd253..49ed396b76b 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1119,6 +1119,106 @@ namespace NSDocxRenderer v_type == eVerticalCrossingType::vctNoCrossingCurrentBelowNext; }; + // после переместим все в output objects + std::vector> ar_paragraphs; + + double avg_spacing{0.0}; + size_t avg_spacing_n{0}; + + double min_left{m_dWidth}; + double max_right{0.0}; + + // совпадает ли left, right, center со строкой ниже + struct Position { + bool left{false}; + bool center{false}; + bool right {false}; + }; + + // параграф будет набиваться строчками + auto paragraph = std::make_shared(); + + // lamda to setup and add paragpraph + auto add_paragraph = [this, &max_right, &min_left, &ar_paragraphs] (std::shared_ptr& paragraph) { + + paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; + paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; + paragraph->m_dRight = max_right; + paragraph->m_dLeft = min_left; + + paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; + paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; + + paragraph->m_dRightBorder = m_dWidth - max_right; + paragraph->m_dLeftBorder = min_left; + + paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); + paragraph->m_bIsNeedFirstLineIndent = false; + paragraph->m_dFirstLine = 0; + paragraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); + + paragraph->MergeLines(); + + // setting TextAlignmentType + if (paragraph->m_arLines.size() > 1) + { + Position position_curr = {true, true, true}; + bool first_left = false; + + for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) + { + auto& curr_line = paragraph->m_arLines[index]; + auto& prev_line = paragraph->m_arLines[index - 1]; + + // indent check + if (index == 1) + first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + else + position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; + auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; + + position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; + } + if (position_curr.left && position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; + else if (position_curr.left) + paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; + else if (position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByRight; + else if (position_curr.center) + paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; + + // indent check + if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) + { + paragraph->m_bIsNeedFirstLineIndent = true; + paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; + } + } + + if (ar_paragraphs.empty()) + paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; + else + paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; + + ar_paragraphs.push_back(std::move(paragraph)); + paragraph = std::make_shared(); + + min_left = m_dWidth; + max_right = 0.0; + }; + + // lamda to add line and setup min_left/max_right + auto add_line = [&min_left, &max_right] (std::shared_ptr& paragraph, std::shared_ptr& curr_line) { + min_left = std::min(min_left, curr_line->m_dLeft); + max_right = std::max(max_right, curr_line->m_dRight); + paragraph->m_arLines.push_back(curr_line); + }; + // линии из которых сделаем шейпы for (size_t index = 0; index < m_arTextLines.size(); ++index) { @@ -1126,21 +1226,14 @@ namespace NSDocxRenderer if (!curr_line) continue; - // 1 строчка в параграфе - if (m_eTextAssociationType == TextAssociationType::tatShapeLine) - { - CreateSingleLineShape(curr_line); - continue; - } - // если у текущей линии есть дубликаты, то создаем из них шейпы if (curr_line->m_iNumDuplicates > 0) { size_t duplicates = curr_line->m_iNumDuplicates; - CreateSingleLineShape(curr_line); + m_arShapes.push_back(CreateSingleLineShape(curr_line)); while (duplicates > 0) { - CreateSingleLineShape(curr_line); + m_arShapes.push_back(CreateSingleLineShape(curr_line)); duplicates--; } continue; @@ -1189,7 +1282,7 @@ namespace NSDocxRenderer } } - if(m_arTextLines.empty()) + if (m_arTextLines.empty()) return; // переместим nullptr в конец и удалим @@ -1201,30 +1294,22 @@ namespace NSDocxRenderer return a->m_dBaselinePos < b->m_dBaselinePos; }); - - // todo обработать все TextAssociationType - // параграф будет набиваться строчками - auto paragraph = std::make_shared(); - - // после переместим все в output objects - std::vector> ar_paragraphs; - - double avg_spacing{0.0}; - size_t avg_spacing_n{0}; - - double min_left{m_dWidth}; - double max_right{0.0}; + // 1 строчка в параграфе + if (m_eTextAssociationType == TextAssociationType::tatPlainLine || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for (auto& curr_line : m_arTextLines) + { + add_line(paragraph, curr_line); + add_paragraph(paragraph); + } + } // ar_spacing[index]- расстояние строки до строки снизу // если 0.0 - строка последняя std::vector ar_spacings(m_arTextLines.size(), 0.0); - // совпадает ли left, right, center со строкой ниже - struct Position { - bool left{false}; - bool center{false}; - bool right {false}; - }; + // позиции относительно других линий std::vector ar_positions(m_arTextLines.size()); // если ar_delims[index] == true, после строчки index нужно начинать новый параграф @@ -1309,99 +1394,22 @@ namespace NSDocxRenderer ar_delims[index] = true; } - // lamda to setup and add paragpraph - auto add_paragraph = [&] () { - - paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; - paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; - paragraph->m_dRight = max_right; - paragraph->m_dLeft = min_left; - - paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; - paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; - - paragraph->m_dRightBorder = m_dWidth - max_right; - paragraph->m_dLeftBorder = min_left; - - paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); - paragraph->m_bIsNeedFirstLineIndent = false; - paragraph->m_dFirstLine = 0; - paragraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); - - paragraph->MergeLines(); - - // setting TextAlignmentType - if (paragraph->m_arLines.size() > 1) + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatParagraphToShape) + { + // на основе ar_delims разбиваем на параграфы + IsShadingPresent + for (size_t index = 0; index < ar_delims.size(); ++index) { - Position position_curr = {true, true, true}; - bool first_left = false; - - for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) + if (m_arTextLines[index]->m_pDominantShape) { - auto& curr_line = paragraph->m_arLines[index]; - auto& prev_line = paragraph->m_arLines[index - 1]; - - // indent check - if (index == 1) - first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - else - position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; - auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; - - position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; - } - if (position_curr.left && position_curr.right) - paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; - else if (position_curr.left) - paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; - else if (position_curr.right) - paragraph->m_eTextAlignmentType = CParagraph::tatByRight; - else if (position_curr.center) - paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; - - // indent check - if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) - { - paragraph->m_bIsNeedFirstLineIndent = true; - paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; + paragraph->m_bIsShadingPresent = true; + paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; + paragraph->RemoveHighlightColor(); } + add_line(paragraph, m_arTextLines[index]); + if (ar_delims[index] || index == ar_delims.size() - 1) + add_paragraph(paragraph); } - - if (ar_paragraphs.empty()) - paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; - else - paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; - - ar_paragraphs.push_back(std::move(paragraph)); - paragraph = std::make_shared(); - - min_left = m_dWidth; - max_right = 0.0; - }; - - // lamda to add line and setup min_left/max_right - auto add_line = [&min_left, &max_right, ¶graph] (std::shared_ptr& curr_line) { - min_left = std::min(min_left, curr_line->m_dLeft); - max_right = std::max(max_right, curr_line->m_dRight); - paragraph->m_arLines.push_back(curr_line); - }; - - // на основе ar_delims разбиваем на параграфы + IsShadingPresent - for (size_t index = 0; index < ar_delims.size(); ++index) - { - if (m_arTextLines[index]->m_pDominantShape) - { - paragraph->m_bIsShadingPresent = true; - paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; - paragraph->RemoveHighlightColor(); - } - add_line(m_arTextLines[index]); - if (ar_delims[index] || index == ar_delims.size() - 1) - add_paragraph(); } using paragraph_ptr_t = std::shared_ptr; @@ -1409,11 +1417,22 @@ namespace NSDocxRenderer return a->m_dBaselinePos < b->m_dBaselinePos; }); - for(auto&& p : ar_paragraphs) - m_arOutputObjects.push_back(std::move(p)); + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + for(auto&& p : ar_paragraphs) + m_arOutputObjects.push_back(std::move(p)); + } + + if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for(auto&& p : ar_paragraphs) + m_arShapes.push_back(CreateSingleParagraphShape(p)); + } } - std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr pLine) + std::shared_ptr CPage::CreateSingleLineShape(std::shared_ptr& pLine) { auto pParagraph = std::make_shared(); @@ -1421,7 +1440,7 @@ namespace NSDocxRenderer pParagraph->m_dLeft = pLine->m_dLeft; pParagraph->m_dTop = pLine->m_dTop; pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - pParagraph->m_dWidth = pLine->m_dWidth * 1.05; // чтобы текст точно уместился + pParagraph->m_dWidth = pLine->m_dWidth * 1.03; // чтобы текст точно уместился pParagraph->m_dHeight = pLine->m_dHeight; pParagraph->m_dRight = pLine->m_dRight; @@ -1447,53 +1466,29 @@ namespace NSDocxRenderer return pShape; } - void CPage::CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText) + std::shared_ptr CPage::CreateSingleParagraphShape(std::shared_ptr& pParagraph) { - if (!pParagraph) - return; - - bool bIsShapesPresent = false; - std::shared_ptr pBackShape = nullptr; - - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - if (m_arOutputObjects[i]->m_eType != COutputObject::eOutputType::etShape) - continue; - - bIsShapesPresent = true; - pBackShape = std::dynamic_pointer_cast(m_arOutputObjects[i]); - } - std::shared_ptr pShape; - if (bIsSameTypeText && bIsShapesPresent) - { - pShape = pBackShape; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_arLines.size() + pParagraph->m_dSpaceBefore; - } - else - { - pShape = std::make_shared(); - pParagraph->m_dSpaceBefore = 0; - pShape->m_dHeight = pParagraph->m_dLineHeight * pParagraph->m_arLines.size(); - } - pShape->m_dLeft = pShape->m_dLeft > 0 ? std::min(pShape->m_dLeft, pParagraph->m_dLeft) : pParagraph->m_dLeft; - pShape->m_dTop = pShape->m_dTop > 0 ? std::min(pShape->m_dTop, pParagraph->m_dTop) : pParagraph->m_dTop; - pShape->m_dRight = pShape->m_dRight > 0 ? std::max(pShape->m_dRight, pParagraph->m_dRight) : pParagraph->m_dRight; - pShape->m_dBaselinePos = pShape->m_dBaselinePos > 0 ? std::max(pShape->m_dBaselinePos, pParagraph->m_dBaselinePos) : pParagraph->m_dBaselinePos; - pShape->m_dWidth = fabs(pShape->m_dRight - pShape->m_dLeft); + pShape = std::make_shared(); + pShape->m_dHeight = pParagraph->m_dHeight; + + pShape->m_dLeft = pParagraph->m_dLeft; + pShape->m_dTop = pParagraph->m_dTop; + pShape->m_dRight = pParagraph->m_dRight; + pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; + pShape->m_dWidth = pParagraph->m_dWidth * 1.03; pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; + pParagraph->m_dSpaceBefore = 0; + pParagraph->m_dSpaceAfter = 0; pShape->m_arOutputObjects.push_back(pParagraph); pShape->m_eType = CShape::eShapeType::stTextBox; pShape->m_bIsBehindDoc = false; - if (!bIsSameTypeText) - { - m_arOutputObjects.push_back(pShape); - } + return pShape; } void CPage::WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 362dd5a49b9..0511827a26a 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -113,8 +113,8 @@ namespace NSDocxRenderer void BuildParagraphes(); - std::shared_ptr CreateSingleLineShape(std::shared_ptr pLine); - void CreateShapeFormParagraphs(std::shared_ptr pParagraph, bool bIsSameTypeText); + std::shared_ptr CreateSingleLineShape(std::shared_ptr& pLine); + std::shared_ptr CreateSingleParagraphShape(std::shared_ptr& pParagraph); void MergeShapes(); void CalcSelected(); diff --git a/DocxRenderer/src/resources/VectorGraphics.cpp b/DocxRenderer/src/resources/VectorGraphics.cpp index 9fc6673cf28..442b2df7ce8 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "VectorGraphics.h" From 1eec0cffdb3148601b36ed5943ea7c237c9ab391 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 13 Feb 2024 14:08:28 +0300 Subject: [PATCH 294/794] Update paragraph logic in progress --- DocxRenderer/src/logic/Page.cpp | 56 ++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 49ed396b76b..5be77347a8c 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1358,14 +1358,43 @@ namespace NSDocxRenderer ar_delims[index] = true; } + // большая высота между строками + for (size_t index = 0; index < ar_spacings.size() - 1; ++index) + { + // если разница больше чем срединий в три раза - отделим + if (ar_spacings[index] > avg_spacing * 3) + ar_delims[index] = true; + } + // width check (слишком большая разница в ширине) for (size_t index = 1; index < ar_spacings.size(); ++index) { - double width_diff = fabs(m_arTextLines[index - 1]->m_dWidth - m_arTextLines[index]->m_dWidth); - bool big_diff = width_diff > std::min(m_arTextLines[index - 1]->m_dWidth, m_arTextLines[index - 1]->m_dWidth) * 3; + double diff = 0; + if (ar_positions[index - 1].right) + diff = m_arTextLines[index - 1]->m_dLeft - m_arTextLines[index]->m_dLeft; + else if (ar_positions[index - 1].center) + diff = m_arTextLines[index - 1]->m_dWidth - m_arTextLines[index]->m_dWidth; + else + diff = m_arTextLines[index - 1]->m_dRight - m_arTextLines[index]->m_dRight; + + bool big_diff = fabs(diff) > std::min(m_arTextLines[index - 1]->m_dWidth, m_arTextLines[index]->m_dWidth) * 3; + bool is_first_less = diff < 0; + + + // два случая + // Text (end paragraph) + // bla-bla-bla (end paragraph) + // + // bla-bla-bla (\n) + // bla (end paragraph) + if (big_diff) + { + if (is_first_less) + ar_delims[index - 1] = true; + else + ar_delims[index] = true; + } - if (big_diff && !ar_delims[index]) - ar_delims[index - 1] = true; } // alignment check @@ -1386,8 +1415,21 @@ namespace NSDocxRenderer else is_first_line = false; - if (is_first_line && !position_bot.right && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) - position_bot.left = true; + // первая строка может быть с отступом + if (is_first_line && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) + { + // если больше трех линий - проверим третью + if (index < ar_positions.size() - 2) + { + if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) + position_bot.left = true; + else + position_bot.left = false; + } + else + position_bot.left = true; + } + bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); if (is_unknown) @@ -1477,7 +1519,7 @@ namespace NSDocxRenderer pShape->m_dTop = pParagraph->m_dTop; pShape->m_dRight = pParagraph->m_dRight; pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; - pShape->m_dWidth = pParagraph->m_dWidth * 1.03; + pShape->m_dWidth = pParagraph->m_dWidth * 1.03; // чтобы текст точно уместился pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; From 4736f93aa840298d5d1d6ad27f81698249dfb280 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 13 Feb 2024 18:10:17 +0300 Subject: [PATCH 295/794] Fixed the unnecessary appearance of the table border in html to ooxml conversion --- .../html/css/src/xhtml/CDocumentStyle.cpp | 3 +++ HtmlFile2/htmlfile2.cpp | 24 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 580326f5945..64041cdbf09 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -422,6 +422,9 @@ namespace NSCSS std::wstring CDocumentStyle::CalculateBorderStyle(const NSProperties::CBorderSide &oBorder) { + if (oBorder.Empty()) + return L""; + std::wstring wsColor = oBorder.GetColor().ToWString(); std::wstring wsStyle = oBorder.GetStyle().ToWString(); double dWidth = oBorder.GetWidth().ToDouble(Point) * 8; // Так как значение указано в восьмых долях точки diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index ac01f9985ea..db61a958414 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1157,15 +1157,21 @@ class CHtmlFile2_Private } else { - const std::wstring wsTopBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetTopBorder()); - const std::wstring wsLeftBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); - const std::wstring wsBottomBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetBottomBorder()); - const std::wstring wsRightBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetRightBorder()); - - return L"" + - L"" + - L"" + - L""; + std::wstring wsTable; + + if (!oBorder.GetTopBorder().Empty()) + wsTable += L""; + + if (!oBorder.GetLeftBorder().Empty()) + wsTable += L""; + + if (!oBorder.GetBottomBorder().Empty()) + wsTable += L""; + + if (!oBorder.GetRightBorder().Empty()) + wsTable += L""; + + return wsTable; } return L""; From e6ebc76ae610e221fa564fcc11af3c6895974666 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 13 Feb 2024 21:17:18 +0300 Subject: [PATCH 296/794] metadata spreadsheets --- .../Sheets/Common/BinReaderWriterDefines.h | 112 ++ OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 559 +++++++++ OOXML/Binary/Sheets/Reader/BinaryWriter.h | 37 + OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 505 ++++++++ OOXML/Binary/Sheets/Writer/BinaryReader.h | 23 + OOXML/Common/SimpleTypes_Drawing.cpp | 2 +- OOXML/Common/SimpleTypes_Spreadsheet.cpp | 102 ++ OOXML/Common/SimpleTypes_Spreadsheet.h | 35 + OOXML/DocxFormat/Drawing/DrawingExt.cpp | 23 + OOXML/DocxFormat/Drawing/DrawingExt.h | 5 + OOXML/DocxFormat/WritingElement.h | 23 +- .../Linux/DocxFormatLib/DocxFormatLib.pro | 8 +- .../Linux/DocxFormatLib/xlsx_format_logic.cpp | 2 + .../DocxFormatLib/DocxFormatLib.vcxproj | 4 + .../DocxFormatLib.vcxproj.filters | 15 + OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp | 18 + OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp | 20 +- OOXML/XlsxFormat/FileTypes_Spreadsheet.h | 7 + OOXML/XlsxFormat/RichData/RdRichValue.cpp | 233 ++++ OOXML/XlsxFormat/RichData/RdRichValue.h | 108 ++ OOXML/XlsxFormat/Workbook/Metadata.cpp | 1063 +++++++++++++++++ OOXML/XlsxFormat/Workbook/Metadata.h | 506 ++++++++ 22 files changed, 3404 insertions(+), 6 deletions(-) create mode 100644 OOXML/XlsxFormat/RichData/RdRichValue.cpp create mode 100644 OOXML/XlsxFormat/RichData/RdRichValue.h create mode 100644 OOXML/XlsxFormat/Workbook/Metadata.cpp create mode 100644 OOXML/XlsxFormat/Workbook/Metadata.h diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index e88d7c0c81d..d29f7c20f71 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -238,6 +238,7 @@ namespace BinXlsxRW ExternalLinksAutoRefresh = 26, TimelineCaches = 27, TimelineCache = 28, + Metadata = 29 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -662,6 +663,7 @@ namespace BinXlsxRW ChildChain = 5, NewThread = 6 };} +//------------------------------------------------------------------------------------------------------------------------------ namespace c_oSer_Timeline {enum c_oSer_Timeline { Name = 0, @@ -717,6 +719,116 @@ namespace BinXlsxRW Name = 0, TabId = 1 };} +//------------------------------------------------------------------------------------------------------------------------------ + namespace c_oSer_Metadata { enum c_oSer_Metadata + { + MetadataTypes = 0, + MetadataStrings = 1, + MdxMetadata = 2, + CellMetadata = 3, + ValueMetadata = 4, + FutureMetadata = 5, + };} + namespace c_oSer_MetadataType { enum c_oSer_MetadataType + { + MetadataType = 0, + Name = 1, + MinSupportedVersion = 2, + GhostRow = 3, + GhostCol = 4, + Edit = 5, + Delete = 6, + Copy = 7, + PasteAll = 8, + PasteFormulas = 9, + PasteValues = 10, + PasteFormats = 11, + PasteComments = 12, + PasteDataValidation = 13, + PasteBorders = 14, + PasteColWidths = 15, + PasteNumberFormats = 16, + Merge = 17, + SplitFirst = 18, + SplitAll = 19, + RowColShift = 30, + ClearAll = 21, + ClearFormats = 22, + ClearContents = 23, + ClearComments = 24, + Assign = 25, + Coerce = 26, + CellMeta = 27, + };} + namespace c_oSer_MetadataString {enum c_oSer_MetadataString + { + MetadataString = 0, + + };} + namespace c_oSer_MetadataBlock {enum c_oSer_MetadataBlock + { + MetadataBlock = 0, + MetadataRecord = 1, + MetadataRecordType = 2, + MetadataRecordValue = 3, + };} + namespace c_oSer_FutureMetadataBlock {enum c_oSer_FutureMetadataBlock + { + Name = 0, + FutureMetadataBlock = 1, + RichValueBlock = 2, + DynamicArrayProperties = 3, + DynamicArray = 4, + CollapsedArray = 5 + };} + namespace c_oSer_MdxMetadata {enum c_oSer_MdxMetadata + { + Mdx = 0, + NameIndex = 1, + FunctionTag = 2, + MdxTuple = 3, + MdxSet = 4, + MdxKPI = 5, + MdxMemeberProp = 6 + };} + namespace c_oSer_MetadataMdxTuple { enum c_oSer_MetadataMdxTuple + { + IndexCount = 0, + CultureCurrency = 1, + StringIndex = 2, + NumFmtIndex = 3, + BackColor = 4, + ForeColor = 5, + Italic = 6, + Underline = 7, + Strike = 8, + Bold = 9, + MetadataStringIndex = 10 + };} + namespace c_oSer_MetadataStringIndex {enum c_oSer_MetadataStringIndex + { + StringIsSet = 0, + IndexValue = 1 + };} + namespace c_oSer_MetadataMdxSet {enum c_oSer_MetadataMdxSet + { + Count = 0, + Index = 1, + SortOrder = 2, + MetadataStringIndex = 3 + };} + namespace c_oSer_MetadataMdxKPI {enum c_oSer_MetadataMdxKPI + { + NameIndex = 0, + Index = 1, + Property = 2 + };} + namespace c_oSer_MetadataMemberProperty {enum c_oSer_MetadataMemberProperty + { + NameIndex = 0, + Index = 1 + };} +//------------------------------------------------------------------------------------------------------------------------------ namespace c_oSerCustoms {enum c_oSerCustoms { Custom = 0, diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index ba79f56c674..bbbb71ad285 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -71,6 +71,7 @@ #include "../../../XlsxFormat/Styles/dxf.h" #include "../../../XlsxFormat/Styles/TableStyles.h" #include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" #include "../../../../DesktopEditor/common/Directory.h" @@ -2263,6 +2264,14 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb m_oBcw.m_oStream.WriteStringW3(*workbook.m_oOleSize); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + pFile = workbook.Find(OOX::Spreadsheet::FileTypes::Metadata); + OOX::Spreadsheet::CMetadataFile* pMetadataFile = dynamic_cast(pFile.GetPointer()); + if ((pMetadataFile) && (pMetadataFile->m_oMetadata.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Metadata); + WriteMetadata(pMetadataFile->m_oMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorkbookTableWriter::WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing) { @@ -3538,6 +3547,556 @@ void BinaryWorkbookTableWriter::WriteTimelineState(OOX::Spreadsheet::CTimelineSt m_oBcw.WriteItemWithLengthEnd(nCurPos); } } +void BinaryWorkbookTableWriter::WriteMetadata(OOX::Spreadsheet::CMetadata* pMetadata) +{ + if (!pMetadata) return; + + int nCurPos = 0; + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataTypes); + WriteMetadataTypes(pMetadata->m_oMetadataTypes.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataStrings); + WriteMetadataStrings(pMetadata->m_oMetadataStrings.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMdxMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MdxMetadata); + WriteMdxMetadata(pMetadata->m_oMdxMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::CellMetadata); + WriteMetadataBlocks(pMetadata->m_oCellMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::ValueMetadata); + WriteMetadataBlocks(pMetadata->m_oValueMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMetadata->m_arFutureMetadata.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::FutureMetadata); + WriteFutureMetadata(pMetadata->m_arFutureMetadata[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataTypes(OOX::Spreadsheet::CMetadataTypes* pMetadataTypes) +{ + if (!pMetadataTypes) return; + + for (size_t i = 0; i < pMetadataTypes->m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MetadataType); + WriteMetadataType(pMetadataTypes->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataType(OOX::Spreadsheet::CMetadataType* pMetadataType) +{ + if (!pMetadataType) return; + + if (pMetadataType->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Name); + m_oBcw.m_oStream.WriteStringW3(*pMetadataType->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMinSupportedVersion.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MinSupportedVersion); + m_oBcw.m_oStream.WriteULONG(*pMetadataType->m_oMinSupportedVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostRow.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostRow); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostRow); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostCol.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostCol); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostCol); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oEdit.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Edit); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oEdit); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oDelete.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Delete); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oDelete); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCopy.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Copy); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCopy); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormulas.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormulas); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormulas); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteValues.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteValues); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteValues); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteDataValidation.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteDataValidation); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteDataValidation); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteBorders.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteBorders); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteBorders); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteColWidths.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteColWidths); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteColWidths); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteNumberFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteNumberFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteNumberFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMerge.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Merge); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oMerge); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitFirst.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitFirst); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitFirst); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oRowColShift.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::RowColShift); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oRowColShift); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearContents.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearContents); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearContents); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oAssign.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Assign); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oAssign); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCoerce.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Coerce); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCoerce); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCellMeta.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::CellMeta); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCellMeta); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStrings(OOX::Spreadsheet::CMetadataStrings* pMetadataStrings) +{ + if (!pMetadataStrings) return; + + for (size_t i = 0; i < pMetadataStrings->m_arrItems.size(); ++i) + { + if ((pMetadataStrings->m_arrItems[i]) && (pMetadataStrings->m_arrItems[i]->m_oV.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataString::MetadataString); + m_oBcw.m_oStream.WriteStringW3(pMetadataStrings->m_arrItems[i]->m_oV.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteMdxMetadata(OOX::Spreadsheet::CMdxMetadata* pMdxMetadata) +{ + if (!pMdxMetadata) return; + + for (size_t i = 0; i < pMdxMetadata->m_arrItems.size(); ++i) + { + if (!pMdxMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::Mdx); + WriteMdx(pMdxMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdx(OOX::Spreadsheet::CMdx* pMdx) +{ + if (!pMdx) return; + + if (pMdx->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdx->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oF.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::NameIndex); + m_oBcw.m_oStream.WriteBYTE(pMdx->m_oF->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxTuple.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxTuple); + WriteMdxTuple(pMdx->m_oMdxTuple.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxSet.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxSet); + WriteMdxSet(pMdx->m_oMdxSet.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oCMdxKPI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxKPI); + WriteMdxKPI(pMdx->m_oCMdxKPI.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxMemeberProp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxMemeberProp); + WriteMdxMemeberProp(pMdx->m_oMdxMemeberProp.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxTuple(OOX::Spreadsheet::CMdxTuple* pMdxTuple) +{ + if (!pMdxTuple) return; + + if (pMdxTuple->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::IndexCount); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oCt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::CultureCurrency); + m_oBcw.m_oStream.WriteStringW3(*pMdxTuple->m_oCt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::StringIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oSi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::NumFmtIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oBc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::BackColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oBc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::ForeColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Italic); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oI); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oB.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Bold); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oB); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oU.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Underline); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oU); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Strike); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oSt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxTuple->m_arrItems.size(); ++i) + { + if (!pMdxTuple->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::MetadataStringIndex); + WriteMetadataStringIndex(pMdxTuple->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStringIndex(OOX::Spreadsheet::CMetadataStringIndex* pStringIndex) +{ + if (!pStringIndex) return; + + if (pStringIndex->m_oX.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::IndexValue); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oX); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pStringIndex->m_oS.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::StringIsSet); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oS); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxSet(OOX::Spreadsheet::CMdxSet* pMdxSet) +{ + if (!pMdxSet) return; + + if (pMdxSet->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Count); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oNs.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oNs); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oO.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::SortOrder); + m_oBcw.m_oStream.WriteBYTE(pMdxSet->m_oO->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxSet->m_arrItems.size(); ++i) + { + if (!pMdxSet->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::MetadataStringIndex); + WriteMetadataStringIndex(pMdxSet->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxKPI(OOX::Spreadsheet::CMdxKPI* pMdxKPI) +{ + if (!pMdxKPI) return; + + if (pMdxKPI->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oP.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Property); + m_oBcw.m_oStream.WriteBYTE(pMdxKPI->m_oP->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxMemeberProp(OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp) +{ + if (!pMdxMemeberProp) return; + + if (pMdxMemeberProp->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxMemeberProp->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks) +{ + if (!pMetadataBlocks) return; + + for (size_t i = 0; i < pMetadataBlocks->m_arrItems.size(); ++i) + { + if (!pMetadataBlocks->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataBlock); + WriteMetadataBlock(pMetadataBlocks->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock) +{ + if (!pMetadataBlock) return; + + for (size_t i = 0; i < pMetadataBlock->m_arrItems.size(); ++i) + { + if (!pMetadataBlock->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecord); + WriteMetadataRecord(pMetadataBlock->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord) +{ + if (!pMetadataRecord) return; + + if (pMetadataRecord->m_oT.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordType); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oT); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataRecord->m_oV.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordValue); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oV); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteFutureMetadataBlock(OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock) +{ + if (!pFutureMetadataBlock) return; + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) return; + + for (size_t i = 0; i < pFutureMetadataBlock->m_oExtLst->m_arrExt.size(); ++i) + { + if (!pFutureMetadataBlock->m_oExtLst->m_arrExt[i]) continue; + + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArrayProperties); + { + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + + } + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::CollapsedArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + } + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if ((pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock.IsInit()) && + (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::RichValueBlock); + m_oBcw.m_oStream.WriteULONG(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pFutureMetadata) +{ + if (!pFutureMetadata) return; + + if (pFutureMetadata->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::Name); + m_oBcw.m_oStream.WriteStringW3(*pFutureMetadata->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pFutureMetadata->m_arrItems.size(); ++i) + { + if (!pFutureMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::FutureMetadataBlock); + WriteFutureMetadataBlock(pFutureMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} + void BinaryWorkbookTableWriter::WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange) { if (!pTimelineRange) return; diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.h b/OOXML/Binary/Sheets/Reader/BinaryWriter.h index bead4217d97..f07dd9d740a 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.h +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.h @@ -84,6 +84,23 @@ namespace OOX class CTimelineStyle; class CTimelineStyles; class CTimelineStyleElement; + + class CMetadata; + class CFutureMetadata; + class CFutureMetadataBlock; + class CMetadataBlocks; + class CMetadataBlock; + class CMetadataRecord; + class CMetadataTypes; + class CMetadataType; + class CMdxMetadata; + class CMdxKPI; + class CMdxMemeberProp; + class CMdxTuple; + class CMdx; + class CMdxSet; + class CMetadataStrings; + class CMetadataStringIndex; } } @@ -188,6 +205,7 @@ namespace BinXlsxRW void WriteWorkbookView(const OOX::Spreadsheet::CWorkbookView& workbookView); void WriteDefinedNames(const OOX::Spreadsheet::CDefinedNames& definedNames); void WriteCalcPr(const OOX::Spreadsheet::CCalcPr& CCalcPr); + void WriteConnections(const OOX::Spreadsheet::CConnections& connections); void WriteConnection(const OOX::Spreadsheet::CConnection& connection); void WriteConnectionDbPr(const OOX::Spreadsheet::CDbPr& dbPr); @@ -197,6 +215,7 @@ namespace BinXlsxRW void WriteConnectionTextField(const OOX::Spreadsheet::CTextField& textField); void WriteConnectionWebPr(const OOX::Spreadsheet::CWebPr& webPr); void WriteConnectionRangePr(const OOX::Spreadsheet::CRangePr& rangePr); + void WriteExternalReferences(const OOX::Spreadsheet::CExternalReferences& externalReferences, OOX::Spreadsheet::CWorkbook& workbook); void WriteExternalBook(const OOX::Spreadsheet::CExternalBook& externalBook, OOX::Spreadsheet::CExternalLink* pExternalLink); void WriteExternalAlternateUrls(const OOX::Spreadsheet::CAlternateUrls& alternateUrls, OOX::Spreadsheet::CExternalLink* pExternalLink); @@ -207,6 +226,7 @@ namespace BinXlsxRW void WriteExternalSheetData(const OOX::Spreadsheet::CExternalSheetData& sheetData); void WriteExternalRow(const OOX::Spreadsheet::CExternalRow& row); void WriteExternalCell(const OOX::Spreadsheet::CExternalCell& cell); + void WriteOleLink(const OOX::Spreadsheet::COleLink& oleLink, const std::wstring& sLink); void WriteOleItem(const OOX::Spreadsheet::COleItem& oleItem); void WriteDdeLink(const OOX::Spreadsheet::CDdeLink& ddeLink); @@ -216,6 +236,7 @@ namespace BinXlsxRW void WriteDefinedName(const OOX::Spreadsheet::CDefinedName& definedName); void WriteSlicerCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CSlicerCaches& oSlicerCaches); void WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing); + void WriteTimelineCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CTimelineCacheRefs& oTimelineCacheRefs); void WriteTimelineCache(OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache); void WriteTimelineState(OOX::Spreadsheet::CTimelineState* pState); @@ -224,6 +245,22 @@ namespace BinXlsxRW void WriteTimelineCachePivotTable(OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable); void WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange); + void WriteMetadata(OOX::Spreadsheet::CMetadata* pMetadata); + void WriteMetadataTypes(OOX::Spreadsheet::CMetadataTypes* pMetadataTypes); + void WriteMetadataType(OOX::Spreadsheet::CMetadataType* pMetadataType); + void WriteMetadataStrings(OOX::Spreadsheet::CMetadataStrings* pMetadataStrings); + void WriteMdxMetadata(OOX::Spreadsheet::CMdxMetadata* pMdxMetadata); + void WriteMdx(OOX::Spreadsheet::CMdx* pMdx); + void WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks); + void WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock); + void WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord); + void WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pMetadata); + void WriteFutureMetadataBlock(OOX::Spreadsheet::CFutureMetadataBlock* pMetadataBlock); + void WriteMdxTuple(OOX::Spreadsheet::CMdxTuple* pMdxTuple); + void WriteMdxSet(OOX::Spreadsheet::CMdxSet* pMdxSet); + void WriteMdxKPI(OOX::Spreadsheet::CMdxKPI* pMdxKPI); + void WriteMdxMemeberProp(OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp); + void WriteMetadataStringIndex(OOX::Spreadsheet::CMetadataStringIndex* pStringIndex); }; class BinaryPersonTableWriter { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index e6024775c7c..0990e50d6b7 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -73,6 +73,7 @@ #include "../../../XlsxFormat/Table/Connections.h" #include "../../../XlsxFormat/Controls/Controls.h" #include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" #include "../../../DocxFormat/Media/VbaProject.h" #include "../../../DocxFormat/Media/JsaProject.h" @@ -2322,6 +2323,15 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, m_oWorkbook.m_oExtLst.Init(); m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); } + else if (c_oSerWorkbookTypes::Metadata == type) + { + smart_ptr oMetadataFile(new OOX::Spreadsheet::CMetadataFile(NULL)); + oMetadataFile->m_oMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadata, oMetadataFile->m_oMetadata.GetPointer()); + + smart_ptr oFile = oMetadataFile.smart_dynamic_cast(); + m_oWorkbook.Add(oFile); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -7914,6 +7924,501 @@ int BinaryCustomsReader::ReadCustomContent(BYTE type, long length, void* poResul res = c_oSerConstants::ReadUnknown; return res; } +int BinaryWorkbookTableReader::ReadMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadata* pMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_Metadata::MetadataTypes == type) + { + pMetadata->m_oMetadataTypes.Init(); + READ1_DEF(length, res, this->ReadMetadataTypes, pMetadata->m_oMetadataTypes.GetPointer()); + } + else if (c_oSer_Metadata::MetadataStrings == type) + { + pMetadata->m_oMetadataStrings.Init(); + READ1_DEF(length, res, this->ReadMetadataStrings, pMetadata->m_oMetadataStrings.GetPointer()); + } + else if (c_oSer_Metadata::MdxMetadata == type) + { + pMetadata->m_oMdxMetadata.Init(); + READ1_DEF(length, res, this->ReadMdxMetadata, pMetadata->m_oMdxMetadata.GetPointer()); + } + else if (c_oSer_Metadata::CellMetadata == type) + { + pMetadata->m_oCellMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oCellMetadata.GetPointer()); + } + else if (c_oSer_Metadata::ValueMetadata == type) + { + pMetadata->m_oValueMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oValueMetadata.GetPointer()); + } + else if (c_oSer_Metadata::FutureMetadata == type) + { + OOX::Spreadsheet::CFutureMetadata* pFutureMetadata = new OOX::Spreadsheet::CFutureMetadata(); + READ1_DEF(length, res, this->ReadFutureMetadata, pFutureMetadata); + pMetadata->m_arFutureMetadata.push_back(pFutureMetadata); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataTypes(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataTypes* pMetadataTypes = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataType::MetadataType == type) + { + OOX::Spreadsheet::CMetadataType* pMetadataType = new OOX::Spreadsheet::CMetadataType(); + READ1_DEF(length, res, this->ReadMetadataType, pMetadataType); + pMetadataTypes->m_arrItems.push_back(pMetadataType); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataType(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CMetadataType* pMetadataType = static_cast(poResult); + + if (c_oSer_MetadataType::Name == type) + { + pMetadataType->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataType::MinSupportedVersion == type) + { + pMetadataType->m_oMinSupportedVersion = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataType::GhostRow == type) + { + pMetadataType->m_oGhostRow = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::GhostCol == type) + { + pMetadataType->m_oGhostCol = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Edit == type) + { + pMetadataType->m_oEdit = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Delete == type) + { + pMetadataType->m_oDelete = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Copy == type) + { + pMetadataType->m_oCopy = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteAll == type) + { + pMetadataType->m_oPasteAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormulas == type) + { + pMetadataType->m_oPasteFormulas = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteValues == type) + { + pMetadataType->m_oPasteValues = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormats == type) + { + pMetadataType->m_oPasteFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteComments == type) + { + pMetadataType->m_oPasteComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteDataValidation == type) + { + pMetadataType->m_oPasteDataValidation = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteBorders == type) + { + pMetadataType->m_oPasteBorders = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteColWidths == type) + { + pMetadataType->m_oPasteColWidths = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteNumberFormats == type) + { + pMetadataType->m_oPasteNumberFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Merge == type) + { + pMetadataType->m_oMerge = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitFirst == type) + { + pMetadataType->m_oSplitFirst = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitAll == type) + { + pMetadataType->m_oSplitAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::RowColShift == type) + { + pMetadataType->m_oRowColShift = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearAll == type) + { + pMetadataType->m_oClearAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearFormats == type) + { + pMetadataType->m_oClearFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearContents == type) + { + pMetadataType->m_oClearContents = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearComments == type) + { + pMetadataType->m_oClearComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Assign == type) + { + pMetadataType->m_oAssign = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Coerce == type) + { + pMetadataType->m_oCoerce = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::CellMeta == type) + { + pMetadataType->m_oCellMeta = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStrings(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStrings* pMetadataStrings = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataString::MetadataString == type) + { + OOX::Spreadsheet::CMetadataString* pMetadataString = new OOX::Spreadsheet::CMetadataString(); + pMetadataString->m_oV = m_oBufferedStream.GetString3(length); + pMetadataStrings->m_arrItems.push_back(pMetadataString); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMetadata* pMdxMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::Mdx == type) + { + OOX::Spreadsheet::CMdx* pMdx = new OOX::Spreadsheet::CMdx(); + READ1_DEF(length, res, this->ReadMdx, pMdx); + pMdxMetadata->m_arrItems.push_back(pMdx); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdx(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdx* pMdx = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::NameIndex == type) + { + pMdx->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MdxMetadata::FunctionTag == type) + { + pMdx->m_oF.Init(); + pMdx->m_oF->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MdxMetadata::MdxTuple == type) + { + pMdx->m_oMdxTuple.Init(); + READ1_DEF(length, res, this->ReadMdxTuple, pMdx->m_oMdxTuple.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxSet == type) + { + pMdx->m_oMdxSet.Init(); + READ1_DEF(length, res, this->ReadMdxSet, pMdx->m_oMdxSet.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxKPI == type) + { + pMdx->m_oCMdxKPI.Init(); + READ1_DEF(length, res, this->ReadMdxKPI, pMdx->m_oCMdxKPI.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxMemeberProp == type) + { + pMdx->m_oMdxMemeberProp.Init(); + READ1_DEF(length, res, this->ReadMdxMemeberProp, pMdx->m_oMdxMemeberProp.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlocks(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataBlock == type) + { + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = new OOX::Spreadsheet::CMetadataBlock(); + READ1_DEF(length, res, this->ReadMetadataBlock, pMetadataBlock); + pMetadataBlocks->m_arrItems.push_back(pMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecord == type) + { + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = new OOX::Spreadsheet::CMetadataRecord(); + READ1_DEF(length, res, this->ReadMetadataRecord, pMetadataRecord); + pMetadataBlock->m_arrItems.push_back(pMetadataRecord); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataRecord(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecordType == type) + { + pMetadataRecord->m_oT = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataBlock::MetadataRecordValue == type) + { + pMetadataRecord->m_oV = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDynamicArrayProperties(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDynamicArrayProperties* pDynamicArrayProperties = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::DynamicArray == type) + { + pDynamicArrayProperties->m_oFDynamic = m_oBufferedStream.GetBool(); + } + else if (c_oSer_FutureMetadataBlock::CollapsedArray == type) + { + pDynamicArrayProperties->m_oFCollapsed = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStringIndex(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStringIndex* pStringIndex = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataStringIndex::StringIsSet == type) + { + pStringIndex->m_oS = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataStringIndex::IndexValue == type) + { + pStringIndex->m_oX = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMemeberProp(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMemberProperty::NameIndex == type) + { + pMdxMemeberProp->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMemberProperty::Index == type) + { + pMdxMemeberProp->m_oNp = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxKPI(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxKPI* pMdxKPI = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxKPI::NameIndex == type) + { + pMdxKPI->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Index == type) + { + pMdxKPI->m_oNp = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Property == type) + { + pMdxKPI->m_oP.Init(); + pMdxKPI->m_oP->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxSet(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxSet* pMdxSet = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxSet::Count == type) + { + pMdxSet->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::Index == type) + { + pMdxSet->m_oNs = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::SortOrder == type) + { + pMdxSet->m_oO.Init(); + pMdxSet->m_oO->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MetadataMdxSet::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxSet->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxTuple(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxTuple* pMdxTuple = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxTuple::IndexCount == type) + { + pMdxTuple->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::StringIndex == type) + { + pMdxTuple->m_oSi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::CultureCurrency == type) + { + pMdxTuple->m_oCt = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataMdxTuple::NumFmtIndex == type) + { + pMdxTuple->m_oFi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::BackColor == type) + { + pMdxTuple->m_oBc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::ForeColor == type) + { + pMdxTuple->m_oFc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::Italic == type) + { + pMdxTuple->m_oI = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Bold == type) + { + pMdxTuple->m_oB = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Underline == type) + { + pMdxTuple->m_oU = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Strike == type) + { + pMdxTuple->m_oSt = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxTuple->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadata* pCFutureMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::Name == type) + { + pCFutureMetadata->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_FutureMetadataBlock::FutureMetadataBlock == type) + { + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = new OOX::Spreadsheet::CFutureMetadataBlock(); + READ1_DEF(length, res, this->ReadFutureMetadataBlock, pFutureMetadataBlock); + pCFutureMetadata->m_arrItems.push_back(pFutureMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_FutureMetadataBlock::RichValueBlock == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}"; + pExt->m_oRichValueBlock.Init(); + pExt->m_oRichValueBlock->m_oI = m_oBufferedStream.GetULong(); + + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else if (c_oSer_FutureMetadataBlock::DynamicArrayProperties == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"; + pExt->m_oDynamicArrayProperties.Init(); + + READ1_DEF(length, res, this->ReadDynamicArrayProperties, pExt->m_oDynamicArrayProperties.GetPointer()); + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + //------------------------------------------------------------------------------------------------------------------------------------ BinaryFileReader::BinaryFileReader() { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 3ad6d9a7a9e..17ede45e952 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -219,6 +219,7 @@ namespace BinXlsxRW int ReadDefinedNames(BYTE type, long length, void* poResult); int ReadDefinedName(BYTE type, long length, void* poResult); int ReadCalcPr(BYTE type, long length, void* poResult); + int ReadExternalBook(BYTE type, long length, void* poResult); int ReadExternalSheetNames(BYTE type, long length, void* poResult); int ReadExternalDefinedNames(BYTE type, long length, void* poResult); @@ -228,6 +229,7 @@ namespace BinXlsxRW int ReadExternalRow(BYTE type, long length, void* poResult); int ReadExternalCell(BYTE type, long length, void* poResult); int ReadExternalAlternateUrls(BYTE type, long length, void* poResult); + int ReadOleLink(BYTE type, long length, void* poResult); int ReadOleItem(BYTE type, long length, void* poResult); int ReadDdeLink(BYTE type, long length, void* poResult); @@ -236,6 +238,7 @@ namespace BinXlsxRW int ReadDdeValue(BYTE type, long length, void* poResult); int ReadPivotCaches(BYTE type, long length, void* poResult); int ReadPivotCache(BYTE type, long length, void* poResult); + int ReadConnections(BYTE type, long length, void* poResult); int ReadConnection(BYTE type, long length, void* poResult); int ReadConnectionDbPr(BYTE type, long length, void* poResult); @@ -245,7 +248,9 @@ namespace BinXlsxRW int ReadConnectionRangePr(BYTE type, long length, void* poResult); int ReadConnectionTextFields(BYTE type, long length, void* poResult); int ReadConnectionTextField(BYTE type, long length, void* poResult); + int ReadSlicerCaches(BYTE type, long length, void* poResult); + int ReadTimelineCaches(BYTE type, long length, void* poResult); int ReadTimelineCache(BYTE type, long length, void* poResult); int ReadTimelineState(BYTE type, long length, void* poResult); @@ -253,6 +258,24 @@ namespace BinXlsxRW int ReadTimelineCachePivotTables(BYTE type, long length, void* poResult); int ReadTimelineCachePivotTable(BYTE type, long length, void* poResult); int ReadTimelineRange(BYTE type, long length, void* poResult); + + int ReadMetadata(BYTE type, long length, void* poResult); + int ReadMetadataTypes(BYTE type, long length, void* poResult); + int ReadMetadataType(BYTE type, long length, void* poResult); + int ReadMetadataStrings(BYTE type, long length, void* poResult); + int ReadMdxMetadata(BYTE type, long length, void* poResult); + int ReadMdx(BYTE type, long length, void* poResult); + int ReadMetadataBlocks(BYTE type, long length, void* poResult); + int ReadMetadataBlock(BYTE type, long length, void* poResult); + int ReadMetadataRecord(BYTE type, long length, void* poResult); + int ReadFutureMetadata(BYTE type, long length, void* poResult); + int ReadFutureMetadataBlock(BYTE type, long length, void* poResult); + int ReadMdxTuple(BYTE type, long length, void* poResult); + int ReadMdxSet(BYTE type, long length, void* poResult); + int ReadMdxKPI(BYTE type, long length, void* poResult); + int ReadMdxMemeberProp(BYTE type, long length, void* poResult); + int ReadMetadataStringIndex(BYTE type, long length, void* poResult); + int ReadDynamicArrayProperties(BYTE type, long length, void* poResult); }; class BinaryCommentReader : public Binary_CommonReader { diff --git a/OOXML/Common/SimpleTypes_Drawing.cpp b/OOXML/Common/SimpleTypes_Drawing.cpp index f30ec34625f..64d8902a909 100644 --- a/OOXML/Common/SimpleTypes_Drawing.cpp +++ b/OOXML/Common/SimpleTypes_Drawing.cpp @@ -5324,7 +5324,7 @@ namespace SimpleTypes EHierBranch CHierBranch::FromString(const std::wstring &sValue) { - if (L"none" == sValue) this->m_eValue = hierBranch_hang; + if (L"hang" == sValue) this->m_eValue = hierBranch_hang; else if (L"init" == sValue) this->m_eValue = hierBranch_init; else if (L"l" == sValue) this->m_eValue = hierBranch_l; else if (L"r" == sValue) this->m_eValue = hierBranch_r; diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 9373dd4aa63..4df1ea497fe 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -3291,5 +3291,107 @@ namespace SimpleTypes } return L"unselectedItemWithData"; } + + EMdxKPIProperty CMdxKPIProperty::FromString(const std::wstring& sValue) + { + if (L"v" == sValue) + this->m_eValue = mdxKPIProperty_v; + else if (L"g" == sValue) + this->m_eValue = mdxKPIProperty_g; + else if (L"s" == sValue) + this->m_eValue = mdxKPIProperty_s; + else if (L"t" == sValue) + this->m_eValue = mdxKPIProperty_t; + else if (L"w" == sValue) + this->m_eValue = mdxKPIProperty_w; + else if (L"m" == sValue) + this->m_eValue = mdxKPIProperty_m; + else + this->m_eValue = mdxKPIProperty_v; + return this->m_eValue; + } + std::wstring CMdxKPIProperty::ToString() const + { + switch (this->m_eValue) + { + case mdxKPIProperty_v: return L"v"; break; + case mdxKPIProperty_g: return L"g"; break; + case mdxKPIProperty_s: return L"s"; break; + case mdxKPIProperty_t: return L"t"; break; + case mdxKPIProperty_w: return L"w"; break; + case mdxKPIProperty_m: return L"m"; break; + } + return L"v"; + } + + EMdxSetOrder CMdxSetOrder::FromString(const std::wstring& sValue) + { + if (L"u" == sValue) + this->m_eValue = mdxSetOrder_u; + else if (L"a" == sValue) + this->m_eValue = mdxSetOrder_a; + else if (L"d" == sValue) + this->m_eValue = mdxSetOrder_d; + else if (L"aa" == sValue) + this->m_eValue = mdxSetOrder_aa; + else if (L"ad" == sValue) + this->m_eValue = mdxSetOrder_ad; + else if (L"na" == sValue) + this->m_eValue = mdxSetOrder_na; + else if (L"nd" == sValue) + this->m_eValue = mdxSetOrder_nd; + else + this->m_eValue = mdxSetOrder_u; + return this->m_eValue; + } + std::wstring CMdxSetOrder::ToString() const + { + switch (this->m_eValue) + { + case mdxSetOrder_u: return L"u"; break; + case mdxSetOrder_a: return L"a"; break; + case mdxSetOrder_d: return L"d"; break; + case mdxSetOrder_aa: return L"aa"; break; + case mdxSetOrder_ad: return L"ad"; break; + case mdxSetOrder_na: return L"na"; break; + case mdxSetOrder_nd: return L"nd"; break; + } + return L"v"; + } + + EMdxFunctionType CMdxFunctionType::FromString(const std::wstring& sValue) + { + if (L"m" == sValue) + this->m_eValue = mdxFunctionType_m; + else if (L"v" == sValue) + this->m_eValue = mdxFunctionType_v; + else if (L"s" == sValue) + this->m_eValue = mdxFunctionType_s; + else if (L"c" == sValue) + this->m_eValue = mdxFunctionType_c; + else if (L"r" == sValue) + this->m_eValue = mdxFunctionType_r; + else if (L"p" == sValue) + this->m_eValue = mdxFunctionType_p; + else if (L"k" == sValue) + this->m_eValue = mdxFunctionType_k; + else + this->m_eValue = mdxFunctionType_m; + return this->m_eValue; + } + std::wstring CMdxFunctionType::ToString() const + { + switch (this->m_eValue) + { + case mdxFunctionType_m: return L"m"; break; + case mdxFunctionType_v: return L"v"; break; + case mdxFunctionType_s: return L"s"; break; + case mdxFunctionType_c: return L"c"; break; + case mdxFunctionType_r: return L"r"; break; + case mdxFunctionType_p: return L"p"; break; + case mdxFunctionType_k: return L"k"; break; + } + return L"v"; + } }// Spreadsheet } // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.h b/OOXML/Common/SimpleTypes_Spreadsheet.h index ba71925b992..d132525ca87 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.h +++ b/OOXML/Common/SimpleTypes_Spreadsheet.h @@ -1406,5 +1406,40 @@ namespace SimpleTypes DEFINE_SIMPLE_TYPE(CTimelineStyleType, ETimelineStyleType, timelineStyle_selectionLabel) + enum EMdxKPIProperty + { + mdxKPIProperty_v = 0, + mdxKPIProperty_g = 1, + mdxKPIProperty_s = 2, + mdxKPIProperty_t = 3, + mdxKPIProperty_w = 4, + mdxKPIProperty_m = 5 + }; + DEFINE_SIMPLE_TYPE(CMdxKPIProperty, EMdxKPIProperty, mdxKPIProperty_v) + + enum EMdxSetOrder + { + mdxSetOrder_u = 0, + mdxSetOrder_a = 1, + mdxSetOrder_d = 2, + mdxSetOrder_aa = 3, + mdxSetOrder_ad = 4, + mdxSetOrder_na = 5, + mdxSetOrder_nd = 6 + }; + DEFINE_SIMPLE_TYPE(CMdxSetOrder, EMdxSetOrder, mdxSetOrder_u) + + enum EMdxFunctionType + { + mdxFunctionType_m = 0, + mdxFunctionType_v = 1, + mdxFunctionType_s = 2, + mdxFunctionType_c = 3, + mdxFunctionType_r = 4, + mdxFunctionType_p = 5, + mdxFunctionType_k = 6 + }; + DEFINE_SIMPLE_TYPE(CMdxFunctionType, EMdxFunctionType, mdxFunctionType_m) + }// Spreadsheet } // SimpleTypes diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index a8592dbdbfc..a8a2bfb9523 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -47,6 +47,7 @@ #include "../../XlsxFormat/Chart/ChartSerialize.h" #include "../../XlsxFormat/Worksheets/WorksheetChildOther.h" #include "../../XlsxFormat/Timelines/Timeline.h" +#include "../../XlsxFormat/Workbook/Metadata.h" #include "../Comments.h" @@ -225,6 +226,8 @@ namespace OOX *m_sUri == L"{7E03D99C-DC04-49d9-9315-930204A7B6E9}" || *m_sUri == L"{D0CA8CA8-9F24-4464-BF8E-62219DCF47F9}" || *m_sUri == L"{9260A510-F301-46a8-8635-F512D64BE5F5}" || + *m_sUri == L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}" || + *m_sUri == L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}" || *m_sUri == L"http://schemas.microsoft.com/office/drawing/2008/diagram")) { int nCurDepth = oReader.GetDepth(); @@ -368,6 +371,14 @@ namespace OOX } } } + else if (sName == L"dynamicArrayProperties") + { + m_oDynamicArrayProperties = oReader; + } + else if (sName == L"rvb") + { + m_oRichValueBlock = oReader; + } } } else @@ -591,6 +602,18 @@ namespace OOX writer.EndNode(L"c16r3:dataDisplayOptions16"); sResult += writer.GetData().c_str(); } + if (m_oDynamicArrayProperties.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oDynamicArrayProperties->toXML(writer); + sResult += writer.GetData().c_str(); + } + if (m_oRichValueBlock.IsInit()) + { + NSStringUtils::CStringBuilder writer; + m_oRichValueBlock->toXML(writer); + sResult += writer.GetData().c_str(); + } sResult += L""; return sResult; diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index be8f59661b8..44ce87b9072 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -60,6 +60,8 @@ namespace OOX class CTimelineRefs; class CTimelineCacheRefs; class CTimelineStyles; + class CDynamicArrayProperties; + class CRichValueBlock; } namespace Drawing @@ -160,6 +162,9 @@ namespace OOX std::vector m_arrConditionalFormatting; + nullable < OOX::Spreadsheet::CDynamicArrayProperties> m_oDynamicArrayProperties; + nullable < OOX::Spreadsheet::CRichValueBlock> m_oRichValueBlock; + nullable m_oPresenceInfo; nullable_string m_oFileKey; diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 1a44d490295..32578b01ffa 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1514,7 +1514,28 @@ namespace OOX et_x_Timeslicer, et_x_TimelineStyles, et_x_TimelineStyle, - et_x_TimelineStyleElement + et_x_TimelineStyleElement, + + et_x_Metadata, + et_x_FutureMetadata, + et_x_FutureMetadataBlock, + et_x_MetadataType, + et_x_MetadataTypes, + et_x_MetadataBlocks, + et_x_MetadataBlock, + et_x_MetadataRecord, + et_x_MetadataString, + et_x_MetadataStrings, + et_x_MdxMetadata, + et_x_Mdx, + et_x_MdxTuple, + et_x_MetadataStringIndex, + et_x_MdxSet, + et_x_MdxMemeberProp, + et_x_MdxKPI, + + et_x_DynamicArrayProperties, + et_x_RichValueBlock }; class File; diff --git a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro index 4ce6ae9f766..e5e719c5109 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro +++ b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro @@ -183,7 +183,9 @@ SOURCES += \ ../../../XlsxFormat/Drawing/Pos.cpp \ ../../../XlsxFormat/ExternalLinks/ExternalLinkPath.cpp \ ../../../XlsxFormat/ExternalLinks/ExternalLinks.cpp \ - ../../../XlsxFormat/Ole/OleObjects.cpp + ../../../XlsxFormat/Workbook/Metadata.cpp \ + ../../../XlsxFormat/RichData/RdRichValue.cpp \ + ../../../XlsxFormat/Ole/OleObjects.cpp } @@ -375,4 +377,6 @@ HEADERS += \ ../../../XlsxFormat/Slicer/SlicerCacheExt.h \ ../../../XlsxFormat/Slicer/Slicer.h \ ../../../XlsxFormat/NamedSheetViews/NamedSheetViews.h \ - docx_format.h + ../../../XlsxFormat/Workbook/Metadata.h \ + ../../../XlsxFormat/RichData/RdRichValue.h \ + docx_format.h diff --git a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp index 0249679a97a..a661caff6ab 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp @@ -95,3 +95,5 @@ #include "../../../XlsxFormat/SharedStrings/XlsxRun.cpp" #include "../../../XlsxFormat/SharedStrings/SharedStrings.cpp" #include "../../../XlsxFormat/Timelines/Timeline.cpp" +#include "../../../XlsxFormat/Workbook/Metadata.cpp" +#include "../../../XlsxFormat/RichData/RdRichValue.cpp" diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj index d1bea1396ca..203228103c7 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -354,6 +354,7 @@ + @@ -383,6 +384,7 @@ + @@ -513,6 +515,7 @@ + @@ -540,6 +543,7 @@ + diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 92b050244f7..0320b64eca4 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -85,6 +85,9 @@ {34deda6e-7347-49f2-be67-d088cdd469db} + + {db25162b-705e-4c13-b6c5-f7c018c6f39a} + @@ -538,6 +541,12 @@ XlsxFormat\Timelines + + XlsxFormat\RichData + + + XlsxFormat\Workbook + @@ -948,5 +957,11 @@ XlsxFormat\Timelines + + XlsxFormat\RichData + + + XlsxFormat\Workbook + \ No newline at end of file diff --git a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp index fba046b2618..8b692b6291a 100644 --- a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp @@ -58,6 +58,8 @@ #include "Slicer/Slicer.h" #include "NamedSheetViews/NamedSheetViews.h" #include "Timelines/Timeline.h" +#include "RichData/RdRichValue.h" +#include "Workbook/Metadata.h" #include "Table/Table.h" #include "Table/QueryTable.h" @@ -181,6 +183,14 @@ namespace OOX return smart_ptr(new CTimelineFile(pMain, oRootPath, oFileName)); else if ( oRelation.Type() == FileTypes::TimelineCache) return smart_ptr(new CTimelineCacheFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Metadata) + return smart_ptr(new CMetadataFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValueStructure) + return smart_ptr(new CRdRichValueStructureFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValue) + return smart_ptr(new CRdRichValueFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValueTypes) + return smart_ptr(new CRdRichValueTypesFile(pMain, oRootPath, oFileName)); return smart_ptr( new UnknowTypeFile(pMain) ); } @@ -313,6 +323,14 @@ namespace OOX return smart_ptr(new CTimelineFile(pMain, oRootPath, oFileName)); else if (pRelation->Type() == FileTypes::TimelineCache) return smart_ptr(new CTimelineCacheFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Metadata) + return smart_ptr(new CMetadataFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValueStructure) + return smart_ptr(new CRdRichValueStructureFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValue) + return smart_ptr(new CRdRichValueFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValueTypes) + return smart_ptr(new CRdRichValueTypesFile(pMain, oRootPath, oFileName)); return smart_ptr( new UnknowTypeFile(pMain) ); } diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp index 52076231ba6..e5c88368dee 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp @@ -155,12 +155,28 @@ namespace OOX L"http://schemas.microsoft.com/office/2011/relationships/timelineCache", L"timelineCaches/timelineCache", true, true); //onlyoffice workbook comments - const FileType WorkbookComments(L"", L"workbookComments.bin", + const FileType WorkbookComments (L"", L"workbookComments.bin", L"", L"http://schemas.onlyoffice.com/workbookComments"); + + const FileType Metadata (L"", L"metadata.xml", + L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata"); - const FileType SpreadsheetFlat(L"", L"", L"", L""); + const FileType RdRichValue (L"richData", L"rdrichvalue.xml", + L"application/vnd.ms-excel.rdrichvalue+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValue"); + + const FileType RdRichValueStructure(L"richData", L"rdrichvaluestructure.xml", + L"application/vnd.ms-excel.rdrichvaluestructure+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure"); + + const FileType RdRichValueTypes (L"richData", L"rdRichValueTypes..xml", + L"application/vnd.ms-excel.rdrichvaluetypes+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueTypes"); + + const FileType SpreadsheetFlat (L"", L"", L"", L""); } // namespace FileTypes } diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h index e73ba16a926..0204c805660 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h @@ -93,6 +93,13 @@ namespace OOX extern const FileType TimelineCache; + extern const FileType Metadata; + + extern const FileType RdRichValue; + + extern const FileType RdRichValueStructure; + + extern const FileType RdRichValueTypes; } // namespace FileTypes } } // namespace OOX diff --git a/OOXML/XlsxFormat/RichData/RdRichValue.cpp b/OOXML/XlsxFormat/RichData/RdRichValue.cpp new file mode 100644 index 00000000000..c0a11484934 --- /dev/null +++ b/OOXML/XlsxFormat/RichData/RdRichValue.cpp @@ -0,0 +1,233 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "RdRichValue.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../Common/SimpleTypes_Shared.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +#include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../DesktopEditor/common/File.h" + +#include "../../Binary/Presentation/XmlWriter.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" + +namespace OOX +{ +namespace Spreadsheet +{ + CRdRichValueFile::CRdRichValueFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueFile::CRdRichValueFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueFile::~CRdRichValueFile() + { + } + void CRdRichValueFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValue; + } + const CPath CRdRichValueFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//--------------------------------------------------------------------------------------------------------------------------- + CRdRichValueStructureFile::CRdRichValueStructureFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueStructureFile::CRdRichValueStructureFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueStructureFile::~CRdRichValueStructureFile() + { + } + void CRdRichValueStructureFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueStructureFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValueStructure; + } + const CPath CRdRichValueStructureFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueStructureFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueStructureFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueStructureFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueStructureFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//--------------------------------------------------------------------------------------------------------------------------- + CRdRichValueTypesFile::CRdRichValueTypesFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CRdRichValueTypesFile::CRdRichValueTypesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CRdRichValueTypesFile::~CRdRichValueTypesFile() + { + } + void CRdRichValueTypesFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CRdRichValueTypesFile::type() const + { + return OOX::Spreadsheet::FileTypes::RdRichValueTypes; + } + const CPath CRdRichValueTypesFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CRdRichValueTypesFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CRdRichValueTypesFile::GetReadPath() + { + return m_oReadPath; + } + void CRdRichValueTypesFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + //m_oMetadata = oReader; + } + void CRdRichValueTypesFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + //if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + //m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +} +} + diff --git a/OOXML/XlsxFormat/RichData/RdRichValue.h b/OOXML/XlsxFormat/RichData/RdRichValue.h new file mode 100644 index 00000000000..1b94966a352 --- /dev/null +++ b/OOXML/XlsxFormat/RichData/RdRichValue.h @@ -0,0 +1,108 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Spreadsheet + { + class CRdRichValueFile : public OOX::File + { + public: + CRdRichValueFile(OOX::Document* pMain); + CRdRichValueFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + //nullable m_oTimelines; + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CRdRichValueStructureFile : public OOX::File + { + public: + CRdRichValueStructureFile(OOX::Document* pMain); + CRdRichValueStructureFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueStructureFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + private: + CPath m_oReadPath; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CRdRichValueTypesFile : public OOX::File + { + public: + CRdRichValueTypesFile(OOX::Document* pMain); + CRdRichValueTypesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRdRichValueTypesFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + private: + CPath m_oReadPath; + }; + } //Spreadsheet +} // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Metadata.cpp b/OOXML/XlsxFormat/Workbook/Metadata.cpp new file mode 100644 index 00000000000..40c07935a69 --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -0,0 +1,1063 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Metadata.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../Common/SimpleTypes_Shared.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +#include "../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../DesktopEditor/common/File.h" + +#include "../../Binary/Presentation/XmlWriter.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" + +namespace OOX +{ + namespace Spreadsheet + { + CMdxKPI::CMdxKPI() {} + CMdxKPI::~CMdxKPI() {} + void CMdxKPI::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxKPI::toXML() const + { + return L""; + } + EElementType CMdxKPI::getType() const + { + return et_x_MdxKPI; + } + void CMdxKPI::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + writer.WriteString(L"/>"); + } + void CMdxKPI::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMdxKPI::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"np", m_oNp) + WritingElement_ReadAttributes_Read_else_if(oReader, L"p", m_oP) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CMdxMemeberProp::CMdxMemeberProp() {} + CMdxMemeberProp::~CMdxMemeberProp() {} + void CMdxMemeberProp::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxMemeberProp::toXML() const + { + return L""; + } + EElementType CMdxMemeberProp::getType() const + { + return et_x_MdxMemeberProp; + } + void CMdxMemeberProp::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMdxMemeberProp::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMdxMemeberProp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"np", m_oNp) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CMdxSet::CMdxSet() {} + CMdxSet::~CMdxSet() {} + void CMdxSet::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxSet::toXML() const + { + return L""; + } + EElementType CMdxSet::getType() const + { + return et_x_MdxSet; + } + void CMdxSet::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"ns", m_oNs); + WritingStringNullableAttrInt2(L"c", m_oC); + WritingStringNullableAttrString(L"o", m_oO, m_oO->ToString()); + writer.WriteString(L">"); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + void CMdxSet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"n" == sName) + { + CMetadataStringIndex* ind = new CMetadataStringIndex(); + *ind = oReader; + m_arrItems.push_back(ind); + } + } + } + void CMdxSet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"ns", m_oNs) + WritingElement_ReadAttributes_Read_else_if(oReader, L"c", m_oC) + WritingElement_ReadAttributes_Read_else_if(oReader, L"o", m_oO) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CMetadataStringIndex::CMetadataStringIndex() {} + CMetadataStringIndex::~CMetadataStringIndex() {} + void CMetadataStringIndex::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataStringIndex::toXML() const + { + return L""; + } + EElementType CMetadataStringIndex::getType() const + { + return et_x_MetadataStringIndex; + } + void CMetadataStringIndex::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataStringIndex::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataStringIndex::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"x", m_oX) + WritingElement_ReadAttributes_Read_else_if(oReader, L"s", m_oS) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CMdxTuple::CMdxTuple() {} + CMdxTuple::~CMdxTuple() {} + void CMdxTuple::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxTuple::toXML() const + { + return L""; + } + EElementType CMdxTuple::getType() const + { + return et_x_MdxTuple; + } + void CMdxTuple::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"c", m_oC); + WritingStringNullableAttrEncodeXmlString2(L"o", m_oCt); + WritingStringNullableAttrInt2(L"si", m_oSi); + WritingStringNullableAttrInt2(L"fi", m_oFi); + WritingStringNullableAttrInt2(L"bc", m_oBc); + WritingStringNullableAttrInt2(L"fc", m_oFc); + WritingStringNullableAttrBool2(L"i", m_oI); + WritingStringNullableAttrBool2(L"u", m_oU); + WritingStringNullableAttrBool2(L"st", m_oSt); + WritingStringNullableAttrBool2(L"b", m_oB); + writer.WriteString(L">"); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + void CMdxTuple::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"n" == sName) + { + CMetadataStringIndex* ind = new CMetadataStringIndex(); + *ind = oReader; + m_arrItems.push_back(ind); + } + } + } + void CMdxTuple::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"c", m_oC) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ct", m_oCt) + WritingElement_ReadAttributes_Read_else_if(oReader, L"si", m_oSi) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fi", m_oFi) + WritingElement_ReadAttributes_Read_else_if(oReader, L"bc", m_oBc) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fc", m_oFc) + WritingElement_ReadAttributes_Read_else_if(oReader, L"i", m_oI) + WritingElement_ReadAttributes_Read_else_if(oReader, L"u", m_oU) + WritingElement_ReadAttributes_Read_else_if(oReader, L"st", m_oSt) + WritingElement_ReadAttributes_Read_else_if(oReader, L"b", m_oB) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CMdx::CMdx() {} + CMdx::~CMdx() {} + void CMdx::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdx::toXML() const + { + return L""; + } + EElementType CMdx::getType() const + { + return et_x_Mdx; + } + void CMdx::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + WritingStringNullableAttrInt2(L"n", m_oN); + WritingStringNullableAttrString(L"f", m_oF, m_oF->ToString()); + + if (m_oMdxTuple.IsInit()) + { + m_oMdxTuple->toXML(writer); + } + if (m_oMdxSet.IsInit()) + { + m_oMdxSet->toXML(writer); + } + if (m_oCMdxKPI.IsInit()) + { + m_oCMdxKPI->toXML(writer); + } + if (m_oMdxMemeberProp.IsInit()) + { + m_oMdxMemeberProp->toXML(writer); + } + writer.WriteString(L""); + } + void CMdx::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"t" == sName) + m_oMdxTuple = oReader; + else if (L"ms" == sName) + m_oMdxSet = oReader; + else if (L"p" == sName) + m_oMdxMemeberProp = oReader; + else if (L"k" == sName) + m_oCMdxKPI = oReader; + } + } + void CMdx::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"n", m_oN) + WritingElement_ReadAttributes_Read_else_if(oReader, L"f", m_oF) + WritingElement_ReadAttributes_End(oReader) + } + //------------------------------------------------------------------------------------- + CMdxMetadata::CMdxMetadata() {} + CMdxMetadata::~CMdxMetadata() {} + void CMdxMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMdxMetadata::toXML() const + { + return L""; + } + EElementType CMdxMetadata::getType() const + { + return et_x_MdxMetadata; + } + void CMdxMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"mdx" == sName) + { + CMdx* mdx = new CMdx(); + *mdx = oReader; + m_arrItems.push_back(mdx); + } + } + } + void CMdxMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //------------------------------------------------------------------------------------- + CMetadataStrings::CMetadataStrings() {} + CMetadataStrings::~CMetadataStrings() {} + void CMetadataStrings::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataStrings::toXML() const + { + return L""; + } + EElementType CMetadataStrings::getType() const + { + return et_x_MetadataStrings; + } + void CMetadataStrings::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"s" == sName) + { + CMetadataString* pS = new CMetadataString(); + *pS = oReader; + m_arrItems.push_back(pS); + } + } + } + void CMetadataStrings::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //-------------------------------------------------------------------------------------------------------- + CMetadataString::CMetadataString() {} + CMetadataString::~CMetadataString() {} + void CMetadataString::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataString::toXML() const + { + return L""; + } + EElementType CMetadataString::getType() const + { + return et_x_MetadataString; + } + void CMetadataString::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataString::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataString::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"v", m_oV) + WritingElement_ReadAttributes_End(oReader) + } + // -------------------------------------------------------------------------------------------------------- + CMetadataRecord::CMetadataRecord() {} + CMetadataRecord::~CMetadataRecord() {} + void CMetadataRecord::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataRecord::toXML() const + { + return L""; + } + EElementType CMetadataRecord::getType() const + { + return et_x_MetadataRecord; + } + void CMetadataRecord::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataRecord::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataRecord::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"t", m_oT) + WritingElement_ReadAttributes_Read_else_if(oReader, L"v", m_oV) + WritingElement_ReadAttributes_End(oReader) + } + //------------------------------------------------------------------------------------- + CMetadataBlock::CMetadataBlock() {} + CMetadataBlock::~CMetadataBlock() {} + void CMetadataBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataBlock::toXML() const + { + return L""; + } + EElementType CMetadataBlock::getType() const + { + return et_x_MetadataBlock; + } + void CMetadataBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"rc" == sName) + { + CMetadataRecord* pR = new CMetadataRecord(); + *pR = oReader; + m_arrItems.push_back(pR); + } + } + } + void CMetadataBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //------------------------------------------------------------------------------------- + CMetadataBlocks::CMetadataBlocks() {} + CMetadataBlocks::~CMetadataBlocks() {} + void CMetadataBlocks::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataBlocks::toXML() const + { + return L""; + } + EElementType CMetadataBlocks::getType() const + { + return et_x_MetadataBlocks; + } + void CMetadataBlocks::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + m_sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"bk" == sName) + { + CMetadataBlock* pB = new CMetadataBlock(); + *pB = oReader; + m_arrItems.push_back(pB); + } + } + } + void CMetadataBlocks::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L"<" + m_sName + L">"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //------------------------------------------------------------------------------------- + CMetadataTypes::CMetadataTypes() {} + CMetadataTypes::~CMetadataTypes() {} + void CMetadataTypes::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataTypes::toXML() const + { + return L""; + } + EElementType CMetadataTypes::getType() const + { + return et_x_MetadataTypes; + } + void CMetadataTypes::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"metadataType" == sName) + { + CMetadataType* pT = new CMetadataType(); + *pT = oReader; + m_arrItems.push_back(pT); + } + } + } + void CMetadataTypes::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //-------------------------------------------------------------------------------------------------------- + CMetadataType::CMetadataType() {} + CMetadataType::~CMetadataType() {} + void CMetadataType::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadataType::toXML() const + { + return L""; + } + EElementType CMetadataType::getType() const + { + return et_x_MetadataType; + } + void CMetadataType::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CMetadataType::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CMetadataType::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_Read_else_if(oReader, L"minSupportedVersion", m_oMinSupportedVersion) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ghostRow", m_oGhostRow) + WritingElement_ReadAttributes_Read_else_if(oReader, L"ghostCol", m_oGhostCol) + WritingElement_ReadAttributes_Read_else_if(oReader, L"edit", m_oEdit) + WritingElement_ReadAttributes_Read_else_if(oReader, L"delete", m_oDelete) + WritingElement_ReadAttributes_Read_else_if(oReader, L"copy", m_oCopy) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteAll", m_oPasteAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteFormulas", m_oPasteFormulas) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteValues", m_oPasteValues) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteFormats", m_oPasteFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteComments", m_oPasteComments) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteDataValidation", m_oPasteDataValidation) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteBorders", m_oPasteBorders) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteColWidths", m_oPasteColWidths) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pasteNumberFormats", m_oPasteNumberFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"merge", m_oMerge) + WritingElement_ReadAttributes_Read_else_if(oReader, L"splitFirst", m_oSplitFirst) + WritingElement_ReadAttributes_Read_else_if(oReader, L"splitAll", m_oSplitAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"rowColShift", m_oRowColShift) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearAll", m_oClearAll) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearFormats", m_oClearFormats) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearContents", m_oClearContents) + WritingElement_ReadAttributes_Read_else_if(oReader, L"clearComments", m_oClearComments) + WritingElement_ReadAttributes_Read_else_if(oReader, L"assign", m_oAssign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"coerce", m_oCoerce) + WritingElement_ReadAttributes_Read_else_if(oReader, L"cellMeta", m_oCellMeta) + WritingElement_ReadAttributes_End(oReader) + } + //-------------------------------------------------------------------------------------------------------- + CFutureMetadataBlock::CFutureMetadataBlock() {} + CFutureMetadataBlock::~CFutureMetadataBlock() {} + void CFutureMetadataBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CFutureMetadataBlock::toXML() const + { + return L""; + } + EElementType CFutureMetadataBlock::getType() const + { + return et_x_FutureMetadataBlock; + } + void CFutureMetadataBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oExtLst.IsInit()) + { + writer.WriteString(m_oExtLst->toXMLWithNS(L"")); + } + writer.WriteString(L""); + } + void CFutureMetadataBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + //------------------------------------------------------------------------------------- + CFutureMetadata::CFutureMetadata() {} + CFutureMetadata::~CFutureMetadata() + { + } + void CFutureMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CFutureMetadata::toXML() const + { + return L""; + } + EElementType CFutureMetadata::getType() const + { + return et_x_FutureMetadata; + } + void CFutureMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"bk" == sName) + { + CFutureMetadataBlock* pT = new CFutureMetadataBlock(); + *pT = oReader; + m_arrItems.push_back(pT); + } + } + } + void CFutureMetadata::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) + WritingElement_ReadAttributes_End(oReader) + } + void CFutureMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + if (m_arrItems.empty()) return; + + writer.WriteString(L""); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); + } + //-------------------------------------------------------------------------------------------------------- + CMetadata::CMetadata() {} + CMetadata::~CMetadata() + { + for (size_t i = 0; i < m_arFutureMetadata.size(); ++i) + { + if (m_arFutureMetadata[i]) delete m_arFutureMetadata[i]; + } + m_arFutureMetadata.clear(); + } + void CMetadata::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CMetadata::toXML() const + { + return L""; + } + EElementType CMetadata::getType() const + { + return et_x_Metadata; + } + void CMetadata::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + + if (m_oMetadataTypes.IsInit()) + { + m_oMetadataTypes->toXML(writer); + } + if (m_oMetadataStrings.IsInit()) + { + m_oMetadataStrings->toXML(writer); + } + if (m_oMdxMetadata.IsInit()) + { + m_oMdxMetadata->toXML(writer); + } + for (size_t i = 0; i < m_arFutureMetadata.size(); ++i) + { + if (m_arFutureMetadata[i]) + { + m_arFutureMetadata[i]->toXML(writer); + } + } + if (m_oCellMetadata.IsInit()) + { + m_oCellMetadata->m_sName = L"cellMetadata"; + m_oCellMetadata->toXML(writer); + } + if (m_oValueMetadata.IsInit()) + { + m_oValueMetadata->m_sName = L"valueMetadata"; + m_oValueMetadata->toXML(writer); + } + if (m_oExtLst.IsInit()) + { + writer.WriteString(m_oExtLst->toXMLWithNS(L"")); + } + writer.WriteString(L""); + } + void CMetadata::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (L"metadataTypes" == sName) + m_oMetadataTypes = oReader; + else if (L"metadataStrings" == sName) + m_oMetadataStrings = oReader; + else if (L"mdxMetadata" == sName) + m_oMdxMetadata = oReader; + else if (L"cellMetadata" == sName) + m_oCellMetadata = oReader; + else if (L"valueMetadata" == sName) + m_oValueMetadata = oReader; + else if (L"futureMetadata" == sName) + { + CFutureMetadata* pF = new CFutureMetadata(); + *pF = oReader; + m_arFutureMetadata.push_back(pF); + } + else if (L"extLst" == sName) + m_oExtLst = oReader; + } + } + //----------------------------------------------------------------------------------------------------------------------------------------------------- + CMetadataFile::CMetadataFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CMetadataFile::CMetadataFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CMetadataFile::~CMetadataFile() + { + } + void CMetadataFile::read(const CPath& oPath) + { + //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) + CPath oRootPath; + read(oRootPath, oPath); + } + const OOX::FileType CMetadataFile::type() const + { + return OOX::Spreadsheet::FileTypes::Metadata; + } + const CPath CMetadataFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CMetadataFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CMetadataFile::GetReadPath() + { + return m_oReadPath; + } + void CMetadataFile::read(const CPath& oRootPath, const CPath& oPath) + { + m_oReadPath = oPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oPath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_oMetadata = oReader; + } + void CMetadataFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L""); + m_oMetadata->toXML(sXml); + + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + + oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + } +//------------------------------------------------------------------------------------------------------------------------------------- + CDynamicArrayProperties::CDynamicArrayProperties() {} + CDynamicArrayProperties::~CDynamicArrayProperties() {} + void CDynamicArrayProperties::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CDynamicArrayProperties::toXML() const + { + return L""; + } + EElementType CDynamicArrayProperties::getType() const + { + return et_x_DynamicArrayProperties; + } + void CDynamicArrayProperties::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CDynamicArrayProperties::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CDynamicArrayProperties::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"fDynamic", m_oFDynamic) + WritingElement_ReadAttributes_Read_else_if(oReader, L"fCollapsed", m_oFCollapsed) + WritingElement_ReadAttributes_End(oReader) + } +//------------------------------------------------------------------------------------------------------------------------------------- + CRichValueBlock::CRichValueBlock() {} + CRichValueBlock::~CRichValueBlock() {} + void CRichValueBlock::fromXML(XmlUtils::CXmlNode& node) + { + } + std::wstring CRichValueBlock::toXML() const + { + return L""; + } + EElementType CRichValueBlock::getType() const + { + return et_x_RichValueBlock; + } + void CRichValueBlock::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L""); + } + void CRichValueBlock::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CRichValueBlock::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"i", m_oI) + WritingElement_ReadAttributes_End(oReader) + } + } + +} // namespace OOX + diff --git a/OOXML/XlsxFormat/Workbook/Metadata.h b/OOXML/XlsxFormat/Workbook/Metadata.h new file mode 100644 index 00000000000..f0b17ae8c5a --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.h @@ -0,0 +1,506 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Drawing + { + class COfficeArtExtensionList; + } + + namespace Spreadsheet + { +//----------------------------------------------------------------------------------------------------------------------- + class CMdxKPI : public WritingElement + { + public: + WritingElement_AdditionMethods(CMdxKPI) + CMdxKPI(); + virtual ~CMdxKPI(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oN; + nullable_uint m_oNp; + nullable m_oP; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMdxMemeberProp : public WritingElement + { + public: + WritingElement_AdditionMethods(CMdxMemeberProp) + CMdxMemeberProp(); + virtual ~CMdxMemeberProp(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oN; + nullable_uint m_oNp; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMetadataStringIndex : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataStringIndex) + CMetadataStringIndex(); + virtual ~CMetadataStringIndex(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oX; + nullable_bool m_oS; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxSet : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMdxSet) + CMdxSet(); + virtual ~CMdxSet(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oNs; + nullable_uint m_oC; + nullable m_oO; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxTuple : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMdxTuple) + CMdxTuple(); + virtual ~CMdxTuple(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oC; + nullable_string m_oCt; + nullable_uint m_oSi; + nullable_uint m_oFi; + nullable_uint m_oBc; + nullable_uint m_oFc; + nullable_bool m_oI; + nullable_bool m_oU; + nullable_bool m_oSt; + nullable_bool m_oB; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdx : public WritingElement + { + public: + WritingElement_AdditionMethods(CMdx) + CMdx(); + virtual ~CMdx(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable m_oMdxTuple; + nullable m_oMdxSet; + nullable m_oCMdxKPI; + nullable m_oMdxMemeberProp; + + nullable_uint m_oN; + nullable m_oF; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxMetadata : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMdxMetadata) + CMdxMetadata(); + virtual ~CMdxMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataString : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataString) + CMetadataString(); + virtual ~CMetadataString(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oV; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataRecord : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataRecord) + CMetadataRecord(); + virtual ~CMetadataRecord(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_uint m_oT; + nullable_uint m_oV; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CFutureMetadataBlock : public WritingElement + { + public: + WritingElement_AdditionMethods(CFutureMetadataBlock) + CFutureMetadataBlock(); + virtual ~CFutureMetadataBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataType : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataType) + CMetadataType(); + virtual ~CMetadataType(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + public: + nullable_string m_oName; + nullable_uint m_oMinSupportedVersion; + nullable_bool m_oGhostRow; + nullable_bool m_oGhostCol; + nullable_bool m_oEdit; + nullable_bool m_oDelete; + nullable_bool m_oCopy; + nullable_bool m_oPasteAll; + nullable_bool m_oPasteFormulas; + nullable_bool m_oPasteValues; + nullable_bool m_oPasteFormats; + nullable_bool m_oPasteComments; + nullable_bool m_oPasteDataValidation; + nullable_bool m_oPasteBorders; + nullable_bool m_oPasteColWidths; + nullable_bool m_oPasteNumberFormats; + nullable_bool m_oMerge; + nullable_bool m_oSplitFirst; + nullable_bool m_oSplitAll; + nullable_bool m_oRowColShift; + nullable_bool m_oClearAll; + nullable_bool m_oClearFormats; + nullable_bool m_oClearContents; + nullable_bool m_oClearComments; + nullable_bool m_oAssign; + nullable_bool m_oCoerce; + nullable_bool m_oCellMeta; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataTypes : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMetadataTypes) + CMetadataTypes(); + virtual ~CMetadataTypes(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataBlock : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMetadataBlock) + CMetadataBlock(); + virtual ~CMetadataBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataBlocks : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMetadataBlocks) + CMetadataBlocks(); + virtual ~CMetadataBlocks(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + + std::wstring m_sName; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataStrings : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CMetadataStrings) + CMetadataStrings(); + virtual ~CMetadataStrings(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CFutureMetadata : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CFutureMetadata) + CFutureMetadata(); + virtual ~CFutureMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_string m_oName; + nullable_uint m_oCount; + + nullable m_oExtLst; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//-------------------------------------------------------------------------------------------------------------- + class CMetadata : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadata) + CMetadata(); + virtual ~CMetadata(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + public: + nullable m_oMetadataTypes; + nullable m_oMetadataStrings; + nullable m_oMdxMetadata; + nullable m_oCellMetadata; + nullable m_oValueMetadata; + + std::vector m_arFutureMetadata; + + nullable m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataFile : public OOX::File + { + public: + CMetadataFile(OOX::Document* pMain); + CMetadataFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CMetadataFile(); + + //void readBin(const CPath& oPath); + //XLS::BaseObjectPtr WriteBin() const; + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + const CPath& GetReadPath(); + + nullable m_oMetadata; + private: + CPath m_oReadPath; + }; +//----------------------------------------------------------------------------------------------------------------------- + class CDynamicArrayProperties : public WritingElement + { + public: + WritingElement_AdditionMethods(CDynamicArrayProperties) + CDynamicArrayProperties(); + virtual ~CDynamicArrayProperties(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_bool m_oFDynamic; + nullable_bool m_oFCollapsed; + + nullable m_oExtLst; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CRichValueBlock : public WritingElement + { + public: + WritingElement_AdditionMethods(CRichValueBlock) + CRichValueBlock(); + virtual ~CRichValueBlock(); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + nullable_uint m_oI; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; + } //Spreadsheet +} // namespace OOX From 47a485999fd69ff09db44a1c06aea4bbc2fcf302 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 14 Feb 2024 12:07:35 +0300 Subject: [PATCH 297/794] . --- OOXML/XlsxFormat/Workbook/Metadata.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/Metadata.cpp b/OOXML/XlsxFormat/Workbook/Metadata.cpp index 40c07935a69..6bfa9e37be2 100644 --- a/OOXML/XlsxFormat/Workbook/Metadata.cpp +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -431,7 +431,7 @@ namespace OOX { if (m_arrItems.empty()) return; - writer.WriteString(L""); + writer.WriteString(L""); for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -595,7 +595,7 @@ namespace OOX { if (m_arrItems.empty()) return; - writer.WriteString(L"<" + m_sName + L">"); + writer.WriteString(L"<" + m_sName + L" count=\"" + std::to_wstring(m_arrItems.size()) + L"\">"); for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -642,7 +642,7 @@ namespace OOX { if (m_arrItems.empty()) return; - writer.WriteString(L""); + writer.WriteString(L""); for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -824,6 +824,7 @@ namespace OOX writer.WriteString(L""); writer.WriteString(L">"); for (size_t i = 0; i < m_arrItems.size(); ++i) From 9a612d454317f20a9d1a5320cd0fac3c40770dfa Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 14 Feb 2024 16:01:11 +0600 Subject: [PATCH 298/794] Fix ptg list conversion --- .../Logic/Biff_structures/SyntaxPtg.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index 8dc53e4695e..e3cce003fcf 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -467,6 +467,8 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: static boost::wregex reg_inside_table1(L"\\[#?[\\s\\w\\d.]+\\]"); static boost::wregex reg_inside_table2(L"\\[#\\w[\\s\\w\\d.]*\\],\\[#\\w[\\s\\w\\d.]*\\]"); static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[\\s\\w\\d.]+\\]"); + static boost::wregex reg_inside_table4(L"\\[#?(\\[.+?\\]\\,)?(\\[.+?\\])?.+?\\]"); + static boost::wregex reg_inside_table5(L"^[,;:]?\\[.+?\\]"); first = results[1].second; @@ -567,6 +569,21 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: } } } + else if(boost::regex_search(first, last, results_1, reg_inside_table5)) + { + insider = results_1.str(0); + insider = boost::algorithm::erase_first_copy(insider, L","); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + if (ptgList.colFirst == 65535) + { + ptgList.columns = 0x01; + ptgList.colFirst = indexColumn; + } + } + first = results_1[0].second; + } if (first != last && *first == ']') ++first; @@ -574,6 +591,22 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: return true; } + else if(boost::regex_search(first, last, results_1, reg_inside_table4)) + { + _UINT16 indexColumn = -1; + auto insider = results_1.str(0); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + ptgList.columns = 0x02; + ptgList.colLast = indexColumn; + first = results_1[0].second; + return true; + } + + if (first != last && *first == ']') + ++first; + } } } return false; From c6b3238fa4d5bd6c80fe3cfe017ce177ac7229ec Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 14 Feb 2024 16:02:06 +0600 Subject: [PATCH 299/794] Fix dvals conversion --- .../XlsxFormat/Worksheets/DataValidation.cpp | 151 +++++++++++------- 1 file changed, 91 insertions(+), 60 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index 36e75317b27..97bacb24ec1 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -216,24 +216,29 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); { auto ptr(new XLSB::DVal); XLS::BaseObjectPtr objectPtr(ptr); - - if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeNone) - ptr->valType = XLS::typeDvNone; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeWhole) - ptr->valType = XLS::typeDvWhole; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDecimal) - ptr->valType = XLS::typeDvDecimal; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeList) - ptr->valType = XLS::typeDvList; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDate) - ptr->valType = XLS::typeDvDate; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTime) - ptr->valType = XLS::typeDvTime; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTextLength) - ptr->valType = XLS::typeDvTextLength; - else if (m_oType == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeCustom) - ptr->valType = XLS::typeDvCustom; - + if(m_oType.IsInit()) + { + if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeNone) + ptr->valType = XLS::typeDvNone; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeWhole) + ptr->valType = XLS::typeDvWhole; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDecimal) + ptr->valType = XLS::typeDvDecimal; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeList) + ptr->valType = XLS::typeDvList; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeDate) + ptr->valType = XLS::typeDvDate; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTime) + ptr->valType = XLS::typeDvTime; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeTextLength) + ptr->valType = XLS::typeDvTextLength; + else if (m_oType->GetValue() == SimpleTypes::Spreadsheet::EDataValidationType::validationTypeCustom) + ptr->valType = XLS::typeDvCustom; + else + ptr->valType = XLS::typeDvNone; + } + else + ptr->valType = XLS::typeDvNone; ptr->fAllowBlank = m_oAllowBlank->GetValue(); if(m_oError.IsInit()) ptr->Error = m_oError.get(); @@ -248,47 +253,64 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); ptr->PromptTitle = m_oPromptTitle.get(); ptr->errStyle = m_oErrorStyle->GetValue(); - - if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOn) - { - ptr->mdImeMode = 0x01; - } - else if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOff) - { - ptr->mdImeMode = 0x02; - } - else - { - ptr->mdImeMode = m_oImeMode->GetValue(); - } - - if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorBetween) - ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotBetween) - ptr->typOperator = XLS::_typOperatorDv::operatorDvNotBetween; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorEqual) - ptr->typOperator = XLS::_typOperatorDv::operatorDvEquals; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotEqual) - ptr->typOperator = XLS::_typOperatorDv::operatorDvNotEquals; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThan) - ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThan; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThan) - ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThan; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThanOrEqual) - ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThanOrEqual; - else if (m_oOperator == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThanOrEqual) - ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThanOrEqual; - - ptr->fSuppressCombo = m_oShowDropDown->GetValue(); - ptr->fShowErrorMsg = m_oShowErrorMessage->GetValue(); - ptr->fShowInputMsg = m_oShowInputMessage->GetValue(); - + if(m_oImeMode.IsInit()) + { + if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOn) + { + ptr->mdImeMode = 0x01; + } + else if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOff) + { + ptr->mdImeMode = 0x02; + } + else + { + ptr->mdImeMode = m_oImeMode->GetValue(); + } + } + else + ptr->mdImeMode = 0; + if(m_oOperator.IsInit()) + { + if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotBetween) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotBetween; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvEquals; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorNotEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvNotEquals; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThan; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThan) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThan; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorGreaterThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThanOrEqual; + else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThanOrEqual) + ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThanOrEqual; + } + + if(m_oShowDropDown.IsInit()) + ptr->fSuppressCombo = m_oShowDropDown->GetValue(); + else + ptr->fSuppressCombo = false; + if(m_oShowErrorMessage.IsInit()) + ptr->fShowErrorMsg = m_oShowErrorMessage->GetValue(); + else + ptr->fShowErrorMsg = false; + if(m_oShowInputMessage.IsInit()) + ptr->fShowInputMsg = m_oShowInputMessage->GetValue(); + else + ptr->fShowInputMsg = false; + if(m_oSqRef.IsInit()) ptr->sqrfx.strValue = m_oSqRef.get(); - ptr->formula1 = m_oFormula1->m_sText; - ptr->formula2 = m_oFormula2->m_sText; + if(m_oFormula1.IsInit()) + ptr->formula1 = m_oFormula1->m_sText; + if(m_oFormula2.IsInit()) + ptr->formula2 = m_oFormula2->m_sText; - return objectPtr; + return objectPtr; } void CDataValidation::fromBin(XLS::BaseObjectPtr& obj) { @@ -602,10 +624,19 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); auto beginPtr(new XLSB::BeginDVals); ptr->m_BrtBeginDVals = XLS::BaseObjectPtr{beginPtr}; - beginPtr->dVals.idvMac = m_oCount.get() ; - beginPtr->dVals.fWnClosed = m_oDisablePrompts->GetValue(); - beginPtr->dVals.xLeft = m_oXWindow->GetValue(); - beginPtr->dVals.yTop = m_oYWindow->GetValue(); + beginPtr->dVals.idvMac = m_arrItems.size(); + if(m_oDisablePrompts.IsInit()) + beginPtr->dVals.fWnClosed = m_oDisablePrompts->GetValue(); + else + beginPtr->dVals.fWnClosed = false; + if(m_oXWindow.IsInit()) + beginPtr->dVals.xLeft = m_oXWindow->GetValue(); + else + beginPtr->dVals.xLeft = 0; + if(m_oYWindow.IsInit()) + beginPtr->dVals.yTop = m_oYWindow->GetValue(); + else + beginPtr->dVals.yTop = false; for(auto i:m_arrItems) { From 3d3daed65590c0c344ef4f863d8f231e87d0ce6b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 14 Feb 2024 16:03:24 +0600 Subject: [PATCH 300/794] Add table and column names to global info for formulas --- OOXML/XlsxFormat/Table/Tables.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 1a434f56383..6982bba32bd 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -610,6 +610,18 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") else if ((L"extLst") == sName) m_oExtLst = oReader; } + if(!m_oName.IsInit() && m_oDisplayName.IsInit()) + m_oName = m_oDisplayName.get(); + + if(m_oTableColumns.IsInit() && !m_oTableColumns->m_arrItems.empty()) + { + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.emplace(m_oId->GetValue(), + std::vector(m_oTableColumns->m_arrItems.size()+1, L"")); + for(auto i:m_oTableColumns->m_arrItems) + if(i->m_oName.IsInit() && i->m_oId.IsInit()) + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).at(i->m_oId->GetValue()) = i->m_oName.get(); + } + XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(m_oId->GetValue(), m_oName.get()); } void CTable::fromBin(XLS::BaseObjectPtr& obj) { From fa90923000d3aab39195a5ebe0938facb6ca5a71 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 14 Feb 2024 16:03:53 +0600 Subject: [PATCH 301/794] Fix table styles conversion --- OOXML/XlsxFormat/Styles/TableStyles.cpp | 30 +++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index f0a6174117b..7e99b76c8ff 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -84,8 +84,14 @@ namespace OOX { auto ptr(new XLSB::TableStyleElement); XLS::BaseObjectPtr objectPtr(ptr); - ptr->index = m_oDxfId->GetValue(); - ptr->size = m_oSize->GetValue(); + if(m_oDxfId.IsInit()) + ptr->index = m_oDxfId->GetValue(); + else + ptr->index = 0; + if(m_oSize.IsInit()) + ptr->size = m_oSize->GetValue(); + else + ptr->size = 0; if(m_oType.IsInit()) { @@ -148,6 +154,8 @@ namespace OOX else ptr->tseType = 19; } + else + ptr->tseType = 19; return objectPtr; } @@ -314,11 +322,19 @@ namespace OOX auto beginStyle(new XLSB::BeginTableStyle); ptr->m_BrtBeginTableStyle = XLS::BaseObjectPtr{beginStyle}; - beginStyle->ctse = m_oCount->GetValue(); - beginStyle->fIsPivot = m_oPivot->GetValue(); - beginStyle->fIsTable = m_oTable->GetValue(); - beginStyle->rgchName = m_oName.get(); - beginStyle->rgchName = m_oDisplayName.get(); + beginStyle->ctse = m_arrItems.size(); + if(m_oPivot.IsInit()) + beginStyle->fIsPivot = m_oPivot->GetValue(); + else + beginStyle->fIsPivot = false; + if(m_oTable.IsInit()) + beginStyle->fIsTable = m_oTable->GetValue(); + else + beginStyle->fIsTable = false; + if(m_oName.IsInit()) + beginStyle->rgchName = m_oName.get(); + else if(m_oDisplayName.IsInit()) + beginStyle->rgchName = m_oDisplayName.get(); for(auto i:m_arrItems) ptr->m_arBrtTableStyleElement.push_back(i->toBin()); From 95146474ffe9ad116bd344a16e0ed1372514ebb6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 14 Feb 2024 16:15:37 +0600 Subject: [PATCH 302/794] Fix comma processing --- .../XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 55d5a2c65a8..892bab3481a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -265,7 +265,8 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } if(!ptg_stack.size() || !left_p) { - // EXCEPT::RT::WrongParenthesisSequence(assembled_formula); + operand_expected = true; + continue;// EXCEPT::RT::WrongParenthesisSequence(assembled_formula); } left_p->incrementParametersNum(); // The count of parameters will be transferred to PtgFuncVar last_ptg = left_p; // PtgParen. Mostly to differ unary and binary minuses and pluses From 17a217267307d871ffb2b4e81e55e73d814067ec Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 15 Feb 2024 12:27:23 +0300 Subject: [PATCH 303/794] for bug #66495 --- OOXML/Binary/Document/BinReader/Readers.cpp | 5 +++++ OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h | 3 ++- OOXML/Binary/Document/BinWriter/BinWriters.cpp | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/OOXML/Binary/Document/BinReader/Readers.cpp b/OOXML/Binary/Document/BinReader/Readers.cpp index 297b16a8ea1..fda10726226 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/Readers.cpp @@ -1036,6 +1036,11 @@ int Binary_pPrReader::ReadContent(BYTE type, long length, void* poResult) pPPr->m_oCnfStyle.Init(); READ1_DEF(length, res, this->ReadCnfStyle, pPPr->m_oCnfStyle.GetPointer()); }break; + case c_oSerProp_pPrType::SnapToGrid: + { + pPPr->m_oSnapToGrid.Init(); + pPPr->m_oSnapToGrid->m_oVal.FromBool(m_oBufferedStream.GetBool()); + }break; default: res = c_oSerConstants::ReadUnknown; break; diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index fa5219571eb..ba1246ee425 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -356,7 +356,8 @@ extern int g_nCurFormatVersion; Tab_Item_PosTwips = 42, Tab_Item_Val = 43, SuppressLineNumbers = 44, - CnfStyle = 45 + CnfStyle = 45, + SnapToGrid = 46 };} namespace c_oSerProp_rPrType{enum c_oSerProp_rPrType { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index de701a62a39..f6ac759c389 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -1132,6 +1132,12 @@ void Binary_pPrWriter::Write_pPr(const OOX::Logic::CParagraphProperty& pPr) WriteCnfStyle(pPr.m_oCnfStyle.GetPointer()); m_oBcw.WriteItemWithLengthEnd(nCurPos2); } + if (pPr.m_oSnapToGrid.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::SnapToGrid); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(pPr.m_oSnapToGrid->m_oVal.ToBool()); + } } void Binary_pPrWriter::WritePPrChange(const OOX::Logic::CPPrChange& pPrChange) { From b9a11bc30deac160319e3c07b7e66a388f140afd Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 15 Feb 2024 13:11:19 +0300 Subject: [PATCH 304/794] Add ID with MetaOForm --- PdfFile/SrcWriter/Document.cpp | 16 ++++++++++++++++ PdfFile/SrcWriter/Metadata.cpp | 6 ++++++ PdfFile/SrcWriter/Metadata.h | 1 + PdfFile/test/test.cpp | 24 ++++-------------------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 7310379f5b2..94097d7d418 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -437,6 +437,22 @@ namespace PdfWriter { if (!m_pMetaData) return false; + + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + + pID->Add(new CBinaryObject(arrId, 16)); + pID->Add(new CBinaryObject(arrId, 16)); + + m_pMetaData->SetID(new CBinaryObject(arrId, 16)); + } + return m_pMetaData->AddMetaData(sMetaName, pMetaData, nMetaLength); } CDictObject* CDocument::CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) diff --git a/PdfFile/SrcWriter/Metadata.cpp b/PdfFile/SrcWriter/Metadata.cpp index 57d56629bda..d0cd8ebab7b 100644 --- a/PdfFile/SrcWriter/Metadata.cpp +++ b/PdfFile/SrcWriter/Metadata.cpp @@ -179,6 +179,12 @@ namespace PdfWriter m_nLengthBegin = 0; m_nLengthEnd = 0; } + void CStreamData::SetID(CBinaryObject* pID) + { + if (!pID) + return; + Add("ID", pID); + } bool CStreamData::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) { if (sMetaName == L"Length") diff --git a/PdfFile/SrcWriter/Metadata.h b/PdfFile/SrcWriter/Metadata.h index 8e5d0da737f..ea3673035d4 100644 --- a/PdfFile/SrcWriter/Metadata.h +++ b/PdfFile/SrcWriter/Metadata.h @@ -62,6 +62,7 @@ namespace PdfWriter return dict_type_STREAM; } + void SetID(CBinaryObject* pID); bool AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); void WriteToStream(CStream* pStream, CEncrypt* pEncrypt) override; void AfterWrite(CStream* pStream) override; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 0ddac403bb0..7c176ad48c3 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -149,21 +149,10 @@ TEST_F(CPdfFileTest, GetMetaData) BYTE* pMetaData = NULL; DWORD nMetaLength = 0; - if (pdfFile->GetMetaData(wsSrcFile, L"Test0", &pMetaData, nMetaLength)) + if (pdfFile->GetMetaData(wsSrcFile, L"ONLYOFFICEFORM", &pMetaData, nMetaLength)) { NSFile::CFileBinary oFile; - if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/resGetMetaData0.png")) - oFile.WriteFile(pMetaData, nMetaLength); - oFile.CloseFile(); - - EXPECT_TRUE(pMetaData); - } - RELEASEARRAYOBJECTS(pMetaData); - - if (pdfFile->GetMetaData(wsSrcFile, L"Test1", &pMetaData, nMetaLength)) - { - NSFile::CFileBinary oFile; - if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/resGetMetaData1.png")) + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf")) oFile.WriteFile(pMetaData, nMetaLength); oFile.CloseFile(); @@ -215,14 +204,9 @@ TEST_F(CPdfFileTest, SetMetaData) BYTE* pFileData = NULL; DWORD nFileSize; - std::wstring sFile = NSFile::GetProcessDirectory() + L"/res0.png"; - EXPECT_TRUE(NSFile::CFileBinary::ReadAllBytes(sFile, &pFileData, nFileSize)); - pdfFile->AddMetaData(L"Test0", pFileData, nFileSize); - RELEASEARRAYOBJECTS(pFileData); - - sFile = NSFile::GetProcessDirectory() + L"/res1.png"; + std::wstring sFile = NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf"; EXPECT_TRUE(NSFile::CFileBinary::ReadAllBytes(sFile, &pFileData, nFileSize)); - pdfFile->AddMetaData(L"Test1", pFileData, nFileSize); + pdfFile->AddMetaData(L"ONLYOFFICEFORM", pFileData, nFileSize); RELEASEARRAYOBJECTS(pFileData); EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); From ebc94a2615e288f5c1c81720705e3738d83093ef Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 15 Feb 2024 17:54:17 +0600 Subject: [PATCH 305/794] Add new string removing from column names --- .../Logic/Biff_structures/StringPtgParser.cpp | 22 ++++++++--------- .../Logic/Biff_structures/SyntaxPtg.cpp | 24 +++++++++++++++---- OOXML/XlsxFormat/Table/Tables.cpp | 5 ++++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 892bab3481a..1245cd1c0fc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -365,17 +365,6 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { rgce.addPtg(found_operand = OperandPtgPtr(new PtgNum(operand_str))); } - - else if(SyntaxPtg::extract_UndefinedName(it, itEnd)) // Shall be placed strongly after extract_PtgName - { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#REF!"))); - } - - else if(SyntaxPtg::extract_PtgArray(it, itEnd, operand_str)) - { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgArray(OperandPtg::ptg_ARRAY))); - rgb.addPtg(PtgPtr(new PtgExtraArray(operand_str))); - } else if(SyntaxPtg::extract_PtgFunc(it, itEnd, operand_str)) { PtgPtr func; @@ -395,6 +384,17 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R rgce.addPtg(PtgPtr(new PtgNameX(operand_str, OperandPtg::ptg_VALUE))); } } + else if(SyntaxPtg::extract_UndefinedName(it, itEnd)) // Shall be placed strongly after extract_PtgName + { + rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#REF!"))); + } + + else if(SyntaxPtg::extract_PtgArray(it, itEnd, operand_str)) + { + rgce.addPtg(found_operand = OperandPtgPtr(new PtgArray(OperandPtg::ptg_ARRAY))); + rgb.addPtg(PtgPtr(new PtgExtraArray(operand_str))); + } + else { // EXCEPT::RT::WrongFormulaString("Unknown operand format in formula.", assembled_formula); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index e3cce003fcf..36c8c51950c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -483,6 +483,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: insider = results_1.str(0); + insider = boost::algorithm::erase_all_copy(insider, L"\n"); if (insider == L"[#Data]") { if (boost::regex_search(first, last, results_1, reg_inside_table2)) @@ -520,7 +521,6 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { ptgList.rowType = 0x10; } - else if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { ptgList.rowType = 0x00; @@ -534,6 +534,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (boost::regex_search(first, last, results_1, reg_inside_table3)) { insider = results_1.str(0); + insider = boost::algorithm::erase_all_copy(insider, L"\n"); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -550,6 +551,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (boost::regex_search(first, last, results_1, reg_inside_table3)) { insider = results_1.str(0); + insider = boost::algorithm::erase_all_copy(insider, L"\n"); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -561,6 +563,19 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: first = results_1[0].second; } } + else if(boost::regex_search(first, last, results_1, reg_inside_table5)) + { + insider = results_1.str(0); + insider = boost::algorithm::erase_all_copy(insider, L"\n"); + insider = boost::algorithm::erase_first_copy(insider, L":"); + + if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) + { + ptgList.columns = 0x02; + ptgList.colLast = indexColumn; + } + first = results_1[0].second; + } } else { @@ -573,6 +588,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { insider = results_1.str(0); insider = boost::algorithm::erase_first_copy(insider, L","); + insider = boost::algorithm::erase_all_copy(insider, L"\n"); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { @@ -594,12 +610,12 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: else if(boost::regex_search(first, last, results_1, reg_inside_table4)) { _UINT16 indexColumn = -1; - auto insider = results_1.str(0); + auto insider = boost::algorithm::erase_all_copy(results_1.str(0), L"\n"); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { - ptgList.columns = 0x02; - ptgList.colLast = indexColumn; + ptgList.columns = 0x01; + ptgList.colFirst = indexColumn; first = results_1[0].second; return true; } diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 6982bba32bd..aaa15cc6ffd 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -619,7 +619,12 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") std::vector(m_oTableColumns->m_arrItems.size()+1, L"")); for(auto i:m_oTableColumns->m_arrItems) if(i->m_oName.IsInit() && i->m_oId.IsInit()) + { + if(i->m_oId->GetValue()+1 > XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).size()) + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).resize(i->m_oId->GetValue()+1); + i->m_oName = boost::algorithm::erase_all_copy(i->m_oName.get(), L"_x000a_"); XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).at(i->m_oId->GetValue()) = i->m_oName.get(); + } } XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(m_oId->GetValue(), m_oName.get()); } From d1da32b9227718ee5a902d9038246365eb42f5de Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 15 Feb 2024 17:54:50 +0600 Subject: [PATCH 306/794] add error style initialization check --- OOXML/XlsxFormat/Worksheets/DataValidation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index 97bacb24ec1..fb9b99a69ec 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -251,8 +251,10 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); if (m_oPromptTitle.IsInit()) ptr->PromptTitle = m_oPromptTitle.get(); - - ptr->errStyle = m_oErrorStyle->GetValue(); + if(m_oErrorStyle.IsInit()) + ptr->errStyle = m_oErrorStyle->GetValue(); + else + ptr->errStyle = 0; if(m_oImeMode.IsInit()) { if(m_oImeMode == SimpleTypes::Spreadsheet::EDataValidationImeMode::imeModeOn) From 8eee4d470c917eefd4a8381c5fc638c7602b8a6a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 15 Feb 2024 19:29:51 +0600 Subject: [PATCH 307/794] Fix sparkline conversion --- OOXML/XlsxFormat/Worksheets/Sparkline.cpp | 163 +++++++++++++++------- 1 file changed, 116 insertions(+), 47 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp index 64ec4da5b80..ca5d524267b 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp @@ -401,54 +401,123 @@ namespace OOX auto ptr(new XLSB::BeginSparklineGroup); ptr1->m_BrtBeginSparklineGroup = XLS::BaseObjectPtr{ptr}; - ptr->dManualMax.data.value = m_oManualMax->GetValue(); - ptr->dManualMin.data.value = m_oManualMin->GetValue(); - ptr->dLineWeight.data.value = m_oLineWeight->GetValue(); - ptr->isltype = static_castisltype)>(m_oType->GetValue()); - ptr->fDateAxis = m_oDateAxis->GetValue(); - ptr->fShowEmptyCellAsZero = (m_oDisplayEmptyCellsAs == OOX::Spreadsheet::ST_DispBlanksAs::st_dispblanksasZERO) ? 0x01 : 0x00; - ptr->fMarkers = m_oMarkers->GetValue(); - ptr->fHigh = m_oHigh->GetValue(); - ptr->fLow = m_oLow->GetValue(); - ptr->fFirst = m_oFirst->GetValue(); - ptr->fLast = m_oLast->GetValue(); - ptr->fNegative = m_oNegative->GetValue(); - ptr->fAxis = m_oDisplayXAxis->GetValue(); - ptr->fDisplayHidden = m_oDisplayHidden->GetValue(); - ptr->fRTL = m_oRightToLeft->GetValue(); - - if(m_oMaxAxisType == SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Individual) + if(m_oManualMax.IsInit()) + ptr->dManualMax.data.value = m_oManualMax->GetValue(); + else + ptr->dManualMax.data.value = 0; + if(m_oManualMin.IsInit()) + ptr->dManualMin.data.value = m_oManualMin->GetValue(); + else + ptr->dManualMin.data.value = 0; + if(m_oLineWeight.IsInit()) + ptr->dLineWeight.data.value = m_oLineWeight->GetValue(); + else + ptr->dLineWeight.data.value = 0; + if(m_oType.IsInit()) + ptr->isltype = static_castisltype)>(m_oType->GetValue()); + else + ptr->isltype = 0; + if(m_oDateAxis.IsInit()) + ptr->fDateAxis = m_oDateAxis->GetValue(); + else + ptr->fDateAxis = 0; + if(m_oDisplayEmptyCellsAs.IsInit()) + ptr->fShowEmptyCellAsZero = (m_oDisplayEmptyCellsAs == OOX::Spreadsheet::ST_DispBlanksAs::st_dispblanksasZERO) ? 0x01 : 0x00; + else + ptr->fShowEmptyCellAsZero = false; + if(m_oMarkers.IsInit()) + ptr->fMarkers = m_oMarkers->GetValue(); + else + ptr->fMarkers = false; + if(m_oHigh.IsInit()) + ptr->fHigh = m_oHigh->GetValue(); + else + ptr->fHigh = false; + if(m_oLow.IsInit()) + ptr->fLow = m_oLow->GetValue(); + else + ptr->fLow = false; + if(m_oFirst.IsInit()) + ptr->fFirst = m_oFirst->GetValue(); + else + ptr->fFirst = false; + if(m_oLast.IsInit()) + ptr->fLast = m_oLast->GetValue(); + else + ptr->fLast = false; + if(m_oNegative.IsInit()) + ptr->fNegative = m_oNegative->GetValue(); + else + ptr->fNegative = false; + if(m_oDisplayXAxis.IsInit()) + ptr->fAxis = m_oDisplayXAxis->GetValue(); + else + ptr->fAxis = false; + if(m_oDisplayHidden.IsInit()) + ptr->fDisplayHidden = m_oDisplayHidden->GetValue(); + else + ptr->fDisplayHidden = false; + if(m_oRightToLeft.IsInit()) + ptr->fRTL = m_oRightToLeft->GetValue(); + else + ptr->fRTL = false; + if(m_oMaxAxisType.IsInit() && m_oMaxAxisType == SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Individual) ptr->fIndividualAutoMax = true; - - - if(m_oColorSeries.IsInit()) - ptr->brtcolorSeries = m_oColorSeries->toColor(); - - if(m_oColorNegative.IsInit()) - ptr->brtcolorNegative = m_oColorNegative->toColor(); - - if(m_oColorAxis.IsInit()) - ptr->brtcolorAxis = m_oColorAxis->toColor(); - - if(m_oColorMarkers.IsInit()) - ptr->brtcolorMarkers = m_oColorMarkers->toColor(); - - if(m_oColorFirst.IsInit()) - ptr->brtcolorFirst = m_oColorFirst->toColor(); - - if(m_oColorLast.IsInit()) - ptr->brtcolorLast = m_oColorLast->toColor(); - - if(m_oColorHigh.IsInit()) - ptr->brtcolorHigh = m_oColorHigh->toColor(); - - if(m_oColorLow.IsInit()) - ptr->brtcolorLow = m_oColorLow->toColor(); - - if(ptr->FRTheader.rgFormulas.array.size() > 0) - { - ptr->FRTheader.rgFormulas.array[0].formula = m_oRef.get(); - } + else + ptr->fIndividualAutoMax = false; + + + if(m_oColorSeries.IsInit()) + ptr->brtcolorSeries = m_oColorSeries->toColor(); + else + ptr->brtcolorSeries = m_oColorSeries->GetDefaultColor(); + + if(m_oColorNegative.IsInit()) + ptr->brtcolorNegative = m_oColorNegative->toColor(); + else + ptr->brtcolorNegative = m_oColorSeries->GetDefaultColor(); + + if(m_oColorAxis.IsInit()) + ptr->brtcolorAxis = m_oColorAxis->toColor(); + else + ptr->brtcolorAxis = m_oColorSeries->GetDefaultColor(); + + if(m_oColorMarkers.IsInit()) + ptr->brtcolorMarkers = m_oColorMarkers->toColor(); + else + ptr->brtcolorMarkers = m_oColorSeries->GetDefaultColor(); + + if(m_oColorFirst.IsInit()) + ptr->brtcolorFirst = m_oColorFirst->toColor(); + else + ptr->brtcolorFirst = m_oColorSeries->GetDefaultColor(); + + if(m_oColorLast.IsInit()) + ptr->brtcolorLast = m_oColorLast->toColor(); + else + ptr->brtcolorLast = m_oColorSeries->GetDefaultColor(); + + if(m_oColorHigh.IsInit()) + ptr->brtcolorHigh = m_oColorHigh->toColor(); + else + ptr->brtcolorHigh = m_oColorHigh->GetDefaultColor(); + + if(m_oColorLow.IsInit()) + ptr->brtcolorLow = m_oColorLow->toColor(); + else + ptr->brtcolorLow = m_oColorLow->GetDefaultColor(); + + ptr->FRTheader.fFormula = false; + ptr->FRTheader.fRef = false; + ptr->FRTheader.fSqref = false; + ptr->FRTheader.fRelID = false; + if(m_oRef.IsInit()) + { + XLSB::FRTFormula fmla; + ptr->FRTheader.rgFormulas.array.push_back(fmla); + ptr->FRTheader.rgFormulas.array[0].formula = m_oRef.get(); + ptr->FRTheader.fFormula = true; + } return objectPtr; } From b7bc83f37d76a00df601c89ca620bce9d445ec98 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 16 Feb 2024 10:47:08 +0300 Subject: [PATCH 308/794] Create ValidMetaData --- PdfFile/PdfFile.cpp | 6 ++++++ PdfFile/PdfFile.h | 1 + PdfFile/PdfReader.cpp | 27 +++++++++++++++++++++++++++ PdfFile/PdfReader.h | 1 + PdfFile/test/test.cpp | 9 +++++++++ 5 files changed, 44 insertions(+) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 7d4d916ad3c..f9f228bac70 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1525,6 +1525,12 @@ int CPdfFile::GetMaxRefID() return m_pInternal->pReader->GetMaxRefID(); } +bool CPdfFile::ValidMetaData() +{ + if (!m_pInternal->pReader) + return false; + return m_pInternal->pReader->ValidMetaData(); +} void CPdfFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) { if (!m_pInternal->pReader) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 46c9a2aab4e..0e436b0dcbc 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -128,6 +128,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + bool ValidMetaData(); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a18fb80e68e..6a6e4b0eb87 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -461,6 +461,33 @@ int CPdfReader::GetMaxRefID() return 0; return m_pPDFDocument->getXRef()->getNumObjects(); } +bool CPdfReader::ValidMetaData() +{ + if (!m_pPDFDocument) + return false; + + XRef* xref = m_pPDFDocument->getXRef(); + Object oMeta, oType, oID; + if (!xref->fetch(1, 0, &oMeta)->isStream() || !oMeta.streamGetDict()->lookup("Type", &oType)->isName("MetaOForm") || !oMeta.streamGetDict()->lookup("ID", &oID)->isString()) + { + oMeta.free(); oType.free(); oID.free(); + return false; + } + oMeta.free(); oType.free(); + + Object oTID, oID2; + Object* pTrailerDict = xref->getTrailerDict(); + if (!pTrailerDict || !pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString()) + { + oID.free(); oTID.free(); oID2.free(); + return false; + } + oTID.free(); + + bool bRes = oID2.getString()->cmp(oID.getString()) == 0; + oID.free(); oID2.free(); + return bRes; +} void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak) { if (m_pPDFDocument && pRenderer) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 03a22536d08..0b869e1b837 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -61,6 +61,7 @@ class CPdfReader int GetError(); int GetRotate(int nPageIndex); int GetMaxRefID(); + bool ValidMetaData(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 7c176ad48c3..6eab94b8e3b 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -161,6 +161,15 @@ TEST_F(CPdfFileTest, GetMetaData) RELEASEARRAYOBJECTS(pMetaData); } +TEST_F(CPdfFileTest, ValidMetaData) +{ + GTEST_SKIP(); + + LoadFromFile(); + + std::cout << "ValidMetaData " << (pdfFile->ValidMetaData() ? "true" : "false") << std::endl; +} + TEST_F(CPdfFileTest, PdfBinToPng) { GTEST_SKIP(); From 65a483461ea6bab5c2a697d803a8c7b70a0f7c58 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 16 Feb 2024 11:57:58 +0300 Subject: [PATCH 309/794] Fix RC parser - span and #text --- .../pro/js/wasm/src/drawingfile_test.cpp | 5 ++- PdfFile/SrcReader/PdfAnnot.cpp | 35 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 192193b9d5e..ec127fabf14 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -3,6 +3,7 @@ #include "../../../../raster/BgraFrame.h" #include "../../../../raster/ImageFileFormatChecker.h" #include "../../../../../common/File.h" +#include "../../../../../common/StringBuilder.h" #include "drawingfile.cpp" unsigned char READ_BYTE(BYTE* x) @@ -1289,7 +1290,9 @@ int main(int argc, char* argv[]) nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << "text:" << std::string((char*)(pAnnots + i), nPathLength) << " "; + std::string sText = std::string((char*)(pAnnots + i), nPathLength); + NSStringUtils::string_replaceA(sText, "\r", "\n"); + std::cout << "text:" << sText << " "; i += nPathLength; std::cout << "} "; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index cef461633ba..191a785ce74 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2150,24 +2150,31 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : do { - if (oLightReader.GetNameA() != "span") - continue; - - CFontData* pFont = new CFontData(oFontBase); - while (oLightReader.MoveToNextAttribute()) + std::string sName = oLightReader.GetNameA(); + if (sName == "span") { - if (oLightReader.GetNameA() == "style") + CFontData* pFont = new CFontData(oFontBase); + while (oLightReader.MoveToNextAttribute()) { - BYTE nTextAlign = ReadFontData(oLightReader.GetTextA(), pFont); - if (nTextAlign != 3) - m_nTextAlign = nTextAlign; - break; + if (oLightReader.GetNameA() == "style") + { + BYTE nTextAlign = ReadFontData(oLightReader.GetTextA(), pFont); + if (nTextAlign != 3) + m_nTextAlign = nTextAlign; + break; + } } - } - oLightReader.MoveToElement(); + oLightReader.MoveToElement(); - pFont->sText = oLightReader.GetText2A(); - m_arrRC.push_back(pFont); + pFont->sText = oLightReader.GetText2A(); + m_arrRC.push_back(pFont); + } + else if (sName == "#text") + { + CFontData* pFont = new CFontData(oFontBase); + pFont->sText = oLightReader.GetTextA(); + m_arrRC.push_back(pFont); + } } while (oLightReader.ReadNextSiblingNode2(nDepthSpan)); } } From 4ee1d598036fd4d8d8a3bd05c7c4df682f5bfde0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 16 Feb 2024 15:56:48 +0600 Subject: [PATCH 310/794] Fix default values setting up --- OOXML/XlsxFormat/Table/Autofilter.cpp | 52 +++++++++++-------- OOXML/XlsxFormat/Table/Connections.cpp | 35 ++++++++++++- .../Worksheets/ConditionalFormatting.cpp | 27 +++++++--- 3 files changed, 83 insertions(+), 31 deletions(-) diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index e9fba5c921e..c21590a25eb 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -109,31 +109,39 @@ namespace OOX auto ptr(new XLSB::BeginSortCond); XLS::BaseObjectPtr objectPtr(ptr); - ptr->fSortDes = m_oDescending->GetValue(); - ptr->rfx = m_oRef->GetValue(); - - if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyValue) - { - ptr->sortOn = 0; - } - else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyCellColor) - { - ptr->sortOn = 1; - ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); - } - else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyFontColor) - { - ptr->sortOn = 2; - ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); - } - else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyIcon) - { - ptr->sortOn = 3; - } + if(m_oDescending.IsInit()) + ptr->fSortDes = m_oDescending->GetValue(); else + ptr->fSortDes = 0; + if(m_oRef.IsInit()) + ptr->rfx = m_oRef->GetValue(); + if(m_oSortBy.IsInit()) { - ptr->sortOn = 0; + if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyValue) + { + ptr->sortOn = 0; + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyCellColor) + { + ptr->sortOn = 1; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyFontColor) + { + ptr->sortOn = 2; + ptr->condDataValue.condDataValue = m_oDxfId->GetValue(); + } + else if(m_oSortBy == SimpleTypes::Spreadsheet::ESortBy::sortbyIcon) + { + ptr->sortOn = 3; + } + else + ptr->sortOn = 0; } + else + ptr->sortOn = 0; + + ptr->stSslist = L""; return objectPtr; } diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index 1eca709bf4f..f1211d70666 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -464,20 +464,42 @@ namespace OOX if(m_oLocalConnection.IsInit()) ptr->stConnLocal = m_oLocalConnection.get(); + else + { + ptr->bLoadConnLocal = false; + ptr->stConnLocal = L""; + } if(m_oRowDrillCount.IsInit()) ptr->nDrillthroughRows = m_oRowDrillCount.get(); + else + ptr->nDrillthroughRows = 0; if(m_oLocal.IsInit()) ptr->fLocalConn = m_oLocal.get(); + else + { + ptr->fLocalConn = false; + ptr->bLoadConnLocal = false; + } if(m_oLocalRefresh.IsInit()) ptr->fNoRefreshCube = m_oLocalRefresh.get(); + else + ptr->fNoRefreshCube = false; if(m_oSendLocale.IsInit()) - ptr->fUseOfficeLcid = m_oSendLocale.get(); + ptr->fUseOfficeLcid = m_oSendLocale.get(); + else + ptr->fUseOfficeLcid = false; if(m_oServerNumberFormat.IsInit()) ptr->fSrvFmtNum = m_oServerNumberFormat.get(); + else + ptr->fSrvFmtNum = false; if(m_oServerFont.IsInit()) ptr->fSrvFmtFlags = m_oServerFont.get(); + else + ptr->fSrvFmtFlags = false; if(m_oServerFontColor.IsInit()) ptr->fSrvFmtFore = m_oServerFontColor.get(); + else + ptr->fSrvFmtFore = false; return XLS::BaseObjectPtr{ptr1}; } EElementType COlapPr::getType() const @@ -943,6 +965,15 @@ namespace OOX auto ptr(new XLSB::EXTCONN15); objectPtr = XLS::BaseObjectPtr{ptr}; auto ptr1(new XLSB::BeginExtConn15); + ptr1->fAutoDelete = false; + ptr1->fExcludeFromRefreshAll = false; + ptr1->fSandbox = false; + ptr1->fUsedByAddin = false; + if(m_oId.IsInit()) + ptr1->irstId = m_oId->GetValue(); + else + ptr1->irstId = false; + ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; ptr->m_source = m_oRangePr->toBin(); } @@ -968,6 +999,8 @@ namespace OOX ptr1->idbtype = m_oType.get(); if(m_oName.IsInit()) ptr1->stConnName = m_oName.get(); + else + ptr1->stConnName = L""; if(m_oId.IsInit()) ptr1->dwConnID = m_oId->GetValue(); if(m_oCredentials.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index f0cd4e2671c..f8ea392135c 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -247,8 +247,10 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() auto ptr1(new XLSB::CFVO); ptr->m_BrtCFVO = XLS::BaseObjectPtr{ptr1}; - ptr1->fGTE = m_oGte->GetValue(); - + if(m_oGte.IsInit()) + ptr1->fGTE = m_oGte->GetValue(); + else + ptr1->fGTE = false; if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) ptr1->iType = XLSB::CFVOtype::CFVONUM; else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) @@ -262,7 +264,8 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) ptr1->iType = XLSB::CFVOtype::CFVOFMLA; - ptr1->numParam.data.value = std::stod(m_oVal.get()); + if(m_oVal.IsInit()) + ptr1->numParam.data.value = std::stod(m_oVal.get()); if(m_oFormula.IsInit()) { @@ -887,15 +890,23 @@ XLS::BaseObjectPtr CDataBar::toBin() auto ptr1(new XLSB::BeginDatabar); ptr->m_BrtBeginDatabar = XLS::BaseObjectPtr{ptr1}; - ptr1->bLenMax = m_oMaxLength->GetValue(); - ptr1->bLenMin = m_oMinLength->GetValue(); - ptr1->fShowValue = m_oShowValue->GetValue(); + if(m_oMaxLength.IsInit()) + ptr1->bLenMax = m_oMaxLength->GetValue(); + else + m_oMaxLength = 100; + if(m_oMinLength.IsInit()) + ptr1->bLenMin = m_oMinLength->GetValue(); + else + ptr1->bLenMin = 0; + if(m_oShowValue.IsInit()) + ptr1->fShowValue = m_oShowValue->GetValue(); + else + ptr1->fShowValue = false; for(auto i:m_arrValues) ptr->m_arCFVO.push_back(i->toBin()); if(m_oColor.IsInit()) - - ptr->m_BrtColor = m_oColor->toBin(); + ptr->m_BrtColor = m_oColor->toBin(); return objectPtr; } From 84425963721d2558591135022294c61dbc5067ba Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 16 Feb 2024 15:58:57 +0600 Subject: [PATCH 311/794] Fix conversion table formulas with empty square brackets --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 16 +++++++++++++++- .../XlsFile/Format/Auxiliary/HelpFunc.h | 1 + .../Logic/Biff_structures/SyntaxPtg.cpp | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 88bfd184ea7..d1b3cbb4e72 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -736,6 +736,20 @@ bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexC } return false; } - +unsigned int getColumnsCount(_UINT32 listIndex) +{ + auto arrColumn = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(listIndex); + if(arrColumn != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + auto counter = 0; + for(auto i:arrColumn->second) + { + if(!i.empty()) + counter++; + } + return counter; + } + return 0; +} } //namespace XMLSTUFF diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index e1d902b868f..a7a06f1e93e 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -95,5 +95,6 @@ unsigned short sheetsnames2ixti(std::wstring name); unsigned int definenames2index(std::wstring name); bool isTableFmla(const std::wstring& tableName, _UINT32& listIndex); bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexColumn); +unsigned int getColumnsCount(_UINT32 listIndex); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index 36c8c51950c..fdd9920eecc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -469,6 +469,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[\\s\\w\\d.]+\\]"); static boost::wregex reg_inside_table4(L"\\[#?(\\[.+?\\]\\,)?(\\[.+?\\])?.+?\\]"); static boost::wregex reg_inside_table5(L"^[,;:]?\\[.+?\\]"); + static boost::wregex reg_inside_table6(L"\\[\\]"); first = results[1].second; @@ -607,6 +608,24 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: return true; } + else if (boost::regex_search(first, last, results_1, reg_inside_table6)) + { + auto colCount = XMLSTUFF::getColumnsCount(indexTable); + if(colCount>1) + { + ptgList.columns = 0x02; + ptgList.colFirst = 0; + ptgList.colLast = colCount-1; + first = results_1[0].second; + } + else + { + ptgList.columns = 0x01; + ptgList.colFirst = 0; + first = results_1[0].second; + } + return true; + } else if(boost::regex_search(first, last, results_1, reg_inside_table4)) { _UINT16 indexColumn = -1; From 56a09831ccb2db44808924a9213c1480b4fd8ce7 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 16 Feb 2024 16:39:50 +0300 Subject: [PATCH 312/794] Improved conversion of style settings of html tables to ooxml --- .../3dParty/html/css/src/CCompiledStyle.cpp | 12 +- Common/3dParty/html/css/src/CCompiledStyle.h | 5 - .../3dParty/html/css/src/CCssCalculator.cpp | 21 --- Common/3dParty/html/css/src/CCssCalculator.h | 6 - .../html/css/src/CCssCalculator_Private.cpp | 38 +----- .../html/css/src/CCssCalculator_Private.h | 9 -- .../html/css/src/CUnitMeasureConverter.cpp | 109 ++++++++------- .../html/css/src/CUnitMeasureConverter.h | 1 + Common/3dParty/html/css/src/ConstValues.cpp | 28 ---- Common/3dParty/html/css/src/ConstValues.h | 15 --- .../3dParty/html/css/src/StyleProperties.cpp | 19 ++- Common/3dParty/html/css/src/StyleProperties.h | 4 + .../html/css/src/xhtml/CDocumentStyle.cpp | 25 ++-- HtmlFile2/htmlfile2.cpp | 126 ++++++++++-------- 14 files changed, 167 insertions(+), 251 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 9e6b4ef38f6..9acb292758c 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -100,16 +100,6 @@ namespace NSCSS m_UnitMeasure = enUnitMeasure; } - void CCompiledStyle::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_oSourceWindow = oSizeWindow; - } - - void CCompiledStyle::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_oDeviceWindow = oSizeWindow; - } - bool CCompiledStyle::Empty() const { return m_oBackground.Empty() && m_oBorder.Empty() && m_oFont.Empty() && @@ -125,7 +115,7 @@ namespace NSCSS { const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true; const double dFontSize = m_oFont.GetSize().ToDouble(NSCSS::Twips); - + for (std::pair pPropertie : mStyle) { std::transform(pPropertie.first.begin(), pPropertie.first.end(), pPropertie.first.begin(), tolower); diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 192db0328e9..2c789d0aac9 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -22,9 +22,6 @@ namespace NSCSS unsigned short int m_nDpi; UnitMeasure m_UnitMeasure; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; - public: NSProperties::CFont m_oFont; NSProperties::CIndent m_oMargin; @@ -41,8 +38,6 @@ namespace NSCSS void SetDpi(const unsigned short& uiDpi); void SetUnitMeasure(const UnitMeasure& enUnitMeasure); - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); bool Empty() const; diff --git a/Common/3dParty/html/css/src/CCssCalculator.cpp b/Common/3dParty/html/css/src/CCssCalculator.cpp index c823ee229db..3493b9fc3fd 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator.cpp @@ -1,7 +1,6 @@ #include "CCssCalculator.h" #include "CCssCalculator_Private.h" - namespace NSCSS { CCssCalculator::CCssCalculator() @@ -54,26 +53,6 @@ namespace NSCSS m_pInternal->SetBodyTree(oTree); } - void CCssCalculator::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_pInternal->SetSizeSourceWindow(oSizeWindow); - } - - void CCssCalculator::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_pInternal->SetSizeDeviceWindow(oSizeWindow); - } - - CSizeWindow CCssCalculator::GetSizeSourceWindow() const - { - return m_pInternal->GetSizeSourceWindow(); - } - - CSizeWindow CCssCalculator::GetSizeDeviceWindow() const - { - return m_pInternal->GetSizeDeviceWindow(); - } - UnitMeasure CCssCalculator::GetUnitMeasure() const { return m_pInternal->GetUnitMeasure(); diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h index fab353426b1..4f58a44073a 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.h +++ b/Common/3dParty/html/css/src/CCssCalculator.h @@ -31,12 +31,6 @@ namespace NSCSS void SetDpi(const unsigned short int& nValue); void SetBodyTree(const CTree &oTree); - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); - - CSizeWindow GetSizeSourceWindow() const; - CSizeWindow GetSizeDeviceWindow() const; - UnitMeasure GetUnitMeasure() const; std::wstring GetEncoding() const; unsigned short int GetDpi() const; diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index c95a7243c76..d041765288b 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -324,9 +324,6 @@ namespace NSCSS oStyle.SetUnitMeasure(m_UnitMeasure); oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - return oStyle; } @@ -335,9 +332,6 @@ namespace NSCSS pStyle->SetDpi(m_nDpi); pStyle->SetUnitMeasure(m_UnitMeasure); - pStyle->SetSizeDeviceWindow(m_oDeviceWindow); - pStyle->SetSizeSourceWindow(m_oSourceWindow); - std::vector arWords; arWords.reserve(arSelectors.size() * 2); @@ -502,6 +496,9 @@ namespace NSCSS }); } + // Данные о border'ах используются только для текущей ноды и не наследуются + pStyle->m_oBorder.Clear(); + pStyle->AddStyle(arSelectors[i].m_mAttributes, i + 1); for (const CElement* oElement : arFindElements) @@ -558,18 +555,12 @@ namespace NSCSS oStyle.SetUnitMeasure(m_UnitMeasure); oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - return false; } oStyle.SetDpi(m_nDpi); oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - std::vector arWords; arWords.reserve(arSelectors.size() * 2); @@ -810,26 +801,6 @@ namespace NSCSS CTree::CountingNumberRepetitions(oTree, *m_mStatictics); } - void CCssCalculator_Private::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_oSourceWindow = oSizeWindow; - } - - void CCssCalculator_Private::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_oDeviceWindow = oSizeWindow; - } - - CSizeWindow CCssCalculator_Private::GetSizeSourceWindow() const - { - return m_oSourceWindow; - } - - CSizeWindow CCssCalculator_Private::GetSizeDeviceWindow() const - { - return m_oDeviceWindow; - } - void CCssCalculator_Private::SetUnitMeasure(const UnitMeasure& nType) { m_UnitMeasure = nType; @@ -863,9 +834,6 @@ namespace NSCSS m_mData.clear(); m_arFiles.clear(); - - m_oDeviceWindow.Clear(); - m_oSourceWindow.Clear(); } } inline static std::wstring StringifyValueList(const KatanaArray* oValues) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 7d0e0bfd47c..965a30bfd7b 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -34,9 +34,6 @@ namespace NSCSS std::wstring m_sEncoding; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; - void GetStylesheet(const KatanaStylesheet* oStylesheet); void GetRule(const KatanaRule* oRule); @@ -69,12 +66,6 @@ namespace NSCSS void SetDpi(unsigned short int nValue); void SetBodyTree(const CTree &oTree); - void SetSizeSourceWindow(const CSizeWindow& oSizeWindow); - void SetSizeDeviceWindow(const CSizeWindow& oSizeWindow); - - CSizeWindow GetSizeSourceWindow() const; - CSizeWindow GetSizeDeviceWindow() const; - UnitMeasure GetUnitMeasure() const; std::wstring GetEncoding() const; unsigned short int GetDpi() const; diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp index 19659e995f1..ce6b08faa88 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp @@ -14,23 +14,21 @@ namespace NSCSS { switch (enUnitMeasure) { - case NSCSS::Pixel: - return dValue; case NSCSS::Point: - return 72. / (double)ushDPI * dValue; + return dValue * 72. / (double)ushDPI; case NSCSS::Cantimeter: return dValue / (double)ushDPI * 2.54; case NSCSS::Millimeter: return dValue / (double)ushDPI * 25.4; case NSCSS::Inch: - return 1. / (double)ushDPI * dValue; + return dValue / (double)ushDPI; case NSCSS::Peak: - return 0.16667 / (double)ushDPI * dValue; + return dValue * 6. / (double)ushDPI; // 1 дюйм = 6 пик case NSCSS::Twips: - return (dValue / (double)ushDPI) * 144.; + return dValue * 1440. / (double)ushDPI; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertCm(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -38,22 +36,20 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return 28.35 * dValue; + return dValue * 28.3465 ; // 1 см = (2.54 / 72) пункта case NSCSS::Pixel: - return (double)ushDPI / 2.54 * dValue; - case NSCSS::Cantimeter: - return dValue; + return dValue * (double)ushDPI / 2.54; case NSCSS::Millimeter: return dValue * 10.; case NSCSS::Inch: - return dValue / 2.54f; + return dValue / 2.54; // 1 дюйм = 2.54 см case NSCSS::Peak: - return 2.36 * dValue; + return dValue * 2.36; // 2.36 = 6 / 2.54 case NSCSS::Twips: - return (dValue) * 0.3937 * (double)ushDPI; + return dValue * 567.; // 1 см = (1440 / 2.54) твипов + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertMm(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -61,22 +57,20 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return 2.835 * dValue; + return dValue * 2.8346; // 1 мм = (25.4 / 72) пункта case NSCSS::Pixel: - return (double)ushDPI / 25.4 * dValue; + return dValue * (double)ushDPI / 25.4; case NSCSS::Cantimeter: return dValue / 10.; - case NSCSS::Millimeter: - return dValue; case NSCSS::Inch: return dValue / 25.4; case NSCSS::Peak: - return 0.236 * dValue; + return dValue * 0.236; // 0.236 = 6 / 25.4 case NSCSS::Twips: - return (dValue / 10.) * 0.3937 * (double)ushDPI; + return dValue * 56.7; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertIn(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -84,45 +78,41 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return dValue / 6.; + return dValue / 72.; case NSCSS::Pixel: return dValue * (double)ushDPI; case NSCSS::Cantimeter: - return dValue * 2.54; + return dValue * 2.54; // 1 дюйм = 2.54 см case NSCSS::Millimeter: return dValue * 25.4; - case NSCSS::Inch: - return dValue; case NSCSS::Peak: - return dValue / 72.; + return dValue * 6.; case NSCSS::Twips: - return dValue * 144.; + return dValue * 1440.; + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertPt(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) { switch (enUnitMeasure) { - case NSCSS::Point: - return dValue; case NSCSS::Pixel: - return (double)ushDPI / 72. * dValue; + return dValue * (double)ushDPI / 72.; case NSCSS::Cantimeter: - return dValue * 0.03528; + return dValue * 0.03528; // 0.03528 = 2.54 / 72 case NSCSS::Millimeter: return dValue * 0.3528; case NSCSS::Inch: - return dValue / 72.; + return dValue / 72.; // 1 дюйм = 72 пункта case NSCSS::Peak: - return dValue / 12.; + return dValue * 0.0833; // 0.0833 = 6 / 72 (1 пункт = 1/72 дюйма) case NSCSS::Twips: - return (dValue / 72.) * 144.; + return dValue * 20.; // 20 = 1440 / 72 + default: + return dValue; } - - return 0.; } double CUnitMeasureConverter::ConvertPc(double dValue, NSCSS::UnitMeasure enUnitMeasure, unsigned short ushDPI) @@ -130,22 +120,41 @@ namespace NSCSS switch (enUnitMeasure) { case NSCSS::Point: - return dValue * 12.; + return dValue * 12.; // 12 = 72 / 6 case NSCSS::Pixel: - return (double)ushDPI / 6. * dValue; + return dValue * (double)ushDPI / 6.; // 1 дюйм = 6 пика case NSCSS::Cantimeter: - return dValue * 0.423; + return dValue * 0.423; // 0.423 = 2.54 / 6 case NSCSS::Millimeter: - return dValue * 4.23; + return dValue * 4.233; // 4.23 = 25.4 / 6 case NSCSS::Inch: return dValue / 6.; + case NSCSS::Twips: + return dValue * 3.333; // 3.333 = 20 / 6 + default: + return dValue; + } + } + + double CUnitMeasureConverter::ConvertTw(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI) + { + switch (enUnitMeasure) + { + case NSCSS::Point: + return dValue * 0.05; // 0.05 = 72. / 1440. + case NSCSS::Pixel: + return dValue * (double)ushDPI / 1440.; // 1 дюйм = 1440 твипов + case NSCSS::Cantimeter: + return dValue * 0.001764; // 0.001764 = 2.54 / 1440 + case NSCSS::Millimeter: + return dValue * 0.01764; + case NSCSS::Inch: + return dValue * 1440.; case NSCSS::Peak: + return dValue * 0.004167; // 0.004167 = 6 / 1440 + default: return dValue; - case NSCSS::Twips: - return dValue * 24.; } - - return 0.; } bool CUnitMeasureConverter::GetValue(const std::wstring &wsValue, double &dValue, UnitMeasure &enUnitMeasure) diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.h b/Common/3dParty/html/css/src/CUnitMeasureConverter.h index f8a87e946c9..f6180f95b6d 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.h +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.h @@ -30,6 +30,7 @@ namespace NSCSS static double ConvertIn(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static double ConvertPt(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static double ConvertPc(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); + static double ConvertTw(double dValue, UnitMeasure enUnitMeasure, unsigned short ushDPI); static bool GetValue(const std::wstring& wsValue, double& dValue, UnitMeasure& enUnitMeasure); }; diff --git a/Common/3dParty/html/css/src/ConstValues.cpp b/Common/3dParty/html/css/src/ConstValues.cpp index 9ebcd733d37..9cbb9368a71 100644 --- a/Common/3dParty/html/css/src/ConstValues.cpp +++ b/Common/3dParty/html/css/src/ConstValues.cpp @@ -2,34 +2,6 @@ namespace NSCSS { - CSizeWindow::CSizeWindow() - : m_ushWidth(0), m_ushHeight(0) - {} - - CSizeWindow::CSizeWindow(unsigned short unWidth, unsigned short unHeight) - : m_ushWidth(unWidth), m_ushHeight(unHeight) - {} - - bool CSizeWindow::Empty() const - { - return ((0 == m_ushWidth) && (0 == m_ushHeight)); - } - - void CSizeWindow::Clear() - { - m_ushWidth = m_ushHeight = 0; - } - - bool CSizeWindow::operator==(const CSizeWindow &oSizeWindow) const - { - return ((m_ushWidth == oSizeWindow.m_ushWidth) && (m_ushHeight == oSizeWindow.m_ushHeight)); - } - - bool CSizeWindow::operator!=(const CSizeWindow &oSizeWindow) const - { - return ((m_ushWidth != oSizeWindow.m_ushWidth) || (m_ushHeight != oSizeWindow.m_ushHeight)); - } - bool StatistickElement::operator<(const StatistickElement &oStatistickElement) const { return sValue < oStatistickElement.sValue; diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index 145aa1caa71..f92f8dd438a 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -16,21 +16,6 @@ namespace NSCSS ScalingDirectionY = 2 } ScalingDirection; - struct CSizeWindow - { - unsigned short m_ushWidth; - unsigned short m_ushHeight; - - CSizeWindow(); - CSizeWindow(unsigned short unWidth, unsigned short unHeight); - - bool Empty() const; - void Clear(); - - bool operator==(const CSizeWindow& oSizeWindow) const; - bool operator!=(const CSizeWindow& oSizeWindow) const; - }; - struct StatistickElement { enum TypeElement diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index d1100d08659..403d004275c 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1302,9 +1302,16 @@ namespace NSCSS // BORDER SIDE CBorderSide::CBorderSide() - : m_bBlock(false) + : m_bBlock(false) {} + void CBorderSide::Clear() + { + m_oWidth.Clear(); + m_oStyle.Clear(); + m_oColor.Clear(); + } + void CBorderSide::Equation(CBorderSide &oFirstBorderSide, CBorderSide &oSecondBorderSide) { CDigit::Equation (oFirstBorderSide.m_oWidth, oSecondBorderSide.m_oWidth); @@ -1360,7 +1367,7 @@ namespace NSCSS { return m_oStyle.SetValue(wsValue, {std::make_pair(L"dotted", L"dotted"), std::make_pair(L"dashed", L"dashed"), std::make_pair(L"solid", L"single"), std::make_pair(L"double", L"double"), std::make_pair(L"groove", L"threeDEmboss"), std::make_pair(L"ridge", L"threeDEngrave"), - std::make_pair(L"inset", L"thinThickMediumGap"), std::make_pair(L"outset", L"thickThinMediumGap")}, unLevel, bHardMode); + std::make_pair(L"inset", L"inset"), std::make_pair(L"outset", L"outset")}, unLevel, bHardMode); } bool CBorderSide::SetColor(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) @@ -1435,6 +1442,14 @@ namespace NSCSS { m_enCollapse.SetMapping({{L"collapse", BorderCollapse::Collapse}, {L"separate", BorderCollapse::Separate}}, BorderCollapse::Separate); } + + void CBorder::Clear() + { + m_oLeft .Clear(); + m_oTop .Clear(); + m_oRight .Clear(); + m_oBottom.Clear(); + } void CBorder::Equation(CBorder &oFirstBorder, CBorder &oSecondBorder) { diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index cbfc5711ad7..c9c234b0128 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -415,6 +415,8 @@ namespace NSCSS public: CBorderSide(); + void Clear(); + static void Equation(CBorderSide &oFirstBorderSide, CBorderSide &oSecondBorderSide); bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); @@ -454,6 +456,8 @@ namespace NSCSS public: CBorder(); + void Clear(); + static void Equation(CBorder &oFirstBorder, CBorder &oSecondBorder); bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 64041cdbf09..a9365991e68 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -7,11 +7,6 @@ #include #define LINEHEIGHTSCALE 10 // Значение LineHeight в OOXML должно быть в 10 раз больше чем указано в стиле -#define LINEHEIGHTCOEF 24 // Используется когда необходимо перевести в twips значение -#define POINTCOEF 20 // Используется для конвертации в OOXML значение интервала между абзацами (Измерение в двадцатых долях от точки) - -#define PAGEWIDTH (12240 / POINTCOEF) -#define PAGEHEIGHT (15840 / POINTCOEF) #define DOUBLE_TO_INTW(dValue) std::to_wstring(static_cast(dValue + 0.5)) @@ -288,8 +283,8 @@ namespace NSCSS const double dLeftSide = oStyle.m_oMargin.GetLeft() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetLeft() .ToDouble(NSCSS::Twips); const double dRightSide = oStyle.m_oMargin.GetRight().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetRight().ToDouble(NSCSS::Twips); - sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(dLeftSide * POINTCOEF) + L"\" "; - sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(dRightSide * POINTCOEF) + L"\" "; + sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(dLeftSide) + L"\" "; + sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(dRightSide) + L"\" "; } const double dIndent = oStyle.m_oText.GetIndent().ToDouble(NSCSS::Twips); @@ -308,8 +303,8 @@ namespace NSCSS const double dSpacingBottom = oStyle.m_oMargin.GetBottom().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetBottom().ToDouble(NSCSS::Twips); const double dSpacingTop = oStyle.m_oMargin.GetTop() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetTop() .ToDouble(NSCSS::Twips);; - sSpacingValue += L" w:after=\"" + DOUBLE_TO_INTW(dSpacingBottom * POINTCOEF) + L"\" "; - sSpacingValue += L" w:before=\"" + DOUBLE_TO_INTW(dSpacingTop * POINTCOEF) + L"\" "; + sSpacingValue += L" w:after=\"" + DOUBLE_TO_INTW(dSpacingBottom) + L"\" "; + sSpacingValue += L" w:before=\"" + DOUBLE_TO_INTW(dSpacingTop) + L"\" "; } else/* if (!oStyle.m_pBorder.Empty() || !oStyle.m_oMargin.GetPermission())*/ sSpacingValue += L"w:after=\"0\" w:before=\"0\""; @@ -318,10 +313,10 @@ namespace NSCSS if (!oStyle.m_oFont.GetLineHeight().Empty()) { - double dLineHeight = oStyle.m_oFont.GetLineHeight().ToDouble(NSCSS::Twips, LINEHEIGHTCOEF) * LINEHEIGHTSCALE; + double dLineHeight = oStyle.m_oFont.GetLineHeight().ToDouble(NSCSS::Twips) * LINEHEIGHTSCALE; - if (NSCSS::None == oStyle.m_oFont.GetLineHeight().GetUnitMeasure()) - dLineHeight *= LINEHEIGHTCOEF; +// if (NSCSS::None == oStyle.m_oFont.GetLineHeight().GetUnitMeasure()) +// dLineHeight *= LINEHEIGHTCOEF; if (0. != dLineHeight) wsLineHeight = DOUBLE_TO_INTW(dLineHeight); @@ -448,11 +443,13 @@ namespace NSCSS return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, DOUBLE_TO_INTW(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Twips))); + oXmlElement.AddPropertiesInR(RProperties::R_Sz, DOUBLE_TO_INTW(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2.)); // Значения шрифта увеличивает на 2 + if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) + oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); + oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); - oXmlElement.AddPropertiesInR(RProperties::R_U, (oStyle.m_oText.GetDecoration().m_oLine.Underline()) ? L"underline" : L""); oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString()); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index db61a958414..e617a0b8985 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -139,15 +139,16 @@ class CHtmlFile2_Private std::vector m_arrImages; // Картинки std::map m_mFootnotes; // Сноски + + UINT m_unWidth; + UINT m_unHeight; public: - CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) - { - //Установим размер исходного и нового окна для Css калькулятора (должны быть одинаковые единицы измерения (желательно пункты)) - //Это нужно для масштабирования некоторых значений - m_oStylesCalculator.SetSizeSourceWindow(NSCSS::CSizeWindow(4940 * (1366 * (25.4 / m_oStylesCalculator.GetDpi())), 0)); - m_oStylesCalculator.SetSizeDeviceWindow(NSCSS::CSizeWindow(4940, 0)); - } + CHtmlFile2_Private() + : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), + m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false), + m_unWidth(12240), m_unHeight(15840) // Размеры страницы указаны в Twips + {} ~CHtmlFile2_Private() { @@ -383,7 +384,7 @@ class CHtmlFile2_Private if (m_bInP) m_oDocXml.WriteString(L""); - m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); NSFile::CFileBinary oDocumentWriter; if (oDocumentWriter.CreateFileW(m_sDst + L"/word/document.xml")) { @@ -649,7 +650,24 @@ class CHtmlFile2_Private } private: + bool NodeBelongToTable(const std::wstring& wsNodeName) + { + return L"table" == wsNodeName || L"tbody" == wsNodeName || L"th" == wsNodeName || L"td" == wsNodeName || + L"tr" == wsNodeName || L"thead" == wsNodeName || L"tfoot" == wsNodeName; + } + // Так как CSS калькулятор не знает для какой ноды производится расчет стиля + // и не знает, что некоторые стили предназначены только определенной ноде, + // то проще пока обрабатывать это заранее + // ! Используется для стилей, заданных через аргументы ! + bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring& wsStyleName) + { + if (L"border" == wsStyleName && L"table" != wsNodeName) + return false; + + return true; + } + std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) { NSCSS::CNode oNode; @@ -678,7 +696,10 @@ class CHtmlFile2_Private else if(sName == L"title") sNote = m_oLightReader.GetText(); else - oNode.m_mAttributes[sName] = m_oLightReader.GetText(); + { + if (CheckArgumentMath(oNode.m_wsName, sName)) + oNode.m_mAttributes[sName] = m_oLightReader.GetText(); + } } m_oLightReader.MoveToElement(); sSelectors.push_back(oNode); @@ -737,6 +758,7 @@ class CHtmlFile2_Private if(sName == L"#text") { std::wstring sText = m_oLightReader.GetText(); + size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) { @@ -1185,6 +1207,17 @@ class CHtmlFile2_Private UINT unMaxColumns = 0; + bool bTableHasBorderAttribute = false; + + for (std::vector::const_reverse_iterator oIter = sSelectors.crbegin(); oIter < sSelectors.crend(); ++oIter) + { + if (L"table" != oIter->m_wsName) + continue; + + if (oIter->m_mAttributes.end() != oIter->m_mAttributes.find(L"border")) + bTableHasBorderAttribute = true; + } + while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) { // tr - строки в таблице @@ -1237,34 +1270,15 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsType = L"dxa"; - - //Если ширина указана в %, то используем тип dxa, если же в других единицах измерения, то в pct - #if 1 - // проблема с regex в старом gcc (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52719) - boost::wregex oWidthRegex(L"((width)+)[\\s]*:[\\s]*(.+%)"); - bool bIsWidthPct = boost::regex_search(sSelectors.back().m_wsStyle, oWidthRegex); - #else - std::wregex oWidthRegex(L"((width)+)[\\s]*:[\\s]*(.+%)"); - bool bIsWidthPct = std::regex_search(sSelectors.back().m_wsStyle, oWidthRegex); - #endif - - if (bIsWidthPct) - wsType = L"pct"; - else + std::wstring wsTcPr; + + if (!oStyle.m_oDisplay.GetWidth().Empty()) { - nWidth *= 10; - // ограничиваем, примерно как в ms (22 inch) - if (nWidth > 31680) - nWidth = 31680; + if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) + wsTcPr += L""; + else + wsTcPr += L""; } - //------------------------- - - std::wstring wsTcPr; - - if (nWidth > 0) - wsTcPr += L""; else wsTcPr += L""; @@ -1272,7 +1286,9 @@ class CHtmlFile2_Private wsTcPr += L""; if (!oStyle.m_oBorder.Empty()) - wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; + wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; + else if (bTableHasBorderAttribute) + wsTcPr += L""; if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) wsTcPr += L""; @@ -1304,26 +1320,24 @@ class CHtmlFile2_Private m_bWasPStyle = false; //Оставляем только всё что не относится к таблице - std::vector arSelectors; - for (const NSCSS::CNode& oItem : sSelectors) - { - if (oItem.m_wsName == L"table" || oItem.m_wsName == L"tbody" || oItem.m_wsName == L"th" || - oItem.m_wsName == L"td" || oItem.m_wsName == L"tr" || oItem.m_wsName == L"thead" || - oItem.m_wsName == L"tfoot") - continue; - arSelectors.push_back(oItem); - } +// std::vector arSelectors; +// for (const NSCSS::CNode& oItem : sSelectors) +// { +// if (NodeBelongToTable(oItem.m_wsName)) +// continue; +// arSelectors.push_back(oItem); +// } // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") { CTextSettings oTSR(oTS); oTSR.sRStyle += L""; - readStream(oXml, arSelectors, oTSR); + readStream(oXml, sSelectors, oTSR); } // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") { - readStream(oXml, arSelectors, oTS); + readStream(oXml, sSelectors, oTS); } sSelectors.pop_back(); if (m_bInP) @@ -1389,16 +1403,18 @@ class CHtmlFile2_Private // Начало таблицы std::wstring wsTable = L""; - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); - - if (0 < nWidth) - wsTable += L""; -// else if (m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth != 0) -// wsTable += L""; + if (!oStyle.m_oDisplay.GetWidth().Empty()) + { + if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) + wsTable += L""; + else + wsTable += L""; + } else wsTable += L""; + std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + if (wsAlign.empty()) { NSCSS::CNode oLastNode = sSelectors.back(); @@ -1417,7 +1433,7 @@ class CHtmlFile2_Private sSelectors.push_back(oLastNode); } - + // borders if (!oStyle.m_oBorder.Empty()) wsTable += L"" + CreateBorders(oStyle.m_oBorder) + L""; From c90394b50af65c780b58e1599e5c39fe47479eac Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 16 Feb 2024 19:37:52 +0300 Subject: [PATCH 313/794] Update logic --- DocxRenderer/src/logic/Page.cpp | 268 +++++++++++++------------ DocxRenderer/src/resources/Constants.h | 3 +- 2 files changed, 140 insertions(+), 131 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 5be77347a8c..d5eebd95ac9 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1240,25 +1240,25 @@ namespace NSDocxRenderer } // если линия пересекается с другим шейпом -// bool next = false; -// for (auto& shape : m_arShapes) -// { -// if (!shape) -// continue; - -// auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); -// auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); - -// if (!no_crossing(h_type, v_type)) -// { -// m_arShapes.push_back(CreateSingleLineShape(curr_line)); -// curr_line = nullptr; -// next = true; -// break; -// } -// } -// if (next) -// continue; + bool next = false; + for (auto& shape : m_arShapes) + { + if (!shape) + continue; + + auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); + auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); + + if (!no_crossing(h_type, v_type)) + { + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + curr_line = nullptr; + next = true; + break; + } + } + if (next) + continue; // если линия пересекается с предыдущей линией if (index && m_arTextLines[index - 1]) @@ -1305,140 +1305,145 @@ namespace NSDocxRenderer } } - // ar_spacing[index]- расстояние строки до строки снизу - // если 0.0 - строка последняя - std::vector ar_spacings(m_arTextLines.size(), 0.0); - - // позиции относительно других линий - std::vector ar_positions(m_arTextLines.size()); - - // если ar_delims[index] == true, после строчки index нужно начинать новый параграф - std::vector ar_delims(m_arTextLines.size()); - - // calcs spacings & positions - for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) + else if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatParagraphToShape) { - ar_spacings[index] = m_arTextLines[index + 1]->m_dTopWithMaxAscent - m_arTextLines[index]->m_dBotWithMaxDescent; - avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); + // ar_spacing[index]- расстояние строки до строки снизу + // если 0.0 - строка последняя + std::vector ar_spacings(m_arTextLines.size(), 0.0); - auto& left_curr = m_arTextLines[index]->m_dLeft; - auto& left_next = m_arTextLines[index + 1]->m_dLeft; + // позиции относительно других линий + std::vector ar_positions(m_arTextLines.size()); - auto& right_curr = m_arTextLines[index]->m_dRight; - auto& right_next = m_arTextLines[index + 1]->m_dRight; + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф + std::vector ar_delims(m_arTextLines.size(), false); - auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; - auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; + // calcs spacings & positions + for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) + { + ar_spacings[index] = m_arTextLines[index + 1]->m_dBaselinePos - m_arTextLines[index]->m_dTop; + avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); - if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) - ar_positions[index].center = true; - if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) - ar_positions[index].left = true; - if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) - ar_positions[index].right = true; - } + auto& left_curr = m_arTextLines[index]->m_dLeft; + auto& left_next = m_arTextLines[index + 1]->m_dLeft; - // spacing check - for (size_t index = 0; index < ar_spacings.size(); ++index) - { - double spacing_top = 0.0; - double spacing_bot = 0.0; + auto& right_curr = m_arTextLines[index]->m_dRight; + auto& right_next = m_arTextLines[index + 1]->m_dRight; - if (index != 0) spacing_top = ar_spacings[index - 1]; - spacing_bot = ar_spacings[index]; + auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; + auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; - if (spacing_top == 0.0) spacing_top = spacing_bot; - if (spacing_bot == 0.0) spacing_bot = spacing_top; + if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) + ar_positions[index].center = true; + if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].left = true; + if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].right = true; + } - if (fabs(spacing_top - spacing_bot) < c_dTHE_SAME_STRING_Y_PRECISION_MM * 3) - ar_delims[index] = false; - else if (spacing_top > spacing_bot) - ar_delims[index - 1] = true; - else if (spacing_top < spacing_bot) - ar_delims[index] = true; - } + // spacing check + for (size_t index = 0; index < ar_spacings.size(); ++index) + { + double spacing_top = 0.0; + double spacing_bot = 0.0; - // большая высота между строками - for (size_t index = 0; index < ar_spacings.size() - 1; ++index) - { - // если разница больше чем срединий в три раза - отделим - if (ar_spacings[index] > avg_spacing * 3) - ar_delims[index] = true; - } + if (index != 0) spacing_top = ar_spacings[index - 1]; + spacing_bot = ar_spacings[index]; - // width check (слишком большая разница в ширине) - for (size_t index = 1; index < ar_spacings.size(); ++index) - { - double diff = 0; - if (ar_positions[index - 1].right) - diff = m_arTextLines[index - 1]->m_dLeft - m_arTextLines[index]->m_dLeft; - else if (ar_positions[index - 1].center) - diff = m_arTextLines[index - 1]->m_dWidth - m_arTextLines[index]->m_dWidth; - else - diff = m_arTextLines[index - 1]->m_dRight - m_arTextLines[index]->m_dRight; + if (spacing_top == 0.0) spacing_top = spacing_bot; + if (spacing_bot == 0.0) spacing_bot = spacing_top; - bool big_diff = fabs(diff) > std::min(m_arTextLines[index - 1]->m_dWidth, m_arTextLines[index]->m_dWidth) * 3; - bool is_first_less = diff < 0; + if (spacing_bot > c_dLINE_DISTANCE_MAX_MM) + ar_delims[index] = true; + else if (fabs(spacing_top - spacing_bot) < c_dLINE_DISTANCE_ERROR_MM) + ar_delims[index] = false; + else + { + // берем доп строчки сверху и снизу для анализа + bool same_double_top = false; + bool same_double_bot = false; + if (index > 1) + { + double spacing_top_next = ar_spacings[index - 2]; + if (fabs(spacing_top - spacing_top_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_top = true; + } + if (index < ar_spacings.size() - 1) + { + double spacing_bot_next = ar_spacings[index + 1]; + if (fabs(spacing_bot - spacing_bot_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_bot = true; + } - // два случая - // Text (end paragraph) - // bla-bla-bla (end paragraph) - // - // bla-bla-bla (\n) - // bla (end paragraph) - if (big_diff) - { - if (is_first_less) - ar_delims[index - 1] = true; - else - ar_delims[index] = true; + // если анализ доп строчек ничего не дал - разбиваем наиболее "вероятным" способом + if ((same_double_top == same_double_bot)) + { + if (spacing_top > spacing_bot) + ar_delims[index - 1] = true; + else if (spacing_top < spacing_bot) + ar_delims[index] = true; + } + // прикрепляем строчку к верху или низу + else + { + if (same_double_top) + ar_delims[index] = true; + else if (same_double_bot) + ar_delims[index - 1] = true; + } + } } - } - - // alignment check - bool is_first_line = false; - for (size_t index = 0; index < ar_positions.size() - 1; ++index) - { - Position position_top; - Position position_bot; + // alignment check + bool is_first_line = false; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position position_top; + Position position_bot; - position_bot = ar_positions[index]; - if (index == 0) - position_top = position_bot; - else - position_top = ar_positions[index - 1]; + position_bot = ar_positions[index]; + if (index == 0) + position_top = position_bot; + else + position_top = ar_positions[index - 1]; - if (index == 0 || ar_delims[index - 1]) - is_first_line = true; - else - is_first_line = false; + if (index == 0 || ar_delims[index - 1]) + is_first_line = true; + else + is_first_line = false; - // первая строка может быть с отступом - if (is_first_line && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) - { - // если больше трех линий - проверим третью - if (index < ar_positions.size() - 2) + // первая строка может быть с отступом + if (is_first_line && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) { - if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) - position_bot.left = true; + // если больше трех линий - проверим третью + if (index < ar_positions.size() - 2) + { + if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) + position_bot.left = true; + else + position_bot.left = false; + } else - position_bot.left = false; + position_bot.left = true; } - else - position_bot.left = true; - } + bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); + if (is_unknown) + ar_delims[index] = true; + } - bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); - if (is_unknown) - ar_delims[index] = true; - } + // отдельно просмотрим возможные параграфы по две строки + for (size_t index = 0; index < ar_delims.size() - 1; ++index) + { + if (!ar_delims[index] && ar_delims[index + 1]) + { + // ширина верхней строчки сильно меньше нижней + if (m_arTextLines[index]->m_dWidth * 3 < m_arTextLines[index + 1]->m_dWidth) + ar_delims[index] = true; + } + } - if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || - m_eTextAssociationType == TextAssociationType::tatParagraphToShape) - { // на основе ar_delims разбиваем на параграфы + IsShadingPresent for (size_t index = 0; index < ar_delims.size(); ++index) { @@ -1466,7 +1471,7 @@ namespace NSDocxRenderer m_arOutputObjects.push_back(std::move(p)); } - if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + else if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || m_eTextAssociationType == TextAssociationType::tatShapeLine) { for(auto&& p : ar_paragraphs) @@ -1523,7 +1528,10 @@ namespace NSDocxRenderer pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; - pParagraph->m_dSpaceBefore = 0; + + // first correction fix + if (pParagraph->m_dSpaceBefore > 0) pParagraph->m_dSpaceBefore = 0; + pParagraph->m_dSpaceAfter = 0; pShape->m_arOutputObjects.push_back(pParagraph); diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index ba529bdf3ce..f6e26afe6f1 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -18,7 +18,7 @@ const double c_dDegreeToAngle = 60000.0; const double c_dSTANDART_STRING_HEIGHT_MM = 4.2333333333333334; const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.01; -const double c_dLINE_DISTANCE_ERROR_MM = 0.5; +const double c_dLINE_DISTANCE_ERROR_MM = 0.03; const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 0.5; const double c_dCENTER_POSITION_ERROR_MM = 1.5; const double c_dTHE_STRING_X_PRECISION_MM = 0.5; @@ -28,6 +28,7 @@ const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3; const double c_dMAX_LINE_HEIGHT_MM = 2.5; const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; const double c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH = 0.8; +const double c_dLINE_DISTANCE_MAX_MM = 50.0; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; From 30fa4b0ea4e81d388ad5d6f4b051dc4a61d2992b Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 16 Feb 2024 20:05:07 +0300 Subject: [PATCH 314/794] [x2t] For vsdx printing --- X2tConverter/src/ASCConverters.cpp | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index cb47269d811..f4c6938576e 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1330,6 +1330,36 @@ namespace NExtractTools else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } + else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)) + { + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DRAW_VSDX)) + { + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; + if (sToRender.empty()) + { + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.vsdx"); + nRes = dir2zip(sFrom, sToRender); + } + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); + } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + } + else + { + //There is no Editor.bin for vsdx + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + } + } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; @@ -1347,7 +1377,7 @@ namespace NExtractTools std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"xsdx_unpacked"); NSDirectory::CreateDirectory(sVsdxDir); - if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatFrom) + if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatFrom)) { convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) @@ -1361,6 +1391,12 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; if (SUCCEEDED_X2T(nRes)) { + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + nRes = fromVsdxDir(sVsdxDir, sTo, nFormatTo, params, convertParams); } return nRes; From 22508420d86c1c398f8b76b88ff1e8bdba5f1c0f Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 16 Feb 2024 23:30:42 +0300 Subject: [PATCH 315/794] [x2t] To fix build --- X2tConverter/src/ASCConverters.cpp | 40 ++++++++++++------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index f4c6938576e..c57329846f8 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1330,35 +1330,27 @@ namespace NExtractTools else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } - else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)) + else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DRAW_VSDX)) + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; + if (sToRender.empty()) { - std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; - if (sToRender.empty()) - { - sToRender = combinePath(convertParams.m_sTempDir, L"toRender.vsdx"); - nRes = dir2zip(sFrom, sToRender); - } - NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT; - if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) - { - convertParams.m_sInternalMediaDirectory = sFrom; - nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); - } - else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) - { - convertParams.m_sInternalMediaDirectory = sFrom; - nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); - } - else - nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.vsdx"); + nRes = dir2zip(sFrom, sToRender); } - else + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { - //There is no Editor.bin for vsdx - nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; From 8a6974a020474e360146e636f23592e300f2c377 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 17 Feb 2024 14:57:38 +0300 Subject: [PATCH 316/794] Add define to use default font to recalc --- DocxRenderer/src/logic/Page.cpp | 12 ++++++++++++ DocxRenderer/src/logic/elements/ContText.cpp | 9 +++------ DocxRenderer/src/logic/elements/ContText.h | 2 ++ DocxRenderer/src/resources/Constants.h | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index d5eebd95ac9..f3649be68ba 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -357,8 +357,20 @@ namespace NSDocxRenderer m_pFontSelector->IsSelectedBold()); pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); + +#ifndef USE_DEFAULT_FONT_TO_RECALC + pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.SetStyle(m_pFont->GetStyle2()); +#else + pCont->m_oSelectedFont.Path = m_pFont->Path; + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.FaceIndex = m_pFont->FaceIndex; +#endif // USE_DEFAULT_FONT_TO_RECALC + m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); + m_arConts.push_back(pCont); } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index cfad18b5d7d..01af9cbd965 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -69,6 +69,8 @@ namespace NSDocxRenderer m_dTopWithAscent = rCont.m_dTopWithAscent; m_dBotWithDescent = rCont.m_dBotWithDescent; + m_oSelectedFont = rCont.m_oSelectedFont; + return *this; } @@ -77,12 +79,7 @@ namespace NSDocxRenderer if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { // нужно перемерять... - NSStructures::CFont oFont; - oFont.Name = m_pFontStyle->wsFontName; - oFont.Bold = m_pFontStyle->bBold; - oFont.Italic = m_pFontStyle->bItalic; - oFont.Size = m_pFontStyle->dFontSize; - m_pManager->LoadFontByName(oFont); + m_pManager->LoadFontByName(m_oSelectedFont); double dBoxX; double dBoxY; diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 1bd6283e500..2464082fbe6 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -58,6 +58,8 @@ namespace NSDocxRenderer bool m_bIsEmbossPresent {false}; bool m_bIsEngravePresent {false}; + // font to calc selected sizes + NSStructures::CFont m_oSelectedFont{}; // sizes double m_dSpaceWidthMM{0}; diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index f6e26afe6f1..1d15c281865 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -2,6 +2,7 @@ #include "../../../DesktopEditor/common/Types.h" #define USING_DELETE_DUPLICATING_CONTS 0 // 0 - все сточки-дубликаты превращаются в shape, 1 - строчки дубликаты удаляются +// #define USE_DEFAULT_FONT_TO_RECALC const double c_dDpiX = 72.0; const double c_dDpiY = 72.0; From 49f5df9f88aeefa051e626447bf55d8e692a7433 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Sun, 18 Feb 2024 12:42:42 +0300 Subject: [PATCH 317/794] [x2t] Fix COfficeFileFormatChecker::isOOXFormatFile for vsdx --- Common/OfficeFileFormatChecker2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index bfaba2dbdcc..1fdb6b6f349 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -900,12 +900,12 @@ bool COfficeFileFormatChecker::isOOXFormatFile(const std::wstring &fileName, boo const char *ppsmFormatLine = "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"; const char *potmFormatLine = "application/vnd.ms-powerpoint.template.macroEnabled.main+xml"; - const char *vsdxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; - const char *vssxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"; - const char *vstxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"; - const char *vsdmFormatLine = "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"; - const char *vssmFormatLine = "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"; - const char *vstmFormatLine = "application/vnd.ms-powerpoint.template.macroEnabled.main+xml"; + const char *vsdxFormatLine = "application/vnd.ms-visio.drawing.main+xml"; + const char *vssxFormatLine = "application/vnd.ms-visio.stencil.main+xml"; + const char *vstxFormatLine = "application/vnd.ms-visio.template.main+xml"; + const char *vsdmFormatLine = "application/vnd.ms-visio.drawing.macroEnabled.main+xml"; + const char *vssmFormatLine = "application/vnd.ms-visio.stencil.macroEnabled.main+xml"; + const char *vstmFormatLine = "application/vnd.ms-visio.template.macroEnabled.main+xml"; std::string strContentTypes((char*)pBuffer, nBufferSize); From efb18b58641e7c4a600e232f6af4dcd74d85de01 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 19 Feb 2024 01:52:06 +0300 Subject: [PATCH 318/794] [x2t] Fix fromDraw --- X2tConverter/src/ASCConverters.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index c57329846f8..54a22070bc5 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1365,7 +1365,6 @@ namespace NExtractTools nFormatTo = *params.m_nFormatTo; _UINT32 nRes = 0; - std::wstring sVsdxFile; std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"xsdx_unpacked"); NSDirectory::CreateDirectory(sVsdxDir); @@ -1377,7 +1376,7 @@ namespace NExtractTools params.setFromChanges(false); nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sVsdxFile, sVsdxDir); + nRes = zip2dir(sFrom, sVsdxDir); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; From 91e5fae5def541ff39e7004b726daf279c58b794 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 19 Feb 2024 10:55:23 +0300 Subject: [PATCH 319/794] fix bug #62141 --- .../Records/Drawing/ShapeContainer.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index 7a4728febc8..49caf34ca4c 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp @@ -222,22 +222,28 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn for (size_t i = 0; i < lCount; ++i) { SetUpPropertyVideo(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); - } - break; - } + } + }break; case PPT::etPicture: { if (reset_default) { - pElement->m_oBrush.Type = c_BrushTypeTexture; + pElement->m_oBrush.Type = c_BrushTypeTexture; // or 3000 set ??? pElement->m_bLine = false; } for (size_t i = 0; i < lCount; ++i) { SetUpPropertyImage(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); } - break; - } + if (false == pElement->m_bIsFilled) + { + pElement->m_oBrush.Type = c_BrushTypeNoFill; + } + else if (pElement->m_oBrush.Type == c_BrushTypeTexture) + { + pElement->m_oBrush.Type = c_BrushTypeSolid; + } + }break; case PPT::etAudio: { if (reset_default) @@ -247,9 +253,8 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn for (size_t i = 0; i < lCount; ++i) { SetUpPropertyAudio(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]); - } - break; - } + } + }break; case PPT::etGroup: { if (reset_default) @@ -282,7 +287,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn pElement->m_oBrush.Type = c_BrushTypeNoFill; } else if (pElement->m_oBrush.Type == c_BrushTypeNotSet && - (pElement->m_lPlaceholderType == 0 && pElement->m_lPlaceholderID < 0 )) + (pElement->m_lPlaceholderType == 0 && pElement->m_lPlaceholderID < 0)) { pElement->m_oBrush.Type = c_BrushTypeSolid; } @@ -292,8 +297,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn pPPTShape->m_oCustomVML.ToCustomShape(pPPTShape, pPPTShape->m_oManager); pPPTShape->ReCalculate(); } - break; - } + }break; default: break; } From 532605894702e14534b3c8bb7adb94bc49a62f43 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 19 Feb 2024 18:06:42 +0300 Subject: [PATCH 320/794] Get fotn from AP --- .../pro/js/wasm/src/drawingfile_test.cpp | 19 ++- PdfFile/PdfReader.cpp | 10 +- PdfFile/SrcReader/PdfAnnot.cpp | 130 +++++++++++++++--- PdfFile/SrcReader/PdfAnnot.h | 13 +- 4 files changed, 141 insertions(+), 31 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index ec127fabf14..f20a23ee807 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1240,10 +1240,7 @@ int main(int argc, char* argv[]) } if (nFlags & (1 << 3)) { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; - std::cout << "RC { text-align: " << arrTextAlign[nPathLength] << "; "; + std::cout << "RC {"; int nFontLength = READ_INT(pAnnots + i); i += 4; @@ -1251,7 +1248,12 @@ int main(int argc, char* argv[]) { std::cout << std::endl << "span" << j << " { "; - std::cout << "font-style:"; + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; + std::cout << "text-align: " << arrTextAlign[nPathLength]; + + std::cout << "; font-style:"; int nFontFlag = READ_INT(pAnnots + i); i += 4; if (nFontFlag & (1 << 0)) @@ -1268,6 +1270,13 @@ int main(int argc, char* argv[]) i += 4; std::cout << "; vertical-align:" << (double)nPathLength / 100.0; } + if (nFontFlag & (1 << 6)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + i += nPathLength; + } nPathLength = READ_INT(pAnnots + i); i += 4; diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a18fb80e68e..02f97ec678a 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1428,7 +1428,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oRes.ClearWithoutAttack(); return bRes; } -void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) +void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); if (!pPage) @@ -1469,7 +1469,9 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSWasm::CData& oRes, int nPageIndex) } else if (sType == "FreeText") { - pAnnot = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); + PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); + pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); + pAnnot = pFreeText; } else if (sType == "Line") { @@ -1529,10 +1531,10 @@ BYTE* CPdfReader::GetAnnots(int nPageIndex) oRes.SkipLen(); if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, oRes, nPageIndex); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPageIndex); else for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(m_pPDFDocument, oRes, nPage); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPage); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 191a785ce74..449505a31eb 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2132,7 +2132,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : { if (oLightReader.GetNameA() == "style") { - m_nTextAlign = ReadFontData(oLightReader.GetTextA(), &oFontBase); + ReadFontData(oLightReader.GetTextA(), &oFontBase); break; } } @@ -2158,9 +2158,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : { if (oLightReader.GetNameA() == "style") { - BYTE nTextAlign = ReadFontData(oLightReader.GetTextA(), pFont); - if (nTextAlign != 3) - m_nTextAlign = nTextAlign; + ReadFontData(oLightReader.GetTextA(), pFont); break; } } @@ -2215,9 +2213,104 @@ CAnnotMarkup::~CAnnotMarkup() for (int i = 0; i < m_arrRC.size(); ++i) RELEASEOBJECT(m_arrRC[i]); } -BYTE CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) +void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +{ + if (m_arrRC.empty()) + return; + + Object oAnnot, oObj; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + + // Теперь для всех шрифтов необходимо извлечь файлы шрифтов из внешнего вида + Object oAP, oN, oR, oFonts; + XRef* xref = pdfDoc->getXRef(); + if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oN)->isStream() && oN.streamGetDict()->lookup("Resources", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + { + Parser* parser = new Parser(xref, new Lexer(xref, &oN), gFalse); + int nFont = 0; + std::string sPredFontName = m_arrRC[0]->sFontFamily, sPredKey; + + Object oObj1, oObj2, oObj3; + parser->getObj(&oObj1); + while (!oObj1.isEOF()) + { + if (nFont == m_arrRC.size()) + break; + + if (oObj1.isName()) + { + parser->getObj(&oObj2); + if (oObj2.isEOF()) + break; + if (oObj2.isNum()) + { + parser->getObj(&oObj3); + if (oObj3.isEOF()) + break; + Object oFontRef; + if (oObj3.isCmd("Tf") && oFonts.dictLookupNF(oObj1.getName(), &oFontRef)->isRef()) + { + std::string sFontName, sActual; + bool bBold = false, bItalic = false; + GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, 7, sFontName, sActual, bBold, bItalic); + + if (!oObj1.isName(sPredKey.c_str())) + { + while (nFont < m_arrRC.size()) + { + if ((bool)((m_arrRC[nFont]->unFontFlags >> 0) & 1) == bBold && + (bool)((m_arrRC[nFont]->unFontFlags >> 1) & 1) == bItalic && + m_arrRC[nFont]->sFontFamily == sPredFontName) + { + m_arrRC[nFont]->sFontFamily = sFontName; + if (!sActual.empty()) + { + m_arrRC[nFont]->unFontFlags |= (1 << 6); + m_arrRC[nFont]->sActualFont = sActual; + } + } + else + { + sPredFontName = m_arrRC[nFont]->sFontFamily; + break; + } + nFont++; + } + sPredKey = oObj1.getName(); + } + } + oFontRef.free(); + } + } + if (oObj2.isName()) + { + oObj1.free(); + oObj2.copy(&oObj1); + oObj2.free(); oObj3.free(); + continue; + } + if (oObj3.isName()) + { + oObj1.free(); + oObj3.copy(&oObj1); + oObj3.free(); oObj2.free(); + continue; + } + oObj1.free(); oObj2.free(); oObj3.free(); + + parser->getObj(&oObj1); + } + + oObj1.free(); oObj2.free(); oObj3.free(); + RELEASEOBJECT(parser); + } + oAP.free(); oN.free(); oR.free(); oFonts.free(); + + oAnnot.free(); +} +void CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) { - BYTE nTextAlign = 0; size_t nSemicolon = 0; size_t nColon = sData.find(':'); while (nColon != std::string::npos && nColon > nSemicolon) @@ -2226,8 +2319,8 @@ BYTE CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) nSemicolon = sData.find(';', nSemicolon); nColon++; std::string sValue = sData.substr(nColon, nSemicolon - nColon); + nColon = sData.find(':', nSemicolon); nSemicolon++; - nColon = sData.find(':', nColon); if (sProperty == "font-size") pFont->dFontSise = std::stod(sValue); @@ -2235,11 +2328,11 @@ BYTE CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) { // 0 start / left if (sValue == "center" || sValue == "middle") - nTextAlign = 1; + pFont->nAlign = 1; else if (sValue == "right" || sValue == "end") - nTextAlign = 2; + pFont->nAlign = 2; else if (sValue == "justify") - nTextAlign = 3; + pFont->nAlign = 3; } else if (sProperty == "color") { @@ -2295,23 +2388,24 @@ BYTE CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) else if (sProperty == "vertical-align") { pFont->unFontFlags |= (1 << 5); - pFont->dVerticalAlign = std::stod(sValue); - if (pFont->dVerticalAlign == 0 && sValue[0] == '-') - pFont->dVerticalAlign = -0.01; + pFont->dVAlign = std::stod(sValue); + if (pFont->dVAlign == 0 && sValue[0] == '-') + pFont->dVAlign = -0.01; } // font-stretch } - return nTextAlign; } CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) { + nAlign = oFont.nAlign; unFontFlags = oFont.unFontFlags; dFontSise = oFont.dFontSise; - dVerticalAlign = oFont.dVerticalAlign; + dVAlign = oFont.dVAlign; dColor[0] = oFont.dColor[0]; dColor[1] = oFont.dColor[1]; dColor[2] = oFont.dColor[2]; sFontFamily = oFont.sFontFamily; + sActualFont = oFont.sActualFont; sText = oFont.sText; } @@ -3251,13 +3345,15 @@ void CAnnotMarkup::ToWASM(NSWasm::CData& oRes) oRes.AddDouble(m_dCA); if (m_unFlags & (1 << 3)) { - oRes.WriteBYTE(m_nTextAlign); oRes.AddInt(m_arrRC.size()); for (int i = 0; i < m_arrRC.size(); ++i) { + oRes.WriteBYTE(m_arrRC[i]->nAlign); oRes.AddInt(m_arrRC[i]->unFontFlags); if (m_arrRC[i]->unFontFlags & (1 << 5)) - oRes.AddDouble(m_arrRC[i]->dVerticalAlign); + oRes.AddDouble(m_arrRC[i]->dVAlign); + if (m_arrRC[i]->unFontFlags & (1 << 6)) + oRes.WriteString(m_arrRC[i]->sActualFont); oRes.AddDouble(m_arrRC[i]->dFontSise); oRes.WriteDouble(m_arrRC[i]->dColor[0]); oRes.WriteDouble(m_arrRC[i]->dColor[1]); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 9175b266698..d9f99180ea1 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -326,6 +326,8 @@ class CAnnotPopup final : public CAnnot class CAnnotMarkup : public CAnnot { +public: + void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CFontList *pFontList); protected: CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); virtual ~CAnnotMarkup(); @@ -335,20 +337,21 @@ class CAnnotMarkup : public CAnnot private: struct CFontData final { - unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 зачеркнутый, 4 подчеркнутый, 5 vertical-align + BYTE nAlign; + unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 зачеркнутый, 4 подчеркнутый, 5 vertical-align, 6 actual font double dFontSise; - double dVerticalAlign; + double dVAlign; double dColor[3]; std::string sFontFamily; + std::string sActualFont; std::string sText; - CFontData() : unFontFlags(4), dFontSise(10), dVerticalAlign(0), dColor{0, 0, 0} {} + CFontData() : nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {} CFontData(const CFontData& oFont); }; - BYTE ReadFontData(const std::string& sData, CFontData* pFont); + void ReadFontData(const std::string& sData, CFontData* pFont); BYTE m_nRT; // Тип аннотации-ответа - BYTE m_nTextAlign; // Выравнивание текста в RC unsigned int m_unRefNumPopup; // Номер ссылки на всплывающую аннотацию unsigned int m_unRefNumIRT; // Номер ссылки на аннотацию-ответ double m_dCA; // Значение непрозрачности From b56e21d6c79e0c19482f6e91f83dfd2fb669a7ed Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Mon, 19 Feb 2024 18:33:31 +0300 Subject: [PATCH 321/794] Improved padding in html to ooxml conversion --- .../3dParty/html/css/src/StyleProperties.cpp | 171 ++++++++++-------- Common/3dParty/html/css/src/StyleProperties.h | 31 ++-- HtmlFile2/htmlfile2.cpp | 30 ++- 3 files changed, 127 insertions(+), 105 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 403d004275c..d86648c4c9f 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1773,10 +1773,12 @@ namespace NSCSS void CIndent::Equation(CIndent &oFirstMargin, CIndent &oSecondMargin) { - CDigit::Equation(oFirstMargin.m_oLeft, oSecondMargin.m_oLeft); - CDigit::Equation(oFirstMargin.m_oTop, oSecondMargin.m_oTop); - CDigit::Equation(oFirstMargin.m_oRight, oSecondMargin.m_oRight); - CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); + //TODO:: добавить корректную реализацию + +// CDigit::Equation(oFirstMargin.m_oLeft, oSecondMargin.m_oLeft); +// CDigit::Equation(oFirstMargin.m_oTop, oSecondMargin.m_oTop); +// CDigit::Equation(oFirstMargin.m_oRight, oSecondMargin.m_oRight); +// CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); } void CIndent::SetPermisson(bool bPermission) @@ -1786,54 +1788,39 @@ namespace NSCSS bool CIndent::AddValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { + if (!m_bPermission) + return false; + const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); switch (arValues.size()) { case 1: { - // TODO:: иногда будет не верный рельтат, если до этого одиен из элементом был с '!important' - // Необходимо добавить обработку такого случая - if (AddValue(m_oLeft, arValues[0], unLevel, bHardMode)) - { - m_oTop = m_oRight = m_oBottom = m_oLeft; - return true; - } - break; + return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arLeftValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arRightValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arBottomValues, arValues[0], unLevel, bHardMode); } case 2: { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[1], unLevel, bHardMode)) - { - m_oBottom = m_oTop; - m_oRight = m_oLeft; - - return true; - } - break; + return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arBottomValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arLeftValues, arValues[1], unLevel, bHardMode) && + AddSide(m_arRightValues, arValues[1], unLevel, bHardMode); } case 3: { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[1], unLevel, bHardMode) && - AddValue(m_oBottom, arValues[2], unLevel, bHardMode)) - { - m_oRight = m_oLeft; - - return true; - } - - break; + return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arLeftValues, arValues[1], unLevel, bHardMode) && + AddSide(m_arRightValues, arValues[1], unLevel, bHardMode) && + AddSide(m_arBottomValues, arValues[2], unLevel, bHardMode); } case 4: { - if (AddValue(m_oTop, arValues[0], unLevel, bHardMode) && - AddValue(m_oRight, arValues[1], unLevel, bHardMode) && - AddValue(m_oBottom, arValues[2], unLevel, bHardMode) && - AddValue(m_oLeft, arValues[3], unLevel, bHardMode)) - return true; - - break; + return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && + AddSide(m_arRightValues, arValues[1], unLevel, bHardMode) && + AddSide(m_arBottomValues, arValues[2], unLevel, bHardMode) && + AddSide(m_arLeftValues, arValues[3], unLevel, bHardMode); } } @@ -1842,22 +1829,22 @@ namespace NSCSS bool CIndent::AddLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oLeft, wsValue, unLevel, bHardMode); + return AddSide(m_arLeftValues, wsValue, unLevel, bHardMode); } bool CIndent::AddTop(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oTop, wsValue, unLevel, bHardMode); + return AddSide(m_arTopValues, wsValue, unLevel, bHardMode); } bool CIndent::AddRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oRight, wsValue, unLevel, bHardMode); + return AddSide(m_arRightValues, wsValue, unLevel, bHardMode); } bool CIndent::AddBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oBottom, wsValue, unLevel, bHardMode); + return AddSide(m_arBottomValues, wsValue, unLevel, bHardMode); } void CIndent::UpdateAll(double dFontSize) @@ -1870,86 +1857,118 @@ namespace NSCSS void CIndent::UpdateLeft(double dFontSize) { - if (NSCSS::Em == m_oLeft.GetUnitMeasure() || NSCSS::Rem == m_oLeft.GetUnitMeasure()) - m_oLeft.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_arLeftValues, dFontSize); } void CIndent::UpdateTop(double dFontSize) { - if (NSCSS::Em == m_oTop.GetUnitMeasure() || NSCSS::Rem == m_oTop.GetUnitMeasure()) - m_oTop.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_arTopValues, dFontSize); } void CIndent::UpdateRight(double dFontSize) { - if (NSCSS::Em == m_oRight.GetUnitMeasure() || NSCSS::Rem == m_oRight.GetUnitMeasure()) - m_oRight.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_arRightValues, dFontSize); } void CIndent::UpdateBottom(double dFontSize) { - if (NSCSS::Em == m_oBottom.GetUnitMeasure() || NSCSS::Rem == m_oBottom.GetUnitMeasure()) - m_oBottom.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_arBottomValues, dFontSize); } - const CDigit& CIndent::GetLeft() const + CDigit CIndent::GetLeft() const { - return m_oLeft; + return CalculateSide(m_arLeftValues); } - const CDigit& CIndent::GetTop() const + CDigit CIndent::GetTop() const { - return m_oTop; + return CalculateSide(m_arTopValues); } - const CDigit& CIndent::GetRight() const + CDigit CIndent::GetRight() const { - return m_oRight; + return CalculateSide(m_arRightValues); } - const CDigit& CIndent::GetBottom() const + CDigit CIndent::GetBottom() const { - return m_oBottom; + return CalculateSide(m_arBottomValues); } bool CIndent::Empty() const { - return m_oLeft.Empty() && m_oTop.Empty() && m_oRight.Empty() && m_oBottom.Empty(); + return m_arLeftValues.empty() && m_arTopValues.empty() && m_arRightValues.empty() && m_arBottomValues.empty(); } - CIndent &CIndent::operator+=(const CIndent &oMargin) + CIndent &CIndent::operator+=(const CIndent &oIndent) { - m_oLeft += oMargin.m_oLeft; - m_oTop += oMargin.m_oTop; - m_oRight += oMargin.m_oRight; - m_oBottom += oMargin.m_oBottom; + m_arLeftValues .insert(m_arLeftValues.end(), oIndent.m_arLeftValues.begin(), oIndent.m_arLeftValues.end()); + m_arTopValues .insert(m_arTopValues.end(), oIndent.m_arTopValues.begin(), oIndent.m_arTopValues.end()); + m_arRightValues .insert(m_arRightValues.end(), oIndent.m_arRightValues.begin(), oIndent.m_arRightValues.end()); + m_arBottomValues.insert(m_arBottomValues.end(), oIndent.m_arBottomValues.begin(), oIndent.m_arBottomValues.end()); return *this; } - bool CIndent::operator==(const CIndent &oMargin) const + bool CIndent::operator==(const CIndent &oIndent) const { - return m_oLeft == oMargin.m_oLeft && - m_oTop == oMargin.m_oTop && - m_oRight == oMargin.m_oRight && - m_oBottom == oMargin.m_oBottom; + // Есть вариант, когда у CIndent разное кол-во значений, но итоговое значение одинаковое + // Пока считаем это не одинаковыми + if (m_arLeftValues .size() != oIndent.m_arLeftValues .size() || + m_arTopValues .size() != oIndent.m_arTopValues .size() || + m_arRightValues .size() != oIndent.m_arRightValues .size() || + m_arBottomValues.size() != oIndent.m_arBottomValues.size()) + return false; + + for (unsigned int unIndex = 0; unIndex < m_arLeftValues.size(); ++unIndex) + { + if (m_arLeftValues [unIndex] != oIndent.m_arLeftValues [unIndex]) return false; + if (m_arTopValues [unIndex] != oIndent.m_arTopValues [unIndex]) return false; + if (m_arRightValues [unIndex] != oIndent.m_arRightValues [unIndex]) return false; + if (m_arBottomValues[unIndex] != oIndent.m_arBottomValues[unIndex]) return false; + } + + return true; } - bool CIndent::AddValue(CDigit &oValue, const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::AddSide(std::vector &arValues, const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - if (!m_bPermission) - return false; - - CDigit oTempValue; + CDigit oValue; - if (!oTempValue.SetValue(wsValue, unLevel, bHardMode)) + if (!oValue.SetValue(wsValue, unLevel, bHardMode)) return false; - oValue += oTempValue; + if (!arValues.empty() && CDigit::LevelIsSame(oValue, arValues.back())) + arValues.pop_back(); + + arValues.push_back(oValue); return true; } + void CIndent::UpdateSide(std::vector &arValues, double dFontSize) + { + if (arValues.empty()) + return; + + const UnitMeasure eUM = arValues.back().GetUnitMeasure(); + if (NSCSS::Em == eUM || NSCSS::Rem == eUM) + arValues.back().ConvertTo(NSCSS::Twips, dFontSize); + } + + CDigit CIndent::CalculateSide(const std::vector &arValues) const + { + if (arValues.empty()) + return CDigit(); + + CDigit oValue{arValues.front()}; + + for (std::vector::const_iterator oIter = arValues.begin() + 1; oIter < arValues.end(); ++oIter) + oValue += *oIter; + + return oValue; + } + // FONT CTextDecorationLine::CTextDecorationLine() : m_bUnderline(false), m_bOverline(false), m_bLineThrough(false) diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index c9c234b0128..a2b670946fa 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -54,6 +54,11 @@ namespace NSCSS } } + static bool LevelIsSame(const CValue& oFirstValue, const CValue& oSecondValue) + { + return oFirstValue.m_unLevel == oSecondValue.m_unLevel; + } + bool operator==(const T& oValue) const { return m_oValue == oValue; } bool operator>=(const T& oValue) const { return m_oValue >= oValue; } bool operator<=(const T& oValue) const { return m_oValue <= oValue; } @@ -595,22 +600,24 @@ namespace NSCSS void UpdateRight(double dFontSize); void UpdateBottom(double dFontSize); - const CDigit& GetLeft () const; - const CDigit& GetTop () const; - const CDigit& GetRight () const; - const CDigit& GetBottom() const; + CDigit GetLeft () const; + CDigit GetTop () const; + CDigit GetRight () const; + CDigit GetBottom() const; bool Empty() const; - CIndent& operator+=(const CIndent& oMargin); - bool operator==(const CIndent& oMargin) const; + CIndent& operator+=(const CIndent& oIndent); + bool operator==(const CIndent& oIndent) const; private: - bool AddValue(CDigit& oValue, const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - - CDigit m_oLeft; - CDigit m_oTop; - CDigit m_oRight; - CDigit m_oBottom; + bool AddSide(std::vector& arValues, const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + void UpdateSide(std::vector& arValues, double dFontSize); + CDigit CalculateSide(const std::vector& arValues) const; + + std::vector m_arLeftValues; + std::vector m_arTopValues; + std::vector m_arRightValues; + std::vector m_arBottomValues; bool m_bPermission; }; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index e617a0b8985..e3529db72a7 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1438,23 +1438,19 @@ class CHtmlFile2_Private if (!oStyle.m_oBorder.Empty()) wsTable += L"" + CreateBorders(oStyle.m_oBorder) + L""; - if (!oStyle.m_oMargin.Empty() && (0 < oStyle.m_oMargin.GetTop().ToInt() || 0 < oStyle.m_oMargin.GetBottom().ToInt())) - { - wsTable += L""; - - if (0 < oStyle.m_oMargin.GetTop().ToInt()) - wsTable += L"(oStyle.m_oMargin.GetTop().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; - -// if (0 < oStyle.m_pMargin.GetLeftSide()) -// wsTable += L"(oStyle.m_pMargin.GetLeftSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; - - if (0 < oStyle.m_oMargin.GetBottom().ToInt()) - wsTable += L"(oStyle.m_oMargin.GetBottom().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; - -// if (0 < oStyle.m_pMargin.GetRightSide()) -// wsTable += L"(oStyle.m_pMargin.GetRightSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; - - wsTable += L""; + if (!oStyle.m_oPadding.Empty()) + { + const int nTopPadding = std::max(0, oStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, m_unHeight)); + const int nLeftPadding = std::max(0, oStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, m_unWidth )); + const int nBottomPadding = std::max(0, oStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, m_unHeight)); + const int nRightPadding = std::max(0, oStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, m_unWidth )); + + wsTable += L"" + "" + "" + "" + "" + ""; } else wsTable += L""; From f672fcc665440c550c34276fb45087d71e59de2d Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 19 Feb 2024 20:07:17 +0300 Subject: [PATCH 322/794] oleObjects from ppt --- MsBinaryFile/PptFile/Drawing/Attributes.h | 49 ++++- MsBinaryFile/PptFile/Drawing/Element.h | 15 +- MsBinaryFile/PptFile/Drawing/Elements.cpp | 17 ++ MsBinaryFile/PptFile/Drawing/Elements.h | 12 ++ MsBinaryFile/PptFile/PPTXWriter/Converter.cpp | 13 +- .../PptFile/PPTXWriter/ImageManager.cpp | 106 ++++++++-- .../PptFile/PPTXWriter/ImageManager.h | 42 ++-- .../PptFile/PPTXWriter/ShapeWriter.cpp | 196 +++++++++++++----- MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h | 3 +- .../PptFile/Reader/PPTDocumentInfo.cpp | 3 +- MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h | 5 + .../PptFile/Reader/PPTDocumentInfoOneUser.cpp | 115 +++++++--- .../PptFile/Reader/PPTDocumentInfoOneUser.h | 6 +- MsBinaryFile/PptFile/Reader/Records.cpp | 3 +- .../Records/Drawing/ShapeContainer.cpp | 22 +- .../PptFile/Records/ExObjListContainer.cpp | 60 ++++++ .../PptFile/Records/ExObjListContainer.h | 12 ++ .../PptFile/Records/ExOleEmbedAtom.cpp | 5 + MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h | 8 +- MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp | 50 ----- MsBinaryFile/PptFile/Records/VBAInfoAtom.h | 12 -- 21 files changed, 548 insertions(+), 206 deletions(-) diff --git a/MsBinaryFile/PptFile/Drawing/Attributes.h b/MsBinaryFile/PptFile/Drawing/Attributes.h index f504f1be85f..701ef71cf0e 100644 --- a/MsBinaryFile/PptFile/Drawing/Attributes.h +++ b/MsBinaryFile/PptFile/Drawing/Attributes.h @@ -83,22 +83,26 @@ namespace PPT eftHyperlink = 3, eftObject = 4, eftSlide = 5, - eftFile = 6 + eftFile = 6, + eftOleObject = 7 }; - ExFilesType m_type = eftNone; - _UINT32 m_dwID = 0; - std::wstring m_strFilePath = L""; - std::wstring m_name; + ExFilesType m_type = ExFilesType::eftNone; + + _UINT32 m_dwID = 0; + std::wstring m_strFilePath; + + std::wstring m_name; + std::wstring m_progName; // clip - double m_dStartTime = 0.0; - double m_dEndTime = 1.0; + double m_dStartTime = 0.0; + double m_dEndTime = 1.0; // loop - bool m_bLoop = false; - bool m_fNarration = false; // isNarration pptx - bool m_fRewind = false; + bool m_bLoop = false; + bool m_fNarration = false; // isNarration pptx + bool m_fRewind = false; CExFilesInfo() { @@ -168,6 +172,7 @@ namespace PPT std::vector m_arHyperlinks; std::vector m_arSlides; std::vector m_arFiles; + std::vector m_arOleObjects; std::vector m_arAudioCollection; @@ -177,9 +182,10 @@ namespace PPT m_arImages.clear(); m_arAudios.clear(); m_arAudioCollection.clear(); + m_arOleObjects.clear(); } - CExMedia() : m_arVideos(), m_arImages(), m_arAudios() + CExMedia() { } @@ -198,6 +204,8 @@ namespace PPT m_arImages.push_back(oSrc.m_arImages[i]); for (size_t i = 0; i < oSrc.m_arVideos.size(); i++) m_arAudios.push_back(oSrc.m_arAudios[i]); + for (size_t i = 0; i < oSrc.m_arOleObjects.size(); i++) + m_arOleObjects.push_back(oSrc.m_arOleObjects[i]); return *this; } @@ -266,6 +274,19 @@ namespace PPT return NULL; } + CExFilesInfo* LockOleObject(_UINT32 dwID) + { + size_t nCount = m_arOleObjects.size(); + for (size_t i = 0; i < nCount; ++i) + { + if (dwID == m_arOleObjects[i].m_dwID) + { + return &m_arOleObjects[i]; + } + } + + return NULL; + } CExFilesInfo* LockAudioFromCollection(_UINT32 dwID) { size_t nCount = m_arAudioCollection.size(); @@ -302,6 +323,12 @@ namespace PPT eType = CExFilesInfo::eftAudio; return pInfo; } + pInfo = LockOleObject(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftOleObject; + return pInfo; + } pInfo = LockSlide(dwID); if (NULL != pInfo) { diff --git a/MsBinaryFile/PptFile/Drawing/Element.h b/MsBinaryFile/PptFile/Drawing/Element.h index a36fc9c2755..3ca24b614a6 100644 --- a/MsBinaryFile/PptFile/Drawing/Element.h +++ b/MsBinaryFile/PptFile/Drawing/Element.h @@ -38,13 +38,14 @@ namespace PPT { enum ElementType { - etGroup = 0, - etVideo = 1, - etAudio = 2, - etPicture = 3, - etShape = 4, - etText = 5, - etTable = 6 + etGroup = 0, + etVideo = 1, + etAudio = 2, + etPicture = 3, + etShape = 4, + etText = 5, + etTable = 6, + etOleObject = 7 }; class CTheme; diff --git a/MsBinaryFile/PptFile/Drawing/Elements.cpp b/MsBinaryFile/PptFile/Drawing/Elements.cpp index 4c8bfa4ecf3..bcbae43ce2c 100644 --- a/MsBinaryFile/PptFile/Drawing/Elements.cpp +++ b/MsBinaryFile/PptFile/Drawing/Elements.cpp @@ -490,7 +490,24 @@ namespace PPT strXmlPPTX += L""; return strXmlPPTX; } + COleObjectElement::COleObjectElement() : CImageElement() + { + m_etType = etOleObject; + } + COleObjectElement::~COleObjectElement() + { + } + CElementPtr COleObjectElement::CreateDublicate() + { + COleObjectElement* pOleObjectElement = new COleObjectElement(); + CElementPtr pElement = CElementPtr(pOleObjectElement); + SetProperiesToDublicate(pElement); + + pOleObjectElement->m_strOleName = m_strOleName; + pOleObjectElement->m_strProgId = m_strProgId; + return pElement; + } CAudioElement::CAudioElement() : CImageElement() { m_etType = etAudio; diff --git a/MsBinaryFile/PptFile/Drawing/Elements.h b/MsBinaryFile/PptFile/Drawing/Elements.h index 3e813fd6776..34e4bdd5cd1 100644 --- a/MsBinaryFile/PptFile/Drawing/Elements.h +++ b/MsBinaryFile/PptFile/Drawing/Elements.h @@ -101,7 +101,19 @@ class CShapeElement : public CElement std::wstring ConvertPPTShapeToPPTX(bool bIsNamespace = false); std::wstring ConvertPPTtoPPTX(CPPTShape* pPPTShape, const NSGuidesVML::CFormParam& pCoef, bool bIsNamespace = false); }; +class COleObjectElement : public CImageElement +{ +public: + std::wstring m_strBinFileName; + + std::wstring m_strOleName; + std::wstring m_strProgId; + COleObjectElement(); + virtual ~COleObjectElement(); + + virtual CElementPtr CreateDublicate(); +}; class CAudioElement : public CImageElement { public: diff --git a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp index a2b6a03c20d..f68adec4daf 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -118,6 +118,8 @@ namespace PPT m_oManager.Clear(); m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); + m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); + m_oManager.SetTempMedia(m_pUserInfo->m_pDocumentInfo->m_pCommonInfo->tempPath); m_pShapeWriter->InitNextId(); @@ -164,6 +166,7 @@ namespace PPT m_pDocument = pDocument; m_oManager.Clear(); m_oManager.SetDstMedia(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR); + m_oManager.SetDstEmbeddings(m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"embeddings" + FILE_SEPARATOR_STR); m_pShapeWriter->InitNextId(); @@ -589,7 +592,6 @@ namespace PPT { std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; - NSDirectory::CreateDirectory(strPptDirectory + L"media"); NSDirectory::CreateDirectory(strPptDirectory + L"theme"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels"); @@ -1544,7 +1546,14 @@ namespace PPT } oWriter.WriteString(std::wstring(L"")); - oWriter.WriteString(std::wstring(L"m_bShowMasterShapes) oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); if (pSlide->m_bHidden) diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index b8a2601462f..6bee2915ff5 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -32,8 +32,9 @@ #include "ImageManager.h" #include #include "../../../OOXML/SystemUtility/SystemUtility.h" +#include "../../../DesktopEditor/common/Directory.h" -CMediaManager::CMediaManager() : m_lIndexNextImage(0), m_lIndexNextAudio(0), m_lIndexNextVideo(0) +CMediaManager::CMediaManager() : m_lIndexNextImage(0), m_lIndexNextAudio(0), m_lIndexNextVideo(0), m_lIndexNextOleObject(0) { } CMediaManager::~CMediaManager() @@ -46,6 +47,7 @@ void CMediaManager::Clear() m_lIndexNextImage = 0; m_lIndexNextAudio = 0; m_lIndexNextVideo = 0; + m_lIndexNextOleObject = 0; } std::wstring CMediaManager::FindMedia(const std::wstring &strInput) @@ -57,6 +59,10 @@ std::wstring CMediaManager::FindMedia(const std::wstring &strInput) } return L""; } +void CMediaManager::SetDstEmbeddings(const std::wstring& strDst) +{ + m_strDstEmbeddings = strDst; +} void CMediaManager::SetDstMedia(const std::wstring &strDst) { m_strDstMedia = strDst; @@ -80,13 +86,69 @@ std::wstring CMediaManager::GenerateImage(const std::wstring &strInput) { return GenerateMedia(strInput, L"image", m_lIndexNextImage, L".png"); } - +std::wstring CMediaManager::GenerateOleObject(const std::wstring& strInput) +{ + return GenerateEmbedding(strInput, L"oleObject", m_lIndexNextOleObject, L".bin"); +} std::wstring CMediaManager::GenerateImageJPEG(const std::wstring &strInput) { return GenerateMedia(strInput, L"image", m_lIndexNextImage, L".jpeg"); } -std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const std::wstring &Template, long &Indexer, const std::wstring &strDefaultExt) +std::wstring CMediaManager::GenerateEmbedding(const std::wstring &strInput, const std::wstring &Template, long &Indexer, const std::wstring &strDefaultExt) +{ + std::map::iterator pPair = m_mapMedia.find(strInput); + if (m_mapMedia.end() != pPair) + { + return pPair->second; + } + +// if (IsNeedDownload(strInput)) +// { +//#ifndef DISABLE_FILE_DOWNLOADER +// NSNetwork::NSFileTransport::CFileDownloader oDownloader(strInput, TRUE); +// if ( oDownloader.DownloadSync() ) +// { +// std::wstring file_name = oDownloader.GetFilePath(); +// +// //todooo - check media file +// return GenerateEmbedding(file_name , Template, Indexer, strDefaultExt); +// } +//#endif +// } + + std::wstring strExts = strDefaultExt; + int nIndexExt = strInput.rfind(wchar_t('.')); + if (-1 != nIndexExt) + strExts = strInput.substr(nIndexExt); + + if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; + + std::wstring strMediaName = Template + std::to_wstring(++Indexer); + + std::wstring strOutput = m_strDstEmbeddings + strMediaName + strExts; + strMediaName = L"../embeddings/" + strMediaName + strExts; + + OOX::CPath pathInput(strInput); + std::wstring strPathInput = pathInput.GetPath(); + + if (std::wstring::npos == strPathInput.find(m_strTempMedia)) + { + return L""; + } + if (strOutput != strInput) + { + NSDirectory::CreateDirectory(m_strDstEmbeddings); + + if (NSFile::CFileBinary::Copy(strInput, strOutput) == false) + { + return L""; + } + } + m_mapMedia[strInput] = strMediaName; + return strMediaName; +} +std::wstring CMediaManager::GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt) { std::map::iterator pPair = m_mapMedia.find(strInput); if (m_mapMedia.end() != pPair) @@ -98,12 +160,12 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const st { #ifndef DISABLE_FILE_DOWNLOADER NSNetwork::NSFileTransport::CFileDownloader oDownloader(strInput, TRUE); - if ( oDownloader.DownloadSync() ) + if (oDownloader.DownloadSync()) { std::wstring file_name = oDownloader.GetFilePath(); //todooo - check media file - return GenerateMedia(file_name , Template, Indexer, strDefaultExt); + return GenerateMedia(file_name, Template, Indexer, strDefaultExt); } #endif } @@ -117,24 +179,26 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const st { std::wstring strInput1 = strInput.substr(0, nIndexExt); nIndexExt = strInput1.rfind(wchar_t('.')); - strExts = nIndexExt < 0 ? L"" : strInput1.substr(nIndexExt); + strExts = nIndexExt < 0 ? L"" : strInput1.substr(nIndexExt); } if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; std::wstring strMediaName = Template + std::to_wstring(++Indexer); std::wstring strOutput = m_strDstMedia + strMediaName + strExts; - strMediaName = L"../media/" + strMediaName + strExts; + strMediaName = L"../media/" + strMediaName + strExts; - OOX::CPath pathInput(strInput); + OOX::CPath pathInput(strInput); std::wstring strPathInput = pathInput.GetPath(); - + if (std::wstring::npos == strPathInput.find(m_strTempMedia)) { return L""; } if (strOutput != strInput) { + NSDirectory::CreateDirectory(m_strDstMedia); + if (NSFile::CFileBinary::Copy(strInput, strOutput) == false) { return L""; @@ -359,19 +423,24 @@ std::wstring CRelsGenerator::WriteHyperlinkMedia(const std::wstring &strMedia, b return strRid; } -std::wstring CRelsGenerator::WriteHyperlinkImage(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkImage(const std::wstring & strFileName, bool bExternal) +{ + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); +} + +std::wstring CRelsGenerator::WriteHyperlinkAudio(const std::wstring & strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio"); } -std::wstring CRelsGenerator::WriteHyperlinkAudio(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkVideo(const std::wstring & strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); } -std::wstring CRelsGenerator::WriteHyperlinkVideo(const std::wstring &strImage, bool bExternal) +std::wstring CRelsGenerator::WriteHyperlinkOleObject(const std::wstring &strFileName, bool bExternal) { - return WriteHyperlinkMedia(strImage, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); + return WriteHyperlinkMedia(strFileName, bExternal, false, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"); } std::wstring CRelsGenerator::WriteMedia(const std::wstring &strMediaPath) @@ -389,7 +458,14 @@ std::wstring CRelsGenerator::WriteImage(const std::wstring &strImagePath) if (strImage.empty()) return WriteHyperlinkImage(CorrectXmlString3(strImagePath), true); return WriteHyperlinkImage(strImage, false); } +std::wstring CRelsGenerator::WriteOleObject(const std::wstring& strOleObjectPath) +{ + std::wstring strOleObject = m_pManager->GenerateOleObject(strOleObjectPath); + if (strOleObject.empty()) + return WriteHyperlinkOleObject(CorrectXmlString3(strOleObjectPath), true); + return WriteHyperlinkOleObject(strOleObject, false); +} std::wstring CRelsGenerator::WriteSlideRef(const std::wstring &strLocation) { int sldNum = PPT::CExFilesInfo::GetSlideNumber(strLocation); diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h index bcb71b8a8dd..bf0bcae0243 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h @@ -43,27 +43,36 @@ class CMediaManager { private: - std::map m_mapMedia; + std::map m_mapMedia; - long m_lIndexNextAudio; - long m_lIndexNextVideo; - long m_lIndexNextImage; + long m_lIndexNextAudio; + long m_lIndexNextVideo; + long m_lIndexNextImage; + long m_lIndexNextOleObject; - std::wstring m_strDstMedia; + std::wstring m_strDstMedia; std::wstring m_strTempMedia; + std::wstring m_strDstEmbeddings; public: CMediaManager(); ~CMediaManager(); void Clear(); std::wstring FindMedia(const std::wstring& strInput); + + void SetDstEmbeddings(const std::wstring& strDst); void SetDstMedia(const std::wstring& strDst); void SetTempMedia(const std::wstring& strSrc); + std::wstring GenerateVideo(const std::wstring& strInput); std::wstring GenerateAudio(const std::wstring& strInput); + std::wstring GenerateOleObject(const std::wstring& strInput); std::wstring GenerateImage(const std::wstring& strInput); std::wstring GenerateImageJPEG(const std::wstring& strInput); - std::wstring GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long & Indexer, const std::wstring& strDefaultExt); + + std::wstring GenerateMedia(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt); + std::wstring GenerateEmbedding(const std::wstring& strInput, const std::wstring& Template, long& Indexer, const std::wstring& strDefaultExt); + void WriteAudioCollection(const std::vector& audioCont); bool IsNeedDownload(const std::wstring& strFile); }; @@ -72,11 +81,11 @@ std::wstring CorrectXmlString3(const std::wstring & str); class CRelsGenerator { private: - PPT::CStringWriter m_oWriter; - int m_lNextRelsID; - std::map m_mapMediaRelsID; - CMediaManager* m_pManager; - std::map m_mapHyperlinks; + PPT::CStringWriter m_oWriter; + int m_lNextRelsID; + std::map m_mapMediaRelsID; + CMediaManager* m_pManager; + std::map m_mapHyperlinks; public: CRelsGenerator(CMediaManager* pManager); @@ -90,20 +99,21 @@ class CRelsGenerator void StartNotes(int nIndexSlide, bool bMaster); void StartSlide(int nIndexLayout, int nIndexNotes); void CloseRels(); - void SaveRels(const std::wstring &strFile); - std::wstring WriteHyperlink(const std::wstring &strHyperlink, bool isExternal = false); + void SaveRels(const std::wstring& strFile); + std::wstring WriteHyperlink(const std::wstring& strHyperlink, bool isExternal = false); void StartLayout(int nIndexTheme); - std::wstring WriteHyperlinkMedia(const std::wstring& strMedia, bool bExternal = true, bool newRIdAlways = false, std::wstring strRelsType = L"http://schemas.microsoft.com/office/2007/relationships/media"); std::wstring WriteHyperlinkImage(const std::wstring& strImage, bool bExternal = true); std::wstring WriteHyperlinkAudio(const std::wstring& strImage, bool bExternal = true); std::wstring WriteHyperlinkVideo(const std::wstring& strImage, bool bExternal = true); + std::wstring WriteHyperlinkOleObject(const std::wstring& strImage, bool bExternal = true); std::wstring WriteMedia(const std::wstring& strMediaPath); std::wstring WriteImage(const std::wstring& strImagePath); std::wstring WriteSlideRef(const std::wstring& strLocation); - std::wstring WriteAudio(const std::wstring& strAudioPath, bool & bExternal); - std::wstring WriteVideo(const std::wstring& strVideoPath, bool & bExternal); + std::wstring WriteAudio(const std::wstring& strAudioPath, bool& bExternal); + std::wstring WriteVideo(const std::wstring& strVideoPath, bool& bExternal); + std::wstring WriteOleObject(const std::wstring& strOleObjectPath); int getRId()const { return m_lNextRelsID; } }; diff --git a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp index f9b19860a26..c22e19b8f07 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp @@ -552,7 +552,8 @@ void PPT::CShapeWriter::WriteImageInfo() if (pImageElement->m_lID < 0) pImageElement->m_lID = m_lNextShapeID; - std::wstring strShapeID = std::to_wstring(pImageElement->m_lID); + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + std::wstring strShapeID = std::to_wstring(pOleObjectElement ? 0 : pImageElement->m_lID); m_oWriter.WriteString(std::wstring(L"")); - WriteHyperlink(m_pElement->m_arrActions); m_oWriter.WriteString(std::wstring(L""; m_oWriter.WriteString(str2); } +void PPT::CShapeWriter::WriteOleObjectInfo(const std::wstring& strRid, const std::wstring& xfrm) +{ + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + if (!pOleObjectElement) return; + + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement->m_lID < 0) + pOleObjectElement->m_lID = m_lNextShapeID; + + std::wstring strTableID = std::to_wstring(pOleObjectElement->m_lID); + + m_oWriter.WriteString(std::wstring(L"m_sName.empty()) pOleObjectElement->m_sName = std::wstring(L"Group ") + strTableID; + + if (pOleObjectElement->m_bHidden) m_oWriter.WriteString(std::wstring(L" hidden=\"1\"")); + + m_oWriter.WriteString(std::wstring(L" name=\"")); + m_oWriter.WriteStringXML(pOleObjectElement->m_sName); + m_oWriter.WriteString(std::wstring(L"\"")); + + if (!pOleObjectElement->m_sDescription.empty()) + { + m_oWriter.WriteString(std::wstring(L" descr=\"")); + m_oWriter.WriteStringXML(XmlUtils::EncodeXmlStringExtend(pOleObjectElement->m_sDescription)); + m_oWriter.WriteString(std::wstring(L"\"")); + } + m_oWriter.WriteString(std::wstring(L">")); + if (!pOleObjectElement->m_sHyperlink.empty()) + { + std::wstring rId = m_pRels->WriteHyperlink(pOleObjectElement->m_sHyperlink); + + if (false == rId.empty()) + { + m_oWriter.WriteString(std::wstring(L"")); + } + } + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + ++m_lNextShapeID; + + m_oWriter.WriteString(std::wstring(L"")); + + m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement->m_bChildAnchorEnabled || pOleObjectElement->m_bAnchorEnabled) + { + m_oWriter.WriteString(std::wstring(L"")); + } + + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"m_strOleName.empty()) + { + m_oWriter.WriteString(std::wstring(L" name=\"") + pOleObjectElement->m_strOleName + L"\""); + } + m_oWriter.WriteString(std::wstring(L" r:id=\"") + strRid + L"\""); + + _INT64 width = (_INT64)(pOleObjectElement->m_bChildAnchorEnabled ? pOleObjectElement->m_rcChildAnchor.GetWidth() : pOleObjectElement->m_rcAnchor.GetWidth()) / 1.78; + _INT64 height = (_INT64)(pOleObjectElement->m_bChildAnchorEnabled ? pOleObjectElement->m_rcChildAnchor.GetHeight() : pOleObjectElement->m_rcAnchor.GetHeight()) / 1.78; + + m_oWriter.WriteString(std::wstring(L" imgW=\"") + std::to_wstring(width) + L"\""); + m_oWriter.WriteString(std::wstring(L" imgH=\"") + std::to_wstring(height) + L"\""); + + if (false == pOleObjectElement->m_strProgId.empty()) + { + m_oWriter.WriteString(std::wstring(L" progId=\"") + pOleObjectElement->m_strProgId + L"\""); + } + m_oWriter.WriteString(std::wstring(L">")); +} void PPT::CShapeWriter::WriteTableInfo() { CGroupElement* pGroupElement = dynamic_cast(m_pElement.get()); @@ -1725,7 +1804,7 @@ std::vector CShapeWriter::getActionsByNum(const int num) } // TODO! Not work correct -std::wstring PPT::CShapeWriter::ConvertTable () +std::wstring PPT::CShapeWriter::ConvertTable() { CGroupElement* pGroupElement = dynamic_cast(m_pElement.get()); if (!pGroupElement) return L""; @@ -2001,12 +2080,11 @@ void PPT::CShapeWriter::ParseXmlAlternative(const std::wstring & xml) } } - std::wstring PPT::CShapeWriter::ConvertImage() -{ +{ CImageElement* pImageElement = dynamic_cast(m_pElement.get()); if (!pImageElement) return L""; - + if (pImageElement->m_bImagePresent == false) { if (pImageElement->m_sName.empty()) return L""; @@ -2027,21 +2105,69 @@ std::wstring PPT::CShapeWriter::ConvertImage() if (strRid.empty()) return L""; - m_oWriter.WriteString(std::wstring(L"")); - - WriteImageInfo(); + std::wstring strAnchor; CGeomShapeInfo oInfo; - oInfo.m_lOriginalWidth = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetWidth() : (LONG)m_pElement->m_rcAnchor.GetWidth(); - oInfo.m_lOriginalHeight = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetHeight() : (LONG)m_pElement->m_rcAnchor.GetHeight(); + oInfo.m_lOriginalWidth = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetWidth() : (LONG)m_pElement->m_rcAnchor.GetWidth(); + oInfo.m_lOriginalHeight = m_pElement->m_bChildAnchorEnabled ? (LONG)m_pElement->m_rcChildAnchor.GetHeight() : (LONG)m_pElement->m_rcAnchor.GetHeight(); m_pElement->NormalizeCoordsByMetric(); oInfo.SetBounds(m_pElement->m_bChildAnchorEnabled ? m_pElement->m_rcChildAnchor : m_pElement->m_rcAnchor); oInfo.m_dRotate = pImageElement->m_dRotate; - oInfo.m_bFlipH = pImageElement->m_bFlipH; - oInfo.m_bFlipV = pImageElement->m_bFlipV; + oInfo.m_bFlipH = pImageElement->m_bFlipH; + oInfo.m_bFlipV = pImageElement->m_bFlipV; + + if (pImageElement->m_bChildAnchorEnabled || pImageElement->m_bAnchorEnabled) + { + if (0 != pImageElement->m_dRotate) + { + strAnchor += L" rot=\"" + std::to_wstring((int)(pImageElement->m_dRotate * 60000)) + L"\""; + } + if (pImageElement->m_bFlipH) + { + strAnchor += L" flipH=\"1\""; + } + if (pImageElement->m_bFlipV) + { + strAnchor += L" flipV=\"1\""; + } + strAnchor += L">"; + + strAnchor += L"m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.left : (int)pImageElement->m_rcAnchor.left) + + L"\" y=\"" + + std::to_wstring(pImageElement->m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.top : (int)pImageElement->m_rcAnchor.top) + + L"\"/>"; + + _INT64 width = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetWidth() : pImageElement->m_rcAnchor.GetWidth()); + _INT64 height = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetHeight() : pImageElement->m_rcAnchor.GetHeight()); + + if ((width > 0 && height > 0) && ((_UINT64)width) < 0xffffffffffff && ((_UINT64)height) < 0xffffffffffff) + { + strAnchor += L""; + } + else + { + strAnchor += L""; + } + } + + COleObjectElement* pOleObjectElement = dynamic_cast(m_pElement.get()); + if (pOleObjectElement) + { + std::wstring strRidOleObject = m_pRels->WriteOleObject(pOleObjectElement->m_strBinFileName); + if (false == strRidOleObject.empty()) + { + WriteOleObjectInfo(strRidOleObject, strAnchor); + } + else pOleObjectElement = NULL; + } + + m_oWriter.WriteString(std::wstring(L"")); + + WriteImageInfo(); m_oWriter.WriteString(std::wstring(L"")); @@ -2107,41 +2233,7 @@ std::wstring PPT::CShapeWriter::ConvertImage() if (pImageElement->m_bChildAnchorEnabled || pImageElement->m_bAnchorEnabled) { - std::wstring str; - - m_oWriter.WriteString(std::wstring(L"m_dRotate) - { - m_oWriter.WriteString(L" rot=\"" + std::to_wstring((int)(pImageElement->m_dRotate * 60000)) + L"\""); - } - if (pImageElement->m_bFlipH) - { - m_oWriter.WriteString(std::wstring(L" flipH=\"1\"")); - } - if (pImageElement->m_bFlipV) - { - m_oWriter.WriteString(std::wstring(L" flipV=\"1\"")); - } - m_oWriter.WriteString(std::wstring(L">")); - - m_oWriter.WriteString(L"m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.left : (int)pImageElement->m_rcAnchor.left) - + L"\" y=\"" + - std::to_wstring(pImageElement->m_bChildAnchorEnabled ? (int)pImageElement->m_rcChildAnchor.top : (int)pImageElement->m_rcAnchor.top) + - L"\"/>"); - - _INT64 width = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetWidth() : pImageElement->m_rcAnchor.GetWidth()); - _INT64 height = (_INT64)(pImageElement->m_bChildAnchorEnabled ? pImageElement->m_rcChildAnchor.GetHeight() : pImageElement->m_rcAnchor.GetHeight()); - - if (( width > 0 && height > 0 ) && ((_UINT64)width) < 0xffffffffffff && ((_UINT64)height) < 0xffffffffffff) - { - m_oWriter.WriteString(L""); - } - else - { - m_oWriter.WriteString(L""); - } - m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); } m_oWriter.WriteString(std::wstring(L"")); @@ -2155,6 +2247,14 @@ std::wstring PPT::CShapeWriter::ConvertImage() m_oWriter.WriteString(std::wstring(L"")); m_oWriter.WriteString(std::wstring(L"")); + + if (pOleObjectElement) + { + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + m_oWriter.WriteString(std::wstring(L"")); + } pImageElement = NULL; return m_oWriter.GetData(); diff --git a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h index f97df3fe0e5..76cebf1e0f9 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h @@ -457,7 +457,8 @@ namespace PPT std::wstring ConvertTableCell(); void WriteShapeInfo(); void WriteImageInfo(); - void WriteTextInfo(CTextCFRun *pLastCF = nullptr); + void WriteOleObjectInfo(const std::wstring& strRid, const std::wstring& xfrm); + void WriteTextInfo(CTextCFRun *pLastCF = nullptr); static std::wstring WriteBullets(CTextPFRun* pPF, CRelsGenerator *pRels); void Write3dShape(); std::wstring getOWriterStr() const; diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp index 408ff9eb5e0..54e0eb5f52b 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp @@ -33,7 +33,7 @@ using namespace PPT; -CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacros(true) +CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacros(true), m_pStream(NULL) { } @@ -57,6 +57,7 @@ void CPPTDocumentInfo::Clear() bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE::Stream *pStream) { + m_pStream = pStream; m_oCurrentUser.FromAtom(pCurrentUser); _UINT32 offsetToEdit = m_oCurrentUser.m_nOffsetToCurrentEdit; diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h index bc29978a11c..880447f4eeb 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h @@ -39,6 +39,8 @@ namespace PPT class CPPTDocumentInfo { public: + friend class CPPTUserInfo; + _commonInfo* m_pCommonInfo = NULL; CCurrentUser m_oCurrentUser; @@ -57,5 +59,8 @@ class CPPTDocumentInfo bool ReadFromStream(CRecordCurrentUserAtom* pCurrentUser, POLE::Stream* pStream); bool LoadDocument(); + +private: + POLE::Stream* m_pStream; }; } diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp index 7efa111bd39..39c18081a22 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -55,7 +55,6 @@ m_pStorageDecrypt(NULL), m_pDecryptor(NULL), m_arOffsetPictures() { - m_VbaProjectStg = NULL; m_pDocumentInfo = NULL; m_lIndexThisUser = -1; @@ -90,7 +89,6 @@ void CPPTUserInfo::Clear() RELEASEOBJECT(m_pDecryptor); RELEASEOBJECT(m_pStorageDecrypt); - RELEASEOBJECT(m_VbaProjectStg); for (std::map<_UINT32, CRecordSlide*>::iterator pPair = m_mapSlides.begin(); pPair != m_mapSlides.end(); ++pPair) { @@ -425,38 +423,46 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) { if (pVbaAtom->m_nHasMacros) { - nIndexPsrRef = m_mapOffsetInPIDs.find(pVbaAtom->m_nObjStgDataRef); + m_sVbaProjectFile = GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); + + m_bMacros = (false == m_sVbaProjectFile.empty()); + } + } + } + return true; +} +std::wstring CPPTUserInfo::GetBinFromStg(const std::wstring& name, _UINT32 nRef) +{ + POLE::Stream* pStream = m_pDocumentInfo->m_pStream; - if (m_mapOffsetInPIDs.end() != nIndexPsrRef) - { - offset_stream = nIndexPsrRef->second; - StreamUtils::StreamSeek(offset_stream, pStream); + std::map<_UINT32, _UINT32>::iterator nIndexPsrRef = m_mapOffsetInPIDs.find(nRef); - POLE::Stream* pStreamTmp = pStream; - if (m_pDecryptor) - { - DecryptStream(pStream, pVbaAtom->m_nObjStgDataRef); - pStreamTmp = m_arStreamDecrypt.back()->stream_; - } - oHeader.ReadFromStream(pStreamTmp); + std::wstring result; + if (m_mapOffsetInPIDs.end() != nIndexPsrRef) + { + _UINT32 offset_stream = nIndexPsrRef->second; + StreamUtils::StreamSeek(offset_stream, pStream); - m_VbaProjectStg = new CRecordVbaProjectStg(m_pDocumentInfo->m_pCommonInfo->tempPath); - m_VbaProjectStg->ReadFromStream(oHeader, pStreamTmp); + POLE::Stream* pStreamTmp = pStream; + if (m_pDecryptor) + { + DecryptStream(pStream, nRef); + pStreamTmp = m_arStreamDecrypt.back()->stream_; + } + SRecordHeader oHeader; + oHeader.ReadFromStream(pStreamTmp); - if (m_VbaProjectStg->m_sFileName.empty()) - { - RELEASEOBJECT(m_VbaProjectStg); - } - else - { - m_sVbaProjectFile = m_VbaProjectStg->m_sFileName; - m_bMacros = true; - } - } - } + CRecordExObjStg *pExObjStg = new CRecordExObjStg(name, m_pDocumentInfo->m_pCommonInfo->tempPath); + + if (pExObjStg) + { + pExObjStg->ReadFromStream(oHeader, pStreamTmp); + result = pExObjStg->m_sFileName; + + RELEASEOBJECT(pExObjStg); } } - return true; + return result; } //-------------------------------------------------------------------------------------------- void CPPTUserInfo::ReadExtenalObjects() @@ -2394,15 +2400,22 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) return; // читаем видео ---------------------------------------------- - std::vector oArray; - pExObjects->GetRecordsByType(&oArray, true); + std::vector oArrayVideo; + pExObjects->GetRecordsByType(&oArrayVideo, true); - for (size_t nIndex = 0; nIndex < oArray.size(); ++nIndex) + for (size_t nIndex = 0; nIndex < oArrayVideo.size(); ++nIndex) { - LoadExVideo(oArray[nIndex]); + LoadExVideo(oArrayVideo[nIndex]); } + // читаем ole ---------------------------------------------- + std::vector oArrayObj; + pExObjects->GetRecordsByType(&oArrayObj, true); - oArray.clear(); + for (size_t nIndex = 0; nIndex < oArrayObj.size(); ++nIndex) + { + LoadExOleObject(oArrayObj[nIndex]); + } + oArrayObj.clear(); // ----------------------------------------------------------- // читаем аудио ---------------------------------------------- @@ -2528,8 +2541,44 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) } } +void CPPTUserInfo::LoadExOleObject(CRecordsContainer* pExObject) +{ + //exOleEmbedAtom + //exOleObjAtom + //menuNameAtom + //progIdAtom + //clipboardNameAtom + //metafile(variable) + + std::vector oArrayExOleEmbed; + std::vector oArrayExOleObj; + std::vector oArrayCString; + + pExObject->GetRecordsByType(&oArrayExOleEmbed, false); + pExObject->GetRecordsByType(&oArrayExOleObj, false); + pExObject->GetRecordsByType(&oArrayCString, false); + + if (1 == oArrayExOleObj.size()) + { + PPT::CExFilesInfo oInfo; + oInfo.m_dwID = oArrayExOleObj[0]->m_nExObjID; + if (oArrayCString.size() > 0) + oInfo.m_name = oArrayCString[0]->m_strText; + + if (oArrayCString.size() > 1) + oInfo.m_progName = oArrayCString[1]->m_strText; + + oInfo.m_strFilePath = GetBinFromStg(L"", oArrayExOleObj[0]->m_nPersistID); // ExOleObjStg || ExControlStg + + m_oExMedia.m_arOleObjects.push_back(oInfo); + } + + oArrayExOleEmbed.clear(); + oArrayExOleObj.clear(); + oArrayCString.clear(); +} void CPPTUserInfo::LoadExVideo(CRecordsContainer* pExObject) { diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h index 18221edeef1..d8c584403aa 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h @@ -100,8 +100,7 @@ class CPPTUserInfo : public CDocument bool m_bHasFooter; int m_nFormatDate; - CRecordVbaProjectStg* m_VbaProjectStg; - int m_lIndexThisUser; + int m_lIndexThisUser; double m_nWriteSlideTimeOffset; double m_nWriteSlideTime; @@ -133,6 +132,8 @@ class CPPTUserInfo : public CDocument bool ReadDocumentPersists(POLE::Stream* pStream); void ReadExtenalObjects(); + std::wstring GetBinFromStg(const std::wstring& name, _UINT32 nRef); + void DecryptStream(POLE::Stream *pStream, int block); void FromDocument(); @@ -161,6 +162,7 @@ class CPPTUserInfo : public CDocument void LoadExVideo(CRecordsContainer* pExObject); void LoadExAudio(CRecordsContainer* pExObject); + void LoadExOleObject(CRecordsContainer* pExObject); void LoadAutoNumbering(CRecordGroupShapeContainer* pGroupContainer, CTheme* pTheme); void LoadBulletBlip(CShapeElement* pShape); diff --git a/MsBinaryFile/PptFile/Reader/Records.cpp b/MsBinaryFile/PptFile/Reader/Records.cpp index b8769b8018e..c8cf143fa57 100644 --- a/MsBinaryFile/PptFile/Reader/Records.cpp +++ b/MsBinaryFile/PptFile/Reader/Records.cpp @@ -624,8 +624,10 @@ IRecord* CreateByType(SRecordHeader oHeader, _commonInfo* commonInfo) //CREATE_BY_TYPE(RECORD_TYPE_METAFILE , CRecordMetafileBlob) CREATE_BY_TYPE(RT_CString, CRecordCString) CREATE_BY_TYPE(RT_SoundCollectionAtom, CRecordSoundCollAtom) + CREATE_BY_TYPE(RT_ExternalOleObjectAtom, CRecordExOleObjAtom) CREATE_BY_TYPE(RT_ExternalOleEmbedAtom, CRecordExOleEmbedAtom) + CREATE_BY_TYPE(RT_ExternalOleEmbed, CRecordExOleEmbedContainer) //CREATE_BY_TYPE(RECORD_TYPE_BOOKMARK_ENTITY_ATOM , CRecordBookmarkEntityAtom) //CREATE_BY_TYPE(RECORD_TYPE_EXLINK_ATOM , CRecordExOleLinkAtom) @@ -672,7 +674,6 @@ IRecord* CreateByType(SRecordHeader oHeader, _commonInfo* commonInfo) CREATE_BY_TYPE(RTE_CLIENTDATA, CRecordOfficeArtClientData) CREATE_BY_TYPE(RTE_CLIENTTEXTBOX, CRecordOfficeArtClientTextbox) - CREATE_BY_TYPE(RT_ExternalCdAudio, CRecordExCDAudioContainer) CREATE_BY_TYPE(RT_ExternalWavAudioLink, CRecordWAVAudioLinkContainer) CREATE_BY_TYPE(RT_ExternalWavAudioEmbedded, CRecordWAVAudioEmbeddedContainer) diff --git a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index 49caf34ca4c..ba8932f0f34 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp @@ -225,6 +225,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn } }break; case PPT::etPicture: + case PPT::etOleObject: { if (reset_default) { @@ -1645,10 +1646,10 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, if (CExFilesInfo::eftVideo == exType) { - CVideoElement* pVideoElem = new CVideoElement(); + CVideoElement* pVideoElem = new CVideoElement(); - pVideoElem->m_strVideoFileName = oInfo.m_strFilePath ; - pVideoElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; + pVideoElem->m_strVideoFileName = oInfo.m_strFilePath ; + pVideoElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; pElement = CElementPtr(pVideoElem); } @@ -1678,9 +1679,20 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, } } + else if (CExFilesInfo::eftOleObject == exType) + { + COleObjectElement* pOleObjectElem = new COleObjectElement(); + pOleObjectElem->m_strBinFileName = oInfo.m_strFilePath; + pOleObjectElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR; + + pOleObjectElem->m_strProgId = oInfo.m_progName; + pOleObjectElem->m_strOleName = oInfo.m_name; + + pElement = CElementPtr(pOleObjectElem); + } else { - CImageElement* pImageElem = new CImageElement(); + CImageElement* pImageElem = new CImageElement(); pImageElem->m_strImageFileName = oInfo.m_strFilePath + FILE_SEPARATOR_STR; pElement = CElementPtr(pImageElem); @@ -1782,7 +1794,7 @@ CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs, GetRecordsByType(&oArrayFooterMeta, true, true); if (0 < oArrayFooterMeta.size()) { - pElement->m_lPlaceholderType = PT_MasterFooter; + pElement->m_lPlaceholderType = PT_MasterFooter; pElement->m_lPlaceholderUserStr = oArrayFooterMeta[0]->m_nPosition; } std::vector oArraySlideNumberMeta; diff --git a/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp b/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp index a104ea3a112..cb00e755444 100644 --- a/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp +++ b/MsBinaryFile/PptFile/Records/ExObjListContainer.cpp @@ -37,3 +37,63 @@ void CRecordExObjListContainer::ReadFromStream(SRecordHeader &oHeader, POLE::Str { CRecordsContainer::ReadFromStream(oHeader, pStream); } + +CRecordExObjStg::CRecordExObjStg(const std::wstring& name, const std::wstring& tempPath) +{ + if (name.empty()) + { + m_sFileName = NSFile::CFileBinary::CreateTempFileWithUniqueName(tempPath, L"bin"); + } + else + { + m_sFileName = tempPath + FILE_SEPARATOR_STR + name; + } +} + +CRecordExObjStg::~CRecordExObjStg() +{ +} + +void CRecordExObjStg::ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) +{ + m_oHeader = oHeader; + + ULONG decompressedSize = m_oHeader.RecLen, compressedSize = m_oHeader.RecLen; + + BYTE* pData = new BYTE[compressedSize]; + if (!pData) return; + + if (m_oHeader.RecInstance == 0x01) + { + decompressedSize = StreamUtils::ReadDWORD(pStream) + 64; + compressedSize -= 4; + } + pStream->read(pData, compressedSize); + + //if (pDecryptor) + //{ + // pDecryptor->Decrypt((char*)pData, compressedSize, 0); + //} + + if (m_oHeader.RecInstance == 0x01) + { + BYTE* pDataUncompress = new BYTE[decompressedSize]; + NSZip::Decompress(pData, compressedSize, pDataUncompress, decompressedSize); + + delete[]pData; + pData = pDataUncompress; + } + + NSFile::CFileBinary file; + if (file.CreateFileW(m_sFileName)) + { + file.WriteFile(pData, decompressedSize); + file.CloseFile(); + } + else + { + m_sFileName.clear(); + } + delete[] pData; + pData = NULL; +} diff --git a/MsBinaryFile/PptFile/Records/ExObjListContainer.h b/MsBinaryFile/PptFile/Records/ExObjListContainer.h index c7194504d56..03ebd9bd366 100644 --- a/MsBinaryFile/PptFile/Records/ExObjListContainer.h +++ b/MsBinaryFile/PptFile/Records/ExObjListContainer.h @@ -39,4 +39,16 @@ class CRecordExObjListContainer : public CRecordsContainer public: virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; }; + + +class CRecordExObjStg : public CUnknownRecord +{ +public: + std::wstring m_sFileName; + + CRecordExObjStg(const std::wstring& name, const std::wstring& tempPath); + ~CRecordExObjStg(); + + virtual void ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) override; +}; } diff --git a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp index 5f84e0ab3ac..db9d45029c0 100644 --- a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp +++ b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.cpp @@ -43,3 +43,8 @@ void CRecordExOleEmbedAtom::ReadFromStream(SRecordHeader &oHeader, POLE::Stream m_nIsTable = StreamUtils::ReadBYTE(pStream); StreamUtils::StreamSkip(1, pStream); } + +void CRecordExOleEmbedContainer::ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) +{ + CRecordsContainer::ReadFromStream(oHeader, pStream); +} \ No newline at end of file diff --git a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h index 683e56c5905..ec5d5bcea8a 100644 --- a/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h +++ b/MsBinaryFile/PptFile/Records/ExOleEmbedAtom.h @@ -41,8 +41,12 @@ class CRecordExOleEmbedAtom : public CUnknownRecord BOOL1 m_nCantLockServer; BOOL1 m_nNoSizeToServer; BOOL1 m_nIsTable; - - virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; }; + +class CRecordExOleEmbedContainer : public CRecordsContainer +{ +public: + virtual void ReadFromStream(SRecordHeader& oHeader, POLE::Stream* pStream) override; +}; } diff --git a/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp b/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp index 28139b6b77c..31f73d3b401 100644 --- a/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp +++ b/MsBinaryFile/PptFile/Records/VBAInfoAtom.cpp @@ -61,53 +61,3 @@ void CRecordVBAInfoContainer::ReadFromStream(SRecordHeader &oHeader, POLE::Strea m_oHeader = oHeader; CRecordsContainer::ReadFromStream(oHeader, pStream); } - -CRecordVbaProjectStg::CRecordVbaProjectStg(std::wstring strTemp) : m_strTmpDirectory(strTemp) -{ -} - -CRecordVbaProjectStg::~CRecordVbaProjectStg() -{ -} - -void CRecordVbaProjectStg::ReadFromStream(SRecordHeader &oHeader, POLE::Stream *pStream) -{ - m_oHeader = oHeader; - - ULONG decompressedSize = m_oHeader.RecLen, compressedSize = m_oHeader.RecLen; - - BYTE* pData = new BYTE[compressedSize]; - if (!pData) return; - - if (m_oHeader.RecInstance == 0x01) - { - decompressedSize = StreamUtils::ReadDWORD(pStream) + 64; - compressedSize -= 4; - } - pStream->read(pData, compressedSize); - - //if (pDecryptor) - //{ - // pDecryptor->Decrypt((char*)pData, compressedSize, 0); - //} - - if (m_oHeader.RecInstance == 0x01) - { - BYTE* pDataUncompress = new BYTE[decompressedSize]; - NSZip::Decompress(pData, compressedSize, pDataUncompress, decompressedSize); - - delete []pData; - pData = pDataUncompress; - } - - m_sFileName = m_strTmpDirectory + FILE_SEPARATOR_STR + L"vbaProject.bin"; - - NSFile::CFileBinary file; - if (file.CreateFileW(m_sFileName)) - { - file.WriteFile(pData, decompressedSize); - file.CloseFile(); - } - delete[] pData; - pData = NULL; -} diff --git a/MsBinaryFile/PptFile/Records/VBAInfoAtom.h b/MsBinaryFile/PptFile/Records/VBAInfoAtom.h index 68c477b2d87..b71d2dea601 100644 --- a/MsBinaryFile/PptFile/Records/VBAInfoAtom.h +++ b/MsBinaryFile/PptFile/Records/VBAInfoAtom.h @@ -57,16 +57,4 @@ class CRecordVBAInfoContainer : public CRecordsContainer virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream); }; -class CRecordVbaProjectStg : public CUnknownRecord -{ -public: - std::wstring m_sFileName; - std::wstring m_strTmpDirectory; - - - CRecordVbaProjectStg(std::wstring strTemp); - ~CRecordVbaProjectStg(); - - virtual void ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream) override; -}; } From f3bdeacf7e4dcdb8b199fdc09924ead63fe5e7cb Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 20 Feb 2024 13:15:44 +0300 Subject: [PATCH 323/794] Fix bugs --- DocxRenderer/src/logic/Page.cpp | 14 +++++++++----- DocxRenderer/src/logic/elements/ContText.cpp | 12 +++++++----- DocxRenderer/src/logic/elements/ContText.h | 1 - DocxRenderer/src/logic/elements/TextLine.cpp | 8 ++++---- DocxRenderer/src/logic/elements/TextLine.h | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f3649be68ba..f1427dfa697 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -361,7 +361,8 @@ namespace NSDocxRenderer #ifndef USE_DEFAULT_FONT_TO_RECALC pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); pCont->m_oSelectedFont.Size = m_pFont->Size; - pCont->m_oSelectedFont.SetStyle(m_pFont->GetStyle2()); + pCont->m_oSelectedFont.Bold = m_pFontSelector->IsSelectedBold(); + pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic(); #else pCont->m_oSelectedFont.Path = m_pFont->Path; pCont->m_oSelectedFont.Size = m_pFont->Size; @@ -424,15 +425,15 @@ namespace NSDocxRenderer // merge conts in text lines BuildLines(); + // calc sizes on selected fonts for m_arConts + CalcSelected(); + // build paragraphs from m_arTextLines BuildParagraphes(); // merge shapes MergeShapes(); - // calc sizes on selected fonts for m_arConts - CalcSelected(); - ToXml(oWriter); WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); } @@ -1301,6 +1302,9 @@ namespace NSDocxRenderer auto right = MoveNullptr(m_arTextLines.begin(), m_arTextLines.end()); m_arTextLines.erase(right, m_arTextLines.end()); + if (m_arTextLines.empty()) + return; + using line_ptr_t = std::shared_ptr; std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { return a->m_dBaselinePos < b->m_dBaselinePos; @@ -1530,12 +1534,12 @@ namespace NSDocxRenderer std::shared_ptr pShape; pShape = std::make_shared(); - pShape->m_dHeight = pParagraph->m_dHeight; pShape->m_dLeft = pParagraph->m_dLeft; pShape->m_dTop = pParagraph->m_dTop; pShape->m_dRight = pParagraph->m_dRight; pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; + pShape->m_dHeight = pParagraph->m_dHeight; pShape->m_dWidth = pParagraph->m_dWidth * 1.03; // чтобы текст точно уместился pParagraph->m_dLeftBorder = 0; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 01af9cbd965..61e9e678bda 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -12,7 +12,6 @@ namespace NSDocxRenderer CSelectedSizes& CSelectedSizes::operator=(const CSelectedSizes& oSelectedSizes) { dWidth = oSelectedSizes.dWidth; - dSpaceWidth = oSelectedSizes.dSpaceWidth; dHeight = oSelectedSizes.dHeight; return *this; } @@ -76,6 +75,7 @@ namespace NSDocxRenderer void CContText::CalcSelected() { +#ifndef USE_DEFAULT_FONT_TO_RECALC if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { // нужно перемерять... @@ -91,9 +91,11 @@ namespace NSDocxRenderer m_oSelectedSizes.dWidth = dBoxWidth; m_oSelectedSizes.dHeight = dBoxHeight; - if(!m_oSelectedSizes.dSpaceWidth) - m_oSelectedSizes.dSpaceWidth = m_pManager->GetSpaceWidthMM(); } +#else + m_oSelectedSizes.dWidth = dBoxWidth; + m_oSelectedSizes.dHeight = dBoxHeight; +#endif // USE_DEFAULT_FONT_TO_RECALC } eVerticalCrossingType CContText::GetVerticalCrossingType(const CContText* pCont) const noexcept @@ -154,7 +156,7 @@ namespace NSDocxRenderer LONG lCalculatedSpacing = 0; - if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) + if (!m_oText.empty()) { double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length()); dSpacing *= c_dMMToDx; @@ -163,7 +165,7 @@ namespace NSDocxRenderer lCalculatedSpacing = static_cast(dSpacing); } - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу lCalculatedSpacing -= 1; if (lCalculatedSpacing != 0) diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 2464082fbe6..462c0b4308b 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -22,7 +22,6 @@ namespace NSDocxRenderer struct CSelectedSizes { double dWidth{0}; - double dSpaceWidth{0}; double dHeight{0}; CSelectedSizes() = default; diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index fee8e8d0539..a538dfecb2a 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -78,7 +78,7 @@ namespace NSDocxRenderer wide_space->CalcSelected(); }; - if(bIsEqual) + if (bIsEqual) { // assign all *wide_space = *pFirst; @@ -92,12 +92,12 @@ namespace NSDocxRenderer m_arConts.insert(m_arConts.begin() + i, wide_space); i++; - while(!m_arConts[i]) i++; + while (!m_arConts[i]) i++; pFirst = m_arConts[i]; } - else if(bIsEqual) + else if (bIsEqual) { - if(!bIsBigDelta) + if (!bIsBigDelta) { pFirst->m_oText += pCurrent->m_oText; } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 8021544608b..63fc1ebff5d 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -42,6 +42,7 @@ namespace NSDocxRenderer void MergeConts(); void RecalcSizes(); void SetVertAlignType(const eVertAlignType& oType); + bool IsShadingPresent(const CTextLine* pLine) const noexcept; bool IsCanBeDeleted() const; }; From 001768d0c6c0a439befb1dfc728d94bac3df622d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 20 Feb 2024 19:58:30 +0300 Subject: [PATCH 324/794] Try get by symbol --- PdfFile/SrcReader/PdfAnnot.cpp | 42 ++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 449505a31eb..2689ba19bcc 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2122,6 +2122,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : // 3 - Форматированный текст - RC std::string sRC = DictLookupString(&oAnnot, "RC", 3); + std::cout << sRC << std::endl; // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock XmlUtils::CXmlLiteReader oLightReader; @@ -2229,7 +2230,7 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana { Parser* parser = new Parser(xref, new Lexer(xref, &oN), gFalse); int nFont = 0; - std::string sPredFontName = m_arrRC[0]->sFontFamily, sPredKey; + std::string sExpectedFontName = m_arrRC[0]->sFontFamily, sPredKey; Object oObj1, oObj2, oObj3; parser->getObj(&oObj1); @@ -2257,11 +2258,42 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana if (!oObj1.isName(sPredKey.c_str())) { + sPredKey = oObj1.getName(); + + int nRead = 0; + oObj1.free(); oObj2.free(); oObj3.free(); + parser->getObj(&oObj1); + while (nRead < m_arrRC[nFont]->sText.length() && !oObj1.isEOF()) + { + if (oObj1.isString()) + { + parser->getObj(&oObj2); + if (oObj2.isEOF()) + { + oObj1.free(); + oObj2.copy(&oObj1); + oObj2.free(); + break; + } + if (oObj2.isCmd("Tj")) + nRead += oObj1.getString()->getLength(); + } + if (oObj2.isString()) + { + oObj1.free(); + oObj2.copy(&oObj1); + oObj2.free(); + continue; + } + parser->getObj(&oObj1); + } + oObj2.free(); + while (nFont < m_arrRC.size()) { if ((bool)((m_arrRC[nFont]->unFontFlags >> 0) & 1) == bBold && (bool)((m_arrRC[nFont]->unFontFlags >> 1) & 1) == bItalic && - m_arrRC[nFont]->sFontFamily == sPredFontName) + m_arrRC[nFont]->sFontFamily == sExpectedFontName) { m_arrRC[nFont]->sFontFamily = sFontName; if (!sActual.empty()) @@ -2272,12 +2304,14 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana } else { - sPredFontName = m_arrRC[nFont]->sFontFamily; + sExpectedFontName = m_arrRC[nFont]->sFontFamily; break; } nFont++; } - sPredKey = oObj1.getName(); + + oFontRef.free(); + continue; } } oFontRef.free(); From ef0e18e1c9f3920bea03efba0f5f12a52b62f3a3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 20 Feb 2024 23:24:20 +0600 Subject: [PATCH 325/794] Fix conditional formating refs conversion --- .../Logic/Biff_structures/CFParsedFormula.cpp | 2 +- .../Format/Logic/Biff_structures/PtgRefN.cpp | 1 + .../Worksheets/ConditionalFormatting.cpp | 15 ++++++++------- .../XlsxFormat/Worksheets/ConditionalFormatting.h | 5 +++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp index ec714649e16..c64c045e87d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp @@ -42,7 +42,7 @@ CFParsedFormula::CFParsedFormula(const CellRef& cell_base_ref) : ParsedFormula(c CFParsedFormula& CFParsedFormula::operator=(const std::wstring& value) { - ParsedFormula::operator = (value); + parseStringFormula(value, L"CFParsedFormulaNoCCE"); return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp index 1bf92087bd9..c673267f0e7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp @@ -48,6 +48,7 @@ PtgRefN::PtgRefN(const std::wstring& word, const PtgDataType data_type, const Ce cell_base_ref(cell_base_ref_init) { loc -= cell_base_ref; + loc_xlsb -= cell_base_ref; bUseLocInit = true; } diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index f8ea392135c..954ac25be5a 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1718,13 +1718,12 @@ void CConditionalFormattingRule::fromBin(XLS::BaseObjectPtr& obj) } } -XLS::BaseObjectPtr CConditionalFormattingRule::toBin() +XLS::BaseObjectPtr CConditionalFormattingRule::toBin(const XLS::CellRef &cellRef) { - XLS::CellRef cellRef; auto ptr(new XLSB::CFRULE(cellRef)); XLS::BaseObjectPtr objPtr(ptr); - ptr->m_BrtBeginCFRule = WriteAttributes(); + ptr->m_BrtBeginCFRule = WriteAttributes(cellRef); if(m_oColorScale.IsInit()) { @@ -1741,9 +1740,9 @@ XLS::BaseObjectPtr CConditionalFormattingRule::toBin() return objPtr; } -XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes() +XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellRef &cellRef) { - XLS::CellRef cellRef; + auto ptr(new XLSB::BeginCFRule(cellRef)); BaseObjectPtr objectPtr(ptr); @@ -2640,9 +2639,10 @@ XLS::BaseObjectPtr CConditionalFormatting::toBin() auto ptr(new XLSB::CONDITIONALFORMATTING); objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::CellRef formatingfirstCell; if(m_oSqRef.IsInit()) { - auto conditionPtr(new XLSB::BeginConditionalFormatting); + auto conditionPtr(new XLSB::BeginConditionalFormatting);// ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; conditionPtr->ccf = m_arrItems.size(); conditionPtr->sqrfx.strValue = m_oSqRef.get(); @@ -2650,11 +2650,12 @@ XLS::BaseObjectPtr CConditionalFormatting::toBin() conditionPtr->fPivot = m_oPivot->GetValue(); else conditionPtr->fPivot = false; + formatingfirstCell = conditionPtr->sqrfx.getLocationFirstCell(); } for(auto i: m_arrItems) { - ptr->m_arCFRULE.push_back(i->toBin()); + ptr->m_arCFRULE.push_back(i->toBin(formatingfirstCell)); } return objectPtr; diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h index acda290e53e..cb0ab73bc6d 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h @@ -33,6 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h" namespace SimpleTypes { @@ -299,7 +300,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin(const XLS::CellRef &cellRef); virtual EElementType getType () const; bool isValid () const; @@ -311,7 +312,7 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr WriteAttributes(); + XLS::BaseObjectPtr WriteAttributes(const XLS::CellRef &cellRef); public: From 3d2ebf31b35c1cede884eca8c5b3c46f5f55082e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 21 Feb 2024 14:32:01 +0600 Subject: [PATCH 326/794] Fix sheet protection conversion --- .../Worksheets/WorksheetChildOther.cpp | 94 +++++++++++++------ 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 499f3089335..c5dde243d34 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2664,72 +2664,72 @@ namespace OOX ptr->protpwd = 0; if (m_oAutoFilter.IsInit()) - ptr->fAutoFilter = m_oAutoFilter->GetValue(); + ptr->fAutoFilter = !m_oAutoFilter->GetValue(); else ptr->fAutoFilter = true; if (m_oDeleteColumns.IsInit()) - ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + ptr->fDeleteColumns = !m_oDeleteColumns->GetValue(); else ptr->fDeleteColumns= true; if (m_oDeleteRows.IsInit()) - ptr->fDeleteRows = m_oDeleteRows->GetValue(); + ptr->fDeleteRows = !m_oDeleteRows->GetValue(); else ptr->fDeleteRows = true; if (m_oFormatCells.IsInit()) - ptr->fFormatCells = m_oFormatCells->GetValue(); + ptr->fFormatCells = !m_oFormatCells->GetValue(); else ptr->fFormatCells = true; if (m_oFormatColumns.IsInit()) - ptr->fFormatColumns = m_oFormatColumns->GetValue(); + ptr->fFormatColumns = !m_oFormatColumns->GetValue(); else ptr->fFormatColumns = true; if (m_oFormatRows.IsInit()) - ptr->fFormatRows = m_oFormatRows->GetValue(); + ptr->fFormatRows = !m_oFormatRows->GetValue(); else ptr->fFormatRows = true; if (m_oInsertColumns.IsInit()) - ptr->fInsertColumns = m_oInsertColumns->GetValue(); + ptr->fInsertColumns = !m_oInsertColumns->GetValue(); else ptr->fInsertColumns = true; if (m_oInsertHyperlinks.IsInit()) - ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + ptr->fInsertHyperlinks = !m_oInsertHyperlinks->GetValue(); else ptr->fInsertHyperlinks = true; if (m_oInsertRows.IsInit()) - ptr->fInsertRows = m_oInsertRows->GetValue(); + ptr->fInsertRows = !m_oInsertRows->GetValue(); else ptr->fInsertRows = true; if (m_oObjects.IsInit()) - ptr->fObjects = m_oObjects->GetValue(); + ptr->fObjects = !m_oObjects->GetValue(); else ptr->fObjects = true; if (m_oPivotTables.IsInit()) - ptr->fPivotTables = m_oPivotTables->GetValue(); + ptr->fPivotTables = !m_oPivotTables->GetValue(); else ptr->fPivotTables = true; if (m_oScenarios.IsInit()) - ptr->fScenarios = m_oScenarios->GetValue(); + ptr->fScenarios = !m_oScenarios->GetValue(); else ptr->fScenarios = true; if (m_oSelectLockedCells.IsInit()) - ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + ptr->fSelLockedCells = !m_oSelectLockedCells->GetValue(); else ptr->fSelLockedCells = true; if (m_oSelectUnlockedCells.IsInit()) - ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + ptr->fSelUnlockedCells = !m_oSelectUnlockedCells->GetValue(); else ptr->fSelUnlockedCells = true; @@ -2739,7 +2739,7 @@ namespace OOX ptr->fLocked = false; if (m_oSort.IsInit()) - ptr->fSort = m_oSort->GetValue(); + ptr->fSort = !m_oSort->GetValue(); else ptr->fSort = true; @@ -2771,53 +2771,85 @@ namespace OOX ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; } - if(m_oAutoFilter.IsInit()) - ptr->fAutoFilter = m_oAutoFilter->GetValue(); + if (m_oAutoFilter.IsInit()) + ptr->fAutoFilter = !m_oAutoFilter->GetValue(); + else + ptr->fAutoFilter = true; if (m_oDeleteColumns.IsInit()) - ptr->fDeleteColumns = m_oDeleteColumns->GetValue(); + ptr->fDeleteColumns = !m_oDeleteColumns->GetValue(); + else + ptr->fDeleteColumns= true; if (m_oDeleteRows.IsInit()) - ptr->fDeleteRows = m_oDeleteRows->GetValue(); + ptr->fDeleteRows = !m_oDeleteRows->GetValue(); + else + ptr->fDeleteRows = true; if (m_oFormatCells.IsInit()) - ptr->fFormatCells = m_oFormatCells->GetValue(); + ptr->fFormatCells = !m_oFormatCells->GetValue(); + else + ptr->fFormatCells = true; if (m_oFormatColumns.IsInit()) - ptr->fFormatColumns = m_oFormatColumns->GetValue(); + ptr->fFormatColumns = !m_oFormatColumns->GetValue(); + else + ptr->fFormatColumns = true; if (m_oFormatRows.IsInit()) - ptr->fFormatRows = m_oFormatRows->GetValue(); + ptr->fFormatRows = !m_oFormatRows->GetValue(); + else + ptr->fFormatRows = true; if (m_oInsertColumns.IsInit()) - ptr->fInsertColumns = m_oInsertColumns->GetValue(); + ptr->fInsertColumns = !m_oInsertColumns->GetValue(); + else + ptr->fInsertColumns = true; if (m_oInsertHyperlinks.IsInit()) - ptr->fInsertHyperlinks = m_oInsertHyperlinks->GetValue(); + ptr->fInsertHyperlinks = !m_oInsertHyperlinks->GetValue(); + else + ptr->fInsertHyperlinks = true; if (m_oInsertRows.IsInit()) - ptr->fInsertRows = m_oInsertRows->GetValue(); + ptr->fInsertRows = !m_oInsertRows->GetValue(); + else + ptr->fInsertRows = true; if (m_oObjects.IsInit()) - ptr->fObjects = m_oObjects->GetValue(); + ptr->fObjects = !m_oObjects->GetValue(); + else + ptr->fObjects = true; if (m_oPivotTables.IsInit()) - ptr->fPivotTables = m_oPivotTables->GetValue(); + ptr->fPivotTables = !m_oPivotTables->GetValue(); + else + ptr->fPivotTables = true; if (m_oScenarios.IsInit()) - ptr->fScenarios = m_oScenarios->GetValue(); + ptr->fScenarios = !m_oScenarios->GetValue(); + else + ptr->fScenarios = true; if (m_oSelectLockedCells.IsInit()) - ptr->fSelLockedCells = m_oSelectLockedCells->GetValue(); + ptr->fSelLockedCells = !m_oSelectLockedCells->GetValue(); + else + ptr->fSelLockedCells = true; if (m_oSelectUnlockedCells.IsInit()) - ptr->fSelUnlockedCells = m_oSelectUnlockedCells->GetValue(); + ptr->fSelUnlockedCells = !m_oSelectUnlockedCells->GetValue(); + else + ptr->fSelUnlockedCells = true; if (m_oSheet.IsInit()) ptr->fLocked = m_oSheet->GetValue(); + else + ptr->fLocked = false; if (m_oSort.IsInit()) - ptr->fSort = m_oSort->GetValue(); + ptr->fSort = !m_oSort->GetValue(); + else + ptr->fSort = true; return castedPtr; } From e8c375c864124eb7cdf7f83bb33055f90a5ec784 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 21 Feb 2024 18:54:58 +0300 Subject: [PATCH 327/794] Add FontSelection to FreeText --- DesktopEditor/fontengine/ApplicationFonts.cpp | 311 ++++++++++++++++++ DesktopEditor/fontengine/ApplicationFonts.h | 1 + .../graphics/pro/js/wasm/src/drawingfile.cpp | 19 +- PdfFile/PdfReader.cpp | 4 +- PdfFile/PdfReader.h | 2 +- PdfFile/SrcReader/PdfAnnot.cpp | 120 ++++++- PdfFile/SrcReader/PdfAnnot.h | 19 +- PdfFile/SrcReader/RendererOutputDev.cpp | 24 +- PdfFile/SrcReader/RendererOutputDev.h | 12 +- 9 files changed, 464 insertions(+), 48 deletions(-) diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index d851460c9e0..6ee32aa0532 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.cpp +++ b/DesktopEditor/fontengine/ApplicationFonts.cpp @@ -1118,6 +1118,317 @@ std::vector CFontList::GetAllByName(const std::wstring& str return aRes; } +void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFlag, bool biBold, bool biItalic) +{ + if (!pStream) + return; + + FT_Library pLibrary = NULL; + if (FT_Init_FreeType(&pLibrary)) + return; + + FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); + pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); + pParams[0].data = NULL; + pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); + pParams[1].data = NULL; + pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; + pParams[2].data = NULL; + pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; + pParams[3].data = NULL; + + FT_Open_Args oOpenArgs; + oOpenArgs.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS; + oOpenArgs.memory_base = pStream->m_pData; + oOpenArgs.memory_size = pStream->m_lSize; + + oOpenArgs.num_params = 4; + oOpenArgs.params = pParams; + + FT_Face pFace = NULL; + if (FT_Open_Face( pLibrary, &oOpenArgs, 0, &pFace )) + return; + + // TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер + // произвольно) мы не грузим. Возможно в будущем надо будет + // сделать, чтобы работал и такой вариант. (в Word такие шрифты + // не используются) + if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) ) + { + FT_Done_Face( pFace ); + return; + } + + int nFacesCount = pFace->num_faces; + if ( FT_Done_Face( pFace ) ) + return; + + for ( int nIndexFace = 0; nIndexFace < nFacesCount; nIndexFace++ ) + { + if (FT_Open_Face( pLibrary, &oOpenArgs, nIndexFace, &pFace)) + continue; + + INT bBold = biBold ? 1 : (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); + INT bItalic = biItalic ? 1 : (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; + + const char* pPostName = FT_Get_Postscript_Name(pFace); + std::string sPostscriptName = ""; + if (NULL != pPostName) + sPostscriptName = FT_Get_Postscript_Name(pFace); + + INT bFixedWidth = FT_IS_FIXED_WIDTH( pFace ); + + TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 ); + + BYTE* pPanose = NULL; + ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0; + USHORT usWidth = 0, usWeight = 0, usType = 0; + SHORT sFamilyClass = 0; + + SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0; + if ( NULL != pOs2 ) + { + pPanose = (BYTE *)pOs2->panose; + + ulRange1 = pOs2->ulUnicodeRange1; + ulRange2 = pOs2->ulUnicodeRange2; + ulRange3 = pOs2->ulUnicodeRange3; + ulRange4 = pOs2->ulUnicodeRange4; + ulCodeRange1 = pOs2->ulCodePageRange1; + ulCodeRange2 = pOs2->ulCodePageRange2; + + usWeight = pOs2->usWeightClass; + usWidth = pOs2->usWidthClass; + + sFamilyClass = pOs2->sFamilyClass; + + usType = pOs2->fsType; + + if ( 0 != pFace->units_per_EM ) + { + double dKoef = ( 1000 / (double)pFace->units_per_EM ); + shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef); + shAscent = (SHORT)(pOs2->sTypoAscender * dKoef); + shDescent = (SHORT)(pOs2->sTypoDescender * dKoef); + shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef); + shXHeight = (SHORT)(pOs2->sxHeight * dKoef); + shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef); + } + else + { + shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth; + shAscent = (SHORT)pOs2->sTypoAscender; + shDescent = (SHORT)pOs2->sTypoDescender; + shLineGap = (SHORT)pOs2->sTypoLineGap; + shXHeight = (SHORT)pOs2->sxHeight; + shCapHeight = (SHORT)pOs2->sCapHeight; + } + } + + if ( true ) + { + // Специальная ветка для случаев, когда charset может быть задан не через значения + // ulCodePageRange, а непосредственно через тип Cmap. + + // Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description + // ------------------------------------------------------------------------------------------------- + // + // SYMBOL_CHARSET 2 (x02) 3 0 Symbol + // SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS + // GB2313_CHARSET 134 (x86) 936 3 3 PRC + // CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5 + // HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung + // JOHAB_CHARSET 130 (x82) 1361 3 6 Johab + + for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ ) + { + // Symbol + if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x80000000; + + // ShiftJIS + if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00020000; + + // PRC + if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00040000; + + // Big5 + if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00100000; + + // Wansung + if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00080000; + + // Johab + if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) + ulCodeRange1 |= 0x00200000; + } + } + + NSFonts::EFontFormat eFormat = GetFontFormat( pFace ); + + bool bSupportFont = ((eFormat == NSFonts::fontTrueType) || ((nFlag & 1) && (eFormat == NSFonts::fontOpenType))); + if (!bSupportFont) + { + FT_Done_Face( pFace ); + continue; + } + + std::wstring wsFamilyName = GetCorrectSfntName(pFace->family_name); + std::wstring wsStyleName = GetCorrectSfntName(pFace->style_name); + + bool isBadASCII = (std::wstring::npos != wsFamilyName.find('?')) ? true : false; + +#ifdef _MAC + if (wsFamilyName.find(L".") == 0) + { + FT_Done_Face( pFace ); + continue; + } +#endif + + NSFonts::CFontInfo* pFontInfo = new NSFonts::CFontInfo( wsFamilyName, + wsStyleName, + sFontPath, + nIndexFace, + bBold, + bItalic, + bFixedWidth, + pPanose, + ulRange1, + ulRange2, + ulRange3, + ulRange4, + ulCodeRange1, + ulCodeRange2, + usWeight, + usWidth, + sFamilyClass, + eFormat, + shAvgCharWidth, + shAscent, + shDescent, + shLineGap, + shXHeight, + shCapHeight, + usType); + + if (pFace && FT_IS_SFNT(pFace)) + { + TT_Face pTTFace = (TT_Face)pFace; + + int nNamesCount = (int)pTTFace->num_names; + TT_NameRec* pNameRecs = pTTFace->name_table.names; + + for (int nNameIndex = 0; nNameIndex < nNamesCount; ++nNameIndex) + { + TT_NameRec* rec = pNameRecs + nNameIndex; + + if (rec->nameID != TT_NAME_ID_FONT_FAMILY || rec->stringLength <= 0) + continue; + + std::string sEncoding = ""; + switch (rec->platformID) + { + case TT_PLATFORM_APPLE_UNICODE: + { + sEncoding = "UTF-16BE"; + break; + } + case TT_PLATFORM_MACINTOSH: + { + break; + } + case TT_PLATFORM_MICROSOFT: + { + switch (rec->encodingID) + { + case TT_MS_ID_SYMBOL_CS: + case TT_MS_ID_UNICODE_CS: + sEncoding = "UTF-16BE"; + break; + case TT_MS_ID_UCS_4: + //sEncoding = "UCS4"; // см tt_ + sEncoding = "UTF-16BE"; + break; + //case TT_MS_ID_SJIS: + // sEncoding = "Shift-JIS"; + // break; + //case TT_MS_ID_GB2312: + // sEncoding = "GB2312"; + // break; + //case TT_MS_ID_BIG_5: + // sEncoding = "Big5"; + // break; + default: + break; + } + } + default: + break; + } + + if (!sEncoding.empty()) + { + FT_Stream stream = pTTFace->name_table.stream; + FT_Memory memory = pFace->memory; + FT_Error error = 0; + + if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) + { + FT_FREE( rec->string ); + rec->stringLength = 0; + } + else + { + NSUnicodeConverter::CUnicodeConverter oConverter; + std::wstring sNameW = oConverter.toUnicode((char*)rec->string, (unsigned int)rec->stringLength, sEncoding.c_str()); + + if (std::wstring::npos == sNameW.find(wsFamilyName) && std::wstring::npos == wsFamilyName.find(sNameW)) + { + std::vector::iterator iter = pFontInfo->names.begin(); + for (std::vector::iterator iter = pFontInfo->names.begin(); iter != pFontInfo->names.end(); iter++) + { + if (*iter == sNameW) + break; + } + + if (isBadASCII && pFontInfo->names.empty()) + { + wsFamilyName = sNameW; + pFontInfo->m_wsFontName = wsFamilyName; + isBadASCII = false; + } + else if (iter == pFontInfo->names.end()) + { + pFontInfo->names.push_back(sNameW); + +#if 0 + FILE* f = fopen("D:\\111.txt", "a+"); + fprintf(f, "%s: %s\n", U_TO_UTF8(wsFamilyName).c_str(), U_TO_UTF8(sNameW).c_str()); + fclose(f); +#endif + } + } + } + } + } + } + + Add(pFontInfo); + + FT_Done_Face( pFace ); + } + + ::free( pParams ); + FT_Done_FreeType(pLibrary); +} + void CFontList::LoadFromArrayFiles(std::vector& oArray, int nFlag) { size_t nCount = oArray.size(); diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index ead47dac86a..fa51a276b9e 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.h +++ b/DesktopEditor/fontengine/ApplicationFonts.h @@ -316,6 +316,7 @@ class CFontList : public NSFonts::IFontList void LoadFromFolder (const std::wstring& strDirectory); bool CheckLoadFromFolderBin(const std::wstring& strDirectory); void CheckLoadFromSelectionBin(const std::wstring& strDirectory, BYTE* pData, DWORD len); + void Add (const std::wstring& sFontPath, CFontStream* pStream, int nFlag = 0, bool bBold = false, bool bItalic = false); void Add (NSFonts::CFontInfo* pInfo); NSFonts::CFontInfo* GetByParams (NSFonts::CFontSelectFormat& oSelect, bool bIsDictionaryUse = true); std::vector GetAllByName (const std::wstring& strFontName); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index ccb252acb2c..b56922f1353 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -211,10 +211,7 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) std::wstring sFontName = UTF8_TO_U(sPathA); std::wstring sFontFile = pGraphics->GetFont(sFontName); if (sFontFile.empty()) - return NULL; - - NSWasm::CData oRes; - oRes.SkipLen(); + sFontFile = sFontName; NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); if (pStorage) @@ -228,20 +225,24 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) if (pData) { + NSWasm::CData oRes; + oRes.SkipLen(); + oRes.AddInt(lLength); unsigned long long npSubMatrix = (unsigned long long)pData; unsigned int npSubMatrix1 = npSubMatrix & 0xFFFFFFFF; oRes.AddInt(npSubMatrix1); oRes.AddInt(npSubMatrix >> 32); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; } } } - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; + return NULL; } WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 02f97ec678a..7522262e015 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -68,7 +68,7 @@ CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) globalParams->setErrQuiet(gTrue); #endif - m_pFontList = new PdfReader::CFontList(); + m_pFontList = new PdfReader::CPdfFontList(); // Создаем менеджер шрифтов с собственным кэшем m_pFontManager = pAppFonts->GenerateFontManager(); @@ -1428,7 +1428,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oRes.ClearWithoutAttack(); return bRes; } -void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) +void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); if (!pPage) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 03a22536d08..70e04eff7b7 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -85,7 +85,7 @@ class CPdfReader PDFDoc* m_pPDFDocument; std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; - PdfReader::CFontList* m_pFontList; + PdfReader::CPdfFontList* m_pFontList; DWORD m_nFileLength; int m_eError; std::map m_mFonts; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 2689ba19bcc..7d9f7d8d35a 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -44,6 +44,7 @@ #include "../../DesktopEditor/common/Types.h" #include "../../DesktopEditor/common/StringExt.h" #include "../../DesktopEditor/xml/include/xmlutils.h" +#include "../../DesktopEditor/fontengine/ApplicationFonts.h" namespace PdfReader { @@ -1050,7 +1051,7 @@ bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oR, Object* oF return bFindResources; } -std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic) +std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic) { XRef* xref = pdfDoc->getXRef(); @@ -1133,7 +1134,7 @@ std::string CAnnotWidget::FieldLookupString(AcroFormField* pField, const char* s oObj.free(); return sRes; } -void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { // Шрифт и размер шрифта - из DA Ref fontID; @@ -1201,7 +1202,7 @@ void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFont if (bItalic) m_unFontStyle |= (1 << 1); } -void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { // Неполноценный шрифт во внешнем виде pushbutton Object oR, oFonts, oFontRef; @@ -1893,7 +1894,7 @@ CAnnotFileAttachment::~CAnnotFileAttachment() // Annots //------------------------------------------------------------------------ -CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -2214,7 +2215,7 @@ CAnnotMarkup::~CAnnotMarkup() for (int i = 0; i < m_arrRC.size(); ++i) RELEASEOBJECT(m_arrRC[i]); } -void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) { if (m_arrRC.empty()) return; @@ -2225,9 +2226,109 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana // Теперь для всех шрифтов необходимо извлечь файлы шрифтов из внешнего вида Object oAP, oN, oR, oFonts; - XRef* xref = pdfDoc->getXRef(); if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oN)->isStream() && oN.streamGetDict()->lookup("Resources", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) { + // 4.2 Доработка: Стандартные шрифты не попадают в подбор, для них необходима отдельная проверка + + // 4.1 Доработка: GetByParams обязательно подберет шрифт, поэтому список должен быть полным. + + // 4 УСПЕХ: Требуется проверка + // 4 ПЛАН: + // Реализовать добавление шрифта в CFontList + // Создать CFontList только из шрифтов в FreeText + // Сделать подбор по параметрам + CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); + + for (int i = 0; i < oFonts.dictGetLength(); ++i) + { + Object oFontRef; + if (oFonts.dictGetValNF(i, &oFontRef)->isRef()) + { + std::string sFontName, sActual; + bool bBold = false, bItalic = false; + std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, 3, sFontName, sActual, bBold, bItalic); + + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + if (!GetBaseFont(sFontPath, pData14, nSize14)) + { + CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); + pAppFontList->Add(sFontPath, pFontStream); + } + } + oFontRef.free(); + } + + for (int i = 0; i < m_arrRC.size(); ++i) + { + std::wstring wsFontName = UTF8_TO_U(m_arrRC[i]->sFontFamily); + bool bBold = (bool)((m_arrRC[i]->unFontFlags >> 0) & 1); + bool bItalic = (bool)((m_arrRC[i]->unFontFlags >> 1) & 1); + // Если стандартный шрифт + if (wsFontName == L"Courier" || wsFontName == L"Helvetica" || wsFontName == L"Symbol" || wsFontName == L"Times New Roman" || wsFontName == L"ZapfDingbats") + { + if (wsFontName == L"Times New Roman") + { + if (bBold && bItalic) + wsFontName = L"Times-BoldItalic"; + else if (bBold) + wsFontName = L"Times-Bold"; + else if (bItalic) + wsFontName = L"Times-Italic"; + else + wsFontName = L"Times-Roman"; + } + else if (wsFontName == L"Courier" || wsFontName == L"Helvetica") + { + if (bBold && bItalic) + wsFontName += L"-BoldOblique"; + else if (bBold) + wsFontName += L"-Bold"; + else if (bItalic) + wsFontName += L"-Oblique"; + } + + if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName)) + { + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + if (GetBaseFont(wsFontName, pData14, nSize14)) + { + NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); + m_arrRC[i]->sFontFamily = U_TO_UTF8(wsFontName); + } + } + } + else + { + NSFonts::CFontSelectFormat oFontSelect; + if (bBold) + oFontSelect.bBold = new INT(1); + if (bItalic) + oFontSelect.bItalic = new INT(1); + oFontSelect.wsName = new std::wstring(wsFontName); + + NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); + if (pFontInfo) + { + // Если шрифт из FreeText + // Иначе шрифт из подбора + } + } + } + + // 3 ПРОВАЛ: PdfReader::CFontList - это не CFontList из ApplicationFonts, т.е. сделать подбор на PdfReader::CFontList не получится + // 3 ПЛАН: + // Загрузить все шрифты FreeText в pFontList + // На pFontList сделать подбор по параметрам + // Если подобранный шрифт неполный или не подобрался, то + // На pFontManager сделать подбор по параметрам + + // 2 ПРОВАЛ: Встречаются составные глифы из 2, 4 бит, из-за чего количество символов разительно отличается + // 2 ПЛАН: Дополнительное сопоставление по количеству символов чтобы проскочить места путаницы со шрифтами. + // 1 ПРОВАЛ: Во внешнем виде используются больше шрифтов, и они не соответствуют RC + // 1 ПЛАН: Последовательное сопоставление шрифта и имени шрифта + /* Parser* parser = new Parser(xref, new Lexer(xref, &oN), gFalse); int nFont = 0; std::string sExpectedFontName = m_arrRC[0]->sFontFamily, sPredKey; @@ -2338,6 +2439,7 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana oObj1.free(); oObj2.free(); oObj3.free(); RELEASEOBJECT(parser); + */ } oAP.free(); oN.free(); oR.free(); oFonts.free(); @@ -2762,7 +2864,7 @@ CAnnot::CBorderType* CAnnot::getBorder(Object* oBorder, bool bBSorBorder) // AP //------------------------------------------------------------------------ -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField) { m_gfx = NULL; m_pFrame = NULL; @@ -2780,7 +2882,7 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLis Clear(); } -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef) { m_gfx = NULL; m_pFrame = NULL; @@ -2818,7 +2920,7 @@ void CAnnotAP::Clear() RELEASEOBJECT(m_pRendererOut); RELEASEOBJECT(m_pRenderer); } -void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) +void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index d9f99180ea1..f6962139b30 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -117,8 +117,8 @@ struct CActionResetForm final : public CAction class CAnnotAP final { public: - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField); - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef); ~CAnnotAP(); void ToWASM(NSWasm::CData& oRes); @@ -134,7 +134,7 @@ class CAnnotAP final void WriteAppearance(unsigned int nColor, CAnnotAPView* pView); BYTE GetBlendMode(); - void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); + void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); void Init(AcroFormField* pField); void Init(Object* oAnnot); void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, int nPageIndex, AcroFormField* pField, const char* sView, const char* sButtonView); @@ -210,15 +210,15 @@ class CAnnot //------------------------------------------------------------------------ bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oR, Object* oFonts, Object* oFontRef, std::string& sFontKey); -std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic); +std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic); class CAnnotWidget : public CAnnot { public: virtual ~CAnnotWidget(); - void SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList); - void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList); + void SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); protected: CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField); @@ -327,7 +327,7 @@ class CAnnotPopup final : public CAnnot class CAnnotMarkup : public CAnnot { public: - void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CFontList *pFontList); + void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); protected: CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); virtual ~CAnnotMarkup(); @@ -337,6 +337,7 @@ class CAnnotMarkup : public CAnnot private: struct CFontData final { + bool bFind; BYTE nAlign; unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 зачеркнутый, 4 подчеркнутый, 5 vertical-align, 6 actual font double dFontSise; @@ -346,7 +347,7 @@ class CAnnotMarkup : public CAnnot std::string sActualFont; std::string sText; - CFontData() : nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {} + CFontData() : bFind(false), nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {} CFontData(const CFontData& oFont); }; void ReadFontData(const std::string& sData, CFontData* pFont); @@ -569,7 +570,7 @@ class CAnnotFileAttachment final : public CAnnotMarkup class CAnnots { public: - CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index e9943ad7bd8..95f4ea3489c 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -264,17 +264,17 @@ namespace PdfReader //-------------------------------------------------------------------------------------- // CFontList //-------------------------------------------------------------------------------------- - CFontList::CFontList() + CPdfFontList::CPdfFontList() { m_oCS.InitializeCriticalSection(); m_oFontMap.clear(); } - CFontList::~CFontList() + CPdfFontList::~CPdfFontList() { m_oCS.DeleteCriticalSection(); Clear(); } - void CFontList::LoadFromFile(std::wstring wsDirPath) + void CPdfFontList::LoadFromFile(std::wstring wsDirPath) { return; //Clear(); @@ -365,7 +365,7 @@ namespace PdfReader // } //} } - void CFontList::SaveToFile(std::wstring wsDirPath) + void CPdfFontList::SaveToFile(std::wstring wsDirPath) { return; //CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") ); @@ -422,7 +422,7 @@ namespace PdfReader //oWriter.SaveToFile( wsFilePath ); } - bool CFontList::Find(Ref oRef, TFontEntry *pEntry) + bool CPdfFontList::Find(Ref oRef, TFontEntry *pEntry) { CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -439,7 +439,7 @@ namespace PdfReader return bResult; } - bool CFontList::Find2(Ref oRef, TFontEntry **ppEntry) + bool CPdfFontList::Find2(Ref oRef, TFontEntry **ppEntry) { CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -462,7 +462,7 @@ namespace PdfReader return bResult; } - TFontEntry* CFontList::Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode) + TFontEntry* CPdfFontList::Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode) { // Данная функция приходит только из Find2, поэтому проверять есть ли данный шрифт уже не надо CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -482,7 +482,7 @@ namespace PdfReader return pNewEntry; } - void CFontList::Remove(Ref oRef) + void CPdfFontList::Remove(Ref oRef) { CRefFontMap::iterator oPos = m_oFontMap.find(oRef); if (m_oFontMap.end() != oPos) @@ -497,7 +497,7 @@ namespace PdfReader m_oFontMap.erase(oPos); } } - void CFontList::Clear() + void CPdfFontList::Clear() { for (auto const &oIt : m_oFontMap) { @@ -511,7 +511,7 @@ namespace PdfReader } m_oFontMap.clear(); } - bool CFontList::GetFont(Ref *pRef, TFontEntry *pEntry) + bool CPdfFontList::GetFont(Ref *pRef, TFontEntry *pEntry) { TFontEntry* pFindEntry = Lookup(*pRef); if (NULL == pFindEntry) @@ -523,7 +523,7 @@ namespace PdfReader //-------------------------------------------------------------------------------------- // RendererOutputDev //-------------------------------------------------------------------------------------- - RendererOutputDev::RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList) + RendererOutputDev::RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { m_pFontManager = pFontManager; m_pFontManager = pFontManager; @@ -1003,7 +1003,7 @@ namespace PdfReader pFontInfo = pFontManager->GetFontInfoByParams(oFontSelect); return pFontInfo; } - void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName) + void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName) { wsFileName = L""; wsFontName = L""; diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index 263a1aaa0de..b41544b757d 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -65,12 +65,12 @@ namespace PdfReader }; - class CFontList + class CPdfFontList { public: - CFontList(); - ~CFontList(); + CPdfFontList(); + ~CPdfFontList(); void LoadFromFile(std::wstring wsDirPath); void SaveToFile(std::wstring wsDirPath); bool Find(Ref oRef, TFontEntry *pEntry); @@ -103,7 +103,7 @@ namespace PdfReader }; NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName); - void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); + void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic); //------------------------------------------------------------------------------------------------------------------------------- template @@ -123,7 +123,7 @@ namespace PdfReader class RendererOutputDev : public OutputDev { public: - RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList = NULL); + RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList = NULL); virtual ~RendererOutputDev(); virtual GBool upsideDown() @@ -314,7 +314,7 @@ namespace PdfReader //GfxTextClip *m_pBufferTextClip; XRef *m_pXref; // Таблица Xref для данного PDF-документа - CFontList *m_pFontList; + CPdfFontList *m_pFontList; bool *m_pbBreak; // Внешняя остановка рендерера From c1f1c3a68301600a74da1707b1a7b022d1e25581 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 21 Feb 2024 20:45:07 +0300 Subject: [PATCH 328/794] add support oleObjects from Word 2003 XML --- .../Document/DocWrapper/DocxSerializer.cpp | 10 +- .../Document/DocWrapper/DocxSerializer.h | 2 +- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 45 ++-- OOXML/Common/SimpleTypes_Vml.cpp | 6 +- OOXML/DocxFormat/CustomXml.cpp | 2 +- OOXML/DocxFormat/Document.cpp | 36 ++- OOXML/DocxFormat/Document.h | 23 +- OOXML/DocxFormat/DocxFlat.cpp | 115 +++++++-- OOXML/DocxFormat/DocxFlat.h | 8 +- OOXML/DocxFormat/FileTypes.cpp | 14 +- OOXML/DocxFormat/Logic/Pict.cpp | 235 +++++++++++------- OOXML/DocxFormat/Logic/Pict.h | 2 +- OOXML/DocxFormat/Logic/Vml.cpp | 10 +- OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp | 38 ++- OOXML/DocxFormat/WritingElement.h | 2 + OdfFile/Writer/Converter/ConvertDrawing.cpp | 3 +- OdfFile/Writer/Converter/XlsxConverter.cpp | 6 +- X2tConverter/src/ASCConverters.cpp | 9 +- X2tConverter/src/cextracttools.h | 1 - X2tConverter/src/lib/docx.h | 6 +- 20 files changed, 401 insertions(+), 172 deletions(-) diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index 0f48a2e1e74..b4d887a3e65 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp @@ -623,9 +623,12 @@ bool BinDocxRW::CDocxSerializer::unpackageFile(const std::wstring& sSrcFileName, return file.unpackage(sSrcFileName, sDstPath); } -bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath) +bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath, bool &bMacro, const std::wstring& sTempPath) { - OOX::CDocxFlat docxflat(sSrcFileName); + OOX::CDocxFlat docxflat; + + docxflat.m_sTempPath = sTempPath; + docxflat.read(sSrcFileName); if (false == docxflat.m_pDocument.IsInit()) return false; @@ -637,6 +640,8 @@ bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, c NSCommon::smart_ptr file = docxflat.m_pDocument.GetPointer(); file.AddRef(); docx.Add(file); docx.m_oMain.document = docxflat.m_pDocument.GetPointer(); + + bMacro = bMacro && docxflat.m_pDocument->m_bMacroEnabled; } if (docxflat.m_pApp.IsInit()) { @@ -648,6 +653,7 @@ bool BinDocxRW::CDocxSerializer::convertFlat(const std::wstring& sSrcFileName, c NSCommon::smart_ptr file(docxflat.m_pCore.GetPointer()); file.AddRef(); docx.Add(file); } + //docxflat.m_oBgPict.GetPointer(); return docx.Write(sDstPath); diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h index 9f0223cec62..57d7935976c 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h @@ -67,7 +67,7 @@ namespace BinDocxRW bool saveToFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sTempPath); bool unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath); - bool convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath); + bool convertFlat(const std::wstring& sSrcFileName, const std::wstring& sDstPath, bool& bMacro, const std::wstring& sTempPath); bool CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath); diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index bbbb71ad285..c8573981b29 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -3031,8 +3031,11 @@ void BinaryWorkbookTableWriter::WriteExternalReferences(const OOX::Spreadsheet:: smart_ptr pFile = pExternalLink->Find(OOX::RId(pExternalLink->m_oOleLink->m_oRid.get().GetValue())); if (pFile.IsInit() && OOX::FileTypes::OleObject == pFile->type()) { - OOX::OleObject* pLinkFile = static_cast(pFile.operator ->()); - sLink = pLinkFile->filename().GetPath(); + smart_ptr pLinkFile = pFile.smart_dynamic_cast(); + if (pLinkFile.IsInit()) + { + sLink = pLinkFile->filename().GetPath(); + } } } if (!sLink.empty()) @@ -4573,18 +4576,21 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet smart_ptr pFile = oWorksheet.Find(oWorksheet.m_oPicture->m_oId->GetValue()); if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - OOX::CPath pathImage = pImageFileCache->filename(); - std::wstring additionalPath; - int additionalType = 0; - double dX = -1.0; //mm - double dY = -1.0; - double dW = -1.0; //mm - double dH = -1.0; - NSShapeImageGen::CMediaInfo oId = m_pOfficeDrawingConverter->m_pBinaryWriter->m_pCommon->m_pMediaManager->WriteImage(pathImage.GetPath(), dX, dY, dW, dH, additionalPath, additionalType); - nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Picture); - m_oBcw.m_oStream.WriteStringW3(oId.GetPath2()); - m_oBcw.WriteItemEnd(nCurPos); + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); + if (pImageFileCache.IsInit()) + { + OOX::CPath pathImage = pImageFileCache->filename(); + std::wstring additionalPath; + int additionalType = 0; + double dX = -1.0; //mm + double dY = -1.0; + double dW = -1.0; //mm + double dH = -1.0; + NSShapeImageGen::CMediaInfo oId = m_pOfficeDrawingConverter->m_pBinaryWriter->m_pCommon->m_pMediaManager->WriteImage(pathImage.GetPath(), dX, dY, dW, dH, additionalPath, additionalType); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Picture); + m_oBcw.m_oStream.WriteStringW3(oId.GetPath2()); + m_oBcw.WriteItemEnd(nCurPos); + } } } if (oWorksheet.m_oSortState.IsInit()) @@ -5823,7 +5829,8 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh olePic->blipFill.blip->oleFilepathBin = olePic->oleObject->m_OleObjectFile->filename().GetPath(); } - OOX::Image* pImageFileCache = NULL; + smart_ptr pImageFileCache; + std::wstring sIdImageFileCache; if ((NULL != pShapeElem) && (OOX::et_v_shapetype != pShapeElem->getType())) { @@ -5854,23 +5861,23 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast(); } } } } } - if (pImageFileCache == NULL && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) + if (pImageFileCache.IsInit() && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) { sIdImageFileCache = pOleObject->m_oObjectPr->m_oRid->GetValue(); smart_ptr pFile = oWorksheet.Find(sIdImageFileCache); if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast(); } } - if (pImageFileCache) + if (pImageFileCache.IsInit()) { OOX::CPath pathImage = pImageFileCache->filename(); diff --git a/OOXML/Common/SimpleTypes_Vml.cpp b/OOXML/Common/SimpleTypes_Vml.cpp index 7c530164e81..a88d23fd14e 100644 --- a/OOXML/Common/SimpleTypes_Vml.cpp +++ b/OOXML/Common/SimpleTypes_Vml.cpp @@ -1224,9 +1224,9 @@ namespace SimpleTypes { switch (this->m_eValue) { - case oletypeEmbed : return L"embed"; - case oletypeLink : return L"link"; - default : return L"embed"; + case oletypeEmbed : return L"Embed"; + case oletypeLink : return L"Link"; + default : return L"Embed"; } } diff --git a/OOXML/DocxFormat/CustomXml.cpp b/OOXML/DocxFormat/CustomXml.cpp index 49f96d5e5ca..0abb012daf1 100644 --- a/OOXML/DocxFormat/CustomXml.cpp +++ b/OOXML/DocxFormat/CustomXml.cpp @@ -155,7 +155,7 @@ namespace OOX CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain) : OOX::FileGlobalEnumerated(pMain) { } - CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain, const OOX::CPath& oFilePath): OOX::FileGlobalEnumerated(pMain) + CCustomXMLProps::CCustomXMLProps(OOX::Document *pMain, const OOX::CPath& oFilePath) : OOX::FileGlobalEnumerated(pMain) { read( oFilePath ); } diff --git a/OOXML/DocxFormat/Document.cpp b/OOXML/DocxFormat/Document.cpp index 588a809522a..d887148c67e 100644 --- a/OOXML/DocxFormat/Document.cpp +++ b/OOXML/DocxFormat/Document.cpp @@ -144,7 +144,42 @@ namespace OOX WritingElement_ReadAttributes_Read_else_if(oReader, L"w:themeTint", m_oThemeTint) WritingElement_ReadAttributes_End(oReader) } +//------------------------------------------------------------------------------------------------------------------------------------------------ + CDocSuppData::CDocSuppData(OOX::Document* pMain) : WritingElement(pMain) + { + } + CDocSuppData::~CDocSuppData() + { + } + void CDocSuppData::fromXML(XmlUtils::CXmlNode& oNode) + { + } + std::wstring CDocSuppData::toXML() const + { + return L""; + } + EElementType CDocSuppData::getType() const + { + return et_w_docSuppData; + } + void CDocSuppData::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + if (L"binData" == sName) + m_oBinData = oReader; + } + } + void CDocSuppData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + } +//------------------------------------------------------------------------------------------------------------------------------------------------ CBgPict::CBgPict(OOX::Document *pMain) : WritingElement(pMain) { } @@ -401,7 +436,6 @@ namespace OOX pItem->fromXML(oReader); m_arrItems.push_back(pItem); } - if ( pItem ) { pItem->fromXML(oReader); diff --git a/OOXML/DocxFormat/Document.h b/OOXML/DocxFormat/Document.h index 206ac8e45ed..bc804c04c59 100644 --- a/OOXML/DocxFormat/Document.h +++ b/OOXML/DocxFormat/Document.h @@ -80,10 +80,28 @@ namespace OOX nullable m_oDrawing; nullable m_oBackground; }; + + class CDocSuppData : public WritingElement + {//Word 2003 XML Reference + public: + WritingElement_AdditionMethods(CDocSuppData) + CDocSuppData(OOX::Document* pMain = NULL); + virtual ~CDocSuppData(); + + virtual void fromXML(XmlUtils::CXmlNode& oNode); + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual std::wstring toXML() const; + virtual EElementType getType() const; - //Word 2003 XML Reference + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable m_oBinData; + }; class CBgPict : public WritingElement - { + {//Word 2003 XML Reference public: WritingElement_AdditionMethods(CBgPict) CBgPict(OOX::Document *pMain = NULL); @@ -104,7 +122,6 @@ namespace OOX nullable_string m_oBackgroundType; nullable m_oBackground; }; - } //-------------------------------------------------------------------------------- diff --git a/OOXML/DocxFormat/DocxFlat.cpp b/OOXML/DocxFormat/DocxFlat.cpp index 75037c6a832..f83f95cca97 100644 --- a/OOXML/DocxFormat/DocxFlat.cpp +++ b/OOXML/DocxFormat/DocxFlat.cpp @@ -46,6 +46,8 @@ #include "Settings/Settings.h" #include "Logic/SectionProperty.h" +#include "../../OfficeUtils/src/OfficeUtils.h" + namespace OOX { CDocxFlat::CDocxFlat() : File(dynamic_cast(this)) @@ -53,19 +55,21 @@ namespace OOX } CDocxFlat::CDocxFlat(const CPath& oFilePath) : File(dynamic_cast(this)) { - read( oFilePath ); + read(oFilePath); } CDocxFlat::~CDocxFlat() { } void CDocxFlat::read(const CPath& oFilePath) { + m_sDocumentPath = oFilePath.GetPath(); + XmlUtils::CXmlLiteReader oReader; - if ( !oReader.FromFile( oFilePath.GetPath() ) ) + if (!oReader.FromFile(oFilePath.GetPath())) return; - if ( !oReader.ReadNextNode() ) + if (!oReader.ReadNextNode()) return; fromXML(oReader); @@ -96,15 +100,15 @@ namespace OOX } void CDocxFlat::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, L"xml:space", m_oSpace ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"xml:space", m_oSpace) + WritingElement_ReadAttributes_End(oReader) } void CDocxFlat::fromXML(XmlUtils::CXmlLiteReader& oReader) { - ReadAttributes( oReader ); + ReadAttributes(oReader); - if ( oReader.IsEmptyNode() ) + if (oReader.IsEmptyNode()) return; m_pComments = new OOX::CComments(this); @@ -112,24 +116,25 @@ namespace OOX m_pEndnotes = new OOX::CEndnotes(this); int nDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode(nDepth) ) + while (oReader.ReadNextSiblingNode(nDepth)) { std::wstring sName = oReader.GetName(); - if ( L"w:body" == sName ) + if (L"w:body" == sName) { m_pDocument = new CDocument(dynamic_cast(this)); m_currentContainer = dynamic_cast(m_pDocument.GetPointer()); m_pDocument->fromXML(oReader); + m_pDocument->m_bMacroEnabled = false; } - else if ( L"w:fonts" == sName ) + else if (L"w:fonts" == sName) m_pFontTable = oReader; else if (L"w:lists" == sName) { m_pNumbering = new CNumbering(dynamic_cast(this)); m_pNumbering->fromXML(oReader); } - else if ( L"w:styles" == sName ) + else if (L"w:styles" == sName) m_pStyles = oReader; else if (L"w:docPr" == sName) { @@ -145,8 +150,26 @@ namespace OOX { ReadDocumentProperties(oReader); } + else if (L"w:docOleData" == sName && !oReader.IsEmptyNode()) + { + m_oDocOleData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); + m_oDocOleData->fromXML(oReader); + + ParsingOleData(); + } + else if (L"w:docSuppData" == sName && !oReader.IsEmptyNode()) + { + m_oDocSuppData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); + m_oDocSuppData->fromXML(oReader); + + ParsingSuppData(); + } } + if ((m_oDocSuppData.IsInit()) && (m_oDocSuppData->m_oBinData.IsInit()) && (m_pDocument.IsInit())) + { + m_pDocument->m_bMacroEnabled = true; + } if (false == m_pStyles->m_oDocDefaults.IsInit()) m_pStyles->m_oDocDefaults.Init(); @@ -211,7 +234,7 @@ namespace OOX { if (oReader.IsEmptyNode()) return; - + m_pApp = new OOX::CApp(this); m_pCore = new OOX::CCore(this); @@ -296,7 +319,7 @@ namespace OOX m_pApp->m_nWords = oReader.GetText2(); } } - OOX::CHdrFtr *CDocxFlat::GetHeaderOrFooter(const OOX::RId& rId) const + OOX::CHdrFtr* CDocxFlat::GetHeaderOrFooter(const OOX::RId& rId) const { OOX::IFileContainer* pDocumentContainer = (OOX::IFileContainer*)m_pDocument.GetPointer(); @@ -307,4 +330,68 @@ namespace OOX return NULL; } + void CDocxFlat::ParsingOleData() + { + if (false == m_oDocOleData.IsInit()) return; + if (false == m_oDocOleData->m_oBinData.IsInit()) return; + + std::vector pData = m_oDocOleData->m_oBinData->GetBytes(); + + NSFile::CFileBinary fileTest; + + std::wstring tempOleData = m_sTempPath + FILE_SEPARATOR_STR + L"DocOleData.bin"; + + if (false == fileTest.CreateFileW(tempOleData)) return; + + fileTest.WriteFile(pData.data(), pData.size()); + fileTest.CloseFile(); + + POLE::Storage storage(tempOleData.c_str()); + if (false == storage.open()) return; + + std::list msoStores = storage.entries(); + + int index = 0; + for (std::list::iterator it = msoStores.begin(); it != msoStores.end(); ++it) + { + POLE::Stream stream(&storage, *it); + if (stream.fail()) continue; + + smart_ptr pOleObjectFile = smart_ptr(new OOX::OleObject(this, false, true)); + OOX::CPath filename(L"oleObject.bin"); + pOleObjectFile->set_filename(filename, false, true); + + pOleObjectFile->m_Data.resize(stream.size()); + _UINT64 size = stream.read(pOleObjectFile->m_Data.data(), stream.size()); + pOleObjectFile->m_Data.resize(size); + + COfficeUtils oCOfficeUtils(NULL); + if (oCOfficeUtils.IsArchive(pOleObjectFile->m_Data.data(), pOleObjectFile->m_Data.size())) + {//gzip + ULONG nBytesUncompress = (std::max)((_UINT32)pOleObjectFile->m_Data.size() * 10, ((_UINT32*)pOleObjectFile->m_Data.data())[0]); + BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + + if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, pOleObjectFile->m_Data.data() + 4, pOleObjectFile->m_Data.size() - 4)) + { + pOleObjectFile->m_Data.resize(nBytesUncompress); + memcpy(pOleObjectFile->m_Data.data(), pDataUncompress, nBytesUncompress); + delete[]pDataUncompress; + } + } + + NSCommon::smart_ptr file = pOleObjectFile.smart_dynamic_cast(); + m_mapOleData[*it] = file; + } + + } + void CDocxFlat::ParsingSuppData() + { + if (false == m_oDocSuppData.IsInit()) return; + if (false == m_oDocSuppData->m_oBinData.IsInit()) return; + + std::vector pData = m_oDocSuppData->m_oBinData->GetBytes(); + //COfficeUtils oCOfficeUtils(NULL); + + + } } diff --git a/OOXML/DocxFormat/DocxFlat.h b/OOXML/DocxFormat/DocxFlat.h index aaa04e5bc73..410509b289a 100644 --- a/OOXML/DocxFormat/DocxFlat.h +++ b/OOXML/DocxFormat/DocxFlat.h @@ -52,12 +52,12 @@ namespace OOX namespace Logic { class CBgPict; + class CDocSuppData; } class CDocxFlat : public Document, public File, public WritingElement { public: - CDocxFlat(); CDocxFlat(const CPath& oFilePath); virtual ~CDocxFlat(); @@ -89,6 +89,8 @@ namespace OOX nullable m_pNumbering; nullable m_pSettings; nullable m_pBgPict; + nullable m_oDocSuppData; + nullable m_oDocOleData; nullable m_pComments; nullable m_pFootnotes; @@ -97,8 +99,12 @@ namespace OOX nullable m_pCore; //----------------------------------------------------------- std::map> m_mapImages; + std::map> m_mapOleData; OOX::IFileContainer *m_currentContainer = NULL; + private: + void ParsingOleData(); + void ParsingSuppData(); }; diff --git a/OOXML/DocxFormat/FileTypes.cpp b/OOXML/DocxFormat/FileTypes.cpp index 6edef1f6614..103b3fc628b 100644 --- a/OOXML/DocxFormat/FileTypes.cpp +++ b/OOXML/DocxFormat/FileTypes.cpp @@ -167,23 +167,23 @@ namespace OOX const FileType Image (L"media", L"image", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true, true); const FileType Audio (L"media", L"audio", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", L"audio", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", L"audio", true, true); const FileType Video (L"media", L"video", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", L"video", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", L"video", true, true); const FileType Media (L"media", L"media", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media", L"media", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media", L"media", true, true); const FileType SvgBlip (L"media", L"image", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", L"image", true, true); const FileType DiagramData (L"diagrams", L"data.xml", @@ -279,7 +279,7 @@ namespace OOX const FileType MicrosoftOfficeUnknown(L"embeddings", L"", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package", L"embeddings/package", true, true); const FileType MicrosoftOfficeExcelWorksheet(L"embeddings", L"Microsoft_Office_Excel_Worksheet.xlsx", L"", @@ -346,7 +346,7 @@ namespace OOX const FileType OleObject (L"embeddings", L"oleObject.bin", L"", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"); + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject", L"embeddings/oleObject", true, true); const FileType VmlDrawing (L"drawings", L"vmlDrawing.vml", L"application/vnd.openxmlformats-officedocument.vmlDrawing", diff --git a/OOXML/DocxFormat/Logic/Pict.cpp b/OOXML/DocxFormat/Logic/Pict.cpp index 6280d493623..11368b18811 100644 --- a/OOXML/DocxFormat/Logic/Pict.cpp +++ b/OOXML/DocxFormat/Logic/Pict.cpp @@ -37,6 +37,7 @@ //#include "Vml.h" #include "VmlOfficeDrawing.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" #include "../../../OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" @@ -104,6 +105,31 @@ namespace OOX oReader.MoveToElement(); } + std::vector CBinData::GetBytes() + { + std::vector result; + if (!m_sData.IsInit()) return result; + + int dstLen = Base64::Base64DecodeGetRequiredLength((int)m_sData->size()); + result.resize(dstLen); + Base64::Base64Decode(m_sData->c_str(), (int)m_sData->size(), result.data(), &dstLen); + result.resize(dstLen); + + //COfficeUtils oCOfficeUtils(NULL); + //if (oCOfficeUtils.IsArchive(result.data(), result.size())) + //{//gzip + // ULONG nBytesUncompress = result.size() * 10; + // BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + // if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, result.data(), result.size())) + // { + // result.resize(nBytesUncompress); + // memcpy(result.data(), pDataUncompress, nBytesUncompress); + // delete[]pDataUncompress; + // } + //} + + return result; + } CControl::CControl(OOX::Document *pMain) : WritingElement(pMain) {} CControl::~CControl() {} @@ -206,84 +232,84 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("o:bottom") == sName) + if (L"o:bottom" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; case 'c': - if (_T("o:callout") == sName) + if (L"o:callout" == sName) pItem = new OOX::VmlOffice::CCallout(m_pMainDocument); - else if (_T("o:clippath") == sName) + else if (L"o:clippath" == sName) pItem = new OOX::VmlOffice::CClipPath(m_pMainDocument); - else if (_T("o:column") == sName) + else if (L"o:column" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); - else if (_T("o:complex") == sName) + else if (L"o:complex" == sName) pItem = new OOX::VmlOffice::CComplex(m_pMainDocument); break; case 'd': - if (_T("o:diagram") == sName) + if (L"o:diagram" == sName) pItem = new OOX::VmlOffice::CDiagram(m_pMainDocument); break; case 'e': - if (_T("o:equationxml") == sName) + if (L"o:equationxml" == sName) pItem = new OOX::VmlOffice::CEquationXml(m_pMainDocument); - else if (_T("o:extrusion") == sName) + else if (L"o:extrusion" == sName) pItem = new OOX::VmlOffice::CExtrusion(m_pMainDocument); break; case 'f': - if (_T("o:fill") == sName) + if (L"o:fill" == sName) pItem = new OOX::VmlOffice::CFill(m_pMainDocument); break; case 'i': - if (_T("o:ink") == sName) + if (L"o:ink" == sName) pItem = new OOX::VmlOffice::CInk(m_pMainDocument); break; case 'l': - if (_T("o:left") == sName) + if (L"o:left" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); - else if (_T("o:lock") == sName) + else if (L"o:lock" == sName) pItem = new OOX::VmlOffice::CLock(m_pMainDocument); break; case 'O': - if (_T("o:OLEObject") == sName) + if (L"o:OLEObject" == sName) { m_oOLEObject = new OOX::VmlOffice::COLEObject(m_pMainDocument); m_oOLEObject->fromXML(oSubReader); }break; case 'r': - if (_T("o:right") == sName) + if (L"o:right" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; case 's': - if (_T("o:shapedefaults") == sName) + if (L"o:shapedefaults" == sName) pItem = new OOX::VmlOffice::CShapeDefaults(m_pMainDocument); - else if (_T("o:shapelayout") == sName) + else if (L"o:shapelayout" == sName) pItem = new OOX::VmlOffice::CShapeLayout(m_pMainDocument); - else if (_T("o:signatureline") == sName) + else if (L"o:signatureline" == sName) pItem = new OOX::VmlOffice::CSignatureLine(m_pMainDocument); - else if (_T("o:skew") == sName) + else if (L"o:skew" == sName) pItem = new OOX::VmlOffice::CSkew(m_pMainDocument); break; case 't': - if (_T("o:top") == sName) + if (L"o:top" == sName) pItem = new OOX::VmlOffice::CStrokeChild(m_pMainDocument); break; @@ -298,59 +324,59 @@ namespace OOX switch (wChar2) { case 'a': - if (_T("v:arc") == sName) + if (L"v:arc" == sName) { m_oShapeElement = new OOX::Vml::CArc(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); }break; case 'b': - if (_T("v:background") == sName) + if (L"v:background" == sName) pItem = new OOX::Vml::CBackground(m_pMainDocument); break; case 'c': - if (_T("v:curve") == sName) + if (L"v:curve" == sName) { m_oShapeElement = new OOX::Vml::CCurve(m_pMainDocument);//??? m_oShapeElement->fromXML(oSubReader); }break; case 'f': - if (_T("v:fill") == sName) + if (L"v:fill" == sName) pItem = new OOX::Vml::CFill(m_pMainDocument); - else if (_T("v:formulas") == sName) + else if (L"v:formulas" == sName) pItem = new OOX::Vml::CFormulas(m_pMainDocument); break; case 'g': - if (_T("v:group") == sName) + if (L"v:group" == sName) { m_oShapeElement = new OOX::Vml::CGroup(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); }break; case 'h': - if (_T("v:handles") == sName) + if (L"v:handles" == sName) pItem = new OOX::Vml::CHandles(m_pMainDocument); break; case 'i': - if (_T("v:image") == sName) + if (L"v:image" == sName) { m_oShapeElement = new OOX::Vml::CImage(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:imagedata") == sName) + else if (L"v:imagedata" == sName) { pItem = pImageData = new OOX::Vml::CImageData(m_pMainDocument); } break; case 'l': - if (_T("v:line") == sName) + if (L"v:line" == sName) { m_oShapeElement = new OOX::Vml::CLine(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -358,7 +384,7 @@ namespace OOX break; case 'o': - if (_T("v:oval") == sName) + if (L"v:oval" == sName) { m_oShapeElement = new OOX::Vml::COval(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -366,9 +392,9 @@ namespace OOX break; case 'p': - if (_T("v:path") == sName) + if (L"v:path" == sName) pItem = new OOX::Vml::CPath(m_pMainDocument); - else if (_T("v:polyline") == sName) + else if (L"v:polyline" == sName) { m_oShapeElement = new OOX::Vml::CPolyLine(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -377,12 +403,12 @@ namespace OOX break; case 'r': - if (_T("v:rect") == sName) + if (L"v:rect" == sName) { m_oShapeElement = new OOX::Vml::CRect(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:roundrect") == sName) + else if (L"v:roundrect" == sName) { m_oShapeElement = new OOX::Vml::CRoundRect(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); @@ -390,27 +416,27 @@ namespace OOX break; case 's': - if (_T("v:shadow") == sName) + if (L"v:shadow" == sName) pItem = new OOX::Vml::CShadow(m_pMainDocument); - else if (_T("v:shape") == sName) + else if (L"v:shape" == sName) { m_oShapeElement = new OOX::Vml::CShape(m_pMainDocument); m_oShapeElement->fromXML(oSubReader); } - else if (_T("v:shapetype") == sName) + else if (L"v:shapetype" == sName) { m_oShapeType = new OOX::Vml::CShapeType(m_pMainDocument); m_oShapeType->fromXML(oSubReader); } - else if (_T("v:stroke") == sName) + else if (L"v:stroke" == sName) pItem = new OOX::Vml::CStroke(m_pMainDocument); break; case 't': - if (_T("v:textbox") == sName) + if (L"v:textbox" == sName) pItem = new OOX::Vml::CTextbox(m_pMainDocument); - else if (_T("v:textpath") == sName) + else if (L"v:textpath" == sName) pItem = new OOX::Vml::CTextPath(m_pMainDocument); break; @@ -434,19 +460,36 @@ namespace OOX if (docx_flat) { smart_ptr pImageFile = smart_ptr(new OOX::Image(m_pMainDocument, true)); - - int dstLen = Base64::Base64DecodeGetRequiredLength((int)m_oBinData->m_sData->size()); - pImageFile->m_Data.resize(dstLen); - Base64::Base64Decode(m_oBinData->m_sData->c_str(), (int)m_oBinData->m_sData->size(), pImageFile->m_Data.data(), &dstLen); - pImageFile->m_Data.resize(dstLen); + pImageFile->m_Data = m_oBinData->GetBytes(); CImageFileFormatChecker fileChecker; - std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), dstLen); + std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), pImageFile->m_Data.size()); + + if (ext.empty()) + { + COfficeUtils oCOfficeUtils(NULL); + if (oCOfficeUtils.IsArchive(pImageFile->m_Data.data(), pImageFile->m_Data.size())) + {//gzip + ULONG nBytesUncompress = pImageFile->m_Data.size() * 10; + BYTE* pDataUncompress = new BYTE[nBytesUncompress]; + if (S_OK == oCOfficeUtils.Uncompress(pDataUncompress, &nBytesUncompress, pImageFile->m_Data.data(), pImageFile->m_Data.size())) + { + ext = fileChecker.DetectFormatByData(pDataUncompress, nBytesUncompress); + + if (false == ext.empty()) + { + pImageFile->m_Data.resize(nBytesUncompress); + memcpy(pImageFile->m_Data.data(), pDataUncompress, nBytesUncompress); + delete []pDataUncompress; + } + } + } + } if (false == ext.empty()) { OOX::CPath filename(L"image." + ext); pImageFile->set_filename(filename, false, true); - + NSCommon::smart_ptr file = pImageFile.smart_dynamic_cast(); const OOX::RId rId = docx_flat->m_currentContainer->Add(file); @@ -458,7 +501,6 @@ namespace OOX } } } - break; } @@ -471,7 +513,7 @@ namespace OOX } std::wstring CPicture::toXML() const { - std::wstring sResult = _T(""); + std::wstring sResult = m_oOLEObject.IsInit() ? L"" : L""; for (size_t i = 0; i < m_arrItems.size(); ++i) { @@ -489,10 +531,12 @@ namespace OOX if (m_oControl.IsInit()) sResult += m_oControl->toXML(); - //if (m_oBinData.IsInit()) - // sResult += m_oBinData->toXML(); + if (m_oOLEObject.IsInit()) + { + sResult += m_oOLEObject->toXML(); + } - sResult += _T(""); + sResult += m_oOLEObject.IsInit() ? L"" : L""; return sResult; } @@ -518,9 +562,24 @@ namespace OOX //альтернатива pptx std::wstring sXml; //??? + ole наверно что то (лень ...) - sXml += _T(""); + sXml += L""; sXml += m_sXml.get(); - sXml += _T(""); + sXml += L""; XmlUtils::CXmlLiteReader oSubReader; oSubReader.FromString(sXml); @@ -545,79 +604,79 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("o:bottom") == sName) + if (L"o:bottom" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; case 'c': - if (_T("o:callout") == sName) + if (L"o:callout" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CCallout, oSubReader) - else if (_T("o:clippath") == sName) + else if (L"o:clippath" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CClipPath, oSubReader) - else if (_T("o:column") == sName) + else if (L"o:column" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) - else if (_T("o:complex") == sName) + else if (L"o:complex" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CComplex, oSubReader) break; case 'd': - if (_T("o:diagram") == sName) + if (L"o:diagram" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CDiagram, oSubReader) break; case 'e': - if (_T("o:equationxml") == sName) + if (L"o:equationxml" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CEquationXml, oSubReader) - else if (_T("o:extrusion") == sName) + else if (L"o:extrusion" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CExtrusion, oSubReader) break; case 'f': - if (_T("o:fill") == sName) + if (L"o:fill" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CFill, oSubReader) break; case 'i': - if (_T("o:ink") == sName) + if (L"o:ink" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CInk, oSubReader) break; case 'l': - if (_T("o:left") == sName) + if (L"o:left" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) - else if (_T("o:lock") == sName) + else if (L"o:lock" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CLock, oSubReader) break; case 'O':// собственно это и есть самый главный под-объект - if (_T("o:OLEObject") == sName) + if (L"o:OLEObject" == sName) m_oOleObject = oSubReader; break; case 'r': - if (_T("o:right") == sName) + if (L"o:right" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; case 's': - if (_T("o:shapedefaults") == sName) + if (L"o:shapedefaults" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CShapeDefaults, oSubReader) - else if (_T("o:shapelayout") == sName) + else if (L"o:shapelayout" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CShapeLayout, oSubReader) - else if (_T("o:signatureline") == sName) + else if (L"o:signatureline" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CSignatureLine, oSubReader) - else if (_T("o:skew") == sName) + else if (L"o:skew" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CSkew, oSubReader) break; case 't': - if (_T("o:top") == sName) + if (L"o:top" == sName) AssignPtrXmlContent(pItem, OOX::VmlOffice::CStrokeChild, oSubReader) break; } @@ -631,51 +690,51 @@ namespace OOX switch (wChar2) { case 'b': - if (_T("v:background") == sName) + if (L"v:background" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CBackground, oSubReader) break; case 'f': - if (_T("v:fill") == sName) + if (L"v:fill" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CFill, oSubReader) - else if (_T("v:formulas") == sName) + else if (L"v:formulas" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CFormulas, oSubReader) break; case 'h': - if (_T("v:handles") == sName) + if (L"v:handles" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CHandles, oSubReader) break; case 'i': - if (_T("v:image") == sName) + if (L"v:image" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CImage, oSubReader) - else if (_T("v:imagedata") == sName) + else if (L"v:imagedata" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CImageData, oSubReader) break; case 'p': - if (_T("v:path") == sName) + if (L"v:path" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CPath, oSubReader) break; case 'r': - if (_T("v:rect") == sName) + if (L"v:rect" == sName) m_oShape = oSubReader; break; case 's': - if (_T("v:shadow") == sName) + if (L"v:shadow" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CShadow, oSubReader) - else if (_T("v:shape") == sName) + else if (L"v:shape" == sName) m_oShape = oSubReader; - else if (_T("v:shapetype") == sName) + else if (L"v:shapetype" == sName) m_oShapeType = oSubReader; - else if (_T("v:stroke") == sName) + else if (L"v:stroke" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CStroke, oSubReader) break; case 't': - if (_T("v:textbox") == sName) + if (L"v:textbox" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CTextbox, oSubReader) - else if (_T("v:textpath") == sName) + else if (L"v:textpath" == sName) AssignPtrXmlContent(pItem, OOX::Vml::CTextPath, oSubReader) break; } @@ -700,7 +759,7 @@ namespace OOX } std::wstring CObject::toXML() const { - return _T(""); + return L""; } EElementType CObject::getType() const { diff --git a/OOXML/DocxFormat/Logic/Pict.h b/OOXML/DocxFormat/Logic/Pict.h index 44f4c367e40..a0973e18feb 100644 --- a/OOXML/DocxFormat/Logic/Pict.h +++ b/OOXML/DocxFormat/Logic/Pict.h @@ -62,9 +62,9 @@ namespace OOX virtual std::wstring toXML() const; virtual EElementType getType() const; + std::vector GetBytes(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - public: nullable m_sName; nullable m_sData; diff --git a/OOXML/DocxFormat/Logic/Vml.cpp b/OOXML/DocxFormat/Logic/Vml.cpp index 1e22b501d45..01aa049fc49 100644 --- a/OOXML/DocxFormat/Logic/Vml.cpp +++ b/OOXML/DocxFormat/Logic/Vml.cpp @@ -195,14 +195,10 @@ namespace OOX if (docx_flat) { smart_ptr pImageFile = smart_ptr(new OOX::Image(document, true)); - - int dstLen = Base64::Base64DecodeGetRequiredLength((int)oBinData.m_sData->size()); - pImageFile->m_Data.resize(dstLen); - Base64::Base64Decode(oBinData.m_sData->c_str(), (int)oBinData.m_sData->size(), pImageFile->m_Data.data(), &dstLen); - pImageFile->m_Data.resize(dstLen); + pImageFile->m_Data = oBinData.GetBytes(); CImageFileFormatChecker fileChecker; - std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), dstLen); + std::wstring ext = fileChecker.DetectFormatByData(pImageFile->m_Data.data(), pImageFile->m_Data.size()); if (false == ext.empty()) { OOX::CPath filename(L"image." + ext); @@ -557,7 +553,7 @@ namespace OOX if (m_oOleIcon.get_value_or(false)) sResult += L"o:oleicon=\"t\" "; - if (m_oOle.get_value_or(false)) + if (m_oOle.IsInit()) sResult += L"o:ole=\"t\" "; if (m_oPreferRelative.get_value_or(false)) diff --git a/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp b/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp index 96ba90ad761..7434f5faf8b 100644 --- a/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp +++ b/OOXML/DocxFormat/Logic/VmlOfficeDrawing.cpp @@ -30,6 +30,7 @@ * */ +#include "../DocxFlat.h" #include "VmlOfficeDrawing.h" namespace OOX @@ -1268,19 +1269,32 @@ namespace OOX { ReadAttributes( oReader ); - if ( oReader.IsEmptyNode() ) - return; - - int nCurDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nCurDepth ) ) + if (false == oReader.IsEmptyNode()) { - std::wstring sName = oReader.GetName(); - if ( L"o:FieldCodes" == sName ) - m_oFieldCodes = oReader; - else if ( L"o:LinkType" == sName ) - m_oLinkType = oReader; - else if ( L"o:LockedField" == sName ) - m_oLockedField = oReader; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + std::wstring sName = oReader.GetName(); + if (L"o:FieldCodes" == sName) + m_oFieldCodes = oReader; + else if (L"o:LinkType" == sName) + m_oLinkType = oReader; + else if (L"o:LockedField" == sName) + m_oLockedField = oReader; + } + } + + OOX::CDocxFlat* docx_flat = dynamic_cast(m_pMainDocument); + if (docx_flat && false == m_oId.IsInit() && m_sObjectId.IsInit()) + { + std::map>::iterator pFind = docx_flat->m_mapOleData.find(*m_sObjectId); + + if (pFind != docx_flat->m_mapOleData.end()) + { + const OOX::RId rId = docx_flat->m_currentContainer->Add(pFind->second); + m_oId.Init(); + m_oId->SetValue(rId.get()); + } } } std::wstring COLEObject::toXML() const diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 32578b01ffa..9a941aeeae5 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -788,6 +788,7 @@ namespace OOX et_w_bdo, // et_w_binData, // et_w_bgPict, // + et_w_docSuppData, // et_w_bookmarkEnd, // et_w_bookmarkStart, // et_w_br, // @@ -1547,6 +1548,7 @@ namespace OOX virtual ~Document(); std::wstring m_sDocumentPath; + std::wstring m_sTempPath; std::map> m_mapContent; }; diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 8b071518dae..7f9ee702cba 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -433,8 +433,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); pathImage = pImageFileCache->filename().GetPath(); } } diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 7b7dc848464..31edbefe002 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -3018,9 +3018,9 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast(pFile.GetPointer()); - - if (pImageFileCache && odf_ref_image.empty()) + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); + + if (pImageFileCache.IsInit() && odf_ref_image.empty()) { odf_ref_image = odf_context()->add_imageobject(pImageFileCache->filename().GetPath()); } diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 54a22070bc5..bd83aeae93e 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -503,7 +503,9 @@ namespace NExtractTools { nRes = docxflat2odt(sFrom, sTo, params, convertParams); } - else if (AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo) + else if ( AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX == nFormatTo || + AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) { nRes = docxflat2docx(sFrom, sTo, params, convertParams); } @@ -1398,8 +1400,9 @@ namespace NExtractTools _UINT32 fromInputParams(InputParams& oInputParams) { TConversionDirection conversion = oInputParams.getConversionDirection(); - std::wstring sFileFrom = *oInputParams.m_sFileFrom; - std::wstring sFileTo = *oInputParams.m_sFileTo; + + std::wstring sFileFrom = oInputParams.m_sFileFrom ? *oInputParams.m_sFileFrom : L""; + std::wstring sFileTo = oInputParams.m_sFileTo ? *oInputParams.m_sFileTo : L""; int nFormatFrom = AVS_OFFICESTUDIO_FILE_UNKNOWN; if (NULL != oInputParams.m_nFormatFrom) diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index 25b961f8d3e..f88553afb0b 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -1176,7 +1176,6 @@ namespace NExtractTools formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_MOBI || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT || - formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) { diff --git a/X2tConverter/src/lib/docx.h b/X2tConverter/src/lib/docx.h index 0c84b853fb8..66148a5f704 100644 --- a/X2tConverter/src/lib/docx.h +++ b/X2tConverter/src/lib/docx.h @@ -206,7 +206,6 @@ namespace NExtractTools m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); m_oCDocxSerializer.setFontDir(params.getFontPath()); - // bool bRes = m_oCDocxSerializer.saveToFile (sResDoct, sSrcDocx, sTemp); _UINT32 nRes = m_oCDocxSerializer.saveToFile(sTo, sFrom, params.getXmlOptions(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; return nRes; @@ -220,9 +219,10 @@ namespace NExtractTools BinDocxRW::CDocxSerializer m_oCDocxSerializer; _UINT32 nRes = 0; - if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX)) + if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX, params.m_bMacro, convertParams.m_sTempDir)) { - nRes = dir2zipMscrypt(sTempUnpackedDOCX, sTo, params, convertParams); + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + nRes = dir2zipMscrypt(sTempUnpackedDOCX, *params.m_sFileTo, params, convertParams); } else { From 33205477355bfbd6989b149f0725d755b03c4f61 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Wed, 21 Feb 2024 22:41:35 +0300 Subject: [PATCH 329/794] Fix bug #66463 --- .../raster/Metafile/svg/CSvgFile.cpp | 11 ++ DesktopEditor/raster/Metafile/svg/CSvgFile.h | 6 +- .../raster/Metafile/svg/CSvgParser.h | 1 - .../raster/Metafile/svg/SvgObjects/CImage.cpp | 28 ++-- HtmlFile2/htmlfile2.cpp | 153 ++++++++++-------- 5 files changed, 116 insertions(+), 83 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index 6843948df19..07035af67fb 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -20,6 +20,12 @@ bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize) return false; } +bool CSvgFile::ReadFromWString(const std::wstring &wsContext) +{ + Clear(); + return m_oParser.LoadFromString(wsContext, &m_oContainer, this); +} + bool CSvgFile::OpenFromFile(const std::wstring &wsFile) { Clear(); @@ -59,6 +65,11 @@ void CSvgFile::SetFontManager(NSFonts::IFontManager *pFontManager) m_oParser.SetFontManager(pFontManager); } +void CSvgFile::SetWorkingDirectory(const std::wstring &wsWorkingDirectory) +{ + m_wsWorkingDirectory = wsWorkingDirectory; +} + bool CSvgFile::MarkObject(SVG::CObject *pObject) { if (NULL == pObject || pObject->GetId().empty()) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.h b/DesktopEditor/raster/Metafile/svg/CSvgFile.h index c2a7f456d09..1f2c71e60ca 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.h @@ -7,19 +7,23 @@ #include "CSvgParser.h" #include "SvgObjects/CStyle.h" -class CSvgFile +#define SVG_DECL_IMPORT Q_DECL_IMPORT + +class SVG_DECL_IMPORT CSvgFile { public: CSvgFile(); ~CSvgFile(); bool ReadFromBuffer(BYTE* pBuffer, unsigned int unSize); + bool ReadFromWString(const std::wstring& wsContext); bool OpenFromFile(const std::wstring& wsFile); bool GetBounds(double& dX, double& dY, double& dWidth, double& dHeight) const; const SVG::CSvgCalculator* GetSvgCalculator() const; void SetFontManager(NSFonts::IFontManager* pFontManager); + void SetWorkingDirectory(const std::wstring& wsWorkingDirectory); bool MarkObject(SVG::CObject* pObject); SVG::CObject* GetMarkedObject(const std::wstring& wsId) const; diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.h b/DesktopEditor/raster/Metafile/svg/CSvgParser.h index 12a69d99063..060aecea5df 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgParser.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.h @@ -1,7 +1,6 @@ #ifndef CSVGPARSER_H #define CSVGPARSER_H -#include "../../graphics/pro/Fonts.h" #include "../../../common/Directory.h" #include "../../../xml/include/xmlutils.h" diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp index a83ee934b9e..465c40afdfe 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp @@ -59,21 +59,23 @@ namespace SVG NSBase64::Base64Decode(wsImageData.c_str(), wsImageData.length(), pBuffer, &(int&)ulSize); } - #ifndef METAFILE_DISABLE_FILESYSTEM - std::wstring wsFilePath = NSSystemPath::ShortenPath(m_wsHref); - - bool bIsAllowExternalLocalFiles = true; - if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) - bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); - - if (!bIsAllowExternalLocalFiles && wsFilePath.length() >= 3 && L"../" == wsFilePath.substr(0, 3)) - return true; - - wsFilePath = pFile->GetWorkingDirectory() + L'/' + wsFilePath; + else + { + std::wstring wsFilePath = NSSystemPath::ShortenPath(m_wsHref); + + bool bIsAllowExternalLocalFiles = true; + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) + bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); - if (!NSFile::CFileBinary::Exists(wsFilePath) || !NSFile::CFileBinary::ReadAllBytes(wsFilePath, &pBuffer, ulSize)) - return false; + if (!bIsAllowExternalLocalFiles && wsFilePath.length() >= 3 && L"../" == wsFilePath.substr(0, 3)) + return false; + + wsFilePath = pFile->GetWorkingDirectory() + L'/' + wsFilePath; + + if (!NSFile::CFileBinary::Exists(wsFilePath) || !NSFile::CFileBinary::ReadAllBytes(wsFilePath, &pBuffer, ulSize)) + return false; + } #endif if (NULL == pBuffer) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index db52ed531d3..2337c798caa 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -23,9 +23,9 @@ #include "../DesktopEditor/common/ProcessEnv.h" #include "../DesktopEditor/xml/include/xmlutils.h" #include "../DesktopEditor/raster/BgraFrame.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" #include "../DesktopEditor/graphics/pro/Graphics.h" -#include "../DesktopEditor/raster/Metafile/MetaFileCommon.h" +#include "../DesktopEditor/raster/Metafile/svg/CSvgFile.h" + #include "htmlfile2.h" #include @@ -2129,87 +2129,104 @@ class CHtmlFile2_Private void readSVG (NSStringUtils::CStringBuilder* oXml) { - // Сохранить как .svg картинку - NSStringUtils::CStringBuilder oSVG; - oSVG.WriteString(L"GenerateFontManager(); + NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); + + pFontCache->SetStreams(pFonts->GetStreams()); + pFontManager->SetOwnerCache(pFontCache); + + oSvgReader.SetFontManager(pFontManager); + + if (!oSvgReader.ReadFromWString(wsSvg)) { - std::wstring sName = m_oLightReader.GetName(); - if(sName.find(L"xmlns") != std::wstring::npos) - continue; - oSVG.WriteString(sName); - oSVG.WriteString(L"=\""); - oSVG.WriteString(m_oLightReader.GetText()); - oSVG.WriteString(L"\" "); + RELEASEINTERFACE(pFontManager); + pFonts->Release(); + return; } - m_oLightReader.MoveToElement(); - oSVG.WriteString(L"xmlns=\"http://www.w3.org/2000/svg\">"); - std::wstring sSVG = m_oLightReader.GetInnerXml(); - size_t nRef = sSVG.find(L"image"); - while (nRef != std::wstring::npos) - { - size_t nRefBegin = sSVG.rfind(L'<', nRef); - if (nRefBegin != std::wstring::npos) - { - if (sSVG[nRefBegin + 1] == L'/') - nRefBegin++; - sSVG.erase(nRefBegin + 1, nRef - nRefBegin - 1); - nRef = nRefBegin + 1; - } + NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); + pGrRenderer->SetFontManager(pFontManager); - size_t nRefEnd = sSVG.find(L'>', nRef); - size_t nHRef = sSVG.find(L"href", nRef); - if (nHRef == std::wstring::npos || nRefEnd == std::wstring::npos) - break; - nHRef += 6; - if (nHRef > nRefEnd || sSVG.compare(nHRef, 4, L"http") == 0) - { - nRef = sSVG.find(L"image", nRef + 5); - continue; - } - size_t nHRefLen = sSVG.find(L"\"", nHRef); - if(nHRefLen == std::wstring::npos) - break; + double dX, dY, dW, dH; + oSvgReader.GetBounds(dX, dY, dW, dH); - const std::wstring sImageName = NSSystemPath::ShortenPath(sSVG.substr(nHRef, nHRefLen - nHRef)); + if (dW < 0) dW = -dW; + if (dH < 0) dH = -dH; - if (!CanUseThisPath(sImageName, GetStatusUsingExternalLocalFiles())) - break; + double dOneMaxSize = (double)1000.; - std::wstring sTIN(sImageName); - sTIN.erase(std::remove_if(sTIN.begin(), sTIN.end(), [] (wchar_t ch) { return std::iswspace(ch) || (ch == L'^'); }), sTIN.end()); - sTIN = NSFile::GetFileName(sTIN); - bool bRes = NSFile::CFileBinary::Copy(m_sSrc + L"/" + sImageName, m_sDst + L"/word/media/" + sTIN); - if(!bRes) - bRes = NSFile::CFileBinary::Copy(m_sSrc + L"/" + NSFile::GetFileName(sImageName), m_sDst + L"/word/media/" + sTIN); - if(bRes) - sSVG.replace(nHRef, nHRefLen - nHRef, sTIN); - nRef = sSVG.find(L"image", nRef + 5); + if (dW > dH) + { + dH *= (dOneMaxSize / dW); + dW = dOneMaxSize; + } + else + { + dW *= (dOneMaxSize / dH); + dH = dOneMaxSize; } - oSVG.WriteString(sSVG); - oSVG.WriteString(L""); + int nWidth = static_cast(dW + 0.5); + int nHeight = static_cast(dH + 0.5); - std::wstring sImageId = std::to_wstring(m_arrImages.size()); - NSFile::CFileBinary oSVGWriter; - std::wstring sImageFile = m_sDst + L"/word/media/i" + sImageId + L".svg"; - if (oSVGWriter.CreateFileW(sImageFile)) + double dWidth = 25.4 * nWidth / 96; + double dHeight = 25.4 * nHeight / 96; + + BYTE* pBgraData = (BYTE*)malloc(nWidth * nHeight * 4); + if (!pBgraData) { - oSVGWriter.WriteStringUTF8(oSVG.GetData()); - oSVGWriter.CloseFile(); + double dKoef = 2000.0 / (nWidth > nHeight ? nWidth : nHeight); + + nWidth = (int)(dKoef * nWidth); + nHeight = (int)(dKoef * nHeight); + + dWidth = 25.4 * nWidth / 96; + dHeight = 25.4 * nHeight / 96; + + pBgraData = (BYTE*)malloc(nWidth * nHeight * 4); } - // Конвертация из svg в png - NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - bool bLoad = pMetafile->LoadFromFile(sImageFile.data()); - if (bLoad) + if (!pBgraData) + return; + + unsigned int alfa = 0xffffff; + //дефолтный тон должен быть прозрачным, а не белым + //memset(pBgraData, 0xff, nWidth * nHeight * 4); + for (int i = 0; i < nWidth * nHeight; i++) { - std::wstring sPngFile = m_sDst + L"/word/media/i" + sImageId + L".png"; - MetaFile::ConvertToRasterMaxSize(pMetafile, sPngFile.data(), 4, 1000); + ((unsigned int*)pBgraData)[i] = alfa; } - pMetafile->Release(); + CBgraFrame oFrame; + oFrame.put_Data(pBgraData); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(-4 * nWidth); + + pGrRenderer->CreateFromBgraFrame(&oFrame); + pGrRenderer->SetSwapRGB(false); + pGrRenderer->put_Width(dWidth); + pGrRenderer->put_Height(dHeight); + + oSvgReader.SetWorkingDirectory(m_sSrc); + oSvgReader.Draw(pGrRenderer, 0, 0, dWidth, dHeight); + + oFrame.SaveFile(m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L".png", 4); + oFrame.put_Data(NULL); + + RELEASEINTERFACE(pFontManager); + RELEASEINTERFACE(pGrRenderer); + + if (pBgraData) + free(pBgraData); + pFonts->Release(); ImageRels(oXml, -1, L"", L"png"); From 620827ad5355d595a224a72e5705c37d59daebbd Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 22 Feb 2024 10:28:49 +0300 Subject: [PATCH 330/794] . --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index c8573981b29..324e608fbb4 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -3809,7 +3809,7 @@ void BinaryWorkbookTableWriter::WriteMdx(OOX::Spreadsheet::CMdx* pMdx) } if (pMdx->m_oF.IsInit()) { - int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::NameIndex); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::FunctionTag); m_oBcw.m_oStream.WriteBYTE(pMdx->m_oF->GetValue()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } From 0bc356ebff84bdac0ce0b86440e37c52304b3562 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 22 Feb 2024 13:13:37 +0300 Subject: [PATCH 331/794] fix bug #66057 --- OOXML/DocxFormat/DocxFlat.cpp | 21 +++++++++++--- OOXML/DocxFormat/DocxFlat.h | 2 ++ OOXML/DocxFormat/Settings/Settings.cpp | 39 ++++++++++++++++++++++++-- OOXML/XlsxFormat/Workbook/Metadata.cpp | 2 +- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/OOXML/DocxFormat/DocxFlat.cpp b/OOXML/DocxFormat/DocxFlat.cpp index f83f95cca97..9496e53909a 100644 --- a/OOXML/DocxFormat/DocxFlat.cpp +++ b/OOXML/DocxFormat/DocxFlat.cpp @@ -159,11 +159,24 @@ namespace OOX } else if (L"w:docSuppData" == sName && !oReader.IsEmptyNode()) { - m_oDocSuppData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); - m_oDocSuppData->fromXML(oReader); - - ParsingSuppData(); + //m_oDocSuppData = new OOX::Logic::CDocSuppData(WritingElement::m_pMainDocument); + //m_oDocSuppData->fromXML(oReader); + // + //ParsingSuppData(); } + //CustomDocumentProperties + } + + if (!m_sCompatibilityMode.IsInit() && m_pCore.IsInit() && (m_pCore->m_sVersion.IsInit())) + { + if (false == m_pSettings.IsInit()) m_pSettings = new CSettings(this); + if (m_pSettings->m_oCompat.IsInit()) m_pSettings->m_oCompat.Init(); + + Settings::CCompatSetting* pSett = new Settings::CCompatSetting(); + pSett->m_sName = L"compatibilityMode"; + pSett->m_sUri = L"http://schemas.microsoft.com/office/word"; + pSett->m_sVal = m_pCore->m_sVersion; + m_pSettings->m_oCompat->m_arrCompatSettings.push_back(pSett); } if ((m_oDocSuppData.IsInit()) && (m_oDocSuppData->m_oBinData.IsInit()) && (m_pDocument.IsInit())) diff --git a/OOXML/DocxFormat/DocxFlat.h b/OOXML/DocxFormat/DocxFlat.h index 410509b289a..2bc52d14cfb 100644 --- a/OOXML/DocxFormat/DocxFlat.h +++ b/OOXML/DocxFormat/DocxFlat.h @@ -98,6 +98,8 @@ namespace OOX nullable m_pApp; nullable m_pCore; //----------------------------------------------------------- + nullable_string m_sCompatibilityMode; + std::map> m_mapImages; std::map> m_mapOleData; diff --git a/OOXML/DocxFormat/Settings/Settings.cpp b/OOXML/DocxFormat/Settings/Settings.cpp index 26f088d2b12..91072ee0d09 100644 --- a/OOXML/DocxFormat/Settings/Settings.cpp +++ b/OOXML/DocxFormat/Settings/Settings.cpp @@ -516,7 +516,6 @@ namespace Settings } void CCompatSetting::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - // Читаем атрибуты if ( oReader.GetAttributesCount() <= 0 ) return; @@ -554,6 +553,15 @@ namespace Settings wsName = oReader.GetName(); } oReader.MoveToElement(); + + if (m_sName.IsInit() && (*m_sName == L"compatibilityMode") && m_sVal.IsInit()) + { + CDocxFlat* flat_docx = dynamic_cast(m_pMainDocument); + if (flat_docx) + { + flat_docx->m_sCompatibilityMode = *m_sVal; + } + } } //-------------------------------------------------------------------------------- @@ -669,24 +677,49 @@ namespace Settings m_oLayoutRawTableWidth = oReader; else if ( L"w:layoutTableRowsApart" == sName ) m_oLayoutTableRowsApart = oReader; - else if ( L"w:useWord97LineBreakRules" == sName ) + else if ( L"w:useWord97LineBreakRules" == sName ) m_oUseWord97LineBreakRules = oReader; + else if (L"w:breakWrappedTables" == sName) + { + m_oDoNotBreakWrappedTables = oReader; + m_oDoNotBreakWrappedTables->m_oVal.FromBool(!m_oDoNotBreakWrappedTables->m_oVal.ToBool()); + } else if ( L"w:doNotBreakWrappedTables" == sName ) m_oDoNotBreakWrappedTables = oReader; + else if (L"w:snapToGridInCell" == sName) + { + m_oDoNotSnapToGridInCell = oReader; + m_oDoNotSnapToGridInCell->m_oVal.FromBool(!m_oDoNotSnapToGridInCell->m_oVal.ToBool()); + } else if ( L"w:doNotSnapToGridInCell" == sName ) m_oDoNotSnapToGridInCell = oReader; else if ( L"w:selectFldWithFirstOrLastChar" == sName ) m_oSelectFldWithFirstOrLastChar = oReader; else if ( L"w:applyBreakingRules" == sName ) m_oApplyBreakingRules = oReader; + else if (L"w:wrapTextWithPunct" == sName) + { + m_oDoNotWrapTextWithPunct = oReader; + m_oDoNotWrapTextWithPunct->m_oVal.FromBool(!m_oDoNotWrapTextWithPunct->m_oVal.ToBool()); + } else if ( L"w:doNotWrapTextWithPunct" == sName ) m_oDoNotWrapTextWithPunct = oReader; + else if (L"w:useAsianBreakRules" == sName) + { + m_oDoNotUseEastAsianBreakRules = oReader; + m_oDoNotUseEastAsianBreakRules->m_oVal.FromBool(!m_oDoNotUseEastAsianBreakRules->m_oVal.ToBool()); + } else if ( L"w:doNotUseEastAsianBreakRules" == sName ) m_oDoNotUseEastAsianBreakRules = oReader; else if ( L"w:useWord2002TableStyleRules" == sName ) m_oUseWord2002TableStyleRules = oReader; else if ( L"w:growAutofit" == sName ) m_oGrowAutofit = oReader; + else if (L"w:dontGrowAutofit" == sName) + { + m_oGrowAutofit = oReader; + m_oGrowAutofit->m_oVal.FromBool(!m_oGrowAutofit->m_oVal.ToBool()); + } else if ( L"w:useFELayout" == sName ) m_oUseFELayout = oReader; else if ( L"w:useNormalStyleForList" == sName ) @@ -724,7 +757,7 @@ namespace Settings OOX::Settings::CCompatSetting *oCS = new OOX::Settings::CCompatSetting(); *oCS = oReader; - if (oCS)m_arrCompatSettings.push_back( oCS ); + if (oCS) m_arrCompatSettings.push_back( oCS ); } } } diff --git a/OOXML/XlsxFormat/Workbook/Metadata.cpp b/OOXML/XlsxFormat/Workbook/Metadata.cpp index 6bfa9e37be2..7da7a64c2c0 100644 --- a/OOXML/XlsxFormat/Workbook/Metadata.cpp +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -824,7 +824,7 @@ namespace OOX writer.WriteString(L""); + writer.WriteString(L" count=\"" + std::to_wstring(m_arrItems.size())); writer.WriteString(L">"); for (size_t i = 0; i < m_arrItems.size(); ++i) From 0a1d3ddd91d8d1a00853affed79a1778510a9766 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 22 Feb 2024 15:03:28 +0300 Subject: [PATCH 332/794] Fix SetFont for FreeText annot --- DesktopEditor/fontengine/ApplicationFonts.cpp | 332 ++---------------- DesktopEditor/fontengine/ApplicationFonts.h | 3 +- .../pro/js/wasm/src/drawingfile_test.cpp | 14 +- PdfFile/PdfReader.cpp | 9 +- PdfFile/SrcReader/PdfAnnot.cpp | 176 ++-------- PdfFile/SrcReader/PdfAnnot.h | 2 +- 6 files changed, 72 insertions(+), 464 deletions(-) diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index 6ee32aa0532..934ee5e2e12 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.cpp +++ b/DesktopEditor/fontengine/ApplicationFonts.cpp @@ -1118,25 +1118,11 @@ std::vector CFontList::GetAllByName(const std::wstring& str return aRes; } -void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFlag, bool biBold, bool biItalic) +void CFontList::Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstring& sFontPath, CFontStream* pStream, int nFlag) { - if (!pStream) - return; - - FT_Library pLibrary = NULL; - if (FT_Init_FreeType(&pLibrary)) + if (!pLibrary || !pParams || !pStream) return; - FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); - pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); - pParams[0].data = NULL; - pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); - pParams[1].data = NULL; - pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; - pParams[2].data = NULL; - pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; - pParams[3].data = NULL; - FT_Open_Args oOpenArgs; oOpenArgs.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS; oOpenArgs.memory_base = pStream->m_pData; @@ -1168,8 +1154,8 @@ void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFl if (FT_Open_Face( pLibrary, &oOpenArgs, nIndexFace, &pFace)) continue; - INT bBold = biBold ? 1 : (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); - INT bItalic = biItalic ? 1 : (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; + INT bBold = (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); + INT bItalic = (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; const char* pPostName = FT_Get_Postscript_Name(pFace); std::string sPostscriptName = ""; @@ -1424,6 +1410,28 @@ void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFl FT_Done_Face( pFace ); } +} + +void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFlag) +{ + if (!pStream) + return; + + FT_Library pLibrary = NULL; + if (FT_Init_FreeType(&pLibrary)) + return; + + FT_Parameter *pParams = (FT_Parameter *)::malloc( sizeof(FT_Parameter) * 4 ); + pParams[0].tag = FT_MAKE_TAG( 'i', 'g', 'p', 'f' ); + pParams[0].data = NULL; + pParams[1].tag = FT_MAKE_TAG( 'i', 'g', 'p', 's' ); + pParams[1].data = NULL; + pParams[2].tag = FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY; + pParams[2].data = NULL; + pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; + pParams[3].data = NULL; + + Add(pLibrary, pParams, sFontPath, pStream, nFlag); ::free( pParams ); FT_Done_FreeType(pLibrary); @@ -1484,293 +1492,7 @@ void CFontList::LoadFromArrayFiles(std::vector& oArray, int nFlag) if (!oStream.CreateFromFile(oArray[nIndex], pDataFontFile)) continue; - FT_Open_Args oOpenArgs; - oOpenArgs.flags = FT_OPEN_MEMORY | FT_OPEN_PARAMS; - oOpenArgs.memory_base = oStream.m_pData; - oOpenArgs.memory_size = oStream.m_lSize; - - oOpenArgs.num_params = 4; - oOpenArgs.params = pParams; - - FT_Face pFace = NULL; - if (FT_Open_Face( pLibrary, &oOpenArgs, 0, &pFace )) - continue; - - // TO DO: Шрифты, которые нельзя скейлить (т.е. изменять размер - // произвольно) мы не грузим. Возможно в будущем надо будет - // сделать, чтобы работал и такой вариант. (в Word такие шрифты - // не используются) - if ( !( pFace->face_flags & FT_FACE_FLAG_SCALABLE ) ) - { - FT_Done_Face( pFace ); - continue; - } - - int nFacesCount = pFace->num_faces; - if ( FT_Done_Face( pFace ) ) - continue; - - for ( int nIndexFace = 0; nIndexFace < nFacesCount; nIndexFace++ ) - { - if (FT_Open_Face( pLibrary, &oOpenArgs, nIndexFace, &pFace)) - continue; - - INT bBold = (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); - INT bItalic = (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; - - const char* pPostName = FT_Get_Postscript_Name(pFace); - std::string sPostscriptName = ""; - if (NULL != pPostName) - sPostscriptName = FT_Get_Postscript_Name(pFace); - - INT bFixedWidth = FT_IS_FIXED_WIDTH( pFace ); - - TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 ); - - BYTE* pPanose = NULL; - ULONG ulRange1 = 0, ulRange2 = 0, ulRange3 = 0, ulRange4 = 0, ulCodeRange1 = 0, ulCodeRange2 = 0; - USHORT usWidth = 0, usWeight = 0, usType = 0; - SHORT sFamilyClass = 0; - - SHORT shAvgCharWidth = 0, shAscent = 0, shDescent = 0, shLineGap = 0, shXHeight = 0, shCapHeight = 0; - if ( NULL != pOs2 ) - { - pPanose = (BYTE *)pOs2->panose; - - ulRange1 = pOs2->ulUnicodeRange1; - ulRange2 = pOs2->ulUnicodeRange2; - ulRange3 = pOs2->ulUnicodeRange3; - ulRange4 = pOs2->ulUnicodeRange4; - ulCodeRange1 = pOs2->ulCodePageRange1; - ulCodeRange2 = pOs2->ulCodePageRange2; - - usWeight = pOs2->usWeightClass; - usWidth = pOs2->usWidthClass; - - sFamilyClass = pOs2->sFamilyClass; - - usType = pOs2->fsType; - - if ( 0 != pFace->units_per_EM ) - { - double dKoef = ( 1000 / (double)pFace->units_per_EM ); - shAvgCharWidth = (SHORT)(pOs2->xAvgCharWidth * dKoef); - shAscent = (SHORT)(pOs2->sTypoAscender * dKoef); - shDescent = (SHORT)(pOs2->sTypoDescender * dKoef); - shLineGap = (SHORT)(pOs2->sTypoLineGap * dKoef); - shXHeight = (SHORT)(pOs2->sxHeight * dKoef); - shCapHeight = (SHORT)(pOs2->sCapHeight * dKoef); - } - else - { - shAvgCharWidth = (SHORT)pOs2->xAvgCharWidth; - shAscent = (SHORT)pOs2->sTypoAscender; - shDescent = (SHORT)pOs2->sTypoDescender; - shLineGap = (SHORT)pOs2->sTypoLineGap; - shXHeight = (SHORT)pOs2->sxHeight; - shCapHeight = (SHORT)pOs2->sCapHeight; - } - } - - if ( true ) - { - // Специальная ветка для случаев, когда charset может быть задан не через значения - // ulCodePageRange, а непосредственно через тип Cmap. - - // Charset Name Charset Value(hex) Codepage number Platform_ID Encoding_ID Description - // ------------------------------------------------------------------------------------------------- - // - // SYMBOL_CHARSET 2 (x02) 3 0 Symbol - // SHIFTJIS_CHARSET 128 (x80) 932 3 2 ShiftJIS - // GB2313_CHARSET 134 (x86) 936 3 3 PRC - // CHINESEBIG5_CHARSET 136 (x88) 950 3 4 Big5 - // HANGEUL_CHARSET 129 (x81) 949 3 5 Wansung - // JOHAB_CHARSET 130 (x82) 1361 3 6 Johab - - for( int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++ ) - { - // Symbol - if ( !( ulCodeRange1 & 0x80000000 ) && 0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x80000000; - - // ShiftJIS - if ( !( ulCodeRange1 & 0x00020000 ) && 2 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00020000; - - // PRC - if ( !( ulCodeRange1 & 0x00040000 ) && 3 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00040000; - - // Big5 - if ( !( ulCodeRange1 & 0x00100000 ) && 4 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00100000; - - // Wansung - if ( !( ulCodeRange1 & 0x00080000 ) && 5 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00080000; - - // Johab - if ( !( ulCodeRange1 & 0x00200000 ) && 6 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id ) - ulCodeRange1 |= 0x00200000; - } - } - - NSFonts::EFontFormat eFormat = GetFontFormat( pFace ); - - bool bSupportFont = ((eFormat == NSFonts::fontTrueType) || ((nFlag & 1) && (eFormat == NSFonts::fontOpenType))); - if (!bSupportFont) - { - FT_Done_Face( pFace ); - continue; - } - - std::wstring wsFamilyName = GetCorrectSfntName(pFace->family_name); - std::wstring wsStyleName = GetCorrectSfntName(pFace->style_name); - - bool isBadASCII = (std::wstring::npos != wsFamilyName.find('?')) ? true : false; - -#ifdef _MAC - if (wsFamilyName.find(L".") == 0) - { - FT_Done_Face( pFace ); - continue; - } -#endif - - NSFonts::CFontInfo* pFontInfo = new NSFonts::CFontInfo( wsFamilyName, - wsStyleName, - oArray[nIndex], - nIndexFace, - bBold, - bItalic, - bFixedWidth, - pPanose, - ulRange1, - ulRange2, - ulRange3, - ulRange4, - ulCodeRange1, - ulCodeRange2, - usWeight, - usWidth, - sFamilyClass, - eFormat, - shAvgCharWidth, - shAscent, - shDescent, - shLineGap, - shXHeight, - shCapHeight, - usType); - - if (pFace && FT_IS_SFNT(pFace)) - { - TT_Face pTTFace = (TT_Face)pFace; - - int nNamesCount = (int)pTTFace->num_names; - TT_NameRec* pNameRecs = pTTFace->name_table.names; - - for (int nNameIndex = 0; nNameIndex < nNamesCount; ++nNameIndex) - { - TT_NameRec* rec = pNameRecs + nNameIndex; - - if (rec->nameID != TT_NAME_ID_FONT_FAMILY || rec->stringLength <= 0) - continue; - - std::string sEncoding = ""; - switch (rec->platformID) - { - case TT_PLATFORM_APPLE_UNICODE: - { - sEncoding = "UTF-16BE"; - break; - } - case TT_PLATFORM_MACINTOSH: - { - break; - } - case TT_PLATFORM_MICROSOFT: - { - switch (rec->encodingID) - { - case TT_MS_ID_SYMBOL_CS: - case TT_MS_ID_UNICODE_CS: - sEncoding = "UTF-16BE"; - break; - case TT_MS_ID_UCS_4: - //sEncoding = "UCS4"; // см tt_ - sEncoding = "UTF-16BE"; - break; - //case TT_MS_ID_SJIS: - // sEncoding = "Shift-JIS"; - // break; - //case TT_MS_ID_GB2312: - // sEncoding = "GB2312"; - // break; - //case TT_MS_ID_BIG_5: - // sEncoding = "Big5"; - // break; - default: - break; - } - } - default: - break; - } - - if (!sEncoding.empty()) - { - FT_Stream stream = pTTFace->name_table.stream; - FT_Memory memory = pFace->memory; - FT_Error error = 0; - - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || - FT_STREAM_SEEK( rec->stringOffset ) || - FT_STREAM_READ( rec->string, rec->stringLength ) ) - { - FT_FREE( rec->string ); - rec->stringLength = 0; - } - else - { - NSUnicodeConverter::CUnicodeConverter oConverter; - std::wstring sNameW = oConverter.toUnicode((char*)rec->string, (unsigned int)rec->stringLength, sEncoding.c_str()); - - if (std::wstring::npos == sNameW.find(wsFamilyName) && std::wstring::npos == wsFamilyName.find(sNameW)) - { - std::vector::iterator iter = pFontInfo->names.begin(); - for (std::vector::iterator iter = pFontInfo->names.begin(); iter != pFontInfo->names.end(); iter++) - { - if (*iter == sNameW) - break; - } - - if (isBadASCII && pFontInfo->names.empty()) - { - wsFamilyName = sNameW; - pFontInfo->m_wsFontName = wsFamilyName; - isBadASCII = false; - } - else if (iter == pFontInfo->names.end()) - { - pFontInfo->names.push_back(sNameW); - -#if 0 - FILE* f = fopen("D:\\111.txt", "a+"); - fprintf(f, "%s: %s\n", U_TO_UTF8(wsFamilyName).c_str(), U_TO_UTF8(sNameW).c_str()); - fclose(f); -#endif - } - } - } - } - } - } - - Add(pFontInfo); - - FT_Done_Face( pFace ); - } + Add(pLibrary, pParams, oArray[nIndex], &oStream, nFlag); } RELEASEARRAYOBJECTS(pDataFontFile); diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index fa51a276b9e..206967dfe6c 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.h +++ b/DesktopEditor/fontengine/ApplicationFonts.h @@ -306,6 +306,7 @@ class CFontList : public NSFonts::IFontList int GetXHeightPenalty(SHORT shCandXHeight, SHORT shReqXHeight); int GetCapHeightPenalty(SHORT shCandCapHeight, SHORT shReqCapHeight); bool CheckEmbeddingRights(const USHORT* ushRights, const USHORT& fsType); + void Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstring& sFontPath, CFontStream* pStream, int nFlag); public: static NSFonts::EFontFormat GetFontFormat(FT_Face pFace); @@ -316,7 +317,7 @@ class CFontList : public NSFonts::IFontList void LoadFromFolder (const std::wstring& strDirectory); bool CheckLoadFromFolderBin(const std::wstring& strDirectory); void CheckLoadFromSelectionBin(const std::wstring& strDirectory, BYTE* pData, DWORD len); - void Add (const std::wstring& sFontPath, CFontStream* pStream, int nFlag = 0, bool bBold = false, bool bItalic = false); + void Add (const std::wstring& sFontPath, CFontStream* pStream, int nFlag = 0); void Add (NSFonts::CFontInfo* pInfo); NSFonts::CFontInfo* GetByParams (NSFonts::CFontSelectFormat& oSelect, bool bIsDictionaryUse = true); std::vector GetAllByName (const std::wstring& strFontName); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index f20a23ee807..b098bb32bca 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1274,7 +1274,7 @@ int main(int argc, char* argv[]) { nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << "font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + std::cout << "; font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; i += nPathLength; } @@ -1294,9 +1294,19 @@ int main(int argc, char* argv[]) nPathLength = READ_INT(pAnnots + i); i += 4; - std::cout << "font-family:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + std::string sFontName((char*)(pAnnots + i), nPathLength); + std::cout << "font-family:" << sFontName << "; "; i += nPathLength; + BYTE* pFont = GetFontBinary(pGrFile, (char*)sFontName.c_str()); + if (pFont) + { + std::cout << "FIND; "; + free(pFont); + } + else + std::cout << "NO; "; + nPathLength = READ_INT(pAnnots + i); i += 4; std::string sText = std::string((char*)(pAnnots + i), nPathLength); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 7522262e015..404e6b79ea4 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1428,7 +1428,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oRes.ClearWithoutAttack(); return bRes; } -void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) +void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, std::map& m_mFonts, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); if (!pPage) @@ -1470,7 +1470,8 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade else if (sType == "FreeText") { PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); - pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); + std::map mFreeText = pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); + m_mFonts.insert(mFreeText.begin(), mFreeText.end()); pAnnot = pFreeText; } else if (sType == "Line") @@ -1531,10 +1532,10 @@ BYTE* CPdfReader::GetAnnots(int nPageIndex) oRes.SkipLen(); if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPageIndex); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, m_mFonts, nPageIndex); else for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPage); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, m_mFonts, nPage); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 7d9f7d8d35a..af27f7bafc6 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2123,7 +2123,6 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : // 3 - Форматированный текст - RC std::string sRC = DictLookupString(&oAnnot, "RC", 3); - std::cout << sRC << std::endl; // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock XmlUtils::CXmlLiteReader oLightReader; @@ -2215,29 +2214,21 @@ CAnnotMarkup::~CAnnotMarkup() for (int i = 0; i < m_arrRC.size(); ++i) RELEASEOBJECT(m_arrRC[i]); } -void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) +std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) { + std::map mRes; if (m_arrRC.empty()) - return; + return mRes; Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - // Теперь для всех шрифтов необходимо извлечь файлы шрифтов из внешнего вида Object oAP, oN, oR, oFonts; if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oN)->isStream() && oN.streamGetDict()->lookup("Resources", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) { - // 4.2 Доработка: Стандартные шрифты не попадают в подбор, для них необходима отдельная проверка - - // 4.1 Доработка: GetByParams обязательно подберет шрифт, поэтому список должен быть полным. - - // 4 УСПЕХ: Требуется проверка - // 4 ПЛАН: - // Реализовать добавление шрифта в CFontList - // Создать CFontList только из шрифтов в FreeText - // Сделать подбор по параметрам CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); + std::vector arrFontFreeText; for (int i = 0; i < oFonts.dictGetLength(); ++i) { @@ -2250,10 +2241,11 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana const unsigned char* pData14 = NULL; unsigned int nSize14 = 0; - if (!GetBaseFont(sFontPath, pData14, nSize14)) + CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); + if (pFontStream && !GetBaseFont(sFontPath, pData14, nSize14)) { - CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); pAppFontList->Add(sFontPath, pFontStream); + arrFontFreeText.push_back(sFontPath); } } oFontRef.free(); @@ -2264,7 +2256,6 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana std::wstring wsFontName = UTF8_TO_U(m_arrRC[i]->sFontFamily); bool bBold = (bool)((m_arrRC[i]->unFontFlags >> 0) & 1); bool bItalic = (bool)((m_arrRC[i]->unFontFlags >> 1) & 1); - // Если стандартный шрифт if (wsFontName == L"Courier" || wsFontName == L"Helvetica" || wsFontName == L"Symbol" || wsFontName == L"Times New Roman" || wsFontName == L"ZapfDingbats") { if (wsFontName == L"Times New Roman") @@ -2288,16 +2279,12 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana wsFontName += L"-Oblique"; } - if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName)) - { - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; - if (GetBaseFont(wsFontName, pData14, nSize14)) - { - NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); - m_arrRC[i]->sFontFamily = U_TO_UTF8(wsFontName); - } - } + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); + m_arrRC[i]->sFontFamily = U_TO_UTF8(wsFontName); + m_arrRC[i]->bFind = true; } else { @@ -2309,141 +2296,27 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana oFontSelect.wsName = new std::wstring(wsFontName); NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); - if (pFontInfo) - { - // Если шрифт из FreeText - // Иначе шрифт из подбора - } - } - } - - // 3 ПРОВАЛ: PdfReader::CFontList - это не CFontList из ApplicationFonts, т.е. сделать подбор на PdfReader::CFontList не получится - // 3 ПЛАН: - // Загрузить все шрифты FreeText в pFontList - // На pFontList сделать подбор по параметрам - // Если подобранный шрифт неполный или не подобрался, то - // На pFontManager сделать подбор по параметрам - - // 2 ПРОВАЛ: Встречаются составные глифы из 2, 4 бит, из-за чего количество символов разительно отличается - // 2 ПЛАН: Дополнительное сопоставление по количеству символов чтобы проскочить места путаницы со шрифтами. - // 1 ПРОВАЛ: Во внешнем виде используются больше шрифтов, и они не соответствуют RC - // 1 ПЛАН: Последовательное сопоставление шрифта и имени шрифта - /* - Parser* parser = new Parser(xref, new Lexer(xref, &oN), gFalse); - int nFont = 0; - std::string sExpectedFontName = m_arrRC[0]->sFontFamily, sPredKey; - - Object oObj1, oObj2, oObj3; - parser->getObj(&oObj1); - while (!oObj1.isEOF()) - { - if (nFont == m_arrRC.size()) - break; - - if (oObj1.isName()) - { - parser->getObj(&oObj2); - if (oObj2.isEOF()) - break; - if (oObj2.isNum()) + if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { - parser->getObj(&oObj3); - if (oObj3.isEOF()) - break; - Object oFontRef; - if (oObj3.isCmd("Tf") && oFonts.dictLookupNF(oObj1.getName(), &oFontRef)->isRef()) + if (std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end()) { - std::string sFontName, sActual; - bool bBold = false, bItalic = false; - GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, 7, sFontName, sActual, bBold, bItalic); - - if (!oObj1.isName(sPredKey.c_str())) - { - sPredKey = oObj1.getName(); - - int nRead = 0; - oObj1.free(); oObj2.free(); oObj3.free(); - parser->getObj(&oObj1); - while (nRead < m_arrRC[nFont]->sText.length() && !oObj1.isEOF()) - { - if (oObj1.isString()) - { - parser->getObj(&oObj2); - if (oObj2.isEOF()) - { - oObj1.free(); - oObj2.copy(&oObj1); - oObj2.free(); - break; - } - if (oObj2.isCmd("Tj")) - nRead += oObj1.getString()->getLength(); - } - if (oObj2.isString()) - { - oObj1.free(); - oObj2.copy(&oObj1); - oObj2.free(); - continue; - } - parser->getObj(&oObj1); - } - oObj2.free(); - - while (nFont < m_arrRC.size()) - { - if ((bool)((m_arrRC[nFont]->unFontFlags >> 0) & 1) == bBold && - (bool)((m_arrRC[nFont]->unFontFlags >> 1) & 1) == bItalic && - m_arrRC[nFont]->sFontFamily == sExpectedFontName) - { - m_arrRC[nFont]->sFontFamily = sFontName; - if (!sActual.empty()) - { - m_arrRC[nFont]->unFontFlags |= (1 << 6); - m_arrRC[nFont]->sActualFont = sActual; - } - } - else - { - sExpectedFontName = m_arrRC[nFont]->sFontFamily; - break; - } - nFont++; - } - - oFontRef.free(); - continue; - } + m_arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); + mRes[pFontInfo->m_wsFontName] = pFontInfo->m_wsFontPath; } - oFontRef.free(); + else + { + m_arrRC[i]->unFontFlags |= (1 << 6); + m_arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); + } + m_arrRC[i]->bFind = true; } } - if (oObj2.isName()) - { - oObj1.free(); - oObj2.copy(&oObj1); - oObj2.free(); oObj3.free(); - continue; - } - if (oObj3.isName()) - { - oObj1.free(); - oObj3.copy(&oObj1); - oObj3.free(); oObj2.free(); - continue; - } - oObj1.free(); oObj2.free(); oObj3.free(); - - parser->getObj(&oObj1); } - - oObj1.free(); oObj2.free(); oObj3.free(); - RELEASEOBJECT(parser); - */ } oAP.free(); oN.free(); oR.free(); oFonts.free(); oAnnot.free(); + return mRes; } void CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) { @@ -2533,6 +2406,7 @@ void CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) } CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) { + bFind = oFont.bFind; nAlign = oFont.nAlign; unFontFlags = oFont.unFontFlags; dFontSise = oFont.dFontSise; diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index f6962139b30..eb90ea9da5a 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -327,7 +327,7 @@ class CAnnotPopup final : public CAnnot class CAnnotMarkup : public CAnnot { public: - void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); protected: CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); virtual ~CAnnotMarkup(); From 0927217246b6b7b6e50388f6bb36b0ef9aaec0de Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 22 Feb 2024 16:59:39 +0300 Subject: [PATCH 333/794] Fix repeat font --- PdfFile/SrcReader/PdfAnnot.cpp | 59 ++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index af27f7bafc6..c70ef31ad0a 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2253,38 +2253,52 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec for (int i = 0; i < m_arrRC.size(); ++i) { - std::wstring wsFontName = UTF8_TO_U(m_arrRC[i]->sFontFamily); + if (m_arrRC[i]->bFind) + continue; + + std::string sFontName = m_arrRC[i]->sFontFamily; bool bBold = (bool)((m_arrRC[i]->unFontFlags >> 0) & 1); bool bItalic = (bool)((m_arrRC[i]->unFontFlags >> 1) & 1); - if (wsFontName == L"Courier" || wsFontName == L"Helvetica" || wsFontName == L"Symbol" || wsFontName == L"Times New Roman" || wsFontName == L"ZapfDingbats") + if (sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats") { - if (wsFontName == L"Times New Roman") + if (sFontName == "Times New Roman") { if (bBold && bItalic) - wsFontName = L"Times-BoldItalic"; + sFontName = "Times-BoldItalic"; else if (bBold) - wsFontName = L"Times-Bold"; + sFontName = "Times-Bold"; else if (bItalic) - wsFontName = L"Times-Italic"; + sFontName = "Times-Italic"; else - wsFontName = L"Times-Roman"; + sFontName = "Times-Roman"; } - else if (wsFontName == L"Courier" || wsFontName == L"Helvetica") + else if (sFontName == "Courier" || sFontName == "Helvetica") { if (bBold && bItalic) - wsFontName += L"-BoldOblique"; + sFontName += "-BoldOblique"; else if (bBold) - wsFontName += L"-Bold"; + sFontName += "-Bold"; else if (bItalic) - wsFontName += L"-Oblique"; + sFontName += "-Oblique"; } const unsigned char* pData14 = NULL; unsigned int nSize14 = 0; + std::wstring wsFontName = UTF8_TO_U(sFontName); if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); - m_arrRC[i]->sFontFamily = U_TO_UTF8(wsFontName); + std::string sFontNameBefore = m_arrRC[i]->sFontFamily; + m_arrRC[i]->sFontFamily = sFontName; m_arrRC[i]->bFind = true; + + for (int j = i; j < m_arrRC.size(); ++j) + { + if (m_arrRC[j]->sFontFamily == sFontNameBefore) + { + m_arrRC[j]->sFontFamily = sFontName; + m_arrRC[j]->bFind = true; + } + } } else { @@ -2293,12 +2307,13 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec oFontSelect.bBold = new INT(1); if (bItalic) oFontSelect.bItalic = new INT(1); - oFontSelect.wsName = new std::wstring(wsFontName); + oFontSelect.wsName = new std::wstring(UTF8_TO_U(sFontName)); NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { - if (std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end()) + bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); + if (bFreeText) { m_arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); mRes[pFontInfo->m_wsFontName] = pFontInfo->m_wsFontPath; @@ -2309,6 +2324,22 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec m_arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); } m_arrRC[i]->bFind = true; + + std::string sFontNameNew = bFreeText ? m_arrRC[i]->sFontFamily : m_arrRC[i]->sActualFont; + for (int j = i; j < m_arrRC.size(); ++j) + { + if (m_arrRC[j]->sFontFamily == sFontName) + { + if (bFreeText) + m_arrRC[j]->sFontFamily = sFontNameNew; + else + { + m_arrRC[j]->unFontFlags |= (1 << 6); + m_arrRC[j]->sActualFont = sFontNameNew; + } + m_arrRC[j]->bFind = true; + } + } } } } From f8184532c8ce94d720eeefff94f95be3fd5c08d8 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 22 Feb 2024 18:10:26 +0300 Subject: [PATCH 334/794] Added support for reading @page and bug fixes in html to ooxml conversion --- .../3dParty/html/css/src/CCompiledStyle.cpp | 24 +- .../3dParty/html/css/src/CCssCalculator.cpp | 5 + Common/3dParty/html/css/src/CCssCalculator.h | 2 + .../html/css/src/CCssCalculator_Private.cpp | 235 +++++++++++++- .../html/css/src/CCssCalculator_Private.h | 15 + .../html/css/src/CUnitMeasureConverter.cpp | 4 +- .../3dParty/html/css/src/StaticFunctions.cpp | 27 +- .../3dParty/html/css/src/StyleProperties.cpp | 307 +++++++++--------- Common/3dParty/html/css/src/StyleProperties.h | 70 ++-- .../html/css/src/xhtml/CDocumentStyle.cpp | 62 ++-- HtmlFile2/HtmlFile2.pro | 1 + HtmlFile2/htmlfile2.cpp | 112 +++++-- 12 files changed, 581 insertions(+), 283 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 9acb292758c..a5ceaae0e62 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -19,9 +19,7 @@ namespace NSCSS typedef std::map::const_iterator styles_iterator; CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point) - { - m_oFont.SetSize(std::to_wstring(DEFAULTFONTSIZE), 0, true); - } + {} CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), @@ -173,7 +171,7 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddValue(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetValues(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateAll(dFontSize); break; } @@ -182,7 +180,7 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddTop(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetTop(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateTop(dFontSize); break; } @@ -192,7 +190,7 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddRight(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetRight(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateRight(dFontSize); break; } @@ -201,7 +199,7 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddBottom(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetBottom(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateBottom(dFontSize); break; } @@ -211,7 +209,7 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddLeft(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetLeft(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateLeft(dFontSize); break; } @@ -219,35 +217,35 @@ namespace NSCSS CASE(L"padding"): CASE(L"mso-padding-alt"): { - m_oPadding.AddValue(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetValues(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateAll(dFontSize); break; } CASE(L"padding-top"): CASE(L"mso-padding-top-alt"): { - m_oPadding.AddTop(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetTop(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateTop(dFontSize); break; } CASE(L"padding-right"): CASE(L"mso-padding-right-alt"): { - m_oPadding.AddRight(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetRight(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateRight(dFontSize); break; } CASE(L"padding-bottom"): CASE(L"mso-padding-bottom-alt"): { - m_oPadding.AddBottom(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetBottom(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateBottom(dFontSize); break; } CASE(L"padding-left"): CASE(L"mso-padding-left-alt"): { - m_oPadding.AddLeft(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetLeft(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateLeft(dFontSize); break; } diff --git a/Common/3dParty/html/css/src/CCssCalculator.cpp b/Common/3dParty/html/css/src/CCssCalculator.cpp index 3493b9fc3fd..3ece3b199ff 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator.cpp @@ -23,6 +23,11 @@ namespace NSCSS return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure); } + bool CCssCalculator::CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors) + { + return m_pInternal->CalculatePageStyle(oPageData, arSelectors); + } + void CCssCalculator::AddStyles(const std::string &sStyle) { m_pInternal->AddStyles(sStyle); diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h index 4f58a44073a..02bd6ed9575 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.h +++ b/Common/3dParty/html/css/src/CCssCalculator.h @@ -22,6 +22,8 @@ namespace NSCSS CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const; bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const; + bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); + // void AddStyle(const std::vector& sSelectors, const std::string& sStyle); void AddStyles (const std::string& sStyle); void AddStyles (const std::wstring& wsStyle); diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index d041765288b..6c7ed0b42c8 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -85,7 +85,41 @@ namespace NSCSS } } + + std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) + { + if (m_arPageDatas.empty()) + return {}; + for (const TPageData& oPageData : m_arPageDatas) + { + if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end()) + return oPageData.m_mData; + } + + return {}; + } + + void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map &mData, unsigned int unLevel, bool bHardMode) + { + for (const std::pair &oData : mData) + { + if (L"margin" == oData.first) + oPage.SetMargin(oData.second, unLevel, bHardMode); + else if (L"size" == oData.first) + oPage.SetSize(oData.second, unLevel, bHardMode); + else if (L"mso-header-margin" == oData.first) + oPage.SetHeader(oData.second, unLevel, bHardMode); + else if (L"mso-footer-margin" == oData.first) + oPage.SetFooter(oData.second, unLevel, bHardMode); + } + } + + void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles) + { + m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); + } + inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet) { for (size_t i = 0; i < oStylesheet->imports.length; ++i) @@ -495,14 +529,16 @@ namespace NSCSS return oFirstElement->GetWeight() > oSecondElement->GetWeight(); }); } + + if (L"table" == arSelectors[i].m_wsName) + pStyle->m_oFont.Clear(); - // Данные о border'ах используются только для текущей ноды и не наследуются - pStyle->m_oBorder.Clear(); + CCompiledStyle oTempStyle; - pStyle->AddStyle(arSelectors[i].m_mAttributes, i + 1); + oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); for (const CElement* oElement : arFindElements) - pStyle->AddStyle(oElement->GetStyle(), i + 1); + oTempStyle.AddStyle(oElement->GetStyle(), i + 1); if (NULL != m_mStatictics) { @@ -512,15 +548,17 @@ namespace NSCSS { if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); else if (!bIsSettings) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else if (bIsSettings) - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else - pStyle->AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + + *pStyle += oTempStyle; } if (!bIsSettings) @@ -714,7 +752,6 @@ namespace NSCSS } } - if (arFindElements.size() > 1) { std::sort(arFindElements.rbegin(), arFindElements.rend(), @@ -759,6 +796,176 @@ namespace NSCSS return true; } + + bool CCssCalculator_Private::CalculatePageStyle(NSProperties::CPage &oPageData, const std::vector &arSelectors) + { + if (arSelectors.empty()) + return false; + + std::vector arWords; + std::vector arNextNodes; + + for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) + { + arWords.push_back(oNode->m_wsName); + + if (!oNode->m_wsClass.empty()) + { + if (oNode->m_wsClass.find(L' ') != std::wstring::npos) + { + std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); + + if (arClasses.size() > 1) + arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); + switch (arClasses.size()) + { + case 1: + { + arWords.push_back(L'.' + arClasses[0]); + break; + } + case 2: + { + arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); + break; + } + case 3: + { + arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); + break; + } + default: + { + arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), + [](std::wstring sRes, const std::wstring& sClass) + {return sRes += L'.' + sClass + L' ';})); + break; + } + } + } + else + arWords.push_back(L'.' + oNode->m_wsClass); + } + if (!oNode->m_wsId.empty()) + arWords.push_back(L'#' + oNode->m_wsId); + } + + std::vector arElements; + + for (size_t i = 0; i < arSelectors.size(); ++i) + { + std::wstring sName, sId; + std::vector arClasses; + + if (arWords.back()[0] == L'#') + { + sId = arWords.back(); + arWords.pop_back(); + arNextNodes.push_back(sId); + } + + if (arWords.back()[0] == L'.') + { + arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); + arNextNodes.push_back(arWords.back()); + arWords.pop_back(); + } + + sName = arWords.back(); + arWords.pop_back(); + arNextNodes.push_back(sName); + + const std::map::const_iterator oFindName = m_mData.find(sName); + std::map::const_iterator oFindId; + std::vector arFindElements; + + if (!sId.empty()) + { + oFindId = m_mData.find(sId); + + if (oFindId != m_mData.end()) + { + if (!oFindId->second->Empty()) + arFindElements.push_back(oFindId->second); + + const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); + + if (!arTempPrev.empty()) + arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + + const std::vector arTempKin = oFindId->second->GetNextOfKin(sName); + + if (!arTempKin.empty()) + arFindElements.insert(arFindElements.end(), arTempKin.begin(), arTempKin.end()); + } + } + + if (!arClasses.empty()) + { + for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) + { + const std::map::const_iterator oFindClass = m_mData.find(*iClass); + if (oFindClass != m_mData.end()) + { + if (!oFindClass->second->Empty()) + arFindElements.push_back(oFindClass->second); + + const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); + const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); + + if (!arTempPrev.empty()) + arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + + if (!arTempKins.empty()) + arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); + } + } + } + + if (oFindName != m_mData.end()) + { + if (!oFindName->second->Empty()) + arFindElements.push_back(oFindName->second); + + const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); + const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); + + if (!arTempPrev.empty()) + arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + + if (!arTempKins.empty()) + arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); + } + + if (arFindElements.size() > 1) + { + std::sort(arFindElements.rbegin(), arFindElements.rend(), + [](CElement* oFirstElement, CElement* oSecondElement) + { + return oFirstElement->GetWeight() > oSecondElement->GetWeight(); + }); + } + + if (!arSelectors[i].m_wsStyle.empty() && std::wstring::npos != arSelectors[i].m_wsStyle.find(L"page")) + { + std::map mRules = NS_STATIC_FUNCTIONS::GetRules(arSelectors[i].m_wsStyle); + if (mRules.end() != mRules.find(L"page")) + SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); + } + + for (const CElement* oElement : arFindElements) + { + std::map mRules = oElement->GetStyle(); + if (mRules.end() != mRules.find(L"page")) + SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); + } + + if (arSelectors[i].m_mAttributes.end() != arSelectors[i].m_mAttributes.find(L"page")) + SetPageData(oPageData, GetPageData(arSelectors[i].m_mAttributes.at(L"page")), i + 1, false); + } + + return true; + } #endif void CCssCalculator_Private::AddStyles(const std::string &sStyle) { @@ -775,6 +982,16 @@ namespace NSCSS if (wsStyle.empty()) return; + std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})"); + std::wsmatch oMatch; + std::wstring::const_iterator oSearchStart(wsStyle.cbegin()); + + while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex)) + { + AddPageData(oMatch[1].str(), oMatch[2].str()); + oSearchStart = oMatch.suffix().first; + } + AddStyles(U_TO_UTF8(wsStyle)); } diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 965a30bfd7b..4926db7a04d 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -25,15 +25,28 @@ namespace NSCSS std::list m_arFiles; std::map m_mData; + + typedef struct + { + std::vector m_wsNames; + std::map m_mData; + } TPageData; + + std::vector m_arPageDatas; std::map *m_mStatictics; // Количество повторений свойств id и style у селекторов #ifdef CSS_CALCULATOR_WITH_XHTML std::map, CCompiledStyle*> m_mUsedStyles; + + std::map GetPageData(const std::wstring& wsPageName); + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); #endif std::wstring m_sEncoding; + void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); + void GetStylesheet(const KatanaStylesheet* oStylesheet); void GetRule(const KatanaRule* oRule); @@ -56,6 +69,8 @@ namespace NSCSS #ifdef CSS_CALCULATOR_WITH_XHTML CCompiledStyle GetCompiledStyle(const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point); bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point); + + bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); #endif void AddStyles(const std::string& sStyle); diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp index ce6b08faa88..d0dc327cd4f 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp @@ -159,7 +159,7 @@ namespace NSCSS bool CUnitMeasureConverter::GetValue(const std::wstring &wsValue, double &dValue, UnitMeasure &enUnitMeasure) { - std::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?)\s*(px|pt|cm|mm|in|pc|%|em|rem)?)"); + std::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?)\s*(px|pt|cm|mm|in|pc|%|em|rem|tw)?)"); std::wsmatch oMatches; if(!std::regex_search(wsValue, oMatches, oRegex)) @@ -185,6 +185,8 @@ namespace NSCSS enUnitMeasure = Em; else if (L"rem" == oMatches[3]) enUnitMeasure = Rem; + else if (L"tw" == oMatches[3]) + enUnitMeasure = Twips; else enUnitMeasure = None; diff --git a/Common/3dParty/html/css/src/StaticFunctions.cpp b/Common/3dParty/html/css/src/StaticFunctions.cpp index 237e83249ca..3a70addd453 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.cpp +++ b/Common/3dParty/html/css/src/StaticFunctions.cpp @@ -141,30 +141,17 @@ namespace NS_STATIC_FUNCTIONS std::map GetRules(const std::wstring& wsStyles) { - if (wsStyles.empty()) - return {}; + std::wregex oCssPropertyRegex(L"([a-zA-Z-]+)\\s*:\\s*([^;\t\n\r\f\v]+)"); + std::wsmatch oMatch; - std::map mRules; + std::wstring::const_iterator oSearchStart(wsStyles.cbegin()); - std::wstring::const_iterator oStartProperty = std::find_if_not(wsStyles.begin(), wsStyles.end(), std::iswspace); - std::wstring::const_iterator oEndProperty, oStartValue, oEndValue; + std::map mRules; - while (wsStyles.end() != oStartProperty) + while (std::regex_search(oSearchStart, wsStyles.cend(), oMatch, oCssPropertyRegex)) { - oEndProperty = std::find_if(oStartProperty, wsStyles.end(), [](const wchar_t &wcChar){ return L':' == wcChar;}); - oStartValue = std::find_if_not(oEndProperty + 1, wsStyles.end(), std::iswspace); - - if (wsStyles.end() == oEndProperty || wsStyles.end() == oStartValue) - break; - - oEndValue = std::find_if(oStartValue, wsStyles.end(), [](const wchar_t &wcChar){ return L';' == wcChar;}); - - mRules.insert({std::wstring(oStartProperty, oEndProperty), std::wstring(oStartValue, oEndValue)}); - - if (wsStyles.end() == oEndValue) - break; - - oStartProperty = std::find_if_not(oEndValue + 1, wsStyles.end(), std::iswspace); + mRules.insert(std::make_pair(oMatch[1], oMatch[2])); + oSearchStart = oMatch.suffix().first; } return mRules; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index d86648c4c9f..db8b5679dbd 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -175,7 +175,7 @@ namespace NSCSS bool CDigit::Zero() const { - return (std::abs(0 - m_oValue) <= DBL_EPSILON); + return (std::abs(0. - m_oValue) <= DBL_EPSILON); } void CDigit::Clear() @@ -191,7 +191,7 @@ namespace NSCSS int CDigit::ToInt() const { - if (DBL_MAX == m_oValue) + if (Empty()) return 0; return static_cast(m_oValue + 0.5); @@ -199,7 +199,7 @@ namespace NSCSS double CDigit::ToDouble() const { - if (DBL_MAX == m_oValue) + if (Empty()) return 0.; return m_oValue; @@ -320,7 +320,16 @@ namespace NSCSS if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || DBL_MAX == oDigit.m_oValue) return *this; - m_oValue += oDigit.ToDouble(m_enUnitMeasure); + if (oDigit.Empty()) + return *this; + else if (NSCSS::Percent == oDigit.m_enUnitMeasure && !Empty()) + m_oValue *= oDigit.m_oValue / 100.; + else + { + m_oValue = oDigit.m_oValue; + m_enUnitMeasure = oDigit.m_enUnitMeasure; + } + m_unLevel = oDigit.m_unLevel; m_bImportant = oDigit.m_bImportant; @@ -369,24 +378,11 @@ namespace NSCSS if (m_bImportant && !bImportant) return false; - double dNewValue; - UnitMeasure enNewUnitMeasure; - - if (!CUnitMeasureConverter::GetValue(wsValue, dNewValue, enNewUnitMeasure)) + if (!CUnitMeasureConverter::GetValue(wsValue, m_oValue, m_enUnitMeasure)) return false; - if (Percent == enNewUnitMeasure && !Empty() && (unLevel > m_unLevel || bHardMode)) - { - m_oValue *= dNewValue / 100.; - } - else - { - m_oValue = dNewValue; - m_enUnitMeasure = enNewUnitMeasure; - } - - m_unLevel = unLevel; - m_bImportant = bImportant; + m_unLevel = unLevel; + m_bImportant = bImportant; return true; } @@ -1113,8 +1109,8 @@ namespace NSCSS { m_oX += oDisplay.m_oX; m_oY += oDisplay.m_oY; - m_oWidth += oDisplay.m_oWidth; - m_oHeight += oDisplay.m_oHeight; + m_oWidth = oDisplay.m_oWidth; + m_oHeight = oDisplay.m_oHeight; m_oHAlign += oDisplay.m_oHAlign; m_oVAlign += oDisplay.m_oVAlign; m_oDisplay += oDisplay.m_oDisplay; @@ -1420,9 +1416,9 @@ namespace NSCSS CBorderSide &CBorderSide::operator+=(const CBorderSide &oBorderSide) { - m_oWidth += oBorderSide.m_oWidth; - m_oStyle += oBorderSide.m_oStyle; - m_oColor += oBorderSide.m_oColor; + m_oWidth = oBorderSide.m_oWidth; + m_oStyle = oBorderSide.m_oStyle; + m_oColor = oBorderSide.m_oColor; if (oBorderSide.m_bBlock) m_bBlock = true; @@ -1646,10 +1642,10 @@ namespace NSCSS CBorder &CBorder::operator+=(const CBorder &oBorder) { - m_oLeft += oBorder.m_oLeft; - m_oTop += oBorder.m_oTop; - m_oRight += oBorder.m_oRight; - m_oBottom += oBorder.m_oBottom; + m_oLeft = oBorder.m_oLeft; + m_oTop = oBorder.m_oTop; + m_oRight = oBorder.m_oRight; + m_oBottom = oBorder.m_oBottom; return *this; } @@ -1768,17 +1764,15 @@ namespace NSCSS // MARGIN CIndent::CIndent() - : m_bPermission(true) - {} + : m_bPermission(true) + {} - void CIndent::Equation(CIndent &oFirstMargin, CIndent &oSecondMargin) + void CIndent::Clear() { - //TODO:: добавить корректную реализацию - -// CDigit::Equation(oFirstMargin.m_oLeft, oSecondMargin.m_oLeft); -// CDigit::Equation(oFirstMargin.m_oTop, oSecondMargin.m_oTop); -// CDigit::Equation(oFirstMargin.m_oRight, oSecondMargin.m_oRight); -// CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); + m_oTop .Clear(); + m_oRight .Clear(); + m_oBottom.Clear(); + m_oLeft .Clear(); } void CIndent::SetPermisson(bool bPermission) @@ -1786,187 +1780,143 @@ namespace NSCSS m_bPermission = bPermission; } - bool CIndent::AddValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + void CIndent::Equation(CIndent &oFirstMargin, CIndent &oSecondMargin) + { + CDigit::Equation(oFirstMargin.m_oLeft, oSecondMargin.m_oLeft); + CDigit::Equation(oFirstMargin.m_oTop, oSecondMargin.m_oTop); + CDigit::Equation(oFirstMargin.m_oRight, oSecondMargin.m_oRight); + CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); + } + + bool CIndent::SetValues(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { if (!m_bPermission) return false; - + const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); switch (arValues.size()) { case 1: - { - return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arLeftValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arRightValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arBottomValues, arValues[0], unLevel, bHardMode); - } + return SetValues(arValues[0], arValues[0], arValues[0], arValues[0], unLevel, bHardMode); case 2: - { - return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arBottomValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arLeftValues, arValues[1], unLevel, bHardMode) && - AddSide(m_arRightValues, arValues[1], unLevel, bHardMode); - } + return SetValues(arValues[0], arValues[1], arValues[0], arValues[1], unLevel, bHardMode); case 3: - { - return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arLeftValues, arValues[1], unLevel, bHardMode) && - AddSide(m_arRightValues, arValues[1], unLevel, bHardMode) && - AddSide(m_arBottomValues, arValues[2], unLevel, bHardMode); - } + return SetValues(arValues[0], arValues[1], arValues[2], arValues[1], unLevel, bHardMode); case 4: - { - return AddSide(m_arTopValues, arValues[0], unLevel, bHardMode) && - AddSide(m_arRightValues, arValues[1], unLevel, bHardMode) && - AddSide(m_arBottomValues, arValues[2], unLevel, bHardMode) && - AddSide(m_arLeftValues, arValues[3], unLevel, bHardMode); - } + return SetValues(arValues[0], arValues[1], arValues[2], arValues[3], unLevel, bHardMode); } return false; } - bool CIndent::AddLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetTop(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddSide(m_arLeftValues, wsValue, unLevel, bHardMode); + return m_oTop.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddTop(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddSide(m_arTopValues, wsValue, unLevel, bHardMode); + return m_oRight.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddSide(m_arRightValues, wsValue, unLevel, bHardMode); + return m_oBottom.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddSide(m_arBottomValues, wsValue, unLevel, bHardMode); + return m_oLeft.SetValue(wsValue, unLevel, bHardMode); } - + void CIndent::UpdateAll(double dFontSize) { - UpdateLeft(dFontSize); - UpdateTop(dFontSize); - UpdateRight(dFontSize); + UpdateTop (dFontSize); + UpdateRight (dFontSize); UpdateBottom(dFontSize); + UpdateLeft (dFontSize); } - - void CIndent::UpdateLeft(double dFontSize) - { - UpdateSide(m_arLeftValues, dFontSize); - } - + void CIndent::UpdateTop(double dFontSize) { - UpdateSide(m_arTopValues, dFontSize); + UpdateSide(m_oTop, dFontSize); } - + void CIndent::UpdateRight(double dFontSize) { - UpdateSide(m_arRightValues, dFontSize); + UpdateSide(m_oRight, dFontSize); } - + void CIndent::UpdateBottom(double dFontSize) { - UpdateSide(m_arBottomValues, dFontSize); + UpdateSide(m_oBottom, dFontSize); } - CDigit CIndent::GetLeft() const + void CIndent::UpdateLeft(double dFontSize) { - return CalculateSide(m_arLeftValues); + UpdateSide(m_oLeft, dFontSize); } - CDigit CIndent::GetTop() const + const CDigit &CIndent::GetTop() const { - return CalculateSide(m_arTopValues); + return m_oTop; } - CDigit CIndent::GetRight() const + const CDigit &CIndent::GetRight() const { - return CalculateSide(m_arRightValues); + return m_oRight; } - CDigit CIndent::GetBottom() const + const CDigit &CIndent::GetBottom() const { - return CalculateSide(m_arBottomValues); + return m_oBottom; } + const CDigit &CIndent::GetLeft() const + { + return m_oLeft; + } + bool CIndent::Empty() const { - return m_arLeftValues.empty() && m_arTopValues.empty() && m_arRightValues.empty() && m_arBottomValues.empty(); + return m_oTop.Empty() && m_oRight.Empty() && m_oBottom.Empty() && m_oLeft.Empty(); } - + CIndent &CIndent::operator+=(const CIndent &oIndent) { - m_arLeftValues .insert(m_arLeftValues.end(), oIndent.m_arLeftValues.begin(), oIndent.m_arLeftValues.end()); - m_arTopValues .insert(m_arTopValues.end(), oIndent.m_arTopValues.begin(), oIndent.m_arTopValues.end()); - m_arRightValues .insert(m_arRightValues.end(), oIndent.m_arRightValues.begin(), oIndent.m_arRightValues.end()); - m_arBottomValues.insert(m_arBottomValues.end(), oIndent.m_arBottomValues.begin(), oIndent.m_arBottomValues.end()); + m_oTop += oIndent.m_oTop; + m_oRight += oIndent.m_oRight; + m_oBottom += oIndent.m_oBottom; + m_oLeft += oIndent.m_oLeft; return *this; } - + bool CIndent::operator==(const CIndent &oIndent) const { - // Есть вариант, когда у CIndent разное кол-во значений, но итоговое значение одинаковое - // Пока считаем это не одинаковыми - if (m_arLeftValues .size() != oIndent.m_arLeftValues .size() || - m_arTopValues .size() != oIndent.m_arTopValues .size() || - m_arRightValues .size() != oIndent.m_arRightValues .size() || - m_arBottomValues.size() != oIndent.m_arBottomValues.size()) - return false; - - for (unsigned int unIndex = 0; unIndex < m_arLeftValues.size(); ++unIndex) - { - if (m_arLeftValues [unIndex] != oIndent.m_arLeftValues [unIndex]) return false; - if (m_arTopValues [unIndex] != oIndent.m_arTopValues [unIndex]) return false; - if (m_arRightValues [unIndex] != oIndent.m_arRightValues [unIndex]) return false; - if (m_arBottomValues[unIndex] != oIndent.m_arBottomValues[unIndex]) return false; - } - - return true; + return m_oTop == oIndent.m_oTop && + m_oRight == oIndent.m_oRight && + m_oBottom == oIndent.m_oBottom && + m_oLeft == oIndent.m_oLeft; } - bool CIndent::AddSide(std::vector &arValues, const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetValues(const std::wstring &wsTopValue, const std::wstring &wsRightValue, const std::wstring &wsBottomValue, const std::wstring &wsLeftValue, unsigned int unLevel, bool bHardMode) { - CDigit oValue; - - if (!oValue.SetValue(wsValue, unLevel, bHardMode)) - return false; - - if (!arValues.empty() && CDigit::LevelIsSame(oValue, arValues.back())) - arValues.pop_back(); - - arValues.push_back(oValue); - - return true; + const bool bTopResult = SetTop (wsTopValue, unLevel, bHardMode); + const bool bRightResult = SetRight (wsRightValue, unLevel, bHardMode); + const bool bBottomResult = SetBottom (wsBottomValue, unLevel, bHardMode); + const bool bLeftResult = SetLeft (wsLeftValue, unLevel, bHardMode); + + return bTopResult || bRightResult || bBottomResult || bLeftResult; } - - void CIndent::UpdateSide(std::vector &arValues, double dFontSize) + + void CIndent::UpdateSide(CDigit &oSide, double dFontSize) { - if (arValues.empty()) + if (oSide.Empty()) return; - const UnitMeasure eUM = arValues.back().GetUnitMeasure(); - if (NSCSS::Em == eUM || NSCSS::Rem == eUM) - arValues.back().ConvertTo(NSCSS::Twips, dFontSize); - } - - CDigit CIndent::CalculateSide(const std::vector &arValues) const - { - if (arValues.empty()) - return CDigit(); - - CDigit oValue{arValues.front()}; - - for (std::vector::const_iterator oIter = arValues.begin() + 1; oIter < arValues.end(); ++oIter) - oValue += *oIter; - - return oValue; + if (NSCSS::Em == oSide.GetUnitMeasure() || NSCSS::Rem == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dFontSize); } // FONT @@ -2534,5 +2484,62 @@ namespace NSCSS return std::wstring(); } + CPage::CPage() + {} + + bool CPage::SetMargin(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oMargin.SetValues(wsValue, unLevel, bHardMode); + } + + bool CPage::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + if (wsValue.empty()) + return false; + + std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue); + + if (1 == arValues.size()) + return m_oWidth.SetValue(arValues[0], unLevel, bHardMode) && m_oHeight.SetValue(arValues[0], unLevel, bHardMode); + else if (2 == arValues.size()) + return m_oWidth.SetValue(arValues[0], unLevel, bHardMode) && m_oHeight.SetValue(arValues[1], unLevel, bHardMode); + + return false; + } + + bool CPage::SetFooter(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oFooter.SetValue(wsValue, unLevel, bHardMode); + } + + bool CPage::SetHeader(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + { + return m_oHeader.SetValue(wsValue, unLevel, bHardMode); + } + + const CDigit &CPage::GetWidth() const + { + return m_oWidth; + } + + const CDigit &CPage::GetHeight() const + { + return m_oHeight; + } + + const CIndent &CPage::GetMargin() const + { + return m_oMargin; + } + + const CDigit &CPage::GetFooter() const + { + return m_oFooter; + } + + const CDigit &CPage::GetHeader() const + { + return m_oHeader; + } } } diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index a2b670946fa..42d763c5016 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -86,8 +86,8 @@ namespace NSCSS return *this; m_oValue = oValue.m_oValue; - m_unLevel = std::max(m_unLevel, oValue.m_unLevel); - m_bImportant = std::max(m_bImportant, oValue.m_bImportant); + m_unLevel = oValue.m_unLevel; + m_bImportant = oValue.m_bImportant; return *this; } @@ -584,40 +584,41 @@ namespace NSCSS public: CIndent(); + void Clear(); + static void Equation(CIndent &oFirstMargin, CIndent &oSecondMargin); void SetPermisson(bool bPermission); - bool AddValue (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - bool AddBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - - void UpdateAll(double dFontSize); - void UpdateLeft(double dFontSize); - void UpdateTop(double dFontSize); - void UpdateRight(double dFontSize); + bool SetValues (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + + void UpdateAll (double dFontSize); + void UpdateTop (double dFontSize); + void UpdateRight (double dFontSize); void UpdateBottom(double dFontSize); + void UpdateLeft (double dFontSize); - CDigit GetLeft () const; - CDigit GetTop () const; - CDigit GetRight () const; - CDigit GetBottom() const; + const CDigit& GetTop () const; + const CDigit& GetRight () const; + const CDigit& GetBottom() const; + const CDigit& GetLeft () const; bool Empty() const; CIndent& operator+=(const CIndent& oIndent); bool operator==(const CIndent& oIndent) const; private: - bool AddSide(std::vector& arValues, const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - void UpdateSide(std::vector& arValues, double dFontSize); - CDigit CalculateSide(const std::vector& arValues) const; + bool SetValues(const std::wstring& wsTopValue, const std::wstring& wsRightValue, const std::wstring& wsBottomValue, const std::wstring& wsLeftValue, unsigned int unLevel, bool bHardMode = false); + void UpdateSide(CDigit& oSide, double dFontSize); - std::vector m_arLeftValues; - std::vector m_arTopValues; - std::vector m_arRightValues; - std::vector m_arBottomValues; + CDigit m_oLeft; + CDigit m_oTop; + CDigit m_oRight; + CDigit m_oBottom; bool m_bPermission; }; @@ -670,6 +671,29 @@ namespace NSCSS TTextDecoration m_oTextDecoration; }; + + class CPage + { + public: + CPage(); + + bool SetMargin (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetSize (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetFooter (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetHeader (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + + const CDigit& GetWidth() const; + const CDigit& GetHeight() const; + const CIndent& GetMargin() const; + const CDigit& GetFooter() const; + const CDigit& GetHeader() const; + private: + CDigit m_oWidth; + CDigit m_oHeight; + CIndent m_oMargin; + CDigit m_oFooter; + CDigit m_oHeader; + }; } } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index a9365991e68..3212f5645b9 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -6,10 +6,9 @@ #include #include +#define DEFAULT_LINEHEIGHT 240 #define LINEHEIGHTSCALE 10 // Значение LineHeight в OOXML должно быть в 10 раз больше чем указано в стиле -#define DOUBLE_TO_INTW(dValue) std::to_wstring(static_cast(dValue + 0.5)) - namespace NSCSS { CStyleUsed::CStyleUsed(const CCompiledStyle &oStyle, bool bIsPStyle) @@ -277,61 +276,40 @@ namespace NSCSS std::wstring sInfValue; sInfValue.reserve(64); - //TODO:: проверить Permission в Margin - if (!oStyle.m_oMargin.Empty() || !oStyle.m_oPadding.Empty() /*&& oStyle.m_oMargin.GetPermission()*/) - { - const double dLeftSide = oStyle.m_oMargin.GetLeft() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetLeft() .ToDouble(NSCSS::Twips); - const double dRightSide = oStyle.m_oMargin.GetRight().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetRight().ToDouble(NSCSS::Twips); +// if (!oStyle.m_oPadding.GetLeft().Empty() && !oStyle.m_oPadding.GetLeft().Zero()) +// sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetLeft().ToDouble(NSCSS::Twips)) + L"\" "; - sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(dLeftSide) + L"\" "; - sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(dRightSide) + L"\" "; - } +// if (!oStyle.m_oPadding.GetRight().Empty() && !oStyle.m_oPadding.GetRight().Zero()) +// sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetRight().ToDouble(NSCSS::Twips)) + L"\" "; - const double dIndent = oStyle.m_oText.GetIndent().ToDouble(NSCSS::Twips); + const int nIndent = oStyle.m_oText.GetIndent().ToInt(NSCSS::Twips); - if (0. != dIndent) - sInfValue += L"w:firstLine=\"" + DOUBLE_TO_INTW(dIndent) + L"\" "; + if (0 != nIndent) + sInfValue += L"w:firstLine=\"" + std::to_wstring(nIndent) + L"\" "; oXmlElement.AddPropertiesInP(PProperties::P_Ind, sInfValue); std::wstring sSpacingValue; sSpacingValue.reserve(128); - //TODO:: проверить Permission в Margin - if (!oStyle.m_oMargin.Empty() || !oStyle.m_oPadding.Empty()/*&& oStyle.m_oMargin.GetPermission()*/) - { - const double dSpacingBottom = oStyle.m_oMargin.GetBottom().ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetBottom().ToDouble(NSCSS::Twips); - const double dSpacingTop = oStyle.m_oMargin.GetTop() .ToDouble(NSCSS::Twips) + oStyle.m_oPadding.GetTop() .ToDouble(NSCSS::Twips);; - - sSpacingValue += L" w:after=\"" + DOUBLE_TO_INTW(dSpacingBottom) + L"\" "; - sSpacingValue += L" w:before=\"" + DOUBLE_TO_INTW(dSpacingTop) + L"\" "; - } - else/* if (!oStyle.m_pBorder.Empty() || !oStyle.m_oMargin.GetPermission())*/ - sSpacingValue += L"w:after=\"0\" w:before=\"0\""; +// if (!oStyle.m_oPadding.GetBottom().Empty() && !oStyle.m_oPadding.GetBottom().Zero()) +// sSpacingValue += L"w:after=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetBottom().ToDouble(NSCSS::Twips)) + L"\" "; - std::wstring wsLineHeight; - - if (!oStyle.m_oFont.GetLineHeight().Empty()) - { - double dLineHeight = oStyle.m_oFont.GetLineHeight().ToDouble(NSCSS::Twips) * LINEHEIGHTSCALE; +// if (!oStyle.m_oPadding.GetTop().Empty() && !oStyle.m_oPadding.GetTop().Zero()) +// sSpacingValue += L"w:before=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetTop().ToDouble(NSCSS::Twips)) + L"\" "; + +// else/* if (!oStyle.m_pBorder.Empty() || !oStyle.m_oMargin.GetPermission())*/ +// sSpacingValue += L"w:after=\"0\" w:before=\"0\""; + + if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) + sSpacingValue += L" w:line=\"" + std::to_wstring(oStyle.m_oFont.GetLineHeight().ToInt(NSCSS::Twips, DEFAULT_LINEHEIGHT)) + L"\" w:lineRule=\"auto\""; -// if (NSCSS::None == oStyle.m_oFont.GetLineHeight().GetUnitMeasure()) -// dLineHeight *= LINEHEIGHTCOEF; - - if (0. != dLineHeight) - wsLineHeight = DOUBLE_TO_INTW(dLineHeight); - } - - if (!wsLineHeight.empty()) - { - sSpacingValue += L" w:line=\"" + wsLineHeight + L"\" w:lineRule=\"auto\""; - } // else if (!oStyle.m_oBorder.Empty()) // { // sSpacingValue += L" w:line=\"" + std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Twips) * 2 * POINTCOEF + 0.5f)) + L"\" w:lineRule=\"auto\""; // } else if (!oStyle.m_oBorder.Empty()) - sSpacingValue += L" w:line=\"240\" w:lineRule=\"auto\" "; + sSpacingValue += L" w:line=\"" + std::to_wstring(DEFAULT_LINEHEIGHT) + L"\" w:lineRule=\"auto\" "; if (!sSpacingValue.empty()) { @@ -443,7 +421,7 @@ namespace NSCSS return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, DOUBLE_TO_INTW(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2.)); // Значения шрифта увеличивает на 2 + oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2.)); // Значения шрифта увеличивает на 2 if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index a246410bc21..f4ffd804490 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -10,6 +10,7 @@ CONFIG += plugin DEFINES += HTMLFILE2_USE_DYNAMIC_LIBRARY DEFINES += CSSCALCULATOR_LIBRARY_STATIC +DEFINES += CSS_CALCULATOR_WITH_XHTML CORE_ROOT_DIR = $$PWD/.. PWD_ROOT_DIR = $$PWD diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index e3529db72a7..9025aec84bd 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -37,6 +37,9 @@ #define MAXCOLUMNSINTABLE 63 #define MAXROWSINTABLE 32767 +#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips +#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips + std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym "; //struct CTree @@ -113,6 +116,8 @@ class CHtmlFile2_Private NSCSS::CCssCalculator m_oStylesCalculator; // Css калькулятор NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль + NSCSS::NSProperties::CPage m_oPageData; // Стили страницы + std::wstring m_sTmp; // Temp папка std::wstring m_sSrc; // Директория источника std::wstring m_sDst; // Директория назначения @@ -139,16 +144,17 @@ class CHtmlFile2_Private std::vector m_arrImages; // Картинки std::map m_mFootnotes; // Сноски - - UINT m_unWidth; - UINT m_unHeight; public: CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), - m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false), - m_unWidth(12240), m_unHeight(15840) // Размеры страницы указаны в Twips - {} + m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) + { + m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); + m_oPageData.SetMargin(L"720tw 720tw 720tw 720tw", 0, true); + m_oPageData.SetFooter(L"720tw", 0, true); + m_oPageData.SetHeader(L"720tw", 0, true); + } ~CHtmlFile2_Private() { @@ -329,7 +335,7 @@ class CHtmlFile2_Private if(oParams && !oParams->m_sdocDefaults.empty()) m_oStylesXml += oParams->m_sdocDefaults; else - m_oStylesXml += L""; + m_oStylesXml += L""; // normal по умолчанию if(oParams && !oParams->m_sNormal.empty()) @@ -384,7 +390,18 @@ class CHtmlFile2_Private if (m_bInP) m_oDocXml.WriteString(L""); - m_oDocXml.WriteString(L""); + + m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); + m_oDocXml.WriteString(L""); + NSFile::CFileBinary oDocumentWriter; if (oDocumentWriter.CreateFileW(m_sDst + L"/word/document.xml")) { @@ -463,14 +480,14 @@ class CHtmlFile2_Private sFileContent.replace(nFind, nFindEnd - nFind, "1.0"); } std::wstring sRes = htmlToXhtml(sFileContent, bNeedConvert); - /* - NSFile::CFileBinary oWriter; - if (oWriter.CreateFileW(m_sTmp + L"/res.html")) - { - oWriter.WriteStringUTF8(sRes); - oWriter.CloseFile(); - } - */ + +// NSFile::CFileBinary oWriter; +// if (oWriter.CreateFileW(m_sTmp + L"/res.html")) +// { +// oWriter.WriteStringUTF8(sRes); +// oWriter.CloseFile(); +// } + return m_oLightReader.FromString(sRes); } @@ -1047,6 +1064,8 @@ class CHtmlFile2_Private // aside возможно использовать для сносок в epub else if (sName == L"aside" || sName == L"div") { + m_oStylesCalculator.CalculatePageStyle(m_oPageData, sSelectors); + int bMsoFootnote = 0; std::wstring sFootnoteID; while (m_oLightReader.MoveToNextAttribute()) @@ -1200,7 +1219,9 @@ class CHtmlFile2_Private } void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const NSCSS::CCompiledStyle& oTableStyle) - { + { + const std::wstring wsName = m_oLightReader.GetName(); + std::vector mTable; int nDeath = m_oLightReader.GetDepth(); int i = 1; // Строка @@ -1230,8 +1251,16 @@ class CHtmlFile2_Private int j = 1; // Столбец oXml->WriteString(L""); - if (oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) - oXml->WriteString(L""); + std::wstring wsTrPr; + + if (L"thead" == wsName) + wsTrPr += L""; + + if (!bTableHasBorderAttribute && oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + wsTrPr += L""; + + if (!wsTrPr.empty()) + oXml->WriteString(L"" + wsTrPr + L""); do { @@ -1265,8 +1294,19 @@ class CHtmlFile2_Private GetSubClass(oXml, sSelectors); oXml->WriteString(L""); - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, true); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, false); + std::vector arNewSelectors; + + for (std::vector::const_iterator oIter = sSelectors.cbegin(); oIter < sSelectors.cend(); ++oIter) + { + if (L"table" == oIter->m_wsName) + { + arNewSelectors.insert(arNewSelectors.end(), oIter, sSelectors.cend()); + break; + } + } + + NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(arNewSelectors, true); + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(arNewSelectors, false); NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); @@ -1300,6 +1340,25 @@ class CHtmlFile2_Private else wsTcPr += L""; + if (!oStyle.m_oPadding.Empty()) + { + const int nTopPadding = std::max(oTableStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(oTableStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nBottomPadding = std::max(oTableStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oStyle .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(oTableStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + + wsTcPr += L"" + "" + "" + "" + "" + ""; + } + if(nRowspan != 1) { oXml->WriteString(L""); @@ -1406,7 +1465,10 @@ class CHtmlFile2_Private if (!oStyle.m_oDisplay.GetWidth().Empty()) { if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) + { + wsTable += L""; + } else wsTable += L""; } @@ -1440,10 +1502,10 @@ class CHtmlFile2_Private if (!oStyle.m_oPadding.Empty()) { - const int nTopPadding = std::max(0, oStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, m_unHeight)); - const int nLeftPadding = std::max(0, oStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, m_unWidth )); - const int nBottomPadding = std::max(0, oStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, m_unHeight)); - const int nRightPadding = std::max(0, oStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, m_unWidth )); + const int nTopPadding = std::max(0, oStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(0, oStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nBottomPadding = std::max(0, oStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(0, oStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); wsTable += L"" "" From 0c998e318b36f74b4050ac980a79ad517c901c24 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 24 Feb 2024 12:10:57 +0300 Subject: [PATCH 335/794] fix bug #34418 --- X2tConverter/src/lib/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X2tConverter/src/lib/common.h b/X2tConverter/src/lib/common.h index 889e31a8668..4e17ab999d8 100644 --- a/X2tConverter/src/lib/common.h +++ b/X2tConverter/src/lib/common.h @@ -453,7 +453,7 @@ namespace NExtractTools else { COfficeUtils oCOfficeUtils(NULL); - hRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOXMLDir, sTo, true)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + hRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOXMLDir, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; } } else if (AVS_ERROR_DRM == hRes) From 7733825458b5156f0fee456cfc1ae6da60a856bd Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 26 Feb 2024 11:56:48 +0300 Subject: [PATCH 336/794] Fix compile --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index fc00ce1b7aa..5bb3bc109e5 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -71,6 +71,12 @@ #include #include +#ifndef MININT32 +#define MAXUINT32 ((uint32_t)~((uint32_t)0)) +#define MAXINT32 ((int32_t)(MAXUINT32 >> 1)) +#define MININT32 ((int32_t)~MAXINT32) +#endif + using namespace XLS; namespace OOX From bb9e5c590a720ac3099b4acd387d76387479b42b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 26 Feb 2024 14:34:31 +0300 Subject: [PATCH 337/794] Create ctShapeStart and ctShapeEnd --- DesktopEditor/graphics/IRenderer.h | 2 ++ DesktopEditor/graphics/MetafileToRenderer.cpp | 4 ++++ DesktopEditor/graphics/MetafileToRenderer.h | 2 ++ .../graphics/MetafileToRendererReader.cpp | 2 ++ DesktopEditor/graphics/commands/AnnotField.h | 16 ++++++++++++++++ PdfFile/PdfFile.cpp | 10 ++++++++++ 6 files changed, 36 insertions(+) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index feb28daab37..10537695936 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -147,6 +147,8 @@ class IAdvancedCommand Annotaion = 4, DeleteAnnot = 5, WidgetsInfo = 6, + ShapeStart = 7, + ShapeEnd = 8, Undefined = 255 }; diff --git a/DesktopEditor/graphics/MetafileToRenderer.cpp b/DesktopEditor/graphics/MetafileToRenderer.cpp index b12fc408a85..cb222a7c851 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -925,6 +925,8 @@ namespace NSOnlineOfficeBinToPdf case ctAnnotField: case ctAnnotFieldDelete: case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Undefined; switch (eCommand) @@ -933,6 +935,8 @@ namespace NSOnlineOfficeBinToPdf case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotaion; break; case ctAnnotFieldDelete: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::DeleteAnnot; break; case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break; + case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break; + case ctShapeEnd: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; break; default: break; } diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index 57f64880f9c..836cd7a6909 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -183,6 +183,8 @@ namespace NSOnlineOfficeBinToPdf ctAnnotField = 164, ctAnnotFieldDelete = 165, ctWidgetsInfo = 166, + ctShapeStart = 167, + ctShapeEnd = 168, ctPageWidth = 200, ctPageHeight = 201, diff --git a/DesktopEditor/graphics/MetafileToRendererReader.cpp b/DesktopEditor/graphics/MetafileToRendererReader.cpp index d40d1029892..46827f59b47 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -58,6 +58,8 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: return Read_Command (this, pCorrector); case ctAnnotFieldDelete: return Read_Command(this, pCorrector); case ctWidgetsInfo: return Read_Command (this, pCorrector); + case ctShapeStart: return Read_Command (this, pCorrector); + case ctShapeEnd: return Read_Command (this, pCorrector); default: break; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 2d403218925..47a182327eb 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -524,4 +524,20 @@ class GRAPHICS_DECL CWidgetsInfo : public IAdvancedCommand std::vector m_arrParents; }; +class GRAPHICS_DECL CShapeStart : public IAdvancedCommand +{ +public: + CShapeStart(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); +}; + +class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand +{ +public: + CShapeEnd(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); +}; + #endif // _BUILD_ANNOTFIELD_H_ diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 7d4d916ad3c..7280c778548 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -2297,6 +2297,8 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma case IAdvancedCommand::AdvancedCommandType::Annotaion: case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: return S_OK; default: break; @@ -2361,6 +2363,14 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) #endif return S_OK; } + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + { + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + { + return S_OK; + } default: break; } From 147d8ca783bd98992b30574ca98e44c4228c0d00 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 26 Feb 2024 16:14:04 +0300 Subject: [PATCH 338/794] for bug #66596 --- .../Presentation/BinaryFileReaderWriter.cpp | 34 +++++++++---------- .../Presentation/BinaryFileReaderWriter.h | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 1c8ac5ae10f..8c0481f39ca 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -231,7 +231,7 @@ namespace NSBinPptxRW if (IsNeedDownload(strInput)) return DownloadImage(strInput); - std::map::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput : strBase64Image); + std::map::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput + oleData : strBase64Image + oleData); if (pPair != m_mapImages.end()) { @@ -386,9 +386,9 @@ namespace NSBinPptxRW } if (strBase64Image.empty()) - m_mapImages[strInput] = oImageManagerInfo; + m_mapImages[strInput + oleData] = oImageManagerInfo; else - m_mapImages [strBase64Image] = oImageManagerInfo; + m_mapImages [strBase64Image + oleData] = oImageManagerInfo; return oImageManagerInfo; } bool CImageManager2::WriteOleData(const std::wstring& sFilePath, const std::wstring& sData) @@ -1399,7 +1399,7 @@ namespace NSBinPptxRW } - CRelsGenerator::CRelsGenerator(CImageManager2* pManager) : m_lNextRelsID(1), m_mapImages() + CRelsGenerator::CRelsGenerator(CImageManager2* pManager) : m_lNextRelsID(1), m_mapRelsImages() { m_pManager = pManager; m_pWriter = new NSStringUtils::CStringBuilder(); @@ -1412,7 +1412,7 @@ namespace NSBinPptxRW { m_pWriter->ClearNoAttack(); m_lNextRelsID = 1; - m_mapImages.clear(); + m_mapRelsImages.clear(); m_mapLinks.clear(); } @@ -1614,20 +1614,20 @@ namespace NSBinPptxRW { _imageManager2Info oImageManagerInfo = m_pManager->GenerateMedia(strImage); - std::wstring strImageRelsPath; + std::wstring strMediaRelsPath; - if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strImageRelsPath = L"media/"; - else strImageRelsPath = L"../media/"; + if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; + else strMediaRelsPath = L"../media/"; _relsGeneratorInfo oRelsGeneratorInfo; if (!oImageManagerInfo.sFilepathImage.empty()) { - strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); + strMediaRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); - std::map::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map::iterator pPair = m_mapRelsImages.find(strMediaRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1640,16 +1640,16 @@ namespace NSBinPptxRW if (type == 0) { m_pWriter->WriteString( L""); + L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + strMediaRelsPath + L"\"/>"); } else if (type == 1) { m_pWriter->WriteString( L""); + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio\" Target=\"" + strMediaRelsPath + L"\"/>"); } } - m_mapImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair(strMediaRelsPath, oRelsGeneratorInfo)); return oRelsGeneratorInfo; } @@ -1668,9 +1668,9 @@ namespace NSBinPptxRW { strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); - std::map::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map::iterator pPair = m_mapRelsImages.find(strImageRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1756,7 +1756,7 @@ namespace NSBinPptxRW } } } - m_mapImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair(strImageRelsPath, oRelsGeneratorInfo)); return oRelsGeneratorInfo; } diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 8d4338d794b..7ac79d1fab2 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -468,7 +468,7 @@ namespace NSBinPptxRW { private: NSStringUtils::CStringBuilder* m_pWriter; - std::map m_mapImages; + std::map m_mapRelsImages; std::map m_mapLinks; public: unsigned int m_lNextRelsID; From 168aa04b8fac8e3ffc176be4249810676ace4291 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 26 Feb 2024 17:27:37 +0300 Subject: [PATCH 339/794] Separate CAnnotMarkup::ReadRC --- PdfFile/PdfReader.cpp | 65 +++++++++++++ PdfFile/SrcReader/PdfAnnot.cpp | 169 ++++++++++++++++++--------------- PdfFile/SrcReader/PdfAnnot.h | 21 ++-- 3 files changed, 167 insertions(+), 88 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 404e6b79ea4..730fa9703bf 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1031,6 +1031,71 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) oR.free(); oFonts.free(); oFontRef.free(); } + for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) + { + Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage + 1); + if (!pPage) + continue; + + Object oAnnots; + if (!pPage->getAnnots(&oAnnots)->isArray()) + { + oAnnots.free(); + continue; + } + + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + { + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + oAnnot.free(); + continue; + } + + Object oSubtype; + std::string sType; + if (oAnnot.dictLookup("Subtype", &oSubtype)->isName()) + sType = oSubtype.getName(); + oSubtype.free(); + + if (sType != "FreeText") + { + oAnnot.free(); + continue; + } + + Object oObj; + if (!oAnnot.dictLookup("RC", &oObj)->isString()) + { + oAnnot.free(); oObj.free(); + continue; + } + + TextString* s = new TextString(oObj.getString()); + std::string sRC = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + oObj.free(); + + Object oAnnotRef; + oAnnots.arrayGetNF(i, &oAnnotRef); + std::vector arrRC = PdfReader::CAnnotMarkup::ReadRC(sRC); + std::map mFreeText = PdfReader::CAnnotMarkup::SetFont(m_pPDFDocument, &oAnnotRef, m_pFontManager, m_pFontList, arrRC, nTypeFonts); + for (std::map::iterator it = mFreeText.begin(); it != mFreeText.end(); ++it) + { + if (m_mFonts.find(it->first) != m_mFonts.end()) + continue; + + oRes.WriteString(U_TO_UTF8(it->first)); + nFontsID++; + m_mFonts[it->first] = it->second; + } + oAnnotRef.free(); + } + + oAnnots.free(); + } + oRes.AddInt(nFontsID, nFontsPos); oRes.WriteLen(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index c70ef31ad0a..8deee839af1 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2125,59 +2125,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : std::string sRC = DictLookupString(&oAnnot, "RC", 3); // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock - XmlUtils::CXmlLiteReader oLightReader; - if (!sRC.empty() && oLightReader.FromStringA(sRC) && oLightReader.ReadNextNode() && oLightReader.GetNameA() == "body") - { - CFontData oFontBase; - while (oLightReader.MoveToNextAttribute()) - { - if (oLightReader.GetNameA() == "style") - { - ReadFontData(oLightReader.GetTextA(), &oFontBase); - break; - } - } - oLightReader.MoveToElement(); - - int nDepthP = oLightReader.GetDepth(); - while (oLightReader.ReadNextSiblingNode2(nDepthP)) - { - if (oLightReader.GetNameA() != "p") - continue; - - int nDepthSpan = oLightReader.GetDepth(); - if (oLightReader.IsEmptyNode() || !oLightReader.ReadNextSiblingNode2(nDepthSpan)) - continue; - - do - { - std::string sName = oLightReader.GetNameA(); - if (sName == "span") - { - CFontData* pFont = new CFontData(oFontBase); - while (oLightReader.MoveToNextAttribute()) - { - if (oLightReader.GetNameA() == "style") - { - ReadFontData(oLightReader.GetTextA(), pFont); - break; - } - } - oLightReader.MoveToElement(); - - pFont->sText = oLightReader.GetText2A(); - m_arrRC.push_back(pFont); - } - else if (sName == "#text") - { - CFontData* pFont = new CFontData(oFontBase); - pFont->sText = oLightReader.GetTextA(); - m_arrRC.push_back(pFont); - } - } while (oLightReader.ReadNextSiblingNode2(nDepthSpan)); - } - } - oLightReader.Clear(); + m_arrRC = ReadRC(sRC); if (m_arrRC.empty()) m_unFlags &= ~(1 << 3); else @@ -2214,10 +2162,73 @@ CAnnotMarkup::~CAnnotMarkup() for (int i = 0; i < m_arrRC.size(); ++i) RELEASEOBJECT(m_arrRC[i]); } -std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList) +std::vector CAnnotMarkup::ReadRC(const std::string& sRC) +{ + std::vector arrRC; + + XmlUtils::CXmlLiteReader oLightReader; + if (sRC.empty() || !oLightReader.FromStringA(sRC) || !oLightReader.ReadNextNode() || oLightReader.GetNameA() != "body") + return arrRC; + + CFontData oFontBase; + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + ReadFontData(oLightReader.GetTextA(), &oFontBase); + break; + } + } + oLightReader.MoveToElement(); + + int nDepthP = oLightReader.GetDepth(); + while (oLightReader.ReadNextSiblingNode2(nDepthP)) + { + if (oLightReader.GetNameA() != "p") + continue; + + int nDepthSpan = oLightReader.GetDepth(); + if (oLightReader.IsEmptyNode() || !oLightReader.ReadNextSiblingNode2(nDepthSpan)) + continue; + + do + { + std::string sName = oLightReader.GetNameA(); + if (sName == "span") + { + CFontData* pFont = new CFontData(oFontBase); + while (oLightReader.MoveToNextAttribute()) + { + if (oLightReader.GetNameA() == "style") + { + ReadFontData(oLightReader.GetTextA(), pFont); + break; + } + } + oLightReader.MoveToElement(); + + pFont->sText = oLightReader.GetText2A(); + arrRC.push_back(pFont); + } + else if (sName == "#text") + { + CFontData* pFont = new CFontData(oFontBase); + pFont->sText = oLightReader.GetTextA(); + arrRC.push_back(pFont); + } + } while (oLightReader.ReadNextSiblingNode2(nDepthSpan)); + } + + return arrRC; +} +std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +{ + return SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); +} +std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, const std::vector& arrRC, int nTypeFonts) { std::map mRes; - if (m_arrRC.empty()) + if (arrRC.empty()) return mRes; Object oAnnot, oObj; @@ -2237,7 +2248,7 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec { std::string sFontName, sActual; bool bBold = false, bItalic = false; - std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, 3, sFontName, sActual, bBold, bItalic); + std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); const unsigned char* pData14 = NULL; unsigned int nSize14 = 0; @@ -2251,14 +2262,14 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec oFontRef.free(); } - for (int i = 0; i < m_arrRC.size(); ++i) + for (int i = 0; i < arrRC.size(); ++i) { - if (m_arrRC[i]->bFind) + if (arrRC[i]->bFind) continue; - std::string sFontName = m_arrRC[i]->sFontFamily; - bool bBold = (bool)((m_arrRC[i]->unFontFlags >> 0) & 1); - bool bItalic = (bool)((m_arrRC[i]->unFontFlags >> 1) & 1); + std::string sFontName = arrRC[i]->sFontFamily; + bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); + bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); if (sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats") { if (sFontName == "Times New Roman") @@ -2287,16 +2298,16 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec std::wstring wsFontName = UTF8_TO_U(sFontName); if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); - std::string sFontNameBefore = m_arrRC[i]->sFontFamily; - m_arrRC[i]->sFontFamily = sFontName; - m_arrRC[i]->bFind = true; + std::string sFontNameBefore = arrRC[i]->sFontFamily; + arrRC[i]->sFontFamily = sFontName; + arrRC[i]->bFind = true; - for (int j = i; j < m_arrRC.size(); ++j) + for (int j = i; j < arrRC.size(); ++j) { - if (m_arrRC[j]->sFontFamily == sFontNameBefore) + if (arrRC[j]->sFontFamily == sFontNameBefore) { - m_arrRC[j]->sFontFamily = sFontName; - m_arrRC[j]->bFind = true; + arrRC[j]->sFontFamily = sFontName; + arrRC[j]->bFind = true; } } } @@ -2315,29 +2326,29 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); if (bFreeText) { - m_arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); + arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); mRes[pFontInfo->m_wsFontName] = pFontInfo->m_wsFontPath; } else { - m_arrRC[i]->unFontFlags |= (1 << 6); - m_arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); + arrRC[i]->unFontFlags |= (1 << 6); + arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); } - m_arrRC[i]->bFind = true; + arrRC[i]->bFind = true; - std::string sFontNameNew = bFreeText ? m_arrRC[i]->sFontFamily : m_arrRC[i]->sActualFont; - for (int j = i; j < m_arrRC.size(); ++j) + std::string sFontNameNew = bFreeText ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont; + for (int j = i; j < arrRC.size(); ++j) { - if (m_arrRC[j]->sFontFamily == sFontName) + if (arrRC[j]->sFontFamily == sFontName) { if (bFreeText) - m_arrRC[j]->sFontFamily = sFontNameNew; + arrRC[j]->sFontFamily = sFontNameNew; else { - m_arrRC[j]->unFontFlags |= (1 << 6); - m_arrRC[j]->sActualFont = sFontNameNew; + arrRC[j]->unFontFlags |= (1 << 6); + arrRC[j]->sActualFont = sFontNameNew; } - m_arrRC[j]->bFind = true; + arrRC[j]->bFind = true; } } } diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index eb90ea9da5a..f28809dd6c9 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -327,14 +327,6 @@ class CAnnotPopup final : public CAnnot class CAnnotMarkup : public CAnnot { public: - std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); -protected: - CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); - virtual ~CAnnotMarkup(); - - virtual void ToWASM(NSWasm::CData& oRes) override; - -private: struct CFontData final { bool bFind; @@ -350,7 +342,18 @@ class CAnnotMarkup : public CAnnot CFontData() : bFind(false), nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {} CFontData(const CFontData& oFont); }; - void ReadFontData(const std::string& sData, CFontData* pFont); + + static std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, const std::vector& arrRC, int nTypeFonts = 3); + std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + static std::vector ReadRC(const std::string& sRC); +protected: + CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + virtual ~CAnnotMarkup(); + + virtual void ToWASM(NSWasm::CData& oRes) override; + +private: + static void ReadFontData(const std::string& sData, CFontData* pFont); BYTE m_nRT; // Тип аннотации-ответа unsigned int m_unRefNumPopup; // Номер ссылки на всплывающую аннотацию From 88a6f5815c9060fe5f0ec640651d1ce8ff9f1249 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 26 Feb 2024 17:29:21 +0300 Subject: [PATCH 340/794] Add ScanPage --- DocxRenderer/DocxRenderer.cpp | 101 ++++++++++-------- DocxRenderer/DocxRenderer.h | 6 +- DocxRenderer/src/logic/Document.cpp | 69 ++++++------ DocxRenderer/src/logic/Document.h | 68 ++++++------ DocxRenderer/src/logic/Page.cpp | 97 ++++++++++------- DocxRenderer/src/logic/Page.h | 46 +++++--- DocxRenderer/src/logic/elements/ContText.cpp | 59 ++++++++-- DocxRenderer/src/logic/elements/ContText.h | 1 + .../src/logic/managers/FontStyleManager.cpp | 4 - .../src/logic/managers/FontStyleManager.h | 9 +- .../src/logic/managers/ImageManager.cpp | 2 +- .../src/logic/managers/ImageManager.h | 2 +- DocxRenderer/test/main.cpp | 8 +- 13 files changed, 277 insertions(+), 195 deletions(-) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index c323a03e13d..3f9321376c1 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -54,27 +54,18 @@ CDocxRenderer::CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts) { m_pInternal = new CDocxRenderer_Private(pAppFonts, this); } - CDocxRenderer::~CDocxRenderer() { RELEASEOBJECT(m_pInternal); } - -HRESULT CDocxRenderer::CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress) -{ - m_pInternal->m_oDocument.m_strDstFilePath = wsPath; - m_pInternal->m_oDocument.m_strTempDirectory = bIsOutCompress ? - NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory) : - m_pInternal->m_sTempDirectory; - m_pInternal->m_oDocument.CreateDocument(); - return S_OK; -} -HRESULT CDocxRenderer::Close() +HRESULT CDocxRenderer::Compress() { COfficeUtils oCOfficeUtils(nullptr); HRESULT hr = oCOfficeUtils.CompressFileOrDirectory(m_pInternal->m_oDocument.m_strTempDirectory, m_pInternal->m_oDocument.m_strDstFilePath, true); + if (!m_pInternal->m_oDocument.m_strTempDirectory.empty()) NSDirectory::DeleteDirectory(m_pInternal->m_oDocument.m_strTempDirectory); + m_pInternal->m_oDocument.m_strTempDirectory = L""; return hr; } @@ -87,52 +78,74 @@ HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociat int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) { - // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", - // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) - // может быть одной и той же. И создание там файлов функцией создания временных файлов - // может вернуть один и тот же путь. И шрифт возьмется из старого файла. - m_pInternal->m_oDocument.m_oFontManager.ClearCache(); - if (m_pInternal->m_oDocument.m_pAppFonts) - m_pInternal->m_oDocument.m_pAppFonts->GetStreams()->Clear(); + m_pInternal->m_oDocument.m_strDstFilePath = sDstFile; - CreateNewFile(sDstFile, bIsOutCompress); + if (bIsOutCompress) + m_pInternal->m_oDocument.m_strTempDirectory = NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory); + else + m_pInternal->m_oDocument.m_strTempDirectory= m_pInternal->m_sTempDirectory; - if (odftPDF == pFile->GetType()) - m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; + m_pInternal->m_oDocument.Init(); + m_pInternal->m_oDocument.CreateTemplates(); int nPagesCount = pFile->GetPagesCount(); m_pInternal->m_oDocument.m_lNumberPages = nPagesCount; for (int i = 0; i < nPagesCount; ++i) - { - //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; - NewPage(); - BeginCommand(c_nPageType); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; - m_pInternal->m_oDocument.m_lPagesCount = i; + DrawPage(pFile, i); - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + HRESULT hr = S_OK; + m_pInternal->m_oDocument.Write(); + m_pInternal->m_oDocument.Clear(); + if (bIsOutCompress) hr = Compress(); + return (hr == S_OK) ? 0 : 1; +} - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; +std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, size_t nPage) +{ + m_pInternal->m_oDocument.Clear(); + m_pInternal->m_oDocument.Init(); - put_Width(dWidth); - put_Height(dHeight); + m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true; + m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true; - pFile->DrawPageOnRenderer(this, i, nullptr); + DrawPage(pFile, nPage); - m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; - EndCommand(c_nPageType); + std::vector xml_shapes; + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXml(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; } - - HRESULT hr = S_OK; - m_pInternal->m_oDocument.Close(); m_pInternal->m_oDocument.Clear(); - if (bIsOutCompress) - hr = Close(); - return (hr == S_OK) ? 0 : 1; + return xml_shapes; +} + +void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage) +{ + //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; + NewPage(); + BeginCommand(c_nPageType); + m_pInternal->m_oDocument.m_bIsDisablePageCommand = true; + m_pInternal->m_oDocument.m_lPageNum = nPage; + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pFile->GetPageInfo(nPage, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + put_Width(dWidth); + put_Height(dHeight); + + pFile->DrawPageOnRenderer(this, nPage, nullptr); + + m_pInternal->m_oDocument.m_bIsDisablePageCommand = false; + EndCommand(c_nPageType); } HRESULT CDocxRenderer::SetTempFolder(const std::wstring& wsPath) diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index abc5aace49d..5a49a66ecd0 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -52,9 +52,7 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer CDocxRenderer(NSFonts::IApplicationFonts* pAppFonts); virtual ~CDocxRenderer(); - HRESULT CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true); - HRESULT Close(); - + HRESULT Compress(); HRESULT SetTempFolder(const std::wstring& wsPath); //---------------------------------------------------------------------------------------- // Тип рендерера @@ -195,7 +193,9 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer // методы, которыми будет пользоваться конвертер HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); + std::vector ScanPage(IOfficeDrawingFile* pFile, size_t nPage); private: CDocxRenderer_Private* m_pInternal; + void DrawPage(IOfficeDrawingFile* pFile, size_t nPage); }; diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 14fe319e0f9..c4638e7796a 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -9,15 +9,7 @@ namespace NSDocxRenderer } void CDocument::Clear() { - m_oPen.SetDefaultParams(); - m_oBrush.SetDefaultParams(); - m_oFont.SetDefaultParams(); - m_oShadow.SetDefaultParams(); - m_oEdge.SetDefaultParams(); - - m_oTransform.Reset(); - m_lClipMode = 0; - m_lPagesCount = 0; + NewPage(); for(auto& val : m_mapXmlString) delete val.second; @@ -481,7 +473,7 @@ namespace NSDocxRenderer return S_OK; } - m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0, m_bIsNeedPDFTextAnalyzer); + m_oCurrentPage.CollectTextData((unsigned int*)pUnicodes, (unsigned int*)pGids, nCount, dX, dY, dW, dH, 0); return S_OK; } @@ -535,19 +527,20 @@ namespace NSDocxRenderer if (c_nPageType == lType && m_bIsDisablePageCommand) return S_OK; - m_lCurrentCommandType = -1; - m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; + m_lCurrentCommandType = -1; + m_oCurrentPage.m_lCurrentCommand = m_lCurrentCommandType; if (c_nPageType == lType) { auto pWriter = new NSStringUtils::CStringBuilder(); pWriter->AddSize(100000); - m_oCurrentPage.ProcessingAndRecordingOfPageData(*pWriter, m_lPagesCount, m_lNumberPages); - m_mapXmlString[m_lPagesCount] = pWriter; + m_oCurrentPage.Analyze(); + m_oCurrentPage.Record(*pWriter, m_lPageNum >= m_lNumberPages - 1); + m_mapXmlString[m_lPageNum] = pWriter; } else if (c_nPathType == lType) { - m_oCurrentPage.End(); + m_oCurrentPage.PathEnd(); } return S_OK; @@ -608,7 +601,7 @@ namespace NSDocxRenderer { if (c_nSimpleGraphicType == m_lCurrentCommandType) { - m_oCurrentPage.Close(); + m_oCurrentPage.PathClose(); } else { @@ -620,7 +613,7 @@ namespace NSDocxRenderer { if (c_nSimpleGraphicType == m_lCurrentCommandType) { - m_oCurrentPage.End(); + m_oCurrentPage.PathEnd(); } else { @@ -648,7 +641,7 @@ namespace NSDocxRenderer { if (c_nSimpleGraphicType == m_lCurrentCommandType) { - m_oCurrentPage.Start(); + m_oCurrentPage.PathStart(); } else { @@ -804,27 +797,42 @@ namespace NSDocxRenderer m_oInstalledFont = m_oFont; } - bool CDocument::CreateDocument() + void CDocument::CreateTemplates() { CreateTemplate(m_strTempDirectory); + m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; + NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); + } - // Init - Clear(); + void CDocument::Init() + { + // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", + // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) + // может быть одной и той же. И создание там файлов функцией создания временных файлов + // может вернуть один и тот же путь. И шрифт возьмется из старого файла. + m_oFontManager.ClearCache(); + if (m_pAppFonts) m_pAppFonts->GetStreams()->Clear(); + Clear(); m_lCurrentCommandType = 0; - m_oCurrentPage.Init(&m_oFont, &m_oPen, &m_oBrush, &m_oShadow, &m_oEdge, &m_oTransform, &m_oSimpleGraphicsConverter, &m_oFontStyleManager, &m_oFontManager, &m_oFontSelector, &m_oParagraphStyleManager); - m_oImageManager.NewDocument(); - m_oFontStyleManager.NewDocument(); + m_oCurrentPage.Init(&m_oFont, + &m_oPen, + &m_oBrush, + &m_oShadow, + &m_oEdge, + &m_oTransform, + &m_oSimpleGraphicsConverter, + &m_oFontStyleManager, + &m_oFontManager, + &m_oFontSelector, + &m_oParagraphStyleManager); - // media - m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; - NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); - - return true; + m_oImageManager.Clear(); + m_oFontStyleManager.Clear(); } - void CDocument::Close() + void CDocument::Write() { BuildDocumentXml(); BuildDocumentXmlRels(); @@ -1215,7 +1223,6 @@ namespace NSDocxRenderer //oWriter.WriteString(L""); //oWriter.WriteString(L""); - m_oFontStyleManager.ToXml(oWriter); m_oParagraphStyleManager.ToXml(oWriter); diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index 9050f4a630b..aee5fdfc167 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -11,57 +11,51 @@ namespace NSDocxRenderer class CDocument { public: - NSFonts::IApplicationFonts* m_pAppFonts; + NSFonts::IApplicationFonts* m_pAppFonts; - NSStructures::CPen m_oPen; - NSStructures::CBrush m_oBrush; - NSStructures::CFont m_oFont; - NSStructures::CShadow m_oShadow; - NSStructures::CEdgeText m_oEdge; + NSStructures::CPen m_oPen; + NSStructures::CBrush m_oBrush; + NSStructures::CFont m_oFont; + NSStructures::CShadow m_oShadow; + NSStructures::CEdgeText m_oEdge; - NSStructures::CFont m_oInstalledFont; + NSStructures::CFont m_oInstalledFont; + Aggplus::CMatrix m_oTransform; - NSFonts::IFontManager* m_pFontManager {nullptr}; - Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - - Aggplus::CMatrix m_oTransform; - - LONG m_lCurrentCommandType {0}; - - LONG m_lClipMode; - CPage m_oCurrentPage; - - CImageManager m_oImageManager; - CFontStyleManager m_oFontStyleManager; + CImageManager m_oImageManager; + CFontStyleManager m_oFontStyleManager; CParagraphStyleManager m_oParagraphStyleManager; - CFontManager m_oFontManager; + CFontManager m_oFontManager; CFontSelector m_oFontSelector; - double m_dWidth {0.0}; - double m_dHeight {0.0}; + CPage m_oCurrentPage; - double m_dDpiX {72.0}; - double m_dDpiY {72.0}; + LONG m_lCurrentCommandType {0}; + LONG m_lClipMode; - std::wstring m_strTempDirectory {L""}; - std::wstring m_strDstFilePath; + double m_dWidth {0.0}; + double m_dHeight {0.0}; + double m_dDpiX {72.0}; + double m_dDpiY {72.0}; - LONG m_lPagesCount {0}; - LONG m_lNumberPages{0}; + std::wstring m_strTempDirectory {L""}; + std::wstring m_strDstFilePath; - bool m_bIsNeedPDFTextAnalyzer {false}; + LONG m_lPageNum {0}; + LONG m_lNumberPages{0}; - bool m_bIsDisablePageCommand {false}; // disable commands inside draw function + bool m_bIsDisablePageCommand {false}; // disable commands inside draw function + + NSFonts::IFontManager* m_pFontManager {nullptr}; + Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; std::map m_mapXmlString; + public: CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts); - void Clear(); - ~CDocument(); public: - HRESULT NewPage(); HRESULT get_Height(double* dHeight); HRESULT put_Height(double dHeight); @@ -194,15 +188,15 @@ namespace NSDocxRenderer protected: void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6); - void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags); - void _SetFont(); public: - bool CreateDocument(); + void CreateTemplates(); + void Init(); + void Write(); + void Clear(); - void Close(); void BuildDocumentXml(); void BuildDocumentXmlRels(); void BuildFontTableXml(); diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index f1427dfa697..a79719689b2 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -10,10 +10,17 @@ namespace NSDocxRenderer { } - void CPage::Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pFontStyleManager, CFontManager *pFontManager, - CFontSelector* pFontSelector, CParagraphStyleManager* pParagraphStyleManager) + void CPage::Init(NSStructures::CFont* pFont, + NSStructures::CPen* pPen, + NSStructures::CBrush* pBrush, + NSStructures::CShadow* pShadow, + NSStructures::CEdgeText* pEdge, + Aggplus::CMatrix* pMatrix, + Aggplus::CGraphicsPathSimpleConverter* pSimple, + CFontStyleManager* pFontStyleManager, + CFontManager *pFontManager, + CFontSelector* pFontSelector, + CParagraphStyleManager* pParagraphStyleManager) { m_pFont = pFont; m_pPen = pPen; @@ -178,16 +185,16 @@ namespace NSDocxRenderer m_oVector.CurveTo(x1, y1, x2, y2, x3, y3); } - void CPage::Start() + void CPage::PathStart() { } - void CPage::End() + void CPage::PathEnd() { m_oVector.End(); } - void CPage::Close() + void CPage::PathClose() { m_oVector.Close(); } @@ -265,9 +272,14 @@ namespace NSDocxRenderer } } - void CPage::CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer) + void CPage::CollectTextData(const PUINT pUnicodes, + const PUINT pGids, + const UINT& nCount, + const double& fX, + const double& fY, + const double& fWidth, + const double& fHeight, + const double& fBaseLineOffset) { // 9 - \t if (pUnicodes != nullptr && nCount == 1 && (IsSpaceUtf32(*pUnicodes) || *pUnicodes == 9)) @@ -358,20 +370,21 @@ namespace NSDocxRenderer pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); -#ifndef USE_DEFAULT_FONT_TO_RECALC - pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); - pCont->m_oSelectedFont.Size = m_pFont->Size; - pCont->m_oSelectedFont.Bold = m_pFontSelector->IsSelectedBold(); - pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic(); -#else - pCont->m_oSelectedFont.Path = m_pFont->Path; - pCont->m_oSelectedFont.Size = m_pFont->Size; - pCont->m_oSelectedFont.FaceIndex = m_pFont->FaceIndex; -#endif // USE_DEFAULT_FONT_TO_RECALC - + if (m_bUseDefaultFont) + { + pCont->m_oSelectedFont.Path = m_pFont->Path; + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.FaceIndex = m_pFont->FaceIndex; + } + else + { + pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.Bold = m_pFontSelector->IsSelectedBold(); + pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic(); + } + pCont->m_bWriteStyleRaw = m_bWriteStyleRaw; m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); - - m_arConts.push_back(pCont); } @@ -408,7 +421,7 @@ namespace NSDocxRenderer m_arTextLines.push_back(pLine); } - void CPage::ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages) + void CPage::Analyze() { // build m_arDiacriticalSymbols BuildDiacriticalSymbols(); @@ -433,9 +446,12 @@ namespace NSDocxRenderer // merge shapes MergeShapes(); + } + void CPage::Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage) + { ToXml(oWriter); - WriteSectionToFile(lPagesCount >= lNumberPages - 1, oWriter); + WriteSectionToFile(bIsLastPage, oWriter); } void CPage::BuildDiacriticalSymbols() @@ -484,8 +500,20 @@ namespace NSDocxRenderer void CPage::CalcSelected() { for (auto& cont : m_arConts) - if (cont) - cont->CalcSelected(); + { + if (cont && cont->m_oSelectedSizes.dHeight == 0.0 && cont->m_oSelectedSizes.dWidth == 0.0) + { + if (m_bUseDefaultFont) + { + cont->m_oSelectedSizes.dHeight = cont->m_dHeight; + cont->m_oSelectedSizes.dWidth = cont->m_dWidth; + } + else + { + cont->CalcSelected(); + } + } + } } void CPage::AnalyzeShapes() @@ -1033,25 +1061,14 @@ namespace NSDocxRenderer } for (const auto& image : m_arImages) - if(image) + if (image) image->ToXml(oWriter); for (const auto& shape : m_arShapes) - if(shape) + if (shape) shape->ToXml(oWriter); - if (bIsTextShapePresent) - { - for (size_t i = 0; i < m_arOutputObjects.size(); ++i) - { - auto pObj = m_arOutputObjects[i]; - CShape* pSahpe = nullptr; - if((pSahpe = dynamic_cast(pObj.get())) != nullptr) - pSahpe->ToXml(oWriter); - } - } - if (bIsNeedWP) { oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 0511827a26a..ffe1894e85c 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -17,6 +17,11 @@ namespace NSDocxRenderer LONG m_lCurrentCommand {0}; + TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; + + bool m_bUseDefaultFont{false}; + bool m_bWriteStyleRaw {false}; + NSStructures::CFont* m_pFont {nullptr}; NSStructures::CPen* m_pPen {nullptr}; NSStructures::CBrush* m_pBrush {nullptr}; @@ -42,22 +47,26 @@ namespace NSDocxRenderer CTextLine* m_pCurrentLine {nullptr}; - TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; - bool m_bIsDeleteTextClipPage {true}; bool m_bIsRecalcFontSize {true}; LONG m_lLastCommand = 0; CPage(NSFonts::IApplicationFonts* pFonts); ~CPage(); - void Init(NSStructures::CFont* pFont, NSStructures::CPen* pPen, NSStructures::CBrush* pBrush, - NSStructures::CShadow* pShadow, NSStructures::CEdgeText* pEdge, Aggplus::CMatrix* pMatrix, - Aggplus::CGraphicsPathSimpleConverter* pSimple, CFontStyleManager* pStyleManager, CFontManager *pFontManager, - CFontSelector* pFontSelector, CParagraphStyleManager* pParagraphStyleManager); + void Init(NSStructures::CFont* pFont, + NSStructures::CPen* pPen, + NSStructures::CBrush* pBrush, + NSStructures::CShadow* pShadow, + NSStructures::CEdgeText* pEdge, + Aggplus::CMatrix* pMatrix, + Aggplus::CGraphicsPathSimpleConverter* pSimple, + CFontStyleManager* pStyleManager, + CFontManager *pFontManager, + CFontSelector* pFontSelector, + CParagraphStyleManager* pParagraphStyleManager); void BeginCommand(DWORD lType); - void Clear(); //удаляем то, что выходит за границы страницы @@ -71,22 +80,27 @@ namespace NSDocxRenderer void MoveTo(double& dX, double& dY); void LineTo(double& dX, double& dY); void CurveTo(double& x1, double& y1, double& x2, double& y2, double& x3, double& y3); - void Start(); - void End(); - void Close(); + void PathStart(); + void PathEnd(); + void PathClose(); //набивается содержимым вектор m_arShapes void DrawPath(LONG lType, const std::shared_ptr pInfo); //набивается содержимым вектор m_arTextData - void CollectTextData(const PUINT pUnicodes, const PUINT pGids, const UINT& nCount, - const double& fX, const double& fY, const double& fWidth, const double& fHeight, - const double& fBaseLineOffset, const bool& bIsPDFAnalyzer); - - void ProcessingAndRecordingOfPageData(NSStringUtils::CStringBuilder& oWriter, LONG lPagesCount, LONG lNumberPages); + void CollectTextData(const PUINT pUnicodes, + const PUINT pGids, + const UINT& nCount, + const double& fX, + const double& fY, + const double& fWidth, + const double& fHeight, + const double& fBaseLineOffset); + + void Analyze(); + void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage); private: - // methods to build text lines void BuildDiacriticalSymbols(); void BuildTextLines(); diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 61e9e678bda..ad9ab166cb1 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -75,11 +75,13 @@ namespace NSDocxRenderer void CContText::CalcSelected() { -#ifndef USE_DEFAULT_FONT_TO_RECALC if (!m_pFontStyle->wsFontName.empty() && !m_oText.empty()) { // нужно перемерять... - m_pManager->LoadFontByName(m_oSelectedFont); + if (m_oSelectedFont.Path.empty()) + m_pManager->LoadFontByName(m_oSelectedFont); + else + m_pManager->LoadFontByFile(m_oSelectedFont); double dBoxX; double dBoxY; @@ -92,10 +94,6 @@ namespace NSDocxRenderer m_oSelectedSizes.dWidth = dBoxWidth; m_oSelectedSizes.dHeight = dBoxHeight; } -#else - m_oSelectedSizes.dWidth = dBoxWidth; - m_oSelectedSizes.dHeight = dBoxHeight; -#endif // USE_DEFAULT_FONT_TO_RECALC } eVerticalCrossingType CContText::GetVerticalCrossingType(const CContText* pCont) const noexcept @@ -150,9 +148,12 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L"wsFontStyleId); - oWriter.WriteString(L"\"/>"); + if (!m_bWriteStyleRaw) + { + oWriter.WriteString(L"wsFontStyleId); + oWriter.WriteString(L"\"/>"); + } LONG lCalculatedSpacing = 0; @@ -225,7 +226,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); } - if(m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) { int lSize = static_cast(3.0 * m_pFontStyle->dFontSize); oWriter.WriteString(L""); } + else if (m_bWriteStyleRaw) + { + int lSize = static_cast(2.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); + } + + if (m_bWriteStyleRaw) + { + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\" w:hAnsi=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:cs=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:hint=\"default\"/>"); + + if (m_pFontStyle->bBold) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (m_pFontStyle->bItalic) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L"oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + } + } + if (m_eVertAlignType == eVertAlignType::vatSubscript) oWriter.WriteString(L""); else if (m_eVertAlignType == eVertAlignType::vatSuperscript) diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 462c0b4308b..6730d5d3e05 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -71,6 +71,7 @@ namespace NSDocxRenderer UINT m_iNumDuplicates{0}; bool m_bIsAddBrEnd{false}; + bool m_bWriteStyleRaw{false}; CContText() = default; CContText(CFontManager* pManager) : m_pManager(pManager) {} diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.cpp b/DocxRenderer/src/logic/managers/FontStyleManager.cpp index 73d76f5a655..619e542d1e5 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.cpp +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -17,10 +17,6 @@ namespace NSDocxRenderer m_arFontStyles.clear(); } - void CFontStyleManager::NewDocument() - { - Clear(); - } void CFontStyleManager::ToXml(NSStringUtils::CStringBuilder& oWriter) { for(auto& val : m_arFontStyles) diff --git a/DocxRenderer/src/logic/managers/FontStyleManager.h b/DocxRenderer/src/logic/managers/FontStyleManager.h index b8673361d23..a46075fd97b 100644 --- a/DocxRenderer/src/logic/managers/FontStyleManager.h +++ b/DocxRenderer/src/logic/managers/FontStyleManager.h @@ -12,15 +12,14 @@ namespace NSDocxRenderer ~CFontStyleManager(); void Clear(); - void NewDocument(); void ToXml(NSStringUtils::CStringBuilder& oWriter); std::shared_ptr GetOrAddFontStyle(const CFontStyle& oFontStyle); std::shared_ptr GetOrAddFontStyle(const NSStructures::CBrush& oBrush, - const std::wstring& wsFontName, - double dFontSize, - bool bItalic, - bool bBold); + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold); private: std::list> m_arFontStyles; diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index 5cc7bc7c899..a7cd7f98ee0 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -3,7 +3,7 @@ namespace NSDocxRenderer { - void CImageManager::NewDocument() + void CImageManager::Clear() { m_strDstMedia = L""; m_lMaxSizeImage = 1200; diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index 9809542d876..2d66dd1feaf 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -24,7 +24,7 @@ namespace NSDocxRenderer CImageManager(){}; - void NewDocument(); + void Clear(); public: std::shared_ptr WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 909ce379c25..1e416fcf32e 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -167,11 +167,13 @@ int main(int argc, char *argv[]) NSDocxRenderer::TextAssociationType taType; //taType = NSDocxRenderer::TextAssociationType::tatPlainLine; //taType = NSDocxRenderer::TextAssociationType::tatShapeLine; - taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; - //taType = NSDocxRenderer::TextAssociationType::tatParagraphToShape; + //taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; + taType = NSDocxRenderer::TextAssociationType::tatParagraphToShape; oDocxRenderer.SetTextAssociationType(taType); - oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); + //oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); + //auto shapes = oDocxRenderer.ScanPage(pReader, 0); + //Если сразу нужен zip-архив //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); #endif From a91500c4b732c8ba75570cf74ff1a7020b4cd06f Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 26 Feb 2024 21:10:22 +0600 Subject: [PATCH 341/794] Fix table conversion --- .../Logic/Biff_structures/StringPtgParser.cpp | 4 ++++ OOXML/XlsxFormat/Table/Tables.cpp | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 1245cd1c0fc..03918299b10 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -281,6 +281,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R unsigned int number; unsigned short ixti; PtgList ptgList(PtgList::fixed_id); + ptgList.type_ = 0x00; if(SyntaxPtg::extract_PtgBool(it, itEnd, operand_str)) { @@ -331,6 +332,9 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList))// Shall be placed strongly before PtgArea and PtgRef { + if((ptgList.rowType == 0x10 || ptgList.rowType == 0x08 || ptgList.rowType == 0x02) + && ptgList.columns == 0x01) + ptgList.type_ = 0x01; rgce.addPtg(found_operand = OperandPtgPtr(new PtgList(ptgList))); } else if(SyntaxPtg::extract_PtgArea(it, itEnd, operand_str)) // Sequence is important (in pair with PtgRef) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index aaa15cc6ffd..4d28e8cbfa8 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -356,12 +356,14 @@ namespace Spreadsheet if(m_oCalculatedColumnFormula.IsInit()) { auto fmla(new XLSB::ListCCFmla); + fmla->fArray = false; fmla->formula = m_oCalculatedColumnFormula.get(); ptr->m_BrtListCCFmla = XLS::BaseObjectPtr{fmla}; } if(m_oTotalsRowFormula.IsInit()) { auto fmla(new XLSB::ListTrFmla); + fmla->fArray = false; fmla->formula = m_oTotalsRowFormula.get(); ptr->m_BrtListTrFmla = XLS::BaseObjectPtr{fmla}; } @@ -616,15 +618,17 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oTableColumns.IsInit() && !m_oTableColumns->m_arrItems.empty()) { XLS::GlobalWorkbookInfo::mapTableColumnNames_static.emplace(m_oId->GetValue(), - std::vector(m_oTableColumns->m_arrItems.size()+1, L"")); + std::vector(m_oTableColumns->m_arrItems.size())); + auto colInd = 0; for(auto i:m_oTableColumns->m_arrItems) - if(i->m_oName.IsInit() && i->m_oId.IsInit()) + { + if(i->m_oName.IsInit()) { - if(i->m_oId->GetValue()+1 > XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).size()) - XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).resize(i->m_oId->GetValue()+1); i->m_oName = boost::algorithm::erase_all_copy(i->m_oName.get(), L"_x000a_"); - XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).at(i->m_oId->GetValue()) = i->m_oName.get(); + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).at(colInd) = i->m_oName.get(); } + colInd++; + } } XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(m_oId->GetValue(), m_oName.get()); } @@ -768,6 +772,8 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oTotalsRowShown.IsInit()) ptr1->fShownTotalRow = m_oTotalsRowShown.get(); + else if(m_oTotalsRowCount.IsInit() && m_oTotalsRowCount->GetValue() > 0) + ptr1->fShownTotalRow = true; else ptr1->fShownTotalRow = false; ptr1->fSingleCell = false; From 306a61ba140cee3cc7029e8868759e0d27d7143c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 27 Feb 2024 12:12:56 +0300 Subject: [PATCH 342/794] Fix NSFonts::IFontList::Add --- DesktopEditor/fontengine/ApplicationFonts.cpp | 4 +- DesktopEditor/fontengine/ApplicationFonts.h | 2 +- DesktopEditor/graphics/pro/Fonts.h | 1 + .../pro/js/wasm/js/drawingfile_base.js | 6 +- PdfFile/PdfReader.cpp | 140 +++++++++--------- PdfFile/SrcReader/PdfAnnot.cpp | 45 +++++- 6 files changed, 117 insertions(+), 81 deletions(-) diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index 934ee5e2e12..3b54c8365d2 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.cpp +++ b/DesktopEditor/fontengine/ApplicationFonts.cpp @@ -1412,7 +1412,7 @@ void CFontList::Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstri } } -void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFlag) +void CFontList::Add(const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag) { if (!pStream) return; @@ -1431,7 +1431,7 @@ void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFl pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; pParams[3].data = NULL; - Add(pLibrary, pParams, sFontPath, pStream, nFlag); + Add(pLibrary, pParams, sFontPath, (CFontStream*)pStream, nFlag); ::free( pParams ); FT_Done_FreeType(pLibrary); diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index 206967dfe6c..2b2658451f7 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.h +++ b/DesktopEditor/fontengine/ApplicationFonts.h @@ -317,7 +317,7 @@ class CFontList : public NSFonts::IFontList void LoadFromFolder (const std::wstring& strDirectory); bool CheckLoadFromFolderBin(const std::wstring& strDirectory); void CheckLoadFromSelectionBin(const std::wstring& strDirectory, BYTE* pData, DWORD len); - void Add (const std::wstring& sFontPath, CFontStream* pStream, int nFlag = 0); + void Add (const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag = 0); void Add (NSFonts::CFontInfo* pInfo); NSFonts::CFontInfo* GetByParams (NSFonts::CFontSelectFormat& oSelect, bool bIsDictionaryUse = true); std::vector GetAllByName (const std::wstring& strFontName); diff --git a/DesktopEditor/graphics/pro/Fonts.h b/DesktopEditor/graphics/pro/Fonts.h index 1a06368fac0..d41a82ee79c 100644 --- a/DesktopEditor/graphics/pro/Fonts.h +++ b/DesktopEditor/graphics/pro/Fonts.h @@ -766,6 +766,7 @@ namespace NSFonts virtual std::vector* GetFonts() = 0; virtual CFontInfo* GetByParams(CFontSelectFormat& oSelect, bool bIsDictionaryUse = true) = 0; virtual void ToBuffer(BYTE** pDstData, LONG* pLen, CFontListToBufferSerializer& oSerializer) = 0; + virtual void Add(const std::wstring& sFontPath, IFontStream* pStream, int nFlag = 0) = 0; }; class GRAPHICS_DECL IApplicationFonts : public NSBase::CBaseRefCounter diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index fcfc1f32e05..5f253963719 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1126,13 +1126,13 @@ // RC if (flags & (1 << 3)) { - // 0 - left, 1 - centered, 2 - right, 3 - justify - rec["alignment"] = reader.readByte(); let n = reader.readInt(); rec["RC"] = []; for (let i = 0; i < n; ++i) { let oFont = {}; + // 0 - left, 1 - centered, 2 - right, 3 - justify + oFont["alignment"] = reader.readByte(); let nFontFlag = reader.readInt(); oFont["bold"] = (nFontFlag >> 0) & 1; oFont["italic"] = (nFontFlag >> 1) & 1; @@ -1140,6 +1140,8 @@ oFont["underlined"] = (nFontFlag >> 4) & 1; if (nFontFlag & (1 << 5)) oFont["vertical"] = reader.readDouble(); + if (nFontFlag & (1 << 6)) + oFont["actual"] = reader.readDouble(); oFont["size"] = reader.readDouble(); oFont["color"] = []; oFont["color"].push(reader.readDouble2()); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 730fa9703bf..46dafed8bfa 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -926,10 +926,6 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - if (!pAcroForms || !m_pPDFDocument->getXRef()) - return NULL; - NSWasm::CData oRes; oRes.SkipLen(); @@ -937,69 +933,55 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) int nFontsPos = oRes.GetSize(); oRes.AddInt(nFontsID); - std::vector arrFontsRef; - for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + if (pAcroForms) { - AcroFormField* pField = pAcroForms->getField(nField); - if (!pField) - continue; + std::vector arrFontsRef; + for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + { + AcroFormField* pField = pAcroForms->getField(nField); + if (!pField) + continue; - // Шрифт и размер шрифта - из DA - Ref fontID; - double dFontSize = 0; - pField->getFont(&fontID, &dFontSize); + // Шрифт и размер шрифта - из DA + Ref fontID; + double dFontSize = 0; + pField->getFont(&fontID, &dFontSize); - if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) - { - std::string sFontKey; - Object oR, oFonts, oFontRef; - if (PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey) && - std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) { - std::string sFontName; - bool bBold = false, bItalic = false; - std::wstring wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - - if (!sFontName.empty()) + std::string sFontKey; + Object oR, oFonts, oFontRef; + if (PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey) && + std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) { - oRes.WriteString(sFontName); - nFontsID++; - arrFontsRef.push_back(oFontRef.getRefNum()); - m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + std::string sFontName; + bool bBold = false, bItalic = false; + std::wstring wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - if (fontID.num == oFontRef.getRefNum()) + if (!sFontName.empty()) { - oR.free(); oFonts.free(); oFontRef.free(); - continue; + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + + if (fontID.num == oFontRef.getRefNum()) + { + oR.free(); oFonts.free(); oFontRef.free(); + continue; + } } } + oR.free(); oFonts.free(); oFontRef.free(); } - oR.free(); oFonts.free(); oFontRef.free(); - } - if (fontID.num < 0 || std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) - continue; - - Object oR, oFonts, oFontRef; - bool bFindResources = false; - if (pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) - { - for (int i = 0; i < oFonts.dictGetLength(); ++i) - { - if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) - { - bFindResources = true; - break; - } - oFontRef.free(); - } - } + if (fontID.num < 0 || std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) + continue; - if (!bFindResources) - { - oR.free(); oFonts.free(); - Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + Object oR, oFonts, oFontRef; + bool bFindResources = false; + if (pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) { for (int i = 0; i < oFonts.dictGetLength(); ++i) { @@ -1011,24 +993,42 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) oFontRef.free(); } } - } - std::string sFontName; - std::wstring wsFileName; - if (bFindResources) - { - bool bBold = false, bItalic = false; - wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - } + if (!bFindResources) + { + oR.free(); oFonts.free(); + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + { + for (int i = 0; i < oFonts.dictGetLength(); ++i) + { + if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) + { + bFindResources = true; + break; + } + oFontRef.free(); + } + } + } - if (!sFontName.empty()) - { - oRes.WriteString(sFontName); - nFontsID++; - arrFontsRef.push_back(oFontRef.getRefNum()); - m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + std::string sFontName; + std::wstring wsFileName; + if (bFindResources) + { + bool bBold = false, bItalic = false; + wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + } + + if (!sFontName.empty()) + { + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + } + oR.free(); oFonts.free(); oFontRef.free(); } - oR.free(); oFonts.free(); oFontRef.free(); } for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 8deee839af1..53e794b1f5c 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2255,7 +2255,21 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); if (pFontStream && !GetBaseFont(sFontPath, pData14, nSize14)) { - pAppFontList->Add(sFontPath, pFontStream); + bool bNew = true; + std::vector* arrFontList = pAppFontList->GetFonts(); + for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) + { + if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || + (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && + (*arrFontList)[nIndex]->m_bBold == bBold && + (*arrFontList)[nIndex]->m_bItalic == bItalic) + { + bNew = false; + break; + } + } + if (bNew) + pAppFontList->Add(sFontPath, pFontStream); arrFontFreeText.push_back(sFontPath); } } @@ -2270,7 +2284,8 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec std::string sFontName = arrRC[i]->sFontFamily; bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); - if (sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats") + bool bBase = sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats"; + if ((nTypeFonts & 2) && bBase) { if (sFontName == "Times New Roman") { @@ -2301,6 +2316,7 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec std::string sFontNameBefore = arrRC[i]->sFontFamily; arrRC[i]->sFontFamily = sFontName; arrRC[i]->bFind = true; + mRes[wsFontName] = wsFontName; for (int j = i; j < arrRC.size(); ++j) { @@ -2311,7 +2327,7 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec } } } - else + if ((nTypeFonts & 1) && !bBase) { NSFonts::CFontSelectFormat oFontSelect; if (bBold) @@ -2324,15 +2340,32 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); + std::wstring wsFontBaseName = pFontInfo->m_wsFontName; + if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) + { + wchar_t nChar = wsFontBaseName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + wsFontBaseName.erase(0, 7); + } + if (bFreeText) { - arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); - mRes[pFontInfo->m_wsFontName] = pFontInfo->m_wsFontPath; + arrRC[i]->sFontFamily = U_TO_UTF8(wsFontBaseName); + mRes[wsFontBaseName] = pFontInfo->m_wsFontPath; } else { arrRC[i]->unFontFlags |= (1 << 6); - arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); + arrRC[i]->sActualFont = U_TO_UTF8(wsFontBaseName); } arrRC[i]->bFind = true; From 9bb45aa05d9cbc1c79e80304bfa047bc0a9fc60d Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 27 Feb 2024 14:15:20 +0300 Subject: [PATCH 343/794] fix bug #66622 --- .../Converter/docx_conversion_context.cpp | 27 +++++++++++++++++++ .../Converter/docx_conversion_context.h | 1 + OdfFile/Reader/Converter/oox_package.cpp | 7 ++++- OdfFile/Reader/Converter/oox_package.h | 2 ++ OdfFile/Reader/Format/paragraph_elements.cpp | 5 +++- .../Reader/Format/styles_lite_container.cpp | 23 ++++++++++++++++ OdfFile/Reader/Format/styles_lite_container.h | 1 + 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/OdfFile/Reader/Converter/docx_conversion_context.cpp b/OdfFile/Reader/Converter/docx_conversion_context.cpp index 3f43a5fbd55..647bcf01ce2 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/docx_conversion_context.cpp @@ -751,6 +751,15 @@ void docx_conversion_context::end_document() output_document_->get_docProps_files().set_app(package::simple_element::create(L"app.xml", dump_settings_app())); output_document_->get_docProps_files().set_core(package::simple_element::create(L"core.xml", dump_settings_core())); + std::wstring settings_custom = dump_settings_custom(); + if (false == settings_custom.empty()) + { + output_document_->get_docProps_files().set_custom(package::simple_element::create(L"custom.xml", settings_custom)); + output_document_->get_content_types_file().content()->add_override(L"/docProps/custom.xml", L"application/vnd.openxmlformats-officedocument.custom-properties+xml"); + output_document_->get_rels_files().add( + relationship(L"rCstmId", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties", L"docProps/custom.xml")); + } + for (size_t i = 0; i < charts_.size(); i++) { package::chart_content_ptr content = package::chart_content::create(); @@ -899,6 +908,24 @@ std::wstring docx_conversion_context::dump_settings_app() } return output.str(); } +std::wstring docx_conversion_context::dump_settings_custom() +{ + std::wstring user_defined = odf_document_->odf_context().DocProps().dump_user_defined(); + if (user_defined.empty()) return L""; + + std::wstringstream output; + CP_XML_WRITER(output) + { + CP_XML_NODE(L"Properties") + { + CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"); + CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); + + CP_XML_STREAM() << user_defined; + } + } + return output.str(); +} std::wstring docx_conversion_context::dump_settings_core() { std::wstringstream output; diff --git a/OdfFile/Reader/Converter/docx_conversion_context.h b/OdfFile/Reader/Converter/docx_conversion_context.h index 895252b8e57..8ae7c5c4f95 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.h +++ b/OdfFile/Reader/Converter/docx_conversion_context.h @@ -803,6 +803,7 @@ class docx_conversion_context : boost::noncopyable std::wstring dump_settings_document(); std::wstring dump_settings_app(); std::wstring dump_settings_core(); + std::wstring dump_settings_custom(); bool next_dump_page_properties_; bool next_dump_section_; diff --git a/OdfFile/Reader/Converter/oox_package.cpp b/OdfFile/Reader/Converter/oox_package.cpp index 73f71f9cb24..c7ae4fc7f20 100644 --- a/OdfFile/Reader/Converter/oox_package.cpp +++ b/OdfFile/Reader/Converter/oox_package.cpp @@ -314,7 +314,6 @@ simple_element_ptr simple_element::create(const std::wstring & FileName, const s //----------------------------------------------------------------------------------------------- docProps_files::docProps_files() { - } std::wstring docProps_files::create_core() { @@ -358,6 +357,10 @@ void docProps_files::set_core(element_ptr Element) { core_ = Element; } +void docProps_files::set_custom(element_ptr Element) +{ + custom_ = Element; +} void docProps_files::write(const std::wstring & RootPath) { std::wstring path = RootPath + FILE_SEPARATOR_STR + L"docProps"; @@ -368,6 +371,8 @@ void docProps_files::write(const std::wstring & RootPath) core_->write(path); app_->write(path); + + if (custom_) custom_->write(path); } //--------------------------------------------------------------------------------------------------- media::media(mediaitems_ptr & _mediaitems, NSFonts::IApplicationFonts *pAppFonts) : mediaItems_(_mediaitems), appFonts_(pAppFonts) diff --git a/OdfFile/Reader/Converter/oox_package.h b/OdfFile/Reader/Converter/oox_package.h index 314537181ab..38169628f68 100644 --- a/OdfFile/Reader/Converter/oox_package.h +++ b/OdfFile/Reader/Converter/oox_package.h @@ -203,6 +203,7 @@ class docProps_files : public element void set_app(element_ptr Element); void set_core(element_ptr Element); + void set_custom(element_ptr Element); virtual void write(const std::wstring & RootPath); @@ -212,6 +213,7 @@ class docProps_files : public element element_ptr core_; element_ptr app_; + element_ptr custom_; }; class document : public element { diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 455e28aefe7..dd5bc730bf0 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -1874,7 +1874,10 @@ void text_user_defined::docx_convert(oox::docx_conversion_context & Context) if (!value.empty()) text_ = text::create(value) ; - docx_serialize_run(text_, Context); + if (text_name_) + docx_serialize_field(XmlUtils::EncodeXmlString(L"DOCPROPERTY \"" + *text_name_ + L"\""), text_, Context, false); + else + docx_serialize_run(text_, Context); } //----------------------------------------------------------------------------------------------- // text:bibliography-mark diff --git a/OdfFile/Reader/Format/styles_lite_container.cpp b/OdfFile/Reader/Format/styles_lite_container.cpp index 59e80fe20f3..a6552526ae1 100644 --- a/OdfFile/Reader/Format/styles_lite_container.cpp +++ b/OdfFile/Reader/Format/styles_lite_container.cpp @@ -35,6 +35,7 @@ #include "styles_lite_container.h" #include "office_settings.h" +#include "..\..\Common\xml\simple_xml_writer.h" namespace cpdoccore { @@ -107,6 +108,28 @@ std::wstring doc_props_container::get_user_defined(const std::wstring & name) return pFind != impl_->map_user_defineds.end() ? pFind->second : L""; } +std::wstring doc_props_container::dump_user_defined() +{ + std::wstringstream output; + + CP_XML_WRITER(output) + { + for (std::map::iterator it = impl_->map_user_defineds.begin(); it != impl_->map_user_defineds.end(); ++it) + { + CP_XML_NODE(L"property") + { + CP_XML_ATTR(L"fmtid", L"{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"); + CP_XML_ATTR(L"name", it->first); + CP_XML_ATTR(L"pid", 2); + CP_XML_NODE(L"vt:lpwstr") + { + CP_XML_STREAM() << it->second; + } + } + } + } + return output.str(); +} //---------------------------------------------------------------------------------- struct settings_value diff --git a/OdfFile/Reader/Format/styles_lite_container.h b/OdfFile/Reader/Format/styles_lite_container.h index 3d5dedbb2cb..06fc5f34848 100644 --- a/OdfFile/Reader/Format/styles_lite_container.h +++ b/OdfFile/Reader/Format/styles_lite_container.h @@ -64,6 +64,7 @@ class doc_props_container void add_user_defined(const std::wstring & name, const std::wstring & value); std::wstring get_user_defined(const std::wstring & name); + std::wstring dump_user_defined(); std::wstring dc_creator_; std::wstring dc_date_; From 849ad8ac8768f1ff925aafc15eff0845fe2b3a17 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 27 Feb 2024 14:18:04 +0300 Subject: [PATCH 344/794] Fixed bugs with styles in html->ooxml conversion and refactoring --- .../html/css/src/CCssCalculator_Private.cpp | 687 ++++-------------- .../html/css/src/CCssCalculator_Private.h | 7 +- Common/3dParty/html/css/src/CElement.cpp | 14 +- Common/3dParty/html/css/src/CElement.h | 2 +- .../3dParty/html/css/src/StyleProperties.cpp | 64 +- Common/3dParty/html/css/src/StyleProperties.h | 5 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 2 +- .../html/css/src/xhtml/CXmlElement.cpp | 4 +- HtmlFile2/htmlfile2.cpp | 152 ++-- 9 files changed, 287 insertions(+), 650 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 6c7ed0b42c8..7b75a9f653e 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -114,7 +114,143 @@ namespace NSCSS oPage.SetFooter(oData.second, unLevel, bHardMode); } } - + + std::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors) + { + std::vector arNodes; + + for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) + { + if (!oNode->m_wsName.empty()) + arNodes.push_back(oNode->m_wsName); + + if (!oNode->m_wsClass.empty()) + { + if (oNode->m_wsClass.find(L' ') != std::wstring::npos) + { + std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); + + arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), + [](std::wstring sRes, const std::wstring& sClass) + {return sRes += L'.' + sClass + L' ';})); + } + else + arNodes.push_back(L'.' + oNode->m_wsClass); + } + + if (!oNode->m_wsId.empty()) + arNodes.push_back(L'#' + oNode->m_wsId); + } + + return arNodes; + } + + void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector &arNextNodes, std::vector& arFindedElements, const std::wstring &wsName, const std::vector &arClasses) + { + if (arNextNodes.empty()) + return; + + const std::vector arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend()); + const std::vector arTempKins = pElement->GetNextOfKin(wsName, arClasses); + + if (!arTempPrev.empty()) + arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end()); + + if (!arTempKins.empty()) + arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end()); + } + + std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes, bool bIsSettings) + { + std::vector arFindedElements; + + std::wstring wsName, wsId; + std::vector arClasses; + + if (arNodes.back()[0] == L'#') + { + wsId = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsId); + } + + if (arNodes.back()[0] == L'.') + { + arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" "); + arNextNodes.push_back(arNodes.back()); + arNodes.pop_back(); + } + + wsName = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsName); + +// pStyle->AddParent(wsName); + + const std::map::const_iterator oFindName = m_mData.find(wsName); + std::map::const_iterator oFindId; + + if (!wsId.empty()) + { + oFindId = m_mData.find(wsId); + + if (oFindId != m_mData.end() && NULL != m_mStatictics) + { + std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, wsId}); + + if ((m_mStatictics->end() != oFindCountId) && + (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || + (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) + { + if (!oFindId->second->Empty()) + arFindedElements.push_back(oFindId->second); + } + + FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName); + } + } + + if (!arClasses.empty()) + { + if (!bIsSettings) + { + for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) + { + const std::map::const_iterator oFindClass = m_mData.find(*iClass); + if (oFindClass != m_mData.end()) + { + if (!oFindClass->second->Empty()) + arFindedElements.push_back(oFindClass->second); + + FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName); + } + } + } + } + + if (oFindName != m_mData.end()) + { + if (!bIsSettings) + { + if (!oFindName->second->Empty()) + arFindedElements.push_back(oFindName->second); + + FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses); + } + } + + if (arFindedElements.size() > 1) + { + std::sort(arFindedElements.rbegin(), arFindedElements.rend(), + [](CElement* oFirstElement, CElement* oSecondElement) + { + return oFirstElement->GetWeight() > oSecondElement->GetWeight(); + }); + } + + return arFindedElements; + } + void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles) { m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); @@ -342,232 +478,11 @@ namespace NSCSS if (arSelectors.empty()) return CCompiledStyle(); - SetUnitMeasure(unitMeasure); - - if (!bIsSettings) - { - const std::map, CCompiledStyle*>::iterator oItem = m_mUsedStyles.find(arSelectors); - - if (oItem != m_mUsedStyles.end()) - return *oItem->second; - } - else if (NULL == m_mStatictics || m_mStatictics->empty()) - { - CCompiledStyle oStyle; - oStyle.SetDpi(m_nDpi); - oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - - return oStyle; - } - - CCompiledStyle *pStyle = new CCompiledStyle(); - - pStyle->SetDpi(m_nDpi); - pStyle->SetUnitMeasure(m_UnitMeasure); - - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); - - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); - - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) - { - arWords.push_back(oNode->m_wsName); - - //TODO:: проверить данный момент -// if (oNode->m_sName == L"td") -// pStyle->m_oMargin.SetPermission(false); - - if (oNode->m_wsName == L"table") - pStyle->m_oBorder.Block(); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - switch (arClasses.size()) - { - case 1: - { - arWords.push_back(L'.' + arClasses[0]); - break; - } - case 2: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); - break; - } - case 3: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); - break; - } - default: - { - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - break; - } - } - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); - } - - std::vector arElements; - - for (size_t i = 0; i < arSelectors.size(); ++i) - { - std::wstring sName, sId; - std::vector arClasses; - - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } - - if (arWords.back()[0] == L'.') - { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - pStyle->AddParent(sName); - - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = m_mData.find(sId); - - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); - - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - } - - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } - - if (!arClasses.empty()) - { - if (!bIsSettings) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.end()) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } - } - - if (oFindName != m_mData.end()) - { - if (!bIsSettings) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); - - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - - - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } - - if (L"table" == arSelectors[i].m_wsName) - pStyle->m_oFont.Clear(); - - CCompiledStyle oTempStyle; - - oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); - - for (const CElement* oElement : arFindElements) - oTempStyle.AddStyle(oElement->GetStyle(), i + 1); - - if (NULL != m_mStatictics) - { - std::map::const_iterator oFindCountStyle = m_mStatictics->find(StatistickElement{StatistickElement::IsStyle, arSelectors[i].m_wsStyle}); - - if (oFindCountStyle != m_mStatictics->end()) - { - if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - else if (!bIsSettings) - oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - } - else if (bIsSettings) - oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - } - else - oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - - *pStyle += oTempStyle; - } + CCompiledStyle oStyle; - if (!bIsSettings) - { - pStyle->SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - m_mUsedStyles[arSelectors] = pStyle; - } + GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure); - return *pStyle; + return oStyle; } bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) @@ -599,167 +514,23 @@ namespace NSCSS oStyle.SetDpi(m_nDpi); oStyle.SetUnitMeasure(m_UnitMeasure); - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); - - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); - - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) - { - arWords.push_back(oNode->m_wsName); - -// if (oNode->m_sName == L"td") -// oStyle.m_pMargin.SetPermission(false); - - if (oNode->m_wsName == L"table") - oStyle.m_oBorder.Block(); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - switch (arClasses.size()) - { - case 1: - { - arWords.push_back(L'.' + arClasses[0]); - break; - } - case 2: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); - break; - } - case 3: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); - break; - } - default: - { - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - break; - } - } - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); - } - - std::vector arElements; + std::vector arNodes = CalculateAllNodes(arSelectors); + std::vector arPrevNodes; for (size_t i = 0; i < arSelectors.size(); ++i) { - std::wstring sName, sId; - std::vector arClasses; - - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } - - if (arWords.back()[0] == L'.') - { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - oStyle.AddParent(sName); - - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = m_mData.find(sId); - - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); - - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - } - - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } - - if (!arClasses.empty()) - { - if (!bIsSettings) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.end()) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } - } + oStyle.AddParent(arSelectors[i].m_wsName); - if (oFindName != m_mData.end()) - { - if (!bIsSettings) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); - - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); + // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются + if (L"table" == arSelectors[i].m_wsName) + oStyle.m_oFont.SetLineHeight(L"100%", 0, true); - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); + CCompiledStyle oTempStyle; - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } + oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } + for (const CElement* oElement : FindElements(arNodes, arPrevNodes, bIsSettings)) + oTempStyle.AddStyle(oElement->GetStyle(), i + 1); if (NULL != m_mStatictics) { @@ -769,20 +540,17 @@ namespace NSCSS { if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); else if (!bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else if (bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - - for (const CElement* oElement : arFindElements) - oStyle.AddStyle(oElement->GetStyle(), i + 1); - - oStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + + oStyle += oTempStyle; } if (!bIsSettings) @@ -802,150 +570,11 @@ namespace NSCSS if (arSelectors.empty()) return false; - std::vector arWords; + std::vector arNodes = CalculateAllNodes(arSelectors); std::vector arNextNodes; - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) - { - arWords.push_back(oNode->m_wsName); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - switch (arClasses.size()) - { - case 1: - { - arWords.push_back(L'.' + arClasses[0]); - break; - } - case 2: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1]); - break; - } - case 3: - { - arWords.push_back(L'.' + arClasses[0] + L" ." + arClasses[1] + L" ." + arClasses[2]); - break; - } - default: - { - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - break; - } - } - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); - } - - std::vector arElements; - for (size_t i = 0; i < arSelectors.size(); ++i) { - std::wstring sName, sId; - std::vector arClasses; - - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } - - if (arWords.back()[0] == L'.') - { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = m_mData.find(sId); - - if (oFindId != m_mData.end()) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - const std::vector arTempKin = oFindId->second->GetNextOfKin(sName); - - if (!arTempKin.empty()) - arFindElements.insert(arFindElements.end(), arTempKin.begin(), arTempKin.end()); - } - } - - if (!arClasses.empty()) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.end()) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } - - if (oFindName != m_mData.end()) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); - - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } - if (!arSelectors[i].m_wsStyle.empty() && std::wstring::npos != arSelectors[i].m_wsStyle.find(L"page")) { std::map mRules = NS_STATIC_FUNCTIONS::GetRules(arSelectors[i].m_wsStyle); @@ -953,7 +582,7 @@ namespace NSCSS SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); } - for (const CElement* oElement : arFindElements) + for (const CElement* oElement : FindElements(arNodes, arNextNodes, false)) { std::map mRules = oElement->GetStyle(); if (mRules.end() != mRules.find(L"page")) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 4926db7a04d..814da70b583 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -25,7 +25,7 @@ namespace NSCSS std::list m_arFiles; std::map m_mData; - + typedef struct { std::vector m_wsNames; @@ -41,6 +41,11 @@ namespace NSCSS std::map GetPageData(const std::wstring& wsPageName); void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + + std::vector CalculateAllNodes(const std::vector& arSelectors); + + void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); + std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes, bool bIsSettings); #endif std::wstring m_sEncoding; diff --git a/Common/3dParty/html/css/src/CElement.cpp b/Common/3dParty/html/css/src/CElement.cpp index 2d33e11a128..c6144ee26fe 100644 --- a/Common/3dParty/html/css/src/CElement.cpp +++ b/Common/3dParty/html/css/src/CElement.cpp @@ -173,26 +173,26 @@ namespace NSCSS return arElements; } - std::vector CElement::GetPrevElements(const std::vector::reverse_iterator &arNodesRBegin, const std::vector::reverse_iterator &arNodesREnd) const + std::vector CElement::GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const { - if (arNodesRBegin >= arNodesREnd || m_arPrevElements.empty()) + if (oNodesRBegin >= oNodesREnd || m_arPrevElements.empty()) return std::vector(); std::vector arElements; - for (std::vector::reverse_iterator iWord = arNodesRBegin; iWord != arNodesREnd; ++iWord) + for (std::vector::const_reverse_iterator iWord = oNodesRBegin; iWord != oNodesREnd; ++iWord) { if ((*iWord)[0] == L'.' && ((*iWord).find(L" ") != std::wstring::npos)) { std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(*iWord, false, L" "); - for (std::wstring sClass : arClasses) + for (const std::wstring& wsClass : arClasses) { for (CElement* oPrevElement : m_arPrevElements) { - if (oPrevElement->m_sSelector == sClass) + if (oPrevElement->m_sSelector == wsClass) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, arNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); } } @@ -205,7 +205,7 @@ namespace NSCSS if (oPrevElement->m_sSelector == *iWord) { arElements.push_back(oPrevElement); - std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, arNodesREnd); + std::vector arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd); arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end()); // return arElements; } diff --git a/Common/3dParty/html/css/src/CElement.h b/Common/3dParty/html/css/src/CElement.h index 1669b07d90f..0cb32d7935f 100644 --- a/Common/3dParty/html/css/src/CElement.h +++ b/Common/3dParty/html/css/src/CElement.h @@ -39,7 +39,7 @@ namespace NSCSS std::map GetFullStyle(const std::vector& arSelectors) const; std::map GetFullStyle(const std::vector& arNodes) const; std::vector GetNextOfKin(const std::wstring& sName, const std::vector& arClasses = {}) const; - std::vector GetPrevElements(const std::vector::reverse_iterator &arNodesRBegin, const std::vector::reverse_iterator &arNodesREnd) const; + std::vector GetPrevElements(const std::vector::const_reverse_iterator& oNodesRBegin, const std::vector::const_reverse_iterator& oNodesREnd) const; std::map GetConvertStyle(const std::vector& arNodes) const; CElement *FindPrevElement(const std::wstring& sSelector) const; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index db8b5679dbd..d665a462416 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -109,6 +109,8 @@ namespace NSCSS void CString::Clear() { m_oValue.clear(); + m_unLevel = NULL; + m_bImportant = false; } int CString::ToInt() const @@ -180,7 +182,10 @@ namespace NSCSS void CDigit::Clear() { - m_oValue = DBL_MAX; + m_oValue = DBL_MAX; + m_unLevel = NULL; + m_enUnitMeasure = None; + m_bImportant = false; } void CDigit::ConvertTo(UnitMeasure enUnitMeasure, double dPrevValue) @@ -463,6 +468,9 @@ namespace NSCSS if ((CHECK_CONDITIONS && !bHardMode) || (wsValue.empty() && unLevel == m_unLevel)) return false; + if (8 == unLevel) + unLevel = 8; + if (wsValue.empty()) { SetEmpty(unLevel); @@ -575,6 +583,8 @@ namespace NSCSS void CColor::Clear() { m_oValue.Clear(); + m_unLevel = NULL; + m_bImportant = false; } ColorType CColor::GetType() const @@ -1411,7 +1421,7 @@ namespace NSCSS bool CBorderSide::Empty() const { - return (m_oWidth.Empty() || m_oWidth == 0) && m_oStyle.Empty() && m_oColor.Empty(); + return m_oWidth.Empty() || m_oWidth.Zero(); } CBorderSide &CBorderSide::operator+=(const CBorderSide &oBorderSide) @@ -1642,10 +1652,12 @@ namespace NSCSS CBorder &CBorder::operator+=(const CBorder &oBorder) { - m_oLeft = oBorder.m_oLeft; - m_oTop = oBorder.m_oTop; - m_oRight = oBorder.m_oRight; - m_oBottom = oBorder.m_oBottom; + m_oLeft = oBorder.m_oLeft; + m_oTop = oBorder.m_oTop; + m_oRight = oBorder.m_oRight; + m_oBottom = oBorder.m_oBottom; + + m_enCollapse = oBorder.m_enCollapse; return *this; } @@ -1758,7 +1770,7 @@ namespace NSCSS { return m_oIndent == oText.m_oIndent && m_oAlign == oText.m_oAlign && -// m_oDecoration == oText.m_oDecoration && + m_oDecoration == oText.m_oDecoration && m_oColor == oText.m_oColor; } @@ -1894,10 +1906,18 @@ namespace NSCSS bool CIndent::operator==(const CIndent &oIndent) const { - return m_oTop == oIndent.m_oTop && - m_oRight == oIndent.m_oRight && + return m_oTop == oIndent.m_oTop && + m_oRight == oIndent.m_oRight && m_oBottom == oIndent.m_oBottom && - m_oLeft == oIndent.m_oLeft; + m_oLeft == oIndent.m_oLeft; + } + + bool CIndent::operator!=(const CIndent &oIndent) const + { + return m_oTop != oIndent.m_oTop || + m_oRight != oIndent.m_oRight || + m_oBottom != oIndent.m_oBottom || + m_oLeft != oIndent.m_oLeft; } bool CIndent::SetValues(const std::wstring &wsTopValue, const std::wstring &wsRightValue, const std::wstring &wsBottomValue, const std::wstring &wsLeftValue, unsigned int unLevel, bool bHardMode) @@ -1982,6 +2002,13 @@ namespace NSCSS return *this; } + bool CTextDecorationLine::operator==(const CTextDecorationLine &oTextDecorationLine) const + { + return m_bUnderline == oTextDecorationLine.m_bUnderline && + m_bOverline == oTextDecorationLine.m_bOverline && + m_bLineThrough == oTextDecorationLine.m_bLineThrough; + } + TTextDecoration &TTextDecoration::operator+=(const TTextDecoration &oTextDecoration) { m_oLine += oTextDecoration.m_oLine; @@ -1991,6 +2018,13 @@ namespace NSCSS return *this; } + bool TTextDecoration::operator==(const TTextDecoration &oTextDecoration) const + { + return m_oLine == oTextDecoration.m_oLine && + m_oStyle == oTextDecoration.m_oStyle && + m_oColor == oTextDecoration.m_oColor; + } + CFont::CFont() {} @@ -2137,7 +2171,7 @@ namespace NSCSS { return m_oWeight.SetValue(wsValue, {std::make_pair(L"normal", L"normal"), std::make_pair(L"300", L"normal"), std::make_pair(L"400", L"normal"), std::make_pair(L"500", L"normal"), std::make_pair(L"bold", L"bold"), std::make_pair(L"bolder", L"bold"), std::make_pair(L"600", L"bold"), - std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode); + std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode); } void CFont::UpdateSize(double dFontSize) @@ -2407,7 +2441,7 @@ namespace NSCSS } CEnum::CEnum() - : CValue(INT_MIN, 0, false){} + : CValue(INT_MAX, 0, false){} bool CEnum::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { @@ -2445,12 +2479,14 @@ namespace NSCSS bool CEnum::Empty() const { - return m_mMap.empty() || INT_MIN == m_oValue; + return m_mMap.empty() || INT_MAX == m_oValue; } void CEnum::Clear() { - m_oValue = INT_MIN; + m_oValue = INT_MAX; + m_unLevel = NULL; + m_bImportant = false; } CEnum &CEnum::operator =(int nValue) diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 42d763c5016..909a184be73 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -536,6 +536,7 @@ namespace NSCSS bool LineThrough() const; CTextDecorationLine &operator+=(const CTextDecorationLine& oTextDecoration); + bool operator==(const CTextDecorationLine& oTextDecorationLine) const; }; struct TTextDecoration @@ -545,6 +546,7 @@ namespace NSCSS CColor m_oColor; TTextDecoration& operator+=(const TTextDecoration& oTextDecoration); + bool operator==(const TTextDecoration& oTextDecoration) const; }; class CText @@ -611,6 +613,7 @@ namespace NSCSS CIndent& operator+=(const CIndent& oIndent); bool operator==(const CIndent& oIndent) const; + bool operator!=(const CIndent& oIndent) const; private: bool SetValues(const std::wstring& wsTopValue, const std::wstring& wsRightValue, const std::wstring& wsBottomValue, const std::wstring& wsLeftValue, unsigned int unLevel, bool bHardMode = false); void UpdateSide(CDigit& oSide, double dFontSize); @@ -668,8 +671,6 @@ namespace NSCSS CString m_oStyle; CString m_oVariant; CString m_oWeight; - - TTextDecoration m_oTextDecoration; }; class CPage diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 3212f5645b9..42fa4cd18d8 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -421,7 +421,7 @@ namespace NSCSS return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2.)); // Значения шрифта увеличивает на 2 + oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2)); // Значения шрифта увеличивает на 2 if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 451b4f0358c..fc49313ebd0 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -429,8 +429,8 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const } case CSSProperties::RunnerProperties::R_Sz: { - sRStyle += L"" + L""; + sRStyle += L"" + + L""; break; } case CSSProperties::RunnerProperties::R_B: diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 9025aec84bd..82976f347ed 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -93,6 +93,12 @@ void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2 } } +void ReplaceSpaces(std::wstring& wsValue) +{ + boost::wregex oRegex(L"\\s+"); + wsValue = boost::regex_replace(wsValue, oRegex, L" "); +} + std::wstring EncodeXmlString(const std::wstring& s) { std::wstring sRes = s; @@ -240,7 +246,7 @@ class CHtmlFile2_Private } // settings.xml - std::wstring sSettings = L""; + std::wstring sSettings = L""; NSFile::CFileBinary oSettingsWriter; if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml")) { @@ -348,7 +354,7 @@ class CHtmlFile2_Private // Ссылки m_oStylesXml += L""; // Таблицы - m_oStylesXml += L""; +// m_oStylesXml += L""; // Сноски m_oStylesXml += L""; } @@ -684,6 +690,21 @@ class CHtmlFile2_Private return true; } + + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) + { + m_bWasSpace = false; + + if (!m_bInP) + return; + + for (const NSCSS::CNode& item : arSelectors) + if (item.m_wsName == L"a") + pXml->WriteString(L""); + + pXml->WriteString(L""); + m_bInP = false; + } std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) { @@ -778,26 +799,19 @@ class CHtmlFile2_Private size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) - { - m_bWasSpace = true; return; - } - else if (find != 1 || m_bWasSpace || sText.front() != L' ') - sText.erase(0, find); + + if (m_bInP && !iswspace(sText.front()) && !m_bWasSpace) + oXml->WriteString(L" "); std::wstring sPStyle = wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); std::wstring sRStyle = wrR(oXml, sSelectors, oTS); oXml->WriteString(L""); - std::wstring::iterator end; if(oTS.bBdo) std::reverse(sText.begin(), sText.end()); - if (m_bWasSpace) - { - sText.insert(sText.begin(), L' '); - m_bWasSpace = false; - } + if(oTS.bPre) { size_t nAfter = sText.find_first_of(L"\n\r"); @@ -821,14 +835,15 @@ class CHtmlFile2_Private sText.erase(0, nAfter + 1); nAfter = sText.find_first_of(L"\n\r"); } - end = sText.end(); } else - end = std::unique(sText.begin(), sText.end(), [] (wchar_t l, wchar_t r) { return std::iswspace(l) && std::iswspace(r); }); + ReplaceSpaces(sText); - sText = std::wstring(sText.begin(), end); oXml->WriteEncodeXmlString(sText); oXml->WriteString(L""); + + m_bWasSpace = std::iswspace(sText.back()); + return; } @@ -1037,15 +1052,7 @@ class CHtmlFile2_Private // С нового абзаца else { - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); // Адрес if(sName == L"address") @@ -1158,15 +1165,7 @@ class CHtmlFile2_Private readNote(oXml, sSelectors, sNote); sNote = L""; - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); } readNote(oXml, sSelectors, sNote); sSelectors.pop_back(); @@ -1191,10 +1190,10 @@ class CHtmlFile2_Private { const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); - return L"" + - L"" + - L"" + - L""; + return L"" + + L"" + + L"" + + L""; } else { @@ -1236,7 +1235,10 @@ class CHtmlFile2_Private continue; if (oIter->m_mAttributes.end() != oIter->m_mAttributes.find(L"border")) + { bTableHasBorderAttribute = true; + break; + } } while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) @@ -1256,7 +1258,7 @@ class CHtmlFile2_Private if (L"thead" == wsName) wsTrPr += L""; - if (!bTableHasBorderAttribute && oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + if (!bTableHasBorderAttribute && oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) wsTrPr += L""; if (!wsTrPr.empty()) @@ -1340,7 +1342,7 @@ class CHtmlFile2_Private else wsTcPr += L""; - if (!oStyle.m_oPadding.Empty()) + if (!oStyle.m_oPadding.Empty() && oStyle.m_oPadding != oTableStyle.m_oPadding) { const int nTopPadding = std::max(oTableStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); @@ -1378,14 +1380,6 @@ class CHtmlFile2_Private oXml->WriteString(L""); m_bWasPStyle = false; - //Оставляем только всё что не относится к таблице -// std::vector arSelectors; -// for (const NSCSS::CNode& oItem : sSelectors) -// { -// if (NodeBelongToTable(oItem.m_wsName)) -// continue; -// arSelectors.push_back(oItem); -// } // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") { @@ -1399,18 +1393,14 @@ class CHtmlFile2_Private readStream(oXml, sSelectors, oTS); } sSelectors.pop_back(); + if (m_bInP) - { wrP(oXml, sSelectors, oTS); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } else if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") oXml->WriteString(L""); - m_bWasSpace = false; + + CloseP(oXml, sSelectors); + oXml->WriteString(L""); j++; @@ -1457,8 +1447,9 @@ class CHtmlFile2_Private if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") oXml->WriteString(L""); - m_bWasSpace = false; + m_bWasSpace = false; + // Начало таблицы std::wstring wsTable = L""; @@ -1579,14 +1570,8 @@ class CHtmlFile2_Private CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"" }; readStream(oXml, sSelectors, oTSP); if (m_bInP) - { - for (size_t i = 0; i < nHyp; i++) - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; m_bWasPStyle = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); } if(sName == L"thead") readTr(&oHead, sSelectors, oTS, oStyle); @@ -1658,15 +1643,7 @@ class CHtmlFile2_Private { if(m_oLightReader.GetName() != L"label") continue; - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); wrR(oXml, sSelectors, oTS); @@ -1691,29 +1668,16 @@ class CHtmlFile2_Private sStart = m_oLightReader.GetText(); m_oLightReader.MoveToElement(); - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); + CTextSettings oTSLiP(oTS); oTSLiP.nLi++; oTSLiP.sPStyle += L""; + (bType ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/>"; readStream(oXml, sSelectors, oTSLiP); - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bInP = false; - } - m_bWasSpace = false; + + CloseP(oXml, sSelectors); + sSelectors.pop_back(); } // Нумерованный список @@ -2044,8 +2008,10 @@ class CHtmlFile2_Private m_bInP = true; m_bWasPStyle = false; } + if (m_bWasPStyle) return L""; + oXml->WriteString(L"> temporary; @@ -2064,7 +2030,7 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - + std::wstring sPStyle = GetStyle(oStyle, true); m_oXmlStyle.WriteLitePStyle(oStyleSetting); From ed0d1fbdb02163c03ad90bfb8c31acfe4d3f5644 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 27 Feb 2024 14:54:45 +0300 Subject: [PATCH 345/794] Refactoring --- Common/3dParty/html/css/src/CCssCalculator_Private.cpp | 6 ++---- HtmlFile2/htmlfile2.cpp | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 7b75a9f653e..1e75061a5c9 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -185,8 +185,6 @@ namespace NSCSS arNodes.pop_back(); arNextNodes.push_back(wsName); -// pStyle->AddParent(wsName); - const std::map::const_iterator oFindName = m_mData.find(wsName); std::map::const_iterator oFindId; @@ -544,12 +542,12 @@ namespace NSCSS else if (!bIsSettings) oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } - else if (bIsSettings) + else /*if (bIsSettings)*/ oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - + oStyle += oTempStyle; } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 82976f347ed..200b6158964 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -842,7 +842,8 @@ class CHtmlFile2_Private oXml->WriteEncodeXmlString(sText); oXml->WriteString(L""); - m_bWasSpace = std::iswspace(sText.back()); + if (!sText.empty()) + m_bWasSpace = std::iswspace(sText.back()); return; } @@ -1138,9 +1139,8 @@ class CHtmlFile2_Private else if(sName == L"pre" || sName == L"xmp") { CTextSettings oTSPre(oTS); + sSelectors.back().m_wsStyle += L" font-family:Consolas;"; oTSPre.bPre = true; - oTSPre.sRStyle += L""; - oTSPre.sPStyle += L""; readStream(oXml, sSelectors, oTSPre); } // Таблицы From fc3e6592f4bc44cb3759cd35db66b9f4b84be6c0 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Tue, 27 Feb 2024 15:00:33 +0300 Subject: [PATCH 346/794] Fixes for support in js module --- .../graphics/pro/js/drawingfile.json | 43 +- .../pro/js/wasm/js/drawingfile_base.js | 27 + .../graphics/pro/js/wasm/src/drawingfile.cpp | 5 + .../graphics/pro/js/wasm/src/drawingfile.h | 23 + .../graphics/pro/js/wasm/src/serialize.h | 860 +++++++++--------- DocxRenderer/DocxRenderer.cpp | 4 + DocxRenderer/DocxRenderer.pro | 103 ++- DocxRenderer/src/logic/Document.cpp | 20 +- DocxRenderer/src/logic/Document.h | 8 +- .../src/logic/managers/FontManager.cpp | 2 + 10 files changed, 609 insertions(+), 486 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index efdba26d0b0..e11f8076fa4 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -44,11 +44,21 @@ "_IsFontBinaryExist", "_DestroyTextInfo", "_IsNeedCMap", - "_SetCMapData" + "_SetCMapData", + "_ScanPage" ], "include_path": [ - "wasm/src/lib", "../../../agg-2.4/include", "../../../cximage/jasper/include", "../../../cximage/jpeg", "../../../cximage/png", "freetype-2.10.4/include", "freetype-2.10.4/include/freetype", "../../../../OfficeUtils/src/zlib-1.2.11", "../../../../OfficeUtils/src", "../../../../Common/3dParty/icu/icu/source/common", "../../../xml/libxml2/include", "../../../xml/build/qt", "../../../../OfficeUtils/src/zlib-1.2.11/contrib/minizip", "../../../../PdfFile/lib/goo", "../../../../PdfFile/lib/fofi", "../../../../PdfFile/lib/splash", "../../../../PdfFile/lib", "../../../raster/Jp2/openjpeg", "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2", - "../../../../Common/3dParty/openssl/openssl/include" + "wasm/src/lib", + "../../../agg-2.4/include", + "../../../cximage/jasper/include", "../../../cximage/jpeg", "../../../cximage/png", + "freetype-2.10.4/include", "freetype-2.10.4/include/freetype", + "../../../../OfficeUtils/src/zlib-1.2.11", "../../../../OfficeUtils/src/zlib-1.2.11/contrib/minizip", "../../../../OfficeUtils/src", + "../../../../Common/3dParty/icu/icu/source/common", + "../../../xml/libxml2/include", "../../../xml/build/qt", + "../../../../PdfFile/lib/goo", "../../../../PdfFile/lib/fofi", "../../../../PdfFile/lib/splash", "../../../../PdfFile/lib", + "../../../raster/Jp2/openjpeg", "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2", + "../../../../Common/3dParty/openssl/openssl/include", + "../../../../DocxRenderer" ], "define": [ "__linux__", "_LINUX", "UNIX", @@ -66,7 +76,8 @@ "_tcsnicmp=strncmp", "_lseek=lseek", "_getcwd=getcwd", "NO_CONSOLE_IO", "USE_EXTERNAL_JPEG2000", "USE_JPIP", "OPJ_STATIC", "FONT_ENGINE_DISABLE_FILESYSTEM", "IMAGE_CHECKER_DISABLE_XML", - "USE_OPENSSL_HASH" + "USE_OPENSSL_HASH", + "DISABLE_FULL_DOCUMENT_CREATION", "DISABLE_FILESYSTEM" ], "compile_files_array": [ { @@ -188,6 +199,30 @@ { "folder": "../../../../UnicodeConverter/", "files": ["UnicodeConverter.cpp"] + }, + { + "folder": "../../../../DocxRenderer/", + "files": ["DocxRenderer.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/resources", + "files": ["VectorGraphics.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic", + "files": ["styles/FontStyle.cpp", "styles/ParagraphStyle.cpp", "Page.cpp", "Document.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic/managers", + "files": ["FontManager.cpp", "FontStyleManager.cpp", "ImageManager.cpp", "ParagraphStyleManager.cpp"] + }, + { + "folder": "../../../../DocxRenderer/src/logic/elements", + "files": ["BaseItem.cpp", "ContText.cpp", "DropCap.cpp", "Image.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp"] + }, + { + "folder": "../../../common", + "files": ["StringUTF32.cpp", "StringBuilder.cpp"] } ] } diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 838e3c515ed..6096fdffc5f 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1575,6 +1575,33 @@ return res; }; + CFile.prototype["scanPage"] = function(page) + { + let data = Module["_ScanPage"](this.nativeFile, page); + if (data == 0) + return []; + + let lenArray = new Int32Array(Module["HEAP8"].buffer, data, 4); + if (lenArray == null) + return []; + + let len = lenArray[0]; + if (0 == len) + return []; + + let buffer = new Uint8Array(Module["HEAP8"].buffer, data + 4, len); + let reader = new CBinaryReader(buffer, 0, len); + + let shapesCount = reader.readInt(); + let shapes = new Array(shapesCount); + + for (let i = 0; i < shapesCount; i++) + shapes[i] = reader.readString(); + + Module["_free"](data); + return shapes; + }; + CFile.prototype.memory = function() { return Module["HEAP8"]; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index ccb252acb2c..ec9539a3bcb 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -256,6 +256,11 @@ WASM_EXPORT void SetCMapData(CGraphicsFileDrawing* pGraphics, BYTE* data, int si pGraphics->SetCMapData(data, size); } +WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex) +{ + return pGraphics->GetPageShapes(nPageIndex); +} + #ifdef __cplusplus } #endif diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index bcd36616c02..07cbc995326 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -7,6 +7,7 @@ #include "../../../../../../DjVuFile/DjVu.h" #include "../../../../../../PdfFile/PdfFile.h" #include "../../../../../../HtmlRenderer/include/HTMLRendererText.h" +#include "../../../../../../DocxRenderer/DocxRenderer.h" #include "serialize.h" class CGraphicsFileDrawing @@ -185,6 +186,28 @@ class CGraphicsFileDrawing { RELEASEOBJECT(pTextRenderer); } + + BYTE* GetPageShapes(const int& nPageIndex) + { + CDocxRenderer oRenderer(pApplicationFonts); + + std::vector arShapes = oRenderer.ScanPage(pReader, nPageIndex); + + int nLen = (int)arShapes.size(); + + NSWasm::CData oRes; + oRes.SkipLen(); + oRes.AddInt(nLen); + + for (int i = 0; i < nLen; ++i) + oRes.WriteString(arShapes[i]); + + oRes.WriteLen(); + + BYTE* res = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return res; + } }; #endif // _WASM_GRAPHICS_ diff --git a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h index 72f151d2539..665efebb843 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h @@ -1,439 +1,449 @@ #ifndef _WASM_SERIALIZE_H #define _WASM_SERIALIZE_H -#include "../../../../../graphics/IRenderer.h" #include "../../../../../common/StringExt.h" #include "../../../../../common/StringUTF32.h" +#include "../../../../../graphics/IRenderer.h" #include "../../../../../graphics/pro/Fonts.h" +#include "../../../../../common/File.h" namespace NSWasm { - class CData - { - protected: - BYTE* m_pData; - size_t m_lSize; - - BYTE* m_pDataCur; - size_t m_lSizeCur; - - public: - CData() - { - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - } - virtual ~CData() - { - Clear(); - } - - inline void AddSize(size_t nSize) - { - if (NULL == m_pData) - { - m_lSize = 1000; - if (nSize > m_lSize) - m_lSize = nSize; - - m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - m_lSize *= 2; - - BYTE* pRealloc = (BYTE*)realloc(m_pData, m_lSize * sizeof(BYTE)); - if (NULL != pRealloc) - { - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - BYTE* pMalloc = (BYTE*)malloc(m_lSize * sizeof(BYTE)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(BYTE)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } - - public: - void AddInt(unsigned int value) - { - AddSize(4); - memcpy(m_pDataCur, &value, sizeof(unsigned int)); - m_pDataCur += 4; - m_lSizeCur += 4; - } - void AddInt(unsigned int value, size_t pos) - { - if (pos < m_lSizeCur) - memcpy(m_pData + pos, &value, sizeof(unsigned int)); - } - void AddDouble(double value) - { - // такой точности хватит - int nV = value * 100; - AddInt(nV); - } - void WriteBYTE(BYTE value) - { - AddSize(sizeof(BYTE)); - memcpy(m_pDataCur, &value, sizeof(BYTE)); - m_pDataCur += sizeof(BYTE); - m_lSizeCur += sizeof(BYTE); - } - void WriteDouble(double value) - { - int nV = value * 10000; - AddInt(nV); - } - void WriteDouble2(double value) - { - SHORT lValue = (SHORT)(value * 100); - AddSize(sizeof(SHORT)); - memcpy(m_pDataCur, &lValue, sizeof(SHORT)); - m_pDataCur += sizeof(SHORT); - m_lSizeCur += sizeof(SHORT); - } - void WriteWCHAR(int value) - { - if (value < 0x10000) - WriteUSHORT(value); - else - { - AddSize(4); - int code = value - 0x10000; - USHORT c1 = 0xD800 | ((code >> 10) & 0x03FF); - USHORT c2 = 0xDC00 | (code & 0x03FF); - memcpy(m_pDataCur, &c1, sizeof(USHORT)); - memcpy(m_pDataCur + 2, &c2, sizeof(USHORT)); - m_pDataCur += 4; - m_lSizeCur += 4; - } - } - void WriteUSHORT(USHORT value) - { - AddSize(sizeof(USHORT)); - memcpy(m_pDataCur, &value, sizeof(USHORT)); - m_pDataCur += sizeof(USHORT); - m_lSizeCur += sizeof(USHORT); - } - void WriteString(BYTE* value, unsigned int len) - { - AddSize(len + 4); - memcpy(m_pDataCur, &len, sizeof(unsigned int)); - m_pDataCur += 4; - m_lSizeCur += 4; - memcpy(m_pDataCur, value, len); - m_pDataCur += len; - m_lSizeCur += len; - } - void WriteString(const std::string& sStr) - { - WriteString((BYTE*)sStr.c_str(), (unsigned int)sStr.length()); - } - void Write(BYTE* value, unsigned int len) - { - if (!value || len == 0) - return; - AddSize(len); - memcpy(m_pDataCur, value, len); - m_pDataCur += len; - m_lSizeCur += len; - } - BYTE* GetBuffer() - { - return m_pData; - } - - void Clear() - { - if (m_pData) free(m_pData); - - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - void ClearWithoutAttack() - { - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - void ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - unsigned int GetSize() - { - return (unsigned int)m_lSizeCur; - } - - void SkipLen() - { - AddInt(0); - } - void WriteLen() - { - unsigned int len = (unsigned int)m_lSizeCur; - memcpy(m_pData, &len, sizeof(unsigned int)); - } - }; - - class CHChar - { - public: - int unicode; // юникодное значение - int gid; // индекс глифа в файле - double x; // сдвиг по baseline - double width; // ширина символа (сдвиг до след буквы) - double* matrix; // матрица преобразования (!!! без сдвига) - - public: - CHChar() - { - unicode = 0; - gid = 0; - width = 0; - matrix = NULL; - } - CHChar(const CHChar& oSrc) - { - *this = oSrc; - } - CHChar& operator=(const CHChar& oSrc) - { - unicode = oSrc.unicode; - gid = oSrc.gid; - width = oSrc.width; - matrix = NULL; - if (NULL != oSrc.matrix) - { - matrix = new double[4]; - memcpy(matrix, oSrc.matrix, 4 * sizeof(double)); - } - return *this; - } - ~CHChar() - { - RELEASEARRAYOBJECTS(matrix); - } - - inline void Clear() - { - unicode = 0; - gid = 0; - width = 0; - - RELEASEARRAYOBJECTS(matrix); - } - }; - - class CHLine - { - public: - double m_dAscent; - double m_dDescent; - double m_dX; - double m_dY; - - double m_dEndX; - double m_dEndY; - - // baseline ruler: y = k*x + b - double m_dK; - double m_dB; - double m_ex; - double m_ey; - bool m_bIsConstX; - - // symbols - // не менять на списки. постоянное создание объектов и их удаление - - // плохо влияет на скорость - CHChar* m_pChars; - LONG m_lSizeChars; - LONG m_lCharsTail; - - bool m_bIsSetUpTransform; - double m_sx; - double m_sy; - double m_shx; - double m_shy; - - public: - CHLine() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lSizeChars = 1000; - m_lCharsTail = 0; - m_pChars = new CHChar[m_lSizeChars]; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - CHLine& operator=(const CHLine& oLine) - { - m_dAscent = oLine.m_dAscent; - m_dDescent = oLine.m_dDescent; - m_dX = oLine.m_dX; - m_dY = oLine.m_dY; - - m_dK = oLine.m_dK; - m_dB = oLine.m_dB; - - m_lSizeChars = oLine.m_lSizeChars; - m_lCharsTail = oLine.m_lCharsTail; - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = new CHChar[m_lSizeChars]; - - for (LONG i = 0; i < m_lSizeChars; ++i) - m_pChars[i] = oLine.m_pChars[i]; - - m_bIsSetUpTransform = oLine.m_bIsSetUpTransform; - m_sx = oLine.m_sx; - m_sy = oLine.m_sy; - m_shx = oLine.m_shx; - m_shy = oLine.m_shy; - - return *this; - } - ~CHLine() - { - RELEASEARRAYOBJECTS(m_pChars); - } - - inline void Clear() - { - m_dAscent = 0; - m_dDescent = 0; - m_dX = 0; - m_dY = 0; - - m_dK = 0; - m_dB = 0; - m_bIsConstX = false; - - m_ex = 0; - m_ey = 0; - - m_lCharsTail = 0; - - m_bIsSetUpTransform = false; - m_sx = 1; - m_sy = 1; - m_shx = 0; - m_shy = 0; - } - - inline CHChar* AddTail() - { - if (m_lCharsTail >= m_lSizeChars) - { - CHChar* pNews = new CHChar[2 * m_lSizeChars]; - for (LONG i = 0; i < m_lSizeChars; ++i) - { - pNews[i] = m_pChars[i]; - } - - RELEASEARRAYOBJECTS(m_pChars); - m_pChars = pNews; - m_lSizeChars *= 2; - } - - CHChar* pChar = &m_pChars[m_lCharsTail]; - ++m_lCharsTail; - pChar->Clear(); - - return pChar; - } - - inline CHChar* GetTail() - { - if (0 == m_lCharsTail) - return NULL; - - return &m_pChars[m_lCharsTail - 1]; - } - - inline LONG GetCountChars() - { - return m_lCharsTail; - } - }; -} + class CData + { + protected: + BYTE* m_pData; + size_t m_lSize; + + BYTE* m_pDataCur; + size_t m_lSizeCur; + + public: + CData() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + } + virtual ~CData() + { + Clear(); + } + + inline void AddSize(size_t nSize) + { + if (NULL == m_pData) + { + m_lSize = 1000; + if (nSize > m_lSize) + m_lSize = nSize; + + m_pData = (BYTE*)malloc(m_lSize * sizeof(BYTE)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + m_lSize *= 2; + + BYTE* pRealloc = (BYTE*)realloc(m_pData, m_lSize * sizeof(BYTE)); + if (NULL != pRealloc) + { + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + BYTE* pMalloc = (BYTE*)malloc(m_lSize * sizeof(BYTE)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(BYTE)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + public: + void AddInt(unsigned int value) + { + AddSize(4); + memcpy(m_pDataCur, &value, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + } + void AddInt(unsigned int value, size_t pos) + { + if (pos < m_lSizeCur) + memcpy(m_pData + pos, &value, sizeof(unsigned int)); + } + void AddDouble(double value) + { + // такой точности хватит + int nV = value * 100; + AddInt(nV); + } + void WriteBYTE(BYTE value) + { + AddSize(sizeof(BYTE)); + memcpy(m_pDataCur, &value, sizeof(BYTE)); + m_pDataCur += sizeof(BYTE); + m_lSizeCur += sizeof(BYTE); + } + void WriteDouble(double value) + { + int nV = value * 10000; + AddInt(nV); + } + void WriteDouble2(double value) + { + SHORT lValue = (SHORT)(value * 100); + AddSize(sizeof(SHORT)); + memcpy(m_pDataCur, &lValue, sizeof(SHORT)); + m_pDataCur += sizeof(SHORT); + m_lSizeCur += sizeof(SHORT); + } + void WriteWCHAR(int value) + { + if (value < 0x10000) + WriteUSHORT(value); + else + { + AddSize(4); + int code = value - 0x10000; + USHORT c1 = 0xD800 | ((code >> 10) & 0x03FF); + USHORT c2 = 0xDC00 | (code & 0x03FF); + memcpy(m_pDataCur, &c1, sizeof(USHORT)); + memcpy(m_pDataCur + 2, &c2, sizeof(USHORT)); + m_pDataCur += 4; + m_lSizeCur += 4; + } + } + void WriteUSHORT(USHORT value) + { + AddSize(sizeof(USHORT)); + memcpy(m_pDataCur, &value, sizeof(USHORT)); + m_pDataCur += sizeof(USHORT); + m_lSizeCur += sizeof(USHORT); + } + void WriteString(BYTE* value, unsigned int len) + { + AddSize(len + 4); + memcpy(m_pDataCur, &len, sizeof(unsigned int)); + m_pDataCur += 4; + m_lSizeCur += 4; + memcpy(m_pDataCur, value, len); + m_pDataCur += len; + m_lSizeCur += len; + } + void WriteString(const std::string& sStr) + { + WriteString((BYTE*)sStr.c_str(), (unsigned int)sStr.length()); + } + void WriteString(const std::wstring& sStr) + { + BYTE* pDataUtf8 = NULL; + LONG lDataUtf8 = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sStr.c_str(), (LONG)sStr.length(), pDataUtf8, lDataUtf8); + + WriteString(pDataUtf8, (unsigned int)lDataUtf8); + } + void Write(BYTE* value, unsigned int len) + { + if (!value || len == 0) + return; + AddSize(len); + memcpy(m_pDataCur, value, len); + m_pDataCur += len; + m_lSizeCur += len; + } + BYTE* GetBuffer() + { + return m_pData; + } + + void Clear() + { + if (m_pData) + free(m_pData); + + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void ClearWithoutAttack() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + unsigned int GetSize() + { + return (unsigned int)m_lSizeCur; + } + + void SkipLen() + { + AddInt(0); + } + void WriteLen() + { + unsigned int len = (unsigned int)m_lSizeCur; + memcpy(m_pData, &len, sizeof(unsigned int)); + } + }; + + class CHChar + { + public: + int unicode; // юникодное значение + int gid; // индекс глифа в файле + double x; // сдвиг по baseline + double width; // ширина символа (сдвиг до след буквы) + double* matrix; // матрица преобразования (!!! без сдвига) + + public: + CHChar() + { + unicode = 0; + gid = 0; + width = 0; + matrix = NULL; + } + CHChar(const CHChar& oSrc) + { + *this = oSrc; + } + CHChar& operator=(const CHChar& oSrc) + { + unicode = oSrc.unicode; + gid = oSrc.gid; + width = oSrc.width; + matrix = NULL; + if (NULL != oSrc.matrix) + { + matrix = new double[4]; + memcpy(matrix, oSrc.matrix, 4 * sizeof(double)); + } + return *this; + } + ~CHChar() + { + RELEASEARRAYOBJECTS(matrix); + } + + inline void Clear() + { + unicode = 0; + gid = 0; + width = 0; + + RELEASEARRAYOBJECTS(matrix); + } + }; + + class CHLine + { + public: + double m_dAscent; + double m_dDescent; + double m_dX; + double m_dY; + + double m_dEndX; + double m_dEndY; + + // baseline ruler: y = k*x + b + double m_dK; + double m_dB; + double m_ex; + double m_ey; + bool m_bIsConstX; + + // symbols + // не менять на списки. постоянное создание объектов и их удаление - + // плохо влияет на скорость + CHChar* m_pChars; + LONG m_lSizeChars; + LONG m_lCharsTail; + + bool m_bIsSetUpTransform; + double m_sx; + double m_sy; + double m_shx; + double m_shy; + + public: + CHLine() + { + m_dAscent = 0; + m_dDescent = 0; + m_dX = 0; + m_dY = 0; + + m_dK = 0; + m_dB = 0; + m_bIsConstX = false; + + m_ex = 0; + m_ey = 0; + + m_lSizeChars = 1000; + m_lCharsTail = 0; + m_pChars = new CHChar[m_lSizeChars]; + + m_bIsSetUpTransform = false; + m_sx = 1; + m_sy = 1; + m_shx = 0; + m_shy = 0; + } + CHLine& operator=(const CHLine& oLine) + { + m_dAscent = oLine.m_dAscent; + m_dDescent = oLine.m_dDescent; + m_dX = oLine.m_dX; + m_dY = oLine.m_dY; + + m_dK = oLine.m_dK; + m_dB = oLine.m_dB; + + m_lSizeChars = oLine.m_lSizeChars; + m_lCharsTail = oLine.m_lCharsTail; + + RELEASEARRAYOBJECTS(m_pChars); + m_pChars = new CHChar[m_lSizeChars]; + + for (LONG i = 0; i < m_lSizeChars; ++i) + m_pChars[i] = oLine.m_pChars[i]; + + m_bIsSetUpTransform = oLine.m_bIsSetUpTransform; + m_sx = oLine.m_sx; + m_sy = oLine.m_sy; + m_shx = oLine.m_shx; + m_shy = oLine.m_shy; + + return *this; + } + ~CHLine() + { + RELEASEARRAYOBJECTS(m_pChars); + } + + inline void Clear() + { + m_dAscent = 0; + m_dDescent = 0; + m_dX = 0; + m_dY = 0; + + m_dK = 0; + m_dB = 0; + m_bIsConstX = false; + + m_ex = 0; + m_ey = 0; + + m_lCharsTail = 0; + + m_bIsSetUpTransform = false; + m_sx = 1; + m_sy = 1; + m_shx = 0; + m_shy = 0; + } + + inline CHChar* AddTail() + { + if (m_lCharsTail >= m_lSizeChars) + { + CHChar* pNews = new CHChar[2 * m_lSizeChars]; + for (LONG i = 0; i < m_lSizeChars; ++i) + { + pNews[i] = m_pChars[i]; + } + + RELEASEARRAYOBJECTS(m_pChars); + m_pChars = pNews; + m_lSizeChars *= 2; + } + + CHChar* pChar = &m_pChars[m_lCharsTail]; + ++m_lCharsTail; + pChar->Clear(); + + return pChar; + } + + inline CHChar* GetTail() + { + if (0 == m_lCharsTail) + return NULL; + + return &m_pChars[m_lCharsTail - 1]; + } + + inline LONG GetCountChars() + { + return m_lCharsTail; + } + }; +} // namespace NSWasm namespace NSWasm { - struct CPageLinkItem - { - std::string Link; - double Dest; - - double X; - double Y; - double W; - double H; - }; - - class CPageLink - { - public: - std::vector m_arLinks; - - public: - BYTE* Serialize() - { - NSWasm::CData oRes; - oRes.SkipLen(); - for (const CPageLinkItem& link : m_arLinks) - { - oRes.WriteString((BYTE*)link.Link.c_str(), link.Link.length()); - oRes.AddDouble(link.Dest); - oRes.AddDouble(link.X); - oRes.AddDouble(link.Y); - oRes.AddDouble(link.W); - oRes.AddDouble(link.H); - } - oRes.WriteLen(); - - BYTE* res = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return res; - } - }; -} + struct CPageLinkItem + { + std::string Link; + double Dest; + + double X; + double Y; + double W; + double H; + }; + + class CPageLink + { + public: + std::vector m_arLinks; + + public: + BYTE* Serialize() + { + NSWasm::CData oRes; + oRes.SkipLen(); + for (const CPageLinkItem& link : m_arLinks) + { + oRes.WriteString((BYTE*)link.Link.c_str(), link.Link.length()); + oRes.AddDouble(link.Dest); + oRes.AddDouble(link.X); + oRes.AddDouble(link.Y); + oRes.AddDouble(link.W); + oRes.AddDouble(link.H); + } + oRes.WriteLen(); + + BYTE* res = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return res; + } + }; +} // namespace NSWasm #endif // _WASM_SERIALIZE_H diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 3f9321376c1..c9f4129f0f2 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -78,6 +78,7 @@ HRESULT CDocxRenderer::SetTextAssociationType(const NSDocxRenderer::TextAssociat int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) { +#ifndef DISABLE_FULL_DOCUMENT_CREATION m_pInternal->m_oDocument.m_strDstFilePath = sDstFile; if (bIsOutCompress) @@ -99,6 +100,9 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi m_pInternal->m_oDocument.Clear(); if (bIsOutCompress) hr = Compress(); return (hr == S_OK) ? 0 : 1; +#else + return S_FALSE; +#endif } std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, size_t nPage) diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index 504cd24a730..a1c6860787e 100644 --- a/DocxRenderer/DocxRenderer.pro +++ b/DocxRenderer/DocxRenderer.pro @@ -16,58 +16,67 @@ DEFINES += DOCXRENDERER_USE_DYNAMIC_LIBRARY ADD_DEPENDENCY(UnicodeConverter, kernel, graphics) -core_windows { +# Flag for disable full document creation. Enabled in pdf editor +#CONFIG += disable_full_document_creation -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 +core_windows { +LIBS += \ + -lgdi32 \ + -ladvapi32 \ + -luser32 \ + -lshell32 } HEADERS += \ - src/logic/elements/BaseItem.h \ - src/logic/elements/ContText.h \ - src/logic/elements/DropCap.h \ - src/logic/elements/Image.h \ - src/logic/elements/Paragraph.h \ - src/logic/elements/Shape.h \ - src/logic/elements/TextLine.h \ - src/logic/managers/FontStyleManager.h \ - src/logic/managers/ImageManager.h \ - src/logic/managers/FontManager.h \ - src/logic/managers/ParagraphStyleManager.h \ - src/logic/styles/FontStyle.h \ - src/logic/styles/ParagraphStyle.h \ - src/resources/ColorTable.h \ - src/resources/Constants.h \ - src/resources/ImageInfo.h \ - src/resources/LinesTable.h \ - src/resources/VectorGraphics.h \ - src/resources/resources.h \ - src/resources/utils.h \ - src/logic/Page.h \ - src/logic/Document.h \ - DocxRenderer.h + src/logic/elements/BaseItem.h \ + src/logic/elements/ContText.h \ + src/logic/elements/DropCap.h \ + src/logic/elements/Image.h \ + src/logic/elements/Paragraph.h \ + src/logic/elements/Shape.h \ + src/logic/elements/TextLine.h \ + src/logic/managers/FontStyleManager.h \ + src/logic/managers/ImageManager.h \ + src/logic/managers/FontManager.h \ + src/logic/managers/ParagraphStyleManager.h \ + src/logic/styles/FontStyle.h \ + src/logic/styles/ParagraphStyle.h \ + src/resources/ColorTable.h \ + src/resources/Constants.h \ + src/resources/ImageInfo.h \ + src/resources/LinesTable.h \ + src/resources/VectorGraphics.h \ + src/resources/resources.h \ + src/resources/utils.h \ + src/logic/Page.h \ + src/logic/Document.h \ + DocxRenderer.h SOURCES += \ - src/logic/elements/BaseItem.cpp \ - src/logic/elements/ContText.cpp \ - src/logic/elements/DropCap.cpp \ - src/logic/elements/Image.cpp \ - src/logic/elements/Paragraph.cpp \ - src/logic/elements/Shape.cpp \ - src/logic/elements/TextLine.cpp \ - src/logic/managers/FontManager.cpp \ - src/logic/managers/FontStyleManager.cpp \ - src/logic/managers/ImageManager.cpp \ - src/logic/managers/ParagraphStyleManager.cpp \ - src/logic/styles/FontStyle.cpp \ - src/logic/Page.cpp \ - src/logic/Document.cpp \ - src/logic/styles/ParagraphStyle.cpp \ - src/resources/VectorGraphics.cpp \ - src/resources/resources.cpp \ - DocxRenderer.cpp + src/logic/elements/BaseItem.cpp \ + src/logic/elements/ContText.cpp \ + src/logic/elements/DropCap.cpp \ + src/logic/elements/Image.cpp \ + src/logic/elements/Paragraph.cpp \ + src/logic/elements/Shape.cpp \ + src/logic/elements/TextLine.cpp \ + src/logic/managers/FontManager.cpp \ + src/logic/managers/FontStyleManager.cpp \ + src/logic/managers/ImageManager.cpp \ + src/logic/managers/ParagraphStyleManager.cpp \ + src/logic/styles/FontStyle.cpp \ + src/logic/Page.cpp \ + src/logic/Document.cpp \ + src/logic/styles/ParagraphStyle.cpp \ + src/resources/VectorGraphics.cpp \ + DocxRenderer.cpp + +disable_full_document_creation { + DEFINES += DISABLE_FULL_DOCUMENT_CREATION +} else { + SOURCES += \ + src/resources/resources.cpp +} DISTFILES += \ - readme.md + readme.md diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index c4638e7796a..7f217bfe0ae 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -1,5 +1,9 @@ #include "Document.h" +#ifndef DISABLE_FULL_DOCUMENT_CREATION +#include "./../resources/resources.h" +#endif + namespace NSDocxRenderer { CDocument::CDocument(IRenderer* pRenderer, NSFonts::IApplicationFonts* pFonts) : @@ -797,13 +801,6 @@ namespace NSDocxRenderer m_oInstalledFont = m_oFont; } - void CDocument::CreateTemplates() - { - CreateTemplate(m_strTempDirectory); - m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; - NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); - } - void CDocument::Init() { // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", @@ -832,6 +829,14 @@ namespace NSDocxRenderer m_oFontStyleManager.Clear(); } +#ifndef DISABLE_FULL_DOCUMENT_CREATION + void CDocument::CreateTemplates() + { + CreateTemplate(m_strTempDirectory); + m_oImageManager.m_strDstMedia = m_strTempDirectory + L"/word/media"; + NSDirectory::CreateDirectory(m_oImageManager.m_strDstMedia); + } + void CDocument::Write() { BuildDocumentXml(); @@ -1230,4 +1235,5 @@ namespace NSDocxRenderer NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/styles.xml", oWriter.GetData()); } +#endif } diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index aee5fdfc167..fc250006b88 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -1,7 +1,6 @@ #pragma once #include "Page.h" #include "../../../DesktopEditor/common/Directory.h" -#include "../resources/resources.h" #include "managers/ImageManager.h" #include "managers/FontStyleManager.h" #include "managers/ParagraphStyleManager.h" @@ -192,14 +191,17 @@ namespace NSDocxRenderer void _SetFont(); public: - void CreateTemplates(); void Init(); - void Write(); void Clear(); +#ifndef DISABLE_FULL_DOCUMENT_CREATION void BuildDocumentXml(); void BuildDocumentXmlRels(); void BuildFontTableXml(); void BuildStylesXml(); + + void CreateTemplates(); + void Write(); +#endif }; } diff --git a/DocxRenderer/src/logic/managers/FontManager.cpp b/DocxRenderer/src/logic/managers/FontManager.cpp index 42f49770eb3..62d75cce640 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -711,6 +711,7 @@ namespace NSDocxRenderer void CFontManager::CheckPdfResources() { +#ifndef DISABLE_FILESYSTEM bool bIsCID = false; std::wstring sFileExt = NSFile::GetFileExtention(m_oFont.Path); if (std::wstring::npos != sFileExt.find(L"cid")) @@ -766,6 +767,7 @@ namespace NSDocxRenderer } } } +#endif } void CFontManager::ClearCache() From 4dc1751d8989ed3f4f3948d6ae2c98b50c0b4759 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 27 Feb 2024 18:42:33 +0600 Subject: [PATCH 347/794] Fix color conversion --- OOXML/XlsxFormat/Styles/Fills.cpp | 4 ++++ OOXML/XlsxFormat/Styles/rPr.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index 1d8f16f5335..242ef9b09cd 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -154,7 +154,11 @@ namespace OOX ptr->fls = 0x11; else if (m_oPatternType == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray0625) ptr->fls = 0x12; + else + ptr->fls = 0x00; } + else + ptr->fls = 0x00; if(m_oBgColor.IsInit()) ptr->brtColorBack = m_oBgColor->toColor(); diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 6c99fa3e12e..8fe1bf5a5ec 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -494,6 +494,7 @@ namespace OOX ptr.bBlue = m_oRgb->Get_B(); ptr.bGreen = m_oRgb->Get_G(); ptr.bRed = m_oRgb->Get_R(); + ptr.xColorType = 2; } From 487c7500202eb601f72483a43caa7ebc8308fcb2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 27 Feb 2024 16:26:20 +0300 Subject: [PATCH 348/794] Create CShapeStart::Read --- DesktopEditor/graphics/commands/AnnotField.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 4cec1d4d7a8..a2d112d18ae 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -878,3 +878,16 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil return true; } + +CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} +bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + std::string sShape = pReader->ReadStringA(); + return true; +} + +CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} +bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + return true; +} From 8ebd23defb09e35eba4cfa4f0d2662f55816bb23 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 27 Feb 2024 17:17:35 +0300 Subject: [PATCH 349/794] UserProtectedRangeType --- .../Sheets/Common/BinReaderWriterDefines.h | 6 +++-- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 12 ++++++++++ OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 10 +++++++++ OOXML/Common/SimpleTypes_Spreadsheet.cpp | 22 +++++++++++++++++++ OOXML/Common/SimpleTypes_Spreadsheet.h | 8 +++++++ .../Worksheets/WorksheetChildOther.cpp | 6 +++++ .../Worksheets/WorksheetChildOther.h | 3 +++ 7 files changed, 65 insertions(+), 2 deletions(-) diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index d29f7c20f71..b83bf9c7ea3 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -1353,12 +1353,14 @@ namespace BinXlsxRW Name = 2, Text = 3, User = 4, - UsersGroup = 5 + UsersGroup = 5, + Type = 6 };} namespace c_oSer_UserProtectedRangeDesc {enum c_oSer_UserProtectedRangeDesc { Id = 0, - Name = 1 + Name = 1, + Type = 2 };} namespace c_oSer_DataValidation{enum c_oSer_DataValidation { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 324e608fbb4..310abf4fb21 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -8003,6 +8003,12 @@ void BinaryWorksheetTableWriter::WriteUserProtectedRangeDesc(const OOX::Spreadsh m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); m_oBcw.m_oStream.WriteStringW(*desc.name); } + if (desc.type.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRangeDesc::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(desc.type->GetValue()); + } } void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet::CUserProtectedRange& oUserProtectedRange) { @@ -8024,6 +8030,12 @@ void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet: m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oText); m_oBcw.WriteItemEnd(nCurPos); } + if (oUserProtectedRange.m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRange::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oUserProtectedRange.m_oType->GetValue()); + } for (size_t i = 0; i < oUserProtectedRange.m_arUsers.size(); ++i) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::User); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index dad8a2faca7..95fb29a792a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -6844,6 +6844,11 @@ int BinaryWorksheetsTableReader::ReadUserProtectedRangeDesc(BYTE type, long leng { desc->id = m_oBufferedStream.GetString4(length); } + else if (c_oSer_UserProtectedRangeDesc::Type == type) + { + desc->type.Init(); + desc->type->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -6864,6 +6869,11 @@ int BinaryWorksheetsTableReader::ReadUserProtectedRange(BYTE type, long length, { pUserProtectedRange->m_oText = m_oBufferedStream.GetString4(length); } + else if (c_oSer_UserProtectedRange::Type == type) + { + pUserProtectedRange->m_oType.Init(); + pUserProtectedRange->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else if (c_oSer_UserProtectedRange::User == type) { OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc desc; diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 4df1ea497fe..24d91f3e28f 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -3393,5 +3393,27 @@ namespace SimpleTypes } return L"v"; } + EUserProtectedRangeType CUserProtectedRangeType::FromString(const std::wstring& sValue) + { + if (L"notView" == sValue) + this->m_eValue = typeNotView; + else if (L"view" == sValue) + this->m_eValue = typeView; + else if (L"edit" == sValue) + this->m_eValue = typeEdit; + else + this->m_eValue = typeEdit; + return this->m_eValue; + } + std::wstring CUserProtectedRangeType::ToString() const + { + switch (this->m_eValue) + { + case typeNotView: return L"notView"; break; + case typeView: return L"view"; break; + case typeEdit: return L"edit"; break; + } + return L"edit"; + } }// Spreadsheet } // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.h b/OOXML/Common/SimpleTypes_Spreadsheet.h index d132525ca87..97c7808f93d 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.h +++ b/OOXML/Common/SimpleTypes_Spreadsheet.h @@ -1441,5 +1441,13 @@ namespace SimpleTypes }; DEFINE_SIMPLE_TYPE(CMdxFunctionType, EMdxFunctionType, mdxFunctionType_m) + enum EUserProtectedRangeType + { + typeNotView = 0, + typeView = 1, + typeEdit = 2 + }; + DEFINE_SIMPLE_TYPE(CUserProtectedRangeType, EUserProtectedRangeType, typeView) + }// Spreadsheet } // SimpleTypes diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index c5dde243d34..8fd1f883851 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -3332,6 +3332,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"name", m_oName) WritingElement_ReadAttributes_Read_else_if(oReader, L"sqref", m_oSqref) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", m_oType) WritingElement_ReadAttributes_End(oReader) } void CUserProtectedRange::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -3362,6 +3363,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"id", desc.id) WritingElement_ReadAttributes_Read_else_if(oReader, L"name", desc.name) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", desc.type) WritingElement_ReadAttributes_End(oReader) m_arUsers.push_back(desc); } @@ -3379,6 +3381,7 @@ namespace OOX WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"id", desc.id) WritingElement_ReadAttributes_Read_else_if(oReader, L"name", desc.name) + WritingElement_ReadAttributes_Read_else_if(oReader, L"type", desc.type) WritingElement_ReadAttributes_End(oReader) m_arUsersGroups.push_back(desc); } @@ -3391,6 +3394,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L">"); if (m_oText.IsInit()) @@ -3407,6 +3411,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L"/>"); } writer.WriteString(L""); @@ -3419,6 +3424,7 @@ namespace OOX writer.WriteString(L"ToString()) writer.WriteString(L"/>"); } writer.WriteString(L""); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index f6b7c54bcdf..201fea20613 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -55,6 +55,7 @@ namespace SimpleTypes class CPaneState; class CSheetViewType; class CDataConsolidateFunction; + class CUserProtectedRangeType; } } @@ -870,6 +871,7 @@ namespace OOX { nullable_string id; nullable_string name; + nullable type; }; WritingElement_AdditionMethods(CUserProtectedRange) @@ -889,6 +891,7 @@ namespace OOX nullable_string m_oName; nullable_string m_oSqref; nullable_string m_oText; + nullable m_oType; std::vector<_UsersGroupsDesc> m_arUsers; std::vector<_UsersGroupsDesc> m_arUsersGroups; From 163e21acf4ddaa9d5c4a41a734d919b284bac570 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 27 Feb 2024 17:56:13 +0300 Subject: [PATCH 350/794] fix bug #53909 --- .../DocFile/TableRowPropertiesMapping.cpp | 259 ++++++++++-------- 1 file changed, 148 insertions(+), 111 deletions(-) diff --git a/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp b/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp index a74ba36ddac..e322590c9f2 100644 --- a/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp @@ -60,7 +60,9 @@ namespace DocFileFormat std::shared_ptr brcHorz; std::shared_ptr brcVert; - //delete infos + XMLTools::XMLElement* _tcMar = NULL; + + //delete infos RevisionData rev( _rowEndChpx ); if ( ( _rowEndChpx != NULL ) && ( rev.Type == Deleted ) ) @@ -72,133 +74,162 @@ namespace DocFileFormat XMLTools::XMLElement rowHeight(L"w:trHeight"); for ( std::vector::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++ ) { - switch ( iter->OpCode ) + switch (iter->OpCode) + { + case sprmOldTDefTable: + case sprmTDefTable: { - case sprmOldTDefTable: - case sprmTDefTable: + //SprmTDefTable tdef = new SprmTDefTable(sprm.Arguments); + }break; + case sprmOldTTableHeader: + case sprmTTableHeader: + { //header row + + bool fHeader = (iter->Arguments[0] != 0) ? (true) : (false); + + if (fHeader) { - //SprmTDefTable tdef = new SprmTDefTable(sprm.Arguments); - }break; - case sprmOldTTableHeader: - case sprmTTableHeader: - { //header row - - bool fHeader = ( iter->Arguments[0] != 0 ) ? (true) : (false); - - if ( fHeader ) - { - XMLTools::XMLElement header( L"w:tblHeader" ); - _trPr->AppendChild( header ); - } - }break; - case sprmTWidthAfter: - { //width after - XMLTools::XMLElement wAfter( L"w:wAfter" ); - XMLTools::XMLAttribute wAfterValue( L"w:w", FormatUtils::IntToWideString( FormatUtils::BytesToInt16( iter->Arguments, 1, iter->argumentsSize ) ) ); - wAfter.AppendAttribute( wAfterValue ); - - XMLTools::XMLAttribute wAfterType( L"w:type", L"dxa" ); - wAfter.AppendAttribute( wAfterType ); - _trPr->AppendChild( wAfter, true ); - }break; - case sprmTWidthBefore: - { //width before - short before = FormatUtils::BytesToInt16( iter->Arguments, 1, iter->argumentsSize ); - - if ( before != 0 ) - { - XMLTools::XMLElement wBefore( L"w:wBefore" ); - XMLTools::XMLAttribute wBeforeValue( L"w:w", FormatUtils::IntToWideString( before ) ); - wBefore.AppendAttribute( wBeforeValue ); - - XMLTools::XMLAttribute wBeforeType( L"w:type", L"dxa" ); - wBefore.AppendAttribute( wBeforeType ); - _trPr->AppendChild( wBefore, true ); - } - }break; - case sprmOldTDyaRowHeight: - case sprmTDyaRowHeight: - { //row height - XMLTools::XMLAttribute rowHeightVal( L"w:val" ); - XMLTools::XMLAttribute rowHeightRule( L"w:hRule" ); - - short rH = FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ); - - if ( rH > 0 ) - { - rowHeightRule.SetValue( L"atLeast" ); - rowHeightVal.SetValue( FormatUtils::IntToWideString( rH ) ); - rowHeight.AppendAttribute( rowHeightVal ); - } - else if( rH == 0 ) - { - rowHeightRule.SetValue( L"auto" ); - } - else - { - rowHeightRule.SetValue( L"exact" ); - rH *= -1; - rowHeightVal.SetValue( FormatUtils::IntToWideString( rH ) ); - rowHeight.AppendAttribute( rowHeightVal ); - } - rowHeight.AppendAttribute( rowHeightRule ); + XMLTools::XMLElement header(L"w:tblHeader"); + _trPr->AppendChild(header); } - break; - case sprmOldTFCantSplit: - case sprmTFCantSplit: - break; - case sprmTFCantSplit90: - { //can't split - if (iter->argumentsSize > 0 && iter->Arguments[0] != 0) - appendFlagElement( _trPr, *iter, L"cantSplit", true ); - }break; - case sprmTIpgp:// = PGPInfo.ipgpSelf (PGPInfo structure describes the border and margin properties) - { //div id - }break; - case sprmTCellSpacing: - case sprmTCellSpacingDefault: + }break; + case sprmTWidthAfter: + { //width after + XMLTools::XMLElement wAfter(L"w:wAfter"); + XMLTools::XMLAttribute wAfterValue(L"w:w", FormatUtils::IntToWideString(FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize))); + wAfter.AppendAttribute(wAfterValue); + + XMLTools::XMLAttribute wAfterType(L"w:type", L"dxa"); + wAfter.AppendAttribute(wAfterType); + _trPr->AppendChild(wAfter, true); + }break; + case sprmTWidthBefore: + { //width before + short before = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize); + + if (before != 0) + { + XMLTools::XMLElement wBefore(L"w:wBefore"); + XMLTools::XMLAttribute wBeforeValue(L"w:w", FormatUtils::IntToWideString(before)); + wBefore.AppendAttribute(wBeforeValue); + + XMLTools::XMLAttribute wBeforeType(L"w:type", L"dxa"); + wBefore.AppendAttribute(wBeforeType); + _trPr->AppendChild(wBefore, true); + } + }break; + case sprmOldTDyaRowHeight: + case sprmTDyaRowHeight: + { //row height + XMLTools::XMLAttribute rowHeightVal(L"w:val"); + XMLTools::XMLAttribute rowHeightRule(L"w:hRule"); + + short rH = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize); + + if (rH > 0) + { + rowHeightRule.SetValue(L"atLeast"); + rowHeightVal.SetValue(FormatUtils::IntToWideString(rH)); + rowHeight.AppendAttribute(rowHeightVal); + } + else if (rH == 0) + { + rowHeightRule.SetValue(L"auto"); + } + else { - unsigned char grfbrc = iter->Arguments[2]; - short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - std::wstring strValue = FormatUtils::IntToWideString(wSpc); - if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) - { - appendDxaElement(_trPr, L"tblCellSpacing", strValue, true); - } - }break; - case sprmTTableBorders80: + rowHeightRule.SetValue(L"exact"); + rH *= -1; + rowHeightVal.SetValue(FormatUtils::IntToWideString(rH)); + rowHeight.AppendAttribute(rowHeightVal); + } + rowHeight.AppendAttribute(rowHeightRule); + } + break; + case sprmOldTFCantSplit: + case sprmTFCantSplit: + break; + case sprmTFCantSplit90: + { //can't split + if (iter->argumentsSize > 0 && iter->Arguments[0] != 0) + appendFlagElement(_trPr, *iter, L"cantSplit", true); + }break; + case sprmTIpgp:// = PGPInfo.ipgpSelf (PGPInfo structure describes the border and margin properties) + { //div id + }break; + case sprmTCellSpacing: + case sprmTCellSpacingDefault: + { + unsigned char grfbrc = iter->Arguments[2]; + short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); + std::wstring strValue = FormatUtils::IntToWideString(wSpc); + if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01)) { - const int size = 4; - unsigned char brc80[size]; + appendDxaElement(_trPr, L"tblCellSpacing", strValue, true); + } + }break; + case sprmTTableBorders80: + { + const int size = 4; + unsigned char brc80[size]; + + memcpy(brc80, iter->Arguments, size); + brcTop = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 4), size); + brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 8), size); + brcBottom = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, iter->Arguments, size); - brcTop = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 12), size); + brcRight = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 4), size); - brcLeft = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 16), size); + brcHorz = std::shared_ptr(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 8), size); - brcBottom = std::shared_ptr(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 20), size); + brcVert = std::shared_ptr(new BorderCode(brc80, size)); + }break; + case sprmTCellPaddingDefault: + case sprmTCellPadding: + case sprmTCellPaddingOuter: + { + unsigned char first = iter->Arguments[0]; + unsigned char lim = iter->Arguments[1]; + unsigned char ftsMargin = iter->Arguments[3]; + short wMargin = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize); - memcpy(brc80, (iter->Arguments + 12), size); - brcRight = std::shared_ptr(new BorderCode(brc80, size)); + if (!_tcMar) _tcMar = new XMLTools::XMLElement(L"w:tblCellMar"); + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 0) == true) + { + appendDxaElement(_tcMar, L"top", FormatUtils::IntToWideString(wMargin), true); + } + + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 1) == true) + { + appendDxaElement(_tcMar, L"left", FormatUtils::IntToWideString(wMargin), true); + } - memcpy(brc80, (iter->Arguments + 16), size); - brcHorz = std::shared_ptr(new BorderCode(brc80, size)); + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 2) == true) + { + appendDxaElement(_tcMar, L"bottom", FormatUtils::IntToWideString(wMargin), true); + } - memcpy(brc80, (iter->Arguments + 20), size); - brcVert = std::shared_ptr(new BorderCode(brc80, size)); - }break; - default: - break; + if (FormatUtils::GetBitFromInt(iter->Arguments[2], 3) == true) + { + appendDxaElement(_tcMar, L"right", FormatUtils::IntToWideString(wMargin), true); + } + } + default: + break; } } if (rowHeight.GetAttributeCount() > 0) { _trPr->AppendChild(rowHeight); } - - //set borders + //set borders XMLTools::XMLElement* _tblBorders = new XMLTools::XMLElement(L"w:tblBorders"); if (brcTop) { @@ -240,6 +271,10 @@ namespace DocFileFormat { _tblPrEx->AppendChild(*_tblBorders); } + if (_tcMar && _tcMar->GetChildCount() > 0) + { + _tblPrEx->AppendChild(*(_tcMar)); + } //--------------------------------------------------------------------------- if ( _tblPrEx->GetChildCount() > 0 ) { @@ -249,5 +284,7 @@ namespace DocFileFormat { m_pXmlWriter->WriteString( _trPr->GetXMLString() ); } + + RELEASEOBJECT(_tcMar); } } From 56c3b1a6d3a44cacf140e053523e933726fca4af Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 28 Feb 2024 14:31:52 +0300 Subject: [PATCH 351/794] Fix bugs --- DocxRenderer/src/logic/Page.cpp | 104 ++++++++++++-------------------- 1 file changed, 38 insertions(+), 66 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index a79719689b2..06f0b0d38b4 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -524,6 +524,11 @@ namespace NSDocxRenderer void CPage::DetermineLinesType() { + using shape_ptr_t = std::shared_ptr; + std::sort(m_arShapes.begin(), m_arShapes.end(), [] (const shape_ptr_t& a, const shape_ptr_t& b) { + return a->m_dLeft < b->m_dLeft; + }); + for (size_t i = 0; i < m_arShapes.size(); ++i) { if (!m_arShapes[i] || m_arShapes[i]->m_dHeight > c_dMAX_LINE_HEIGHT_MM || // рассматриваем только тонкие объекты @@ -559,10 +564,6 @@ namespace NSDocxRenderer if (curr_shape_indexes.size() > 1) { - std::sort(curr_shape_indexes.begin(), curr_shape_indexes.end(), [this] (size_t a, size_t b) { - return m_arShapes[a]->m_dLeft < m_arShapes[b]->m_dLeft; - }); - size_t j = 0; for (size_t k = 1; k < curr_shape_indexes.size(); ++k) { @@ -618,15 +619,15 @@ namespace NSDocxRenderer std::vector&, std::shared_ptr&>> possible_caps; std::vector> drop_caps; - for(size_t i = 0; i < m_arTextLines.size(); i++) + for (size_t i = 0; i < m_arTextLines.size(); i++) { auto& line = m_arTextLines[i]; - for(auto& cont : line->m_arConts) - if(cont && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) + for (auto& cont : line->m_arConts) + if (cont && cont->m_pFontStyle->dFontSize > 2 * avg_font_size && cont->m_oText.length() == 1) possible_caps.push_back({cont, line}); } - for(auto& possible_cap : possible_caps) + for (auto& possible_cap : possible_caps) { auto& drop_cap_cont = possible_cap.first; auto& drop_cap_line = possible_cap.second; @@ -635,29 +636,29 @@ namespace NSDocxRenderer for(auto& line : m_arTextLines) { - if(!line || line == drop_cap_line) + if (!line || line == drop_cap_line) continue; // буквица должна быть левее - if(line->m_dLeft < drop_cap_cont->m_dLeft) + if (line->m_dLeft < drop_cap_cont->m_dLeft) continue; // если совпадает строка по высоте - берем ее и выходим - if(fabs(line->m_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(line->m_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) { num_of_lines++; break; } - if(line->m_dBaselinePos > drop_cap_cont->m_dBaselinePos) + if (line->m_dBaselinePos > drop_cap_cont->m_dBaselinePos) break; - if(fabs(line->m_dTop - drop_cap_cont->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < drop_cap_cont->m_dTop) + if (fabs(line->m_dTop - drop_cap_cont->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < drop_cap_cont->m_dTop) continue; num_of_lines++; } - if(num_of_lines) + if (num_of_lines > 1) { auto drop_cap = std::make_unique(); *static_cast(drop_cap.get()) = *drop_cap_cont; @@ -669,16 +670,16 @@ namespace NSDocxRenderer drop_caps.push_back(std::move(drop_cap)); drop_cap_cont = nullptr; - if(drop_cap_line->IsCanBeDeleted()) + if (drop_cap_line->IsCanBeDeleted()) drop_cap_line = nullptr; - if(drop_cap_line) + if (drop_cap_line) drop_cap_line->RecalcSizes(); } } // шейпы из буквиц - for(auto&& drop_cap : drop_caps) + for (auto&& drop_cap : drop_caps) { auto shape = std::make_shared(); shape->m_eType = CShape::eShapeType::stTextBox; @@ -786,9 +787,6 @@ namespace NSDocxRenderer for (size_t j = 0; j < m_arTextLines.size(); ++j) { - if(!shape) - break; - auto& pCurrLine = m_arTextLines[j]; if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(shape.get()) && (pCurrLine->m_dTop > shape->m_dBaselinePos || @@ -811,24 +809,17 @@ namespace NSDocxRenderer bool bIsNotComplicatedFigure = shape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; bool bIsLineCrossingText = IsLineCrossingText(shape.get(), curr_cont.get(), eHType); - bool bIsLineBelowText = IsLineBelowText(shape.get(), curr_cont.get(), eHType); bool bIsItHighlightingBackground = IsItHighlightingBackground(shape.get(), curr_cont.get(), eHType); + bool bIsLineBelowText = IsLineBelowText(shape.get(), curr_cont.get(), eHType); - if(bIsLineCrossingText) + if (bIsLineCrossingText) { curr_cont->m_bIsStrikeoutPresent = true; if (shape->m_eLineType == eLineType::ltDouble) curr_cont->m_bIsDoubleStrikeout = true; } - if(bIsLineBelowText) - { - curr_cont->m_bIsUnderlinePresent = true; - curr_cont->m_eUnderlineType = shape->m_eLineType; - curr_cont->m_lUnderlineColor = shape->m_dHeight > 0.3 ? shape->m_oBrush.Color1 : shape->m_oPen.Color; - } - - if(bIsItHighlightingBackground) + else if (bIsItHighlightingBackground) { //Удовлетворяет расположением и размером - привязываем указатель на картинку curr_cont->m_pShape = shape; @@ -836,6 +827,13 @@ namespace NSDocxRenderer curr_cont->m_lHighlightColor = shape->m_oBrush.Color1; } + else if (bIsLineBelowText) + { + curr_cont->m_bIsUnderlinePresent = true; + curr_cont->m_eUnderlineType = shape->m_eLineType; + curr_cont->m_lUnderlineColor = shape->m_dHeight > 0.3 ? shape->m_oBrush.Color1 : shape->m_oPen.Color; + } + // проверили - удаляем if (bIsNotComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) shape_used = true; @@ -900,13 +898,13 @@ namespace NSDocxRenderer bool CPage::IsLineBelowText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) { - //todo распознавание работает не для всех размеров шрифтов - возможно 0.15 мало или улучшить логику bool bIf1 = (pShape->m_eGraphicsType == eGraphicsType::gtRectangle || pShape->m_eGraphicsType == eGraphicsType::gtCurve) && pShape->m_eLineType != eLineType::ltUnknown; //Условие по вертикали - bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < pCont->m_dHeight * 0.5; + double max_diff = std::min(c_dGRAPHICS_ERROR_MM * 3, pCont->m_dHeight * 0.5); + bool bIf2 = fabs(pShape->m_dBaselinePos - pCont->m_dBaselinePos) < max_diff; //Условие пересечения по горизонтали bool bIf3 = eHType != eHorizontalCrossingType::hctUnknown && @@ -915,7 +913,7 @@ namespace NSDocxRenderer eHType != eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext; //Условие для размеров по высоте - bool bIf4 = pShape->m_dHeight < pCont->m_dHeight && + bool bIf4 = pShape->m_dHeight < pCont->m_dHeight * 0.5 && pCont->m_dHeight - pShape->m_dHeight > c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM; return bIf1 && bIf2 && bIf3 && bIf4; @@ -1269,27 +1267,6 @@ namespace NSDocxRenderer continue; } - // если линия пересекается с другим шейпом - bool next = false; - for (auto& shape : m_arShapes) - { - if (!shape) - continue; - - auto h_type = curr_line->GetHorizontalCrossingType(shape.get()); - auto v_type = curr_line->CBaseItem::GetVerticalCrossingType(shape.get()); - - if (!no_crossing(h_type, v_type)) - { - m_arShapes.push_back(CreateSingleLineShape(curr_line)); - curr_line = nullptr; - next = true; - break; - } - } - if (next) - continue; - // если линия пересекается с предыдущей линией if (index && m_arTextLines[index - 1]) { @@ -1322,11 +1299,6 @@ namespace NSDocxRenderer if (m_arTextLines.empty()) return; - using line_ptr_t = std::shared_ptr; - std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { - return a->m_dBaselinePos < b->m_dBaselinePos; - }); - // 1 строчка в параграфе if (m_eTextAssociationType == TextAssociationType::tatPlainLine || m_eTextAssociationType == TextAssociationType::tatShapeLine) @@ -1477,15 +1449,15 @@ namespace NSDocxRenderer } } - // на основе ar_delims разбиваем на параграфы + IsShadingPresent + // на основе ar_delims разбиваем на параграфы for (size_t index = 0; index < ar_delims.size(); ++index) { - if (m_arTextLines[index]->m_pDominantShape) - { - paragraph->m_bIsShadingPresent = true; - paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; - paragraph->RemoveHighlightColor(); - } +// if (m_arTextLines[index]->m_pDominantShape) +// { +// paragraph->m_bIsShadingPresent = true; +// paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; +// paragraph->RemoveHighlightColor(); +// } add_line(paragraph, m_arTextLines[index]); if (ar_delims[index] || index == ar_delims.size() - 1) add_paragraph(paragraph); From 63c38399ad17a9d4df4a035cb16710b51a987497 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 28 Feb 2024 14:50:08 +0300 Subject: [PATCH 352/794] fix build --- OdfFile/Reader/Format/styles_lite_container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Reader/Format/styles_lite_container.cpp b/OdfFile/Reader/Format/styles_lite_container.cpp index a6552526ae1..0b74c34cd94 100644 --- a/OdfFile/Reader/Format/styles_lite_container.cpp +++ b/OdfFile/Reader/Format/styles_lite_container.cpp @@ -35,7 +35,7 @@ #include "styles_lite_container.h" #include "office_settings.h" -#include "..\..\Common\xml\simple_xml_writer.h" +#include "../../Common/xml/simple_xml_writer.h" namespace cpdoccore { From 6a628a21fb92cc4b1da8d54359469e2cce1219e6 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 28 Feb 2024 17:08:44 +0300 Subject: [PATCH 353/794] Add 3dParty list --- 3DPARTY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 3DPARTY.md diff --git a/3DPARTY.md b/3DPARTY.md new file mode 100644 index 00000000000..c4fb68308e6 --- /dev/null +++ b/3DPARTY.md @@ -0,0 +1,18 @@ + +## Third-party + +- boost ([BSL](https://raw.githubusercontent.com/boostorg/boost/master/LICENSE_1_0.txt)) +- icu ([UNICODE LICENSE V3](https://raw.githubusercontent.com/unicode-org/icu/main/LICENSE)) +- freetype ([FTL](https://raw.githubusercontent.com/freetype/freetype/master/docs/FTL.TXT)) +- harfbuzz ([MIT](https://raw.githubusercontent.com/harfbuzz/harfbuzz/main/COPYING)) +- hyphen ([MPL](https://raw.githubusercontent.com/hunspell/hyphen/master/COPYING)) +- hunspell ([MPL](https://raw.githubusercontent.com/hunspell/hunspell/master/COPYING.MPL)) +- gumbo ([Apache-2.0](https://raw.githubusercontent.com/google/gumbo-parser/master/COPYING)) +- katana ([MIT](https://raw.githubusercontent.com/jasenhuang/katana-parser/master/LICENSE)) +- cximage ([CXIMAGE LICENCE](https://raw.githubusercontent.com/movableink/cximage/master/license.txt)) +- openjpeg ([2-clause BSD License](https://raw.githubusercontent.com/uclouvain/openjpeg/master/LICENSE)) +- socket.io-client-cpp ([MIT](https://raw.githubusercontent.com/socketio/socket.io-client-cpp/master/LICENSE)) +- curl ([CURL LICENCE](https://raw.githubusercontent.com/curl/curl/master/COPYING)) +- cryptopp ([BSL](https://raw.githubusercontent.com/weidai11/cryptopp/master/License.txt)) +- openssl ([Apache-2.0](https://raw.githubusercontent.com/openssl/openssl/master/LICENSE.txt)) +- v8 ([3-clause BSD License](https://raw.githubusercontent.com/v8/v8/main/LICENSE)) From f973a0a952abc155a651f7dcc7e1068bfff7ef34 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 28 Feb 2024 21:13:35 +0300 Subject: [PATCH 354/794] fix bug #66651 --- .../Document/BinReader/ReaderClasses.cpp | 2 +- OOXML/DocxFormat/Logic/ParagraphProperty.cpp | 2 +- OOXML/DocxFormat/Logic/RunProperty.cpp | 2 +- OOXML/DocxFormat/Logic/SectionProperty.cpp | 6 +++--- OOXML/DocxFormat/Logic/Table.cpp | 6 +++--- OOXML/DocxFormat/Logic/TableProperty.cpp | 16 +++++++-------- .../Converter/docx_conversion_context.cpp | 4 ++-- OdfFile/Reader/Converter/docx_package.cpp | 2 +- RtfFile/Format/RtfChar.cpp | 12 +++++------ RtfFile/Format/RtfField.cpp | 4 ++-- RtfFile/Format/RtfOle.cpp | 4 ++-- RtfFile/Format/RtfProperty.cpp | 20 +++++++++---------- RtfFile/Format/RtfSection.cpp | 2 +- RtfFile/Format/RtfShape.cpp | 4 ++-- RtfFile/OOXml/Writer/OOXCommentsWriter.cpp | 2 +- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp index cb770c58356..b7821ba0f7d 100644 --- a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp +++ b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp @@ -681,7 +681,7 @@ namespace BinDocxRW { { std::wstring sUserName = XmlUtils::EncodeXmlString(pComment->UserName); sRes += L" w:author=\""; - sRes += (sUserName); + sRes += XmlUtils::EncodeXmlString(sUserName); sRes += L"\""; } if (false == pComment->Date.empty()) diff --git a/OOXML/DocxFormat/Logic/ParagraphProperty.cpp b/OOXML/DocxFormat/Logic/ParagraphProperty.cpp index f2782061277..5f4d01af359 100644 --- a/OOXML/DocxFormat/Logic/ParagraphProperty.cpp +++ b/OOXML/DocxFormat/Logic/ParagraphProperty.cpp @@ -310,7 +310,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } diff --git a/OOXML/DocxFormat/Logic/RunProperty.cpp b/OOXML/DocxFormat/Logic/RunProperty.cpp index fbee069b42d..aa1fac8740b 100644 --- a/OOXML/DocxFormat/Logic/RunProperty.cpp +++ b/OOXML/DocxFormat/Logic/RunProperty.cpp @@ -170,7 +170,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/SectionProperty.cpp b/OOXML/DocxFormat/Logic/SectionProperty.cpp index 9c8e661353c..7b285e12f08 100644 --- a/OOXML/DocxFormat/Logic/SectionProperty.cpp +++ b/OOXML/DocxFormat/Logic/SectionProperty.cpp @@ -1438,9 +1438,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/Table.cpp b/OOXML/DocxFormat/Logic/Table.cpp index 3928acf049e..0ffabd11e57 100644 --- a/OOXML/DocxFormat/Logic/Table.cpp +++ b/OOXML/DocxFormat/Logic/Table.cpp @@ -228,9 +228,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OOXML/DocxFormat/Logic/TableProperty.cpp b/OOXML/DocxFormat/Logic/TableProperty.cpp index a9ea47665fb..5ee91e757f2 100644 --- a/OOXML/DocxFormat/Logic/TableProperty.cpp +++ b/OOXML/DocxFormat/Logic/TableProperty.cpp @@ -68,7 +68,7 @@ namespace ComplexTypes if ( m_sAuthor.IsInit() ) { sResult += L"w:author=\""; - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += L"\" "; } @@ -1004,7 +1004,7 @@ namespace OOX if ( m_sAuthor.IsInit() ) { sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); sResult += _T("\" "); } @@ -1263,9 +1263,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) @@ -1742,9 +1742,9 @@ namespace OOX if ( m_sAuthor.IsInit() ) { - sResult += _T("w:author=\""); - sResult += m_sAuthor.get2(); - sResult += _T("\" "); + sResult += L"w:author=\""; + sResult += XmlUtils::EncodeXmlString(m_sAuthor.get2()); + sResult += L"\" "; } if ( m_oDate.IsInit() ) diff --git a/OdfFile/Reader/Converter/docx_conversion_context.cpp b/OdfFile/Reader/Converter/docx_conversion_context.cpp index 647bcf01ce2..344f467955d 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/docx_conversion_context.cpp @@ -2404,7 +2404,7 @@ void docx_conversion_context::start_text_changes (const std::wstring &id) if (state_.in_paragraph_) { - std::wstring format_change = L" w:date=\"" + state.date + L"\" w:author=\"" + state.author + L"\""; + std::wstring format_change = L" w:date=\"" + state.date + L"\" w:author=\"" + XmlUtils::EncodeXmlString(state.author) + L"\""; finish_run(); state.in_drawing = get_drawing_state_content(); @@ -2465,7 +2465,7 @@ void docx_conversion_context::start_changes(bool in_para) std::wstring change_attr; change_attr += L" w:date=\"" + state.date + L"\""; - change_attr += L" w:author=\"" + state.author + L"\""; + change_attr += L" w:author=\"" + XmlUtils::EncodeXmlString(state.author) + L"\""; if (state.oox_id == 0) { diff --git a/OdfFile/Reader/Converter/docx_package.cpp b/OdfFile/Reader/Converter/docx_package.cpp index 63570d4cf49..45916a33dc1 100644 --- a/OdfFile/Reader/Converter/docx_package.cpp +++ b/OdfFile/Reader/Converter/docx_package.cpp @@ -461,7 +461,7 @@ void comments_elements::write(const std::wstring & RootPath) { content << L"0) - content << L"w:author=\""<< elm.author << "\" "; + content << L"w:author=\""<< XmlUtils::EncodeXmlString(elm.author) << "\" "; if (elm.date.length()>0) content << L"w:date=\""<< elm.date << "\" "; content<< L">"; diff --git a/RtfFile/Format/RtfChar.cpp b/RtfFile/Format/RtfChar.cpp index 47f322b4adf..8bed8689489 100644 --- a/RtfFile/Format/RtfChar.cpp +++ b/RtfFile/Format/RtfChar.cpp @@ -132,7 +132,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -142,7 +142,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L""; @@ -173,7 +173,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -183,7 +183,7 @@ std::wstring RtfChar::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += m_oProperty.RenderToOOX(oRenderParameter);//w:rPr внутри @@ -415,7 +415,7 @@ std::wstring RtfCharSpecial::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -425,7 +425,7 @@ std::wstring RtfCharSpecial::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L""; diff --git a/RtfFile/Format/RtfField.cpp b/RtfFile/Format/RtfField.cpp index 7efac19245b..a18d902e84f 100644 --- a/RtfFile/Format/RtfField.cpp +++ b/RtfFile/Format/RtfField.cpp @@ -289,7 +289,7 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) sAuthor = pRtfDocument->m_oRevisionTable.GetAuthor(m_pInsert->m_oCharProperty.m_nRevauth); sDate = std::wstring(RtfUtility::convertDateTime(m_pInsert->m_oCharProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nRevised = PROP_DEF; } if (m_pInsert->m_oCharProperty.m_nDeleted != PROP_DEF) @@ -299,7 +299,7 @@ std::wstring RtfField::RenderToOOX(RenderParameter oRenderParameter) sAuthor = pRtfDocument->m_oRevisionTable.GetAuthor(m_pInsert->m_oCharProperty.m_nRevauthDel); sDate = std::wstring(RtfUtility::convertDateTime(m_pInsert->m_oCharProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nDeleted = PROP_DEF; } //поверяем на наличие гиперссылки diff --git a/RtfFile/Format/RtfOle.cpp b/RtfFile/Format/RtfOle.cpp index bab4dd3daa4..7a9f0180360 100644 --- a/RtfFile/Format/RtfOle.cpp +++ b/RtfFile/Format/RtfOle.cpp @@ -82,7 +82,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(pCharProps->m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(pCharProps->m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; pCharProps->m_nRevised = PROP_DEF; } if (pCharProps->m_nDeleted != PROP_DEF) @@ -92,7 +92,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(pCharProps->m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(pCharProps->m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; pCharProps->m_nDeleted = PROP_DEF; } //---------- diff --git a/RtfFile/Format/RtfProperty.cpp b/RtfFile/Format/RtfProperty.cpp index a286cb60ab4..f81ac1d4761 100644 --- a/RtfFile/Format/RtfProperty.cpp +++ b/RtfFile/Format/RtfProperty.cpp @@ -1530,7 +1530,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime( m_nRevdttm ).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_nRevised = PROP_DEF; } if (m_nDeleted != PROP_DEF) @@ -1540,7 +1540,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime( m_nRevdttmDel ).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_nDeleted = PROP_DEF; } sResult += L""; @@ -1551,14 +1551,14 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } if ( PROP_DEF != m_nRevised ) { std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } if( PROP_DEF != m_nCharStyle ) { @@ -1793,7 +1793,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += m_pOldCharProp->RenderToOOX(oRenderParameterNew); sResult += L""; @@ -3921,7 +3921,7 @@ std::wstring RtfParagraphProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += m_pOldParagraphProp->RenderToOOX(oRenderParameterNew); sResult += L""; @@ -5060,14 +5060,14 @@ std::wstring RtfRowProperty::RenderToOOX(RenderParameter oRenderParameter) // std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(oReader.m_oState->m_oCharProp.m_nRevauthDel); // std::wstring sDate(RtfUtility::convertDateTime(oReader.m_oState->m_oCharProp.m_nRevdttmDel).c_str()); - // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; //} //if ( PROP_DEF != oReader.m_oState->m_oCharProp.m_nRevised ) //{ // std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(oReader.m_oState->m_oCharProp.m_nRevauth); // std::wstring sDate(RtfUtility::convertDateTime(oReader.m_oState->m_oCharProp.m_nRevdttm).c_str()); // - // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; //} std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nTrAuth); std::wstring sDate(RtfUtility::convertDateTime(m_nTrDate).c_str()); @@ -5078,11 +5078,11 @@ std::wstring RtfRowProperty::RenderToOOX(RenderParameter oRenderParameter) if (rowChangeProps.empty()) { - sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\"/>"; } else { - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L""; sResult += rowChangeProps; sResult += L""; diff --git a/RtfFile/Format/RtfSection.cpp b/RtfFile/Format/RtfSection.cpp index f4cddef8195..50b69589a8c 100644 --- a/RtfFile/Format/RtfSection.cpp +++ b/RtfFile/Format/RtfSection.cpp @@ -1000,7 +1000,7 @@ std::wstring RtfSectionProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; sResult += m_pOldSectionProp->RenderToOOX(oRenderParameterNew); sResult += L""; } diff --git a/RtfFile/Format/RtfShape.cpp b/RtfFile/Format/RtfShape.cpp index f9cbec4508d..c5243517a46 100644 --- a/RtfFile/Format/RtfShape.cpp +++ b/RtfFile/Format/RtfShape.cpp @@ -867,7 +867,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oCharProperty.m_nRevauth); std::wstring sDate(RtfUtility::convertDateTime(m_oCharProperty.m_nRevdttm).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nRevised = PROP_DEF; } if (m_oCharProperty.m_nDeleted != PROP_DEF) @@ -877,7 +877,7 @@ std::wstring RtfShape::RenderToOOXBegin(RenderParameter oRenderParameter) std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_oCharProperty.m_nRevauthDel); std::wstring sDate(RtfUtility::convertDateTime(m_oCharProperty.m_nRevdttmDel).c_str()); - sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nDeleted = PROP_DEF; } std::wstring sCharProp = m_oCharProperty.RenderToOOX(oRenderParameter); diff --git a/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp b/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp index 7b576c52a72..2007ce82a74 100644 --- a/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp +++ b/RtfFile/OOXml/Writer/OOXCommentsWriter.cpp @@ -153,7 +153,7 @@ mc:Ignorable=\"w14 w15 wp14\">"; for (std::map::iterator it = m_mapComments.begin(); it != m_mapComments.end(); ++it) { sResult += L"second.nID) + L"\" w:author=\"" + - it->second.author + L"\" w:date=\"" + it->second.date + L"\" w:initials=\"" + it->second.authorId + L"\">"; + XmlUtils::EncodeXmlString(it->second.author) + L"\" w:date=\"" + it->second.date + L"\" w:initials=\"" + it->second.authorId + L"\">"; sResult += it->second.content; sResult += L""; From 1ab06e503aff7d0272f4728c2bbca6cae333cf13 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 28 Feb 2024 21:25:25 +0300 Subject: [PATCH 355/794] Fix bug --- DocxRenderer/src/logic/Page.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 06f0b0d38b4..494dced878f 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1296,6 +1296,11 @@ namespace NSDocxRenderer auto right = MoveNullptr(m_arTextLines.begin(), m_arTextLines.end()); m_arTextLines.erase(right, m_arTextLines.end()); + using line_ptr_t = std::shared_ptr; + std::sort(m_arTextLines.begin(), m_arTextLines.end(), [] (const line_ptr_t& a, const line_ptr_t& b) { + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + if (m_arTextLines.empty()) return; From ec2687e5d151666b31e7cd4fa153e95cde1fca7e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 28 Feb 2024 21:29:46 +0300 Subject: [PATCH 356/794] for bug #57082 --- DesktopEditor/graphics/pro/Image.h | 3 +- DesktopEditor/raster/Metafile/MetaFile.cpp | 4 ++ DesktopEditor/raster/Metafile/MetaFile.h | 1 + .../Binary/Document/BinWriter/BinWriters.cpp | 24 +++++++ .../Presentation/BinaryFileReaderWriter.cpp | 32 ++++++---- .../Presentation/BinaryFileReaderWriter.h | 10 +-- OOXML/Binary/Presentation/imagemanager.cpp | 4 +- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 5 ++ .../ASCOfficeDrawingConverter.cpp | 64 ++++++++++--------- OOXML/PPTXFormat/Logic/GrpSpPr.cpp | 3 + OOXML/PPTXFormat/Logic/Pic.cpp | 2 +- OOXML/PPTXFormat/Logic/SpTree.cpp | 19 +++++- OOXML/PPTXFormat/Logic/Xfrm.cpp | 10 +++ 13 files changed, 130 insertions(+), 51 deletions(-) diff --git a/DesktopEditor/graphics/pro/Image.h b/DesktopEditor/graphics/pro/Image.h index 9bb1f8d7764..38606d11d67 100644 --- a/DesktopEditor/graphics/pro/Image.h +++ b/DesktopEditor/graphics/pro/Image.h @@ -121,7 +121,8 @@ namespace MetaFile IMetaFile(NSFonts::IApplicationFonts *pAppFonts) {} virtual ~IMetaFile() {} - virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; + virtual void SetImageSize(int nWidth, int nHeight) = 0; + virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0; virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0; virtual void Close() = 0; diff --git a/DesktopEditor/raster/Metafile/MetaFile.cpp b/DesktopEditor/raster/Metafile/MetaFile.cpp index c482571d395..2ed522173d2 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.cpp +++ b/DesktopEditor/raster/Metafile/MetaFile.cpp @@ -81,6 +81,10 @@ namespace MetaFile Close(); RELEASEINTERFACE(m_pFontManager); } + void CMetaFile::SetImageSize(int nWidth, int nHeight) + { + // for meta with empty size + } std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight) { diff --git a/DesktopEditor/raster/Metafile/MetaFile.h b/DesktopEditor/raster/Metafile/MetaFile.h index 74738c1251f..94bcf378238 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.h +++ b/DesktopEditor/raster/Metafile/MetaFile.h @@ -62,6 +62,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts); virtual ~CMetaFile(); + void SetImageSize(int nWidth, int nHeight); bool LoadFromFile(const wchar_t* wsFilePath); bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize); bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight); diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index f6ac759c389..e4f0b698e42 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -6625,6 +6625,8 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr int nCurPos = 0; bool bDeleteDrawing = false; + + m_oBcw.m_oStream.m_dCxCurShape = m_oBcw.m_oStream.m_dCyCurShape = 0; //pptxdata if (pXml) { @@ -6657,6 +6659,28 @@ void BinaryDocumentTableWriter::WriteDrawing(std::wstring* pXml, OOX::Logic::CDr } else if (pGraphic) { + if (NULL != pDrawing) + { + OOX::Logic::CDrawing& img = *pDrawing; + if (img.m_oInline.IsInit()) + { + const OOX::Drawing::CInline& pInline = img.m_oInline.get(); + if (pInline.m_oExtent.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pInline.m_oExtent->m_oCx.GetValue(); + m_oBcw.m_oStream.m_dCyCurShape = pInline.m_oExtent->m_oCy.GetValue(); + } + } + else if (img.m_oAnchor.IsInit()) + { + const OOX::Drawing::CAnchor& pAnchor = img.m_oAnchor.get(); + if (pAnchor.m_oExtent.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pAnchor.m_oExtent->m_oCx.GetValue(); + m_oBcw.m_oStream.m_dCyCurShape = pAnchor.m_oExtent->m_oCy.GetValue(); + } + } + } if (pGraphic->chartRec.IsInit() && pGraphic->chartRec->id_data.IsInit() ) { m_oBcw.m_oStream.WriteBYTE(pGraphic->chartRec->m_bChartEx ? c_oSerImageType2::ChartEx : c_oSerImageType2::Chart); diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 8c0481f39ca..bbc786c582c 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -695,31 +695,33 @@ namespace NSBinPptxRW } double CBinaryFileWriter::GetShapeHeight() { - if (m_lCyCurShape == 0) + if (m_dCyCurShape < 0.001) return -1; - return (double)m_lCyCurShape / 36000; //mm + return m_dCyCurShape / 36000; //mm } double CBinaryFileWriter::GetShapeWidth() { - if (m_lCyCurShape == 0) + if (m_dCyCurShape < 0.001) return -1; - return (double)m_lCxCurShape / 36000; + return m_dCxCurShape / 36000; } double CBinaryFileWriter::GetShapeY() { - return (double)m_lYCurShape / 36000; + return m_dYCurShape / 36000; } double CBinaryFileWriter::GetShapeX() { - return (double)m_lXCurShape / 36000; //mm + return m_dXCurShape / 36000; //mm } void CBinaryFileWriter::ClearCurShapePositionAndSizes() { - m_lXCurShape = 0; - m_lYCurShape = 0; + m_dXCurShape = 0; + m_dYCurShape = 0; - m_lCxCurShape = 0; - m_lCyCurShape = 0; + m_dCxCurShape = 0; + m_dCyCurShape = 0; + + m_bInGroup = false; } void CBinaryFileWriter::Clear() { @@ -732,11 +734,13 @@ namespace NSBinPptxRW m_lStackPosition = 0; memset(m_arStack, 0, MAX_STACK_SIZE * sizeof(_UINT32)); - m_lCxCurShape = 0; - m_lCyCurShape = 0; + m_dCxCurShape = 0; + m_dCyCurShape = 0; + + m_dXCurShape = 0; + m_dYCurShape = 0; - m_lXCurShape = 0; - m_lYCurShape = 0; + m_bInGroup = false; } void CBinaryFileWriter::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 7ac79d1fab2..3c527443699 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -273,11 +273,13 @@ namespace NSBinPptxRW std::vector m_arMainTables; public: - _INT32 m_lCxCurShape; //emu - _INT32 m_lCyCurShape; + double m_dCxCurShape; //emu + double m_dCyCurShape; - _INT32 m_lXCurShape; - _INT32 m_lYCurShape; + double m_dXCurShape; + double m_dYCurShape; + + bool m_bInGroup = false; BYTE* GetBuffer(); virtual _UINT32 GetPosition(); diff --git a/OOXML/Binary/Presentation/imagemanager.cpp b/OOXML/Binary/Presentation/imagemanager.cpp index b058280f4af..b450431349d 100644 --- a/OOXML/Binary/Presentation/imagemanager.cpp +++ b/OOXML/Binary/Presentation/imagemanager.cpp @@ -527,10 +527,12 @@ namespace NSShapeImageGen CDirectory::CopyFile(strFileName, pathSaveItem.GetPath()); ::MetaFile::IMetaFile* pMetafile = MetaFile::Create(m_pFontManager->GetApplication()); + + pMetafile->SetImageSize(lWidth, lHeight); if (pMetafile->LoadFromFile(strFileName.c_str())) { // пробуем сохранить в svg напрямую из метафайлов - std::wstring sInternalSvg = pMetafile->ConvertToSvg(); + std::wstring sInternalSvg = pMetafile->ConvertToSvg(/*lWidth, lHeight*/); if (!sInternalSvg.empty()) { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 310abf4fb21..71ec17e9911 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -6450,6 +6450,11 @@ void BinaryWorksheetTableWriter::WriteDrawing(const OOX::Spreadsheet::CWorksheet WriteCellAnchor(pCellAnchor); + if (pCellAnchor->m_oExt.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pCellAnchor->m_oExt->m_oCx.IsInit() ? pCellAnchor->m_oExt->m_oCx->GetValue() : 0; + m_oBcw.m_oStream.m_dCyCurShape = pCellAnchor->m_oExt->m_oCy.IsInit() ? pCellAnchor->m_oExt->m_oCy->GetValue() : 0; + } if (pCellAnchor->m_sVmlSpId.IsInit() && pVmlDrawing) { std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(pCellAnchor->m_sVmlSpId.get2()); diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index bb27d86df0d..6fd1940e893 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -2074,10 +2074,16 @@ bool CDrawingConverter::ParceObject(const std::wstring& strXml, std::wstring** p pPicture->spPr.Fill = PPTX::Logic::UniFill(); pShape = NULL; - pElem->InitElem(pPicture); + pElem->InitElem(pPicture); + } if ((pPicture) && (pPicture->blipFill.blip.IsInit())) { + if (pPicture->spPr.xfrm.IsInit()) + {// for bad replacemant image for ole + m_pBinaryWriter->m_dCxCurShape = pPicture->spPr.xfrm->extX.get_value_or(0); + m_pBinaryWriter->m_dCyCurShape = pPicture->spPr.xfrm->extY.get_value_or(0); + } if (pOle->m_OleObjectFile.IsInit()) { pPicture->blipFill.blip->oleFilepathBin = pOle->m_OleObjectFile->filename().GetPath(); @@ -2200,26 +2206,26 @@ void CDrawingConverter::ConvertDiagram(PPTX::Logic::SpTreeElem *result, XmlUtils { _pElem.grpSpPr.xfrm = new PPTX::Logic::Xfrm(); - _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; _pElem.grpSpPr.xfrm->chOffX = (int)0; _pElem.grpSpPr.xfrm->chOffY = (int)0; - _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_lCxCurShape; - _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_lCyCurShape; + _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_dCxCurShape; + _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_dCyCurShape; } else { - if (!_pElem.grpSpPr.xfrm->offX.is_init()) _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - if (!_pElem.grpSpPr.xfrm->offY.is_init()) _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - if (!_pElem.grpSpPr.xfrm->extX.is_init()) _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - if (!_pElem.grpSpPr.xfrm->extY.is_init()) _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + if (!_pElem.grpSpPr.xfrm->offX.is_init()) _pElem.grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + if (!_pElem.grpSpPr.xfrm->offY.is_init()) _pElem.grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + if (!_pElem.grpSpPr.xfrm->extX.is_init()) _pElem.grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + if (!_pElem.grpSpPr.xfrm->extY.is_init()) _pElem.grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; if (!_pElem.grpSpPr.xfrm->chOffX.is_init()) _pElem.grpSpPr.xfrm->chOffX = (int)0; if (!_pElem.grpSpPr.xfrm->chOffY.is_init()) _pElem.grpSpPr.xfrm->chOffY = (int)0; - if (!_pElem.grpSpPr.xfrm->chExtX.is_init()) _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_lCxCurShape; - if (!_pElem.grpSpPr.xfrm->chExtY.is_init()) _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_lCyCurShape; + if (!_pElem.grpSpPr.xfrm->chExtX.is_init()) _pElem.grpSpPr.xfrm->chExtX = m_pBinaryWriter->m_dCxCurShape; + if (!_pElem.grpSpPr.xfrm->chExtY.is_init()) _pElem.grpSpPr.xfrm->chExtY = m_pBinaryWriter->m_dCyCurShape; } } @@ -2238,13 +2244,13 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: { XmlUtils::CXmlNode oNodeExt; - m_pBinaryWriter->m_lXCurShape = 0; - m_pBinaryWriter->m_lYCurShape = 0; + m_pBinaryWriter->m_dXCurShape = 0; + m_pBinaryWriter->m_dYCurShape = 0; if (oNodeAnchorInline.GetNode(L"wp:extent", oNodeExt)) { - m_pBinaryWriter->m_lCxCurShape = oNodeExt.ReadAttributeInt(L"cx"); - m_pBinaryWriter->m_lCyCurShape = oNodeExt.ReadAttributeInt(L"cy"); + m_pBinaryWriter->m_dCxCurShape = oNodeExt.ReadAttributeInt(L"cx"); + m_pBinaryWriter->m_dCyCurShape = oNodeExt.ReadAttributeInt(L"cy"); } XmlUtils::CXmlNode oNodeDocPr; if (oNodeAnchorInline.GetNode(L"wp:docPr", oNodeDocPr)) @@ -2275,10 +2281,10 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: PPTX::Logic::SpTree* pTree = new PPTX::Logic::SpTree(); pTree->grpSpPr.xfrm = new PPTX::Logic::Xfrm(); - pTree->grpSpPr.xfrm->offX = m_pBinaryWriter->m_lXCurShape; - pTree->grpSpPr.xfrm->offY = m_pBinaryWriter->m_lYCurShape; - pTree->grpSpPr.xfrm->extX = m_pBinaryWriter->m_lCxCurShape; - pTree->grpSpPr.xfrm->extY = m_pBinaryWriter->m_lCyCurShape; + pTree->grpSpPr.xfrm->offX = m_pBinaryWriter->m_dXCurShape; + pTree->grpSpPr.xfrm->offY = m_pBinaryWriter->m_dYCurShape; + pTree->grpSpPr.xfrm->extX = m_pBinaryWriter->m_dCxCurShape; + pTree->grpSpPr.xfrm->extY = m_pBinaryWriter->m_dCyCurShape; pTree->fromXML(oNodeContent); elem->InitElem(pTree); @@ -2922,11 +2928,11 @@ void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CX } else { - m_pBinaryWriter->m_lXCurShape = 0; - m_pBinaryWriter->m_lYCurShape = 0; + m_pBinaryWriter->m_dXCurShape = 0; + m_pBinaryWriter->m_dYCurShape = 0; - m_pBinaryWriter->m_lCxCurShape = 0; - m_pBinaryWriter->m_lCyCurShape = 0; + m_pBinaryWriter->m_dCxCurShape = 0; + m_pBinaryWriter->m_dCyCurShape = 0; pSpPr->xfrm = new PPTX::Logic::Xfrm(); pSpPr->xfrm->offX = oProps.X; @@ -4122,11 +4128,11 @@ std::wstring CDrawingConverter::GetDrawingMainProps(XmlUtils::CXmlNode& oNode, P oProps.Width = width; oProps.Height = height; - m_pBinaryWriter->m_lXCurShape = left; - m_pBinaryWriter->m_lYCurShape = top; + m_pBinaryWriter->m_dXCurShape = left; + m_pBinaryWriter->m_dYCurShape = top; - m_pBinaryWriter->m_lCxCurShape = width; - m_pBinaryWriter->m_lCyCurShape = height; + m_pBinaryWriter->m_dCxCurShape = width; + m_pBinaryWriter->m_dCyCurShape = height; bool bExtendedSize = false; XmlUtils::CXmlNode oNodeShadow = oNode.ReadNode(L"v:shadow"); diff --git a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp index 7354751380a..4066a8e0987 100644 --- a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp +++ b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp @@ -184,6 +184,9 @@ namespace PPTX pWriter->WriteLimit2(0, bwMode); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->m_dCxCurShape = pWriter->m_dCyCurShape = 1; + pWriter->m_bInGroup = true; + pWriter->WriteRecord2(0, xfrm); pWriter->WriteRecord1(1, Fill); pWriter->WriteRecord1(2, EffectList); diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 63eb8f616f1..225dc853951 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -865,8 +865,8 @@ namespace PPTX pWriter->WriteRecord2(4, oleObject); pWriter->WriteRecord1(0, nvPicPr); - pWriter->WriteRecord1(1, blipFill); pWriter->WriteRecord1(2, spPr); + pWriter->WriteRecord1(1, blipFill); pWriter->WriteRecord2(3, style); if (macro.IsInit()) diff --git a/OOXML/PPTXFormat/Logic/SpTree.cpp b/OOXML/PPTXFormat/Logic/SpTree.cpp index 6c4078b8041..16178058be9 100644 --- a/OOXML/PPTXFormat/Logic/SpTree.cpp +++ b/OOXML/PPTXFormat/Logic/SpTree.cpp @@ -400,8 +400,25 @@ namespace PPTX pWriter->WriteRecord1(0, nvGrpSpPr); pWriter->WriteRecord1(1, grpSpPr); - pWriter->WriteRecordArray(2, 0, SpTreeElems); +//--------------------------------------------------------------------------------------- + //pWriter->WriteRecordArray(2, 0, SpTreeElems); + pWriter->StartRecord(2); + + _UINT32 len = (_UINT32)SpTreeElems.size(); + pWriter->WriteULONG(len); + + double oldCxCurShape = pWriter->m_dCxCurShape; + double oldCyCurShape = pWriter->m_dCyCurShape; + for (_UINT32 i = 0; i < len; ++i) + { + pWriter->WriteRecord1(0, SpTreeElems[i]); + + pWriter->m_dCxCurShape = oldCxCurShape; + pWriter->m_dCyCurShape = oldCyCurShape; + } + pWriter->EndRecord(); +//--------------------------------------------------------------------------------------- pWriter->EndRecord(); } void SpTree::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) diff --git a/OOXML/PPTXFormat/Logic/Xfrm.cpp b/OOXML/PPTXFormat/Logic/Xfrm.cpp index 7370e76518c..c45f861ad6d 100644 --- a/OOXML/PPTXFormat/Logic/Xfrm.cpp +++ b/OOXML/PPTXFormat/Logic/Xfrm.cpp @@ -291,6 +291,16 @@ namespace PPTX } void Xfrm::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { + if (chExtX.IsInit() && extX.IsInit()) + pWriter->m_dCxCurShape = pWriter->m_dCyCurShape * (double)*extX / (double)*chExtX; + else if (extX.IsInit()) + pWriter->m_dCxCurShape = (pWriter->m_bInGroup ? pWriter->m_dCxCurShape : 1) * *extX; + + if (chExtY.IsInit() && extY.IsInit()) + pWriter->m_dCyCurShape = pWriter->m_dCyCurShape * (double)*extY / (double)*chExtY; + else if (extY.IsInit()) + pWriter->m_dCyCurShape = (pWriter->m_bInGroup ? pWriter->m_dCyCurShape : 1) * *extY; + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); pWriter->WriteInt2(0, offX); pWriter->WriteInt2(1, offY); From 7dd1dd3c8a8e7694cc896adcaf64b7d3ff0ecc14 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 28 Feb 2024 22:33:07 +0300 Subject: [PATCH 357/794] Disable clear font streams in ScanPage mode --- DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h | 1 + DocxRenderer/DocxRenderer.cpp | 2 +- DocxRenderer/src/logic/Document.cpp | 4 ++-- DocxRenderer/src/logic/Document.h | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index 07cbc995326..5ff3c25dbb4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -190,6 +190,7 @@ class CGraphicsFileDrawing BYTE* GetPageShapes(const int& nPageIndex) { CDocxRenderer oRenderer(pApplicationFonts); + oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); std::vector arShapes = oRenderer.ScanPage(pReader, nPageIndex); diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index c9f4129f0f2..e2a95a631b4 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -108,7 +108,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFi std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, size_t nPage) { m_pInternal->m_oDocument.Clear(); - m_pInternal->m_oDocument.Init(); + m_pInternal->m_oDocument.Init(false); m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true; m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true; diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index 7f217bfe0ae..e49c498d4ca 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -801,14 +801,14 @@ namespace NSDocxRenderer m_oInstalledFont = m_oFont; } - void CDocument::Init() + void CDocument::Init(const bool& bIsClearStreams) { // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) // может быть одной и той же. И создание там файлов функцией создания временных файлов // может вернуть один и тот же путь. И шрифт возьмется из старого файла. m_oFontManager.ClearCache(); - if (m_pAppFonts) m_pAppFonts->GetStreams()->Clear(); + if (m_pAppFonts && bIsClearStreams) m_pAppFonts->GetStreams()->Clear(); Clear(); m_lCurrentCommandType = 0; diff --git a/DocxRenderer/src/logic/Document.h b/DocxRenderer/src/logic/Document.h index fc250006b88..68006c1c596 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -191,7 +191,7 @@ namespace NSDocxRenderer void _SetFont(); public: - void Init(); + void Init(const bool& bIsClearStreams = true); void Clear(); #ifndef DISABLE_FULL_DOCUMENT_CREATION From db340198d632cca2517386464565dca0085a8088 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 29 Feb 2024 10:04:48 +0300 Subject: [PATCH 358/794] Create GetShapesXML --- .../graphics/commands/AnnotField.cpp | 2 +- DesktopEditor/graphics/commands/AnnotField.h | 5 ++++ .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 ++++ .../graphics/pro/js/wasm/src/drawingfile.h | 6 +++++ PdfFile/PdfFile.cpp | 8 +++++++ PdfFile/PdfFile.h | 1 + PdfFile/PdfReader.cpp | 24 +++++++++++++++++++ PdfFile/PdfReader.h | 1 + PdfFile/PdfWriter.cpp | 5 ++++ PdfFile/PdfWriter.h | 1 + PdfFile/SrcWriter/Document.cpp | 18 ++++++++++++++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Pages.cpp | 11 ++++++++- 13 files changed, 85 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index a2d112d18ae..77b70a5345c 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -882,7 +882,7 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { - std::string sShape = pReader->ReadStringA(); + m_sShapeXML = pReader->ReadStringA(); return true; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 47a182327eb..a402937f8d1 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -529,7 +529,12 @@ class GRAPHICS_DECL CShapeStart : public IAdvancedCommand public: CShapeStart(); + const std::string& GetShapeXML() { return m_sShapeXML; } + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + std::string m_sShapeXML; }; class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index ccb252acb2c..bb3e56f82a1 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -243,6 +243,10 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) oRes.ClearWithoutAttack(); return bRes; } +WASM_EXPORT BYTE* GetShapesXML(CGraphicsFileDrawing* pGraphics, int nPageIndex) +{ + return pGraphics->GetShapesXML(nPageIndex); +} WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { return pGraphics->DestroyText(); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index bcd36616c02..ca969e8beb0 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -148,6 +148,12 @@ class CGraphicsFileDrawing return ((CPdfFile*)pReader)->GetAnnots(nPageIndex); return NULL; } + BYTE* GetShapesXML(int nPageIndex) + { + if (nType == 0) + return ((CPdfFile*)pReader)->GetShapesXML(nPageIndex); + return NULL; + } BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL) { if (nType == 0) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 7280c778548..7bcd6cca94d 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1580,6 +1580,12 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) return NULL; return m_pInternal->pReader->GetAnnots(nPageIndex); } +BYTE* CPdfFile::GetShapesXML(int nPageIndex) +{ + if (!m_pInternal->pReader) + return NULL; + return m_pInternal->pReader->GetShapes(nPageIndex); +} BYTE* CPdfFile::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pInternal->pReader) @@ -2365,6 +2371,8 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) } case IAdvancedCommand::AdvancedCommandType::ShapeStart: { + CShapeStart* pCommand = (CShapeStart*)command; + m_pInternal->pWriter->AddShapeXML(pCommand->GetShapeXML()); return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 46c9a2aab4e..cb444dcf656 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -134,6 +134,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer BYTE* GetWidgetEmbeddedFonts(); BYTE* GetWidgetStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); + BYTE* GetShapesXML (int nPageIndex); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 7d0c7c324a9..b42299c6ad1 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1530,6 +1530,30 @@ BYTE* CPdfReader::GetAnnots(int nPageIndex) oRes.ClearWithoutAttack(); return bRes; } +BYTE* CPdfReader::GetShapes(int nPageIndex) +{ + if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + return NULL; + Ref* pPageRef = m_pPDFDocument->getCatalog()->getPageRef(nPageIndex + 1); + if (!pPageRef) + return NULL; + + Object oPageObj; + XRef* xref = m_pPDFDocument->getXRef(); + if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict()) + { + oPageObj.free(); + return NULL; + } + + NSWasm::CData oRes; + oRes.SkipLen(); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; +} BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, const char* sView) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 03a22536d08..50ed129191a 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -76,6 +76,7 @@ class CPdfReader BYTE* GetWidgets(); BYTE* GetWidgetFonts(int nTypeFonts); BYTE* GetAnnots(int nPageIndex = -1); + BYTE* GetShapes(int nPageIndex); BYTE* VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5ff8a24dc33..94d16e34e52 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2345,6 +2345,11 @@ HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, { return m_pDocument->AddMetaData(sMetaName, pMetaData, nMetaLength) ? S_OK : S_FALSE; } +HRESULT CPdfWriter::AddShapeXML(const std::string& sXML) +{ + m_pDocument->AddShapeXML(sXML); + return S_OK; +} //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index ab64292c354..e0a970b6139 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -198,6 +198,7 @@ class CPdfWriter HRESULT AddFormField (NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory); HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); + HRESULT AddShapeXML(const std::string& sXML); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 7310379f5b2..f6bb3a064fa 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1688,4 +1688,22 @@ namespace PdfWriter RELEASEOBJECT(XRef); vXRefForWrite.clear(); } + void CDocument::AddShapeXML(const std::string& sXML) + { + CDictObject* pMetaOForm = m_pCurPage->GetMetaOForm(); + if (!pMetaOForm) + { + pMetaOForm = new CDictObject(); + m_pXref->Add(pMetaOForm); + pMetaOForm->Add("Type", "MetaOForm"); + m_pCurPage->SetMetaOForm(pMetaOForm); + } + CArrayObject* pArrayMeta = (CArrayObject*)pMetaOForm->Get("Medata"); + if (!pArrayMeta) + { + pArrayMeta = new CArrayObject(); + pMetaOForm->Add("Metadata", pArrayMeta); + } + pArrayMeta->Add(new CStringObject(sXML.c_str())); + } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index f8a1dbead25..baa17417322 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -198,6 +198,7 @@ namespace PdfWriter void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } + void AddShapeXML(const std::string& sXML); private: char* GetTTFontTag(); diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 9654560dc10..956e4cbb126 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -457,6 +457,7 @@ namespace PdfWriter m_eGrMode = grmode_PAGE; m_pGrState = new CGrState(NULL); + m_pMetaOForm = NULL; m_pExtGStates = NULL; m_unExtGStatesCount = 0; m_pFonts = NULL; @@ -1583,7 +1584,15 @@ namespace PdfWriter CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); return pRotate ? pRotate->Get() : 0; } - //---------------------------------------------------------------------------------------- + void CPage::SetMetaOForm(CDictObject* pMetaOForm) + { + if (!m_pMetaOForm) + { + m_pMetaOForm = pMetaOForm; + Add("MetaOForm", m_pMetaOForm); + } + } + //---------------------------------------------------------------------------------------- // CTextWord //---------------------------------------------------------------------------------------- CTextWord::CTextWord() From c7a1e3536de4490387d1d4c0bd88396aeeea6c3d Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 29 Feb 2024 12:02:26 +0300 Subject: [PATCH 359/794] Meta from Cell --- .../Sheets/Common/BinReaderWriterDefines.h | 7 +++++-- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 18 ++++++++++++++++++ OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 15 +++++++++++++-- .../XlsxFormat/ExternalLinks/ExternalLinks.cpp | 4 ++-- OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h | 8 ++++---- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 8 ++++---- OOXML/XlsxFormat/Worksheets/SheetData.h | 8 ++++---- 7 files changed, 50 insertions(+), 18 deletions(-) diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index b83bf9c7ea3..fbbb4ab6e62 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -587,7 +587,9 @@ namespace BinXlsxRW Formula = 4, RefRowCol = 5, ValueText = 6, - ValueCache = 7 + ValueCache = 7, + CellMetadata = 8, + ValueMetadata = 9 };} namespace c_oSerFormulaTypes{enum c_oSerFormulaTypes { @@ -1529,7 +1531,8 @@ namespace BinXlsxRW AbsoluteUrl = 19, RelativeUrl = 20, ExternalAlternateUrlsDriveId = 21, - ExternalAlternateUrlsItemId = 22 + ExternalAlternateUrlsItemId = 22, + ValueMetadata = 23 };} namespace c_oSer_OleLinkTypes{enum c_oSer_OleLinkTypes { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 71ec17e9911..ca1221efeac 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -3247,6 +3247,12 @@ void BinaryWorkbookTableWriter::WriteExternalCell(const OOX::Spreadsheet::CExter m_oBcw.m_oStream.WriteStringW3(cell.m_oValue->ToString()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + if (cell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*cell.m_oValueMetadata); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorkbookTableWriter::WriteOleLink(const OOX::Spreadsheet::COleLink& oleLink, const std::wstring& sLink) { @@ -5633,6 +5639,18 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) m_oBcw.m_oStream.WriteStringW3(*oCell.m_oCacheValue); m_oBcw.WriteItemEnd(nCurPos); } + if (oCell.m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::CellMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oCellMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oValueMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } } void BinaryWorksheetTableWriter::WriteFormula(OOX::Spreadsheet::CFormula& oFormula) { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 95fb29a792a..bd0089227d3 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -3231,8 +3231,7 @@ int BinaryWorkbookTableReader::ReadExternalCell(BYTE type, long length, void* po int res = c_oSerConstants::ReadOk; if (c_oSer_ExternalLinkTypes::SheetDataRowCellRef == type) { - pCell->m_oRef.Init(); - pCell->m_oRef->append(m_oBufferedStream.GetString3(length)); + pCell->m_oRef = m_oBufferedStream.GetString3(length); } else if (c_oSer_ExternalLinkTypes::SheetDataRowCellType == type) { @@ -3244,6 +3243,10 @@ int BinaryWorkbookTableReader::ReadExternalCell(BYTE type, long length, void* po pCell->m_oValue.Init(); pCell->m_oValue->m_sText.append(m_oBufferedStream.GetString3(length)); } + else if (c_oSer_ExternalLinkTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -6375,6 +6378,14 @@ int BinaryWorksheetsTableReader::ReadCell(BYTE type, long length, void* poResult { pCell->m_oCacheValue = m_oBufferedStream.GetString4(length); } + else if (c_oSerCellTypes::CellMetadata == type) + { + pCell->m_oCellMetadata = m_oBufferedStream.GetULong(); + } + else if (c_oSerCellTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } else res = c_oSerConstants::ReadUnknown; return res; diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index 4a4d30d6e19..81927d690c7 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -310,7 +310,7 @@ namespace Spreadsheet writer.WriteString(L"ToString()); - WritingStringNullableAttrInt(L"vm", m_oValueMetadata, m_oValueMetadata->GetValue()); + WritingStringNullableAttrInt2(L"vm", m_oValueMetadata); writer.WriteString(L">"); if (m_oValue.IsInit()) m_oValue->toXML2(writer, (L"v")); @@ -410,7 +410,7 @@ namespace Spreadsheet WritingElement_ReadAttributes_Read_if(oReader, (L"r"), m_oRef) WritingElement_ReadAttributes_Read_else_if(oReader, (L"t"), m_oType) WritingElement_ReadAttributes_Read_else_if(oReader, (L"vm"), m_oValueMetadata) - WritingElement_ReadAttributes_End(oReader) + WritingElement_ReadAttributes_End(oReader) } CExternalRow::CExternalRow() diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index cfb69a2ac57..b9d635bf513 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -168,11 +168,11 @@ namespace OOX void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - nullable m_oRef; - nullable m_oType; - nullable m_oValueMetadata; + nullable_string m_oRef; + nullable m_oType; + nullable_uint m_oValueMetadata; - nullable m_oValue; + nullable m_oValue; }; class CExternalRow : public WritingElementWithChilds diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 5bb3bc109e5..acb7ee86c2f 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1301,8 +1301,8 @@ namespace OOX writer.WriteString(m_oType->ToString()); writer.WriteString(L"\""); } - WritingStringNullableAttrInt(L"cm", m_oCellMetadata, m_oCellMetadata->GetValue()); - WritingStringNullableAttrInt(L"vm", m_oValueMetadata, m_oValueMetadata->GetValue()); + WritingStringNullableAttrInt2(L"cm", m_oCellMetadata); + WritingStringNullableAttrInt2(L"vm", m_oValueMetadata); WritingStringNullableAttrBool(L"ph", m_oShowPhonetic); if(m_oFormula.IsInit() || m_oRichText.IsInit() || m_oValue.IsInit()) { @@ -1807,14 +1807,14 @@ namespace OOX { auto metadata(new XLSB::CellMeta); pCellMeta->m_BrtCellMeta = XLS::BaseObjectPtr{metadata}; - metadata->icmb = m_oCellMetadata->GetValue(); + metadata->icmb = *m_oCellMetadata; } if(m_oValueMetadata.IsInit()) { auto metadata(new XLSB::ValueMeta); pCellMeta->m_BrtValueMeta = XLS::BaseObjectPtr{metadata}; - metadata->ivmb = m_oValueMetadata->GetValue(); + metadata->ivmb = *m_oValueMetadata; } } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 1b18f455f17..94db2004074 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -256,11 +256,11 @@ namespace OOX nullable_int iAcross; nullable_int iDown; public: - nullable m_oCellMetadata; - nullable m_oShowPhonetic; - nullable_uint m_oStyle; nullable m_oType; - nullable m_oValueMetadata; + nullable m_oShowPhonetic; + nullable_uint m_oStyle; + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; nullable m_oRef; nullable_uint m_oRow; From 25ca9b5fcd346eba4ee0d8afccfaab6b73eba6e4 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 29 Feb 2024 12:24:02 +0300 Subject: [PATCH 360/794] meta in cell from/to bin --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 28 ++++++++++++++++++++++- OOXML/XlsxFormat/Worksheets/SheetData.h | 4 +++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index acb7ee86c2f..941afd5089c 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -618,6 +618,8 @@ namespace OOX { m_oShowPhonetic.FromStringA(oReader.GetTextChar()); } + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "cm", m_oCellMetadata) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "vm", m_oValueMetadata) WritingElement_ReadAttributes_EndChar( oReader ) } @@ -729,6 +731,14 @@ namespace OOX { nFlags |= 0x2000; } + if (m_oCellMetadata.IsInit()) + { + nFlags |= 0x4000; + } + if (m_oValueMetadata.IsInit()) + { + nFlags |= 0x8000; + } oStream.WriteUSHORT(nFlags); if(m_oFormula.m_bIsInit) { @@ -738,6 +748,15 @@ namespace OOX { m_oRichText->toXLSBExt(oStream); } + //it's not by XLSB format + if (m_oCellMetadata.IsInit()) + { + oStream.WriteULONG(*m_oCellMetadata); + } + if (m_oValueMetadata.IsInit()) + { + oStream.WriteULONG(*m_oValueMetadata); + } oStream.XlsbEndRecord(); } @@ -1787,7 +1806,14 @@ namespace OOX m_oRichText.Init(); m_oRichText->fromXLSBExt(oStream); } - + if (0 != (nStyleRef & 0x4000)) + { + m_oCellMetadata = oStream.GetULong(); + } + if (0 != (nStyleRef & 0x8000)) + { + m_oValueMetadata = oStream.GetULong(); + } oStream.Seek(nEnd); } XLS::BaseObjectPtr CCell::toBin(sharedFormula &sharedFormulas) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 94db2004074..6a5b885e6c5 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -98,7 +98,9 @@ namespace OOX CTextXLSB m_oValue; CFormulaXLSB m_oFormula; nullable m_oRichText; - + + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; protected: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; From bba6d180dcbb95143a4b997054444f6feb7cd09f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 29 Feb 2024 15:54:56 +0300 Subject: [PATCH 361/794] . --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index ca1221efeac..61c3255e937 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -8038,26 +8038,26 @@ void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet: if (oUserProtectedRange.m_oName.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Name); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oName); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oName); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oSqref.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Sqref); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oSqref); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oSqref); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oText.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Text); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oText); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oText); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oType.IsInit()) { - m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRange::Type); - m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Type); m_oBcw.m_oStream.WriteBYTE(oUserProtectedRange.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); } for (size_t i = 0; i < oUserProtectedRange.m_arUsers.size(); ++i) { From 0dd978c000e51a7aca90ea2232102215db0e6e76 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Thu, 29 Feb 2024 16:02:38 +0300 Subject: [PATCH 362/794] Exist folder check: Add white list for some folders --- DesktopEditor/common/Directory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DesktopEditor/common/Directory.cpp b/DesktopEditor/common/Directory.cpp index 66442dbb01f..c666396a1f7 100644 --- a/DesktopEditor/common/Directory.cpp +++ b/DesktopEditor/common/Directory.cpp @@ -60,6 +60,10 @@ namespace NSDirectory #if !defined(_WIN32) && !defined (_WIN64) static bool is_directory_exist(char* dir) { +#ifdef __ANDROID__ + if (0 == strcmp("/storage/emulated", dir)) + return true; +#endif struct stat st; bool bRes = (0 == stat(dir, &st)) && S_ISDIR(st.st_mode); return bRes; From 808782c1c8778ee28ac6e9df4525c3e7903aede5 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 29 Feb 2024 17:34:37 +0300 Subject: [PATCH 363/794] Write BDC/EMC for MetaOForm --- PdfFile/PdfFile.cpp | 1 + PdfFile/PdfWriter.cpp | 4 +++ PdfFile/PdfWriter.h | 1 + PdfFile/PdfWriter_empty.cpp | 2 ++ PdfFile/SrcWriter/Document.cpp | 57 ++++++++++++++++++++++++++++++++-- PdfFile/SrcWriter/Document.h | 2 ++ PdfFile/SrcWriter/Pages.cpp | 24 +++++++++----- PdfFile/SrcWriter/Pages.h | 2 ++ PdfFile/lib/xpdf/Gfx.cc | 13 ++++++++ 9 files changed, 96 insertions(+), 10 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 31581d0e88f..0739d2b63a2 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -2383,6 +2383,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { + m_pInternal->pWriter->EndMarkedContent(); return S_OK; } default: diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 94d16e34e52..523b75cb236 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2350,6 +2350,10 @@ HRESULT CPdfWriter::AddShapeXML(const std::string& sXML) m_pDocument->AddShapeXML(sXML); return S_OK; } +void CPdfWriter::EndMarkedContent() +{ + m_pDocument->EndMarkedContent(); +} //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index e0a970b6139..810eeea82c6 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -199,6 +199,7 @@ class CPdfWriter HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); HRESULT AddShapeXML(const std::string& sXML); + void EndMarkedContent(); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter_empty.cpp b/PdfFile/PdfWriter_empty.cpp index 0552f1f71dc..85033970f4b 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/PdfFile/PdfWriter_empty.cpp @@ -133,6 +133,7 @@ HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pInfo, const std::wstring& wsTempDirectory) { return 0; } HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { return 0; } HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) { return 0; } +HRESULT CPdfWriter::AddShapeXML(const std::string& sXML) { return 0; } HRESULT CPdfWriter::DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::EnableBrushRect(const LONG& lEnable) { return 0; } HRESULT CPdfWriter::SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2) { return 0; } @@ -159,6 +160,7 @@ void CPdfWriter::Reset() {} bool CPdfWriter::IsValid() { return false; } bool CPdfWriter::IsPageValid() { return false; } void CPdfWriter::SetError() {} +void CPdfWriter::EndMarkedContent() {} void CPdfWriter::AddLink(PdfWriter::CPage* pPage, const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const unsigned int& unDestPage) {} unsigned char* CPdfWriter::EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs) { return NULL; } unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) { return NULL; } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 900412bee36..45067e93c6d 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -172,6 +172,7 @@ namespace PdfWriter m_vFillAlpha.clear(); m_vStrokeAlpha.clear(); m_vRadioGroups.clear(); + m_vMetaOForms.clear(); m_pTransparencyGroup = NULL; @@ -310,6 +311,12 @@ namespace PdfWriter pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + + if (m_pMetaData) + m_pMetaData->SetID(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + + for (int i = 0; i < m_vMetaOForms.size(); ++i) + m_vMetaOForms[i]->Add("ID", new CBinaryObject(pEncrypt->m_anEncryptID, 16)); } void CDocument::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) { @@ -438,6 +445,7 @@ namespace PdfWriter if (!m_pMetaData) return false; + CBinaryObject* sID = NULL; CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); if (!pID) { @@ -450,8 +458,12 @@ namespace PdfWriter pID->Add(new CBinaryObject(arrId, 16)); pID->Add(new CBinaryObject(arrId, 16)); - m_pMetaData->SetID(new CBinaryObject(arrId, 16)); + sID = new CBinaryObject(arrId, 16); } + else + sID = (CBinaryObject*)pID->Get(1)->Copy(); + + m_pMetaData->SetID(sID); return m_pMetaData->AddMetaData(sMetaName, pMetaData, nMetaLength); } @@ -1580,6 +1592,9 @@ namespace PdfWriter CObjectBase* pObject = ((CArrayObject*)pID)->Get(1, false); ((CArrayObject*)pID)->Insert(pObject, new CBinaryObject(arrId, 16), true); + + for (int i = 0; i < m_vMetaOForms.size(); ++i) + m_vMetaOForms[i]->Add("ID", new CBinaryObject(arrId, 16)); } CEncrypt* pEncrypt = NULL; @@ -1706,13 +1721,43 @@ namespace PdfWriter } void CDocument::AddShapeXML(const std::string& sXML) { - CDictObject* pMetaOForm = m_pCurPage->GetMetaOForm(); + // TODO Revision++ + int nRevision = 0; + + CObjectBase* pObj = m_pCurPage->Get("MetaOForm"); + if (pObj && pObj->GetType() != object_type_DICT) + { + m_pCurPage->Remove("MetaOForm"); + pObj = NULL; + } + CDictObject* pMetaOForm = (CDictObject*)pObj; if (!pMetaOForm) { pMetaOForm = new CDictObject(); m_pXref->Add(pMetaOForm); pMetaOForm->Add("Type", "MetaOForm"); - m_pCurPage->SetMetaOForm(pMetaOForm); + pMetaOForm->Add("Revision", nRevision); + m_pCurPage->Add("MetaOForm", pMetaOForm); + m_vMetaOForms.push_back(pMetaOForm); + + CBinaryObject* sID = NULL; + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + + pID->Add(new CBinaryObject(arrId, 16)); + pID->Add(new CBinaryObject(arrId, 16)); + + sID = new CBinaryObject(arrId, 16); + } + else + sID = (CBinaryObject*)pID->Get(1)->Copy(); + pMetaOForm->Add("ID", sID); } CArrayObject* pArrayMeta = (CArrayObject*)pMetaOForm->Get("Medata"); if (!pArrayMeta) @@ -1721,5 +1766,11 @@ namespace PdfWriter pMetaOForm->Add("Metadata", pArrayMeta); } pArrayMeta->Add(new CStringObject(sXML.c_str())); + + m_pCurPage->BeginShape(nRevision); + } + void CDocument::EndMarkedContent() + { + m_pCurPage->EndMarkedContent(); } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index baa17417322..6666c997553 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -199,6 +199,7 @@ namespace PdfWriter bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); + void EndMarkedContent(); private: char* GetTTFontTag(); @@ -281,6 +282,7 @@ namespace PdfWriter CDictObject* m_pAcroForm; CResourcesDict* m_pFieldsResources; std::vector m_vRadioGroups; + std::vector m_vMetaOForms; std::map m_mFields; std::map m_mAnnotations; std::map m_mParents; diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 956e4cbb126..2ef4e523250 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -457,7 +457,6 @@ namespace PdfWriter m_eGrMode = grmode_PAGE; m_pGrState = new CGrState(NULL); - m_pMetaOForm = NULL; m_pExtGStates = NULL; m_unExtGStatesCount = 0; m_pFonts = NULL; @@ -1584,13 +1583,24 @@ namespace PdfWriter CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); return pRotate ? pRotate->Get() : 0; } - void CPage::SetMetaOForm(CDictObject* pMetaOForm) + void CPage::BeginShape(int nRevision) { - if (!m_pMetaOForm) - { - m_pMetaOForm = pMetaOForm; - Add("MetaOForm", m_pMetaOForm); - } + // Operator : BDC + // Description: Начало маркированного контента MetaOForm + + m_pStream->WriteEscapeName("MetaOForm"); + m_pStream->WriteStr(" <<"); + m_pStream->WriteEscapeName("Revision"); + m_pStream->WriteChar(' '); + m_pStream->WriteInt(nRevision); + m_pStream->WriteStr(">> BDC\012"); + } + void CPage::EndMarkedContent() + { + // Operator : EMC + // Description: Конец маркированного контента + + m_pStream->WriteStr("EMC\012"); } //---------------------------------------------------------------------------------------- // CTextWord diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 8989cff8c13..d6e62dbb6b1 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -138,6 +138,8 @@ namespace PdfWriter void DrawShading(CShading* pShading); void SetStrokeAlpha(unsigned char unAlpha); void SetFillAlpha(unsigned char unAlpha); + void BeginShape(int nRevision); + void EndMarkedContent(); void BeginText(); void EndText(); diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 9491883a969..655eb42de15 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,6 +5053,19 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); + } else if (args[0].isName("MetaOForm") && numArgs == 2 && args[1].isDict()) { + if (args[1].dictLookup("Revision", &obj)->isInt()) { + // TODO и совпадает с текущим в adaptor + Object obj2; + getContentObj(&obj2); + while (!obj2.isEOF() && !obj2.isCmd("EMC")) { + obj2.free(); + getContentObj(&obj2); + } + obj2.free(); obj.free(); + return; + } + obj.free(); } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); From f5ee86c94e5ae1bf0ef7f745d5a6212e93f8ae1c Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 29 Feb 2024 19:44:28 +0300 Subject: [PATCH 364/794] Add tests for dictionaries --- Common/3dParty/hunspell/test/main.cpp | 131 +++++++++ .../3dParty/hunspell/test/src/az_Latn_AZ.txt | 213 ++++++++++++++ Common/3dParty/hunspell/test/src/bg_BG.txt | 212 ++++++++++++++ Common/3dParty/hunspell/test/src/ca_ES.txt | 112 ++++++++ .../hunspell/test/src/ca_ES_valencia.txt | 212 ++++++++++++++ Common/3dParty/hunspell/test/src/cs_CZ.txt | 206 ++++++++++++++ Common/3dParty/hunspell/test/src/da_DK.txt | 129 +++++++++ Common/3dParty/hunspell/test/src/de_AT.txt | 131 +++++++++ Common/3dParty/hunspell/test/src/de_CH.txt | 116 ++++++++ Common/3dParty/hunspell/test/src/de_DE.txt | 211 ++++++++++++++ Common/3dParty/hunspell/test/src/el_GR.txt | 123 ++++++++ Common/3dParty/hunspell/test/src/en_AU.txt | 116 ++++++++ Common/3dParty/hunspell/test/src/en_CA.txt | 125 +++++++++ Common/3dParty/hunspell/test/src/en_GB.txt | 122 ++++++++ Common/3dParty/hunspell/test/src/en_US.txt | 213 ++++++++++++++ Common/3dParty/hunspell/test/src/en_ZA.txt | 114 ++++++++ Common/3dParty/hunspell/test/src/es_ES.txt | 208 ++++++++++++++ Common/3dParty/hunspell/test/src/eu_ES.txt | 132 +++++++++ Common/3dParty/hunspell/test/src/fr_FR.txt | 211 ++++++++++++++ Common/3dParty/hunspell/test/src/gl_ES.txt | 120 ++++++++ Common/3dParty/hunspell/test/src/hr_HR.txt | 215 ++++++++++++++ Common/3dParty/hunspell/test/src/hu_HU.txt | 114 ++++++++ Common/3dParty/hunspell/test/src/id_ID.txt | 121 ++++++++ Common/3dParty/hunspell/test/src/it_IT.txt | 200 +++++++++++++ Common/3dParty/hunspell/test/src/kk_KZ.txt | 209 ++++++++++++++ Common/3dParty/hunspell/test/src/ko_KR.txt | 157 +++++++++++ Common/3dParty/hunspell/test/src/lb_LU.txt | 118 ++++++++ Common/3dParty/hunspell/test/src/lt_LT.txt | 127 +++++++++ Common/3dParty/hunspell/test/src/lv_LV.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/src/mn_MN.txt | 103 +++++++ Common/3dParty/hunspell/test/src/nb_NO.txt | 113 ++++++++ Common/3dParty/hunspell/test/src/nl_NL.txt | 115 ++++++++ Common/3dParty/hunspell/test/src/nn_NO.txt | 116 ++++++++ Common/3dParty/hunspell/test/src/oc_FR.txt | 108 ++++++++ Common/3dParty/hunspell/test/src/pl_PL.txt | 225 +++++++++++++++ Common/3dParty/hunspell/test/src/pt_BR.txt | 108 ++++++++ Common/3dParty/hunspell/test/src/pt_PT.txt | 135 +++++++++ Common/3dParty/hunspell/test/src/ro_RO.txt | 210 ++++++++++++++ Common/3dParty/hunspell/test/src/ru_RU.txt | 197 +++++++++++++ Common/3dParty/hunspell/test/src/sk_SK.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/src/sl_SI.txt | 210 ++++++++++++++ .../3dParty/hunspell/test/src/sr_Cyrl_RS.txt | 227 +++++++++++++++ .../3dParty/hunspell/test/src/sr_Latn_RS.txt | 173 ++++++++++++ Common/3dParty/hunspell/test/src/sv_SE.txt | 210 ++++++++++++++ Common/3dParty/hunspell/test/src/tr_TR.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/src/uk_UA.txt | 210 ++++++++++++++ .../3dParty/hunspell/test/src/uz_Cyrl_UZ.txt | 262 ++++++++++++++++++ .../3dParty/hunspell/test/src/uz_Latn_UZ.txt | 200 +++++++++++++ Common/3dParty/hunspell/test/src/vi_VN.txt | 128 +++++++++ Common/3dParty/hunspell/test/test.pro | 29 ++ 50 files changed, 8112 insertions(+) create mode 100644 Common/3dParty/hunspell/test/main.cpp create mode 100644 Common/3dParty/hunspell/test/src/az_Latn_AZ.txt create mode 100644 Common/3dParty/hunspell/test/src/bg_BG.txt create mode 100644 Common/3dParty/hunspell/test/src/ca_ES.txt create mode 100644 Common/3dParty/hunspell/test/src/ca_ES_valencia.txt create mode 100644 Common/3dParty/hunspell/test/src/cs_CZ.txt create mode 100644 Common/3dParty/hunspell/test/src/da_DK.txt create mode 100644 Common/3dParty/hunspell/test/src/de_AT.txt create mode 100644 Common/3dParty/hunspell/test/src/de_CH.txt create mode 100644 Common/3dParty/hunspell/test/src/de_DE.txt create mode 100644 Common/3dParty/hunspell/test/src/el_GR.txt create mode 100644 Common/3dParty/hunspell/test/src/en_AU.txt create mode 100644 Common/3dParty/hunspell/test/src/en_CA.txt create mode 100644 Common/3dParty/hunspell/test/src/en_GB.txt create mode 100644 Common/3dParty/hunspell/test/src/en_US.txt create mode 100644 Common/3dParty/hunspell/test/src/en_ZA.txt create mode 100644 Common/3dParty/hunspell/test/src/es_ES.txt create mode 100644 Common/3dParty/hunspell/test/src/eu_ES.txt create mode 100644 Common/3dParty/hunspell/test/src/fr_FR.txt create mode 100644 Common/3dParty/hunspell/test/src/gl_ES.txt create mode 100644 Common/3dParty/hunspell/test/src/hr_HR.txt create mode 100644 Common/3dParty/hunspell/test/src/hu_HU.txt create mode 100644 Common/3dParty/hunspell/test/src/id_ID.txt create mode 100644 Common/3dParty/hunspell/test/src/it_IT.txt create mode 100644 Common/3dParty/hunspell/test/src/kk_KZ.txt create mode 100644 Common/3dParty/hunspell/test/src/ko_KR.txt create mode 100644 Common/3dParty/hunspell/test/src/lb_LU.txt create mode 100644 Common/3dParty/hunspell/test/src/lt_LT.txt create mode 100644 Common/3dParty/hunspell/test/src/lv_LV.txt create mode 100644 Common/3dParty/hunspell/test/src/mn_MN.txt create mode 100644 Common/3dParty/hunspell/test/src/nb_NO.txt create mode 100644 Common/3dParty/hunspell/test/src/nl_NL.txt create mode 100644 Common/3dParty/hunspell/test/src/nn_NO.txt create mode 100644 Common/3dParty/hunspell/test/src/oc_FR.txt create mode 100644 Common/3dParty/hunspell/test/src/pl_PL.txt create mode 100644 Common/3dParty/hunspell/test/src/pt_BR.txt create mode 100644 Common/3dParty/hunspell/test/src/pt_PT.txt create mode 100644 Common/3dParty/hunspell/test/src/ro_RO.txt create mode 100644 Common/3dParty/hunspell/test/src/ru_RU.txt create mode 100644 Common/3dParty/hunspell/test/src/sk_SK.txt create mode 100644 Common/3dParty/hunspell/test/src/sl_SI.txt create mode 100644 Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt create mode 100644 Common/3dParty/hunspell/test/src/sr_Latn_RS.txt create mode 100644 Common/3dParty/hunspell/test/src/sv_SE.txt create mode 100644 Common/3dParty/hunspell/test/src/tr_TR.txt create mode 100644 Common/3dParty/hunspell/test/src/uk_UA.txt create mode 100644 Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt create mode 100644 Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt create mode 100644 Common/3dParty/hunspell/test/src/vi_VN.txt create mode 100644 Common/3dParty/hunspell/test/test.pro diff --git a/Common/3dParty/hunspell/test/main.cpp b/Common/3dParty/hunspell/test/main.cpp new file mode 100644 index 00000000000..6d9406c53e6 --- /dev/null +++ b/Common/3dParty/hunspell/test/main.cpp @@ -0,0 +1,131 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../../../../Common/3dParty/hunspell/hunspell/src/hunspell/hunspell.h" +#include "../../../../DesktopEditor/common/StringExt.h" +#include "../../../../DesktopEditor/common/Directory.h" + +bool CheckCaret(std::vector& words) +{ + bool bIsCaret = false; + for (int i = 0, len = (int)words.size(); i < len; ++i) + { + if (words[i].find('\r') == (words[i].length() - 1)) + { + words[i] = words[i].substr(0, words[i].length() - 1); + bIsCaret = true; + } + } + return bIsCaret; +} + +std::wstring CheckWord(Hunhandle* pDic, const std::wstring& sWord, const bool& bIsCaret) +{ + std::wstring sResult = sWord; + + std::string sWordA = U_TO_UTF8(sWord); + int nSpellResult = Hunspell_spell(pDic, sWordA.c_str()); + + if (0 == nSpellResult) + { + char** pSuggest; + int nSuggestCount = Hunspell_suggest(pDic, &pSuggest, sWordA.c_str()); + + sResult += L" ["; + + for (int i = 0; i < nSuggestCount; ++i) + { + std::string sSuggestA(pSuggest[i], strlen(pSuggest[i])); + std::wstring sSuggest = UTF8_TO_U(sSuggestA); + + sResult += sSuggest; + if (i != (nSuggestCount - 1)) + sResult += (L", "); + } + + if (0 < nSuggestCount) + Hunspell_free_list(pDic, &pSuggest, nSuggestCount); + + sResult += L"]"; + } + + if (bIsCaret) + sResult += L"\r"; + sResult += L"\n"; + + return sResult; +} + +int main(int argc, char *argv[]) +{ + std::wstring sSrcDir = NSFile::GetProcessDirectory() + L"/../src"; + std::wstring sDstDir = NSFile::GetProcessDirectory() + L"/../dst"; + std::wstring sDictionariesDir = NSFile::GetProcessDirectory() + L"/../../../../../../dictionaries"; + std::vector arSrcFiles = NSDirectory::GetFiles(sSrcDir); + + for (int i = 0, len = (int)arSrcFiles.size(); i < len; ++i) + { + std::wstring sFileWords = arSrcFiles[i]; + std::wstring sName = NSFile::GetFileName(sFileWords); + std::wstring::size_type sNamePos = sName.find(L"."); + if (std::wstring::npos != sNamePos) + sName = sName.substr(0, sNamePos); + + std::wstring sFileWordsContent = L""; + NSFile::CFileBinary::ReadAllTextUtf8(sFileWords, sFileWordsContent); + + std::vector arWords = NSStringExt::Split(sFileWordsContent, '\n'); + bool bIsCaret = CheckCaret(arWords); + + std::wstring sAff = sDictionariesDir + L"/" + sName + L"/" + sName + L".aff"; + std::wstring sDic = sDictionariesDir + L"/" + sName + L"/" + sName + L".dic"; + + std::string sAffA = U_TO_UTF8(sAff); + std::string sDicA = U_TO_UTF8(sDic); + + Hunhandle* pDictionary = Hunspell_create(sAffA.c_str(), sDicA.c_str()); + + std::wstring sFileDst = sDstDir + L"/" + sName + L".txt"; + + std::wstring sResult = L""; + for (const std::wstring& word : arWords) + { + sResult += CheckWord(pDictionary, word, bIsCaret); + } + + Hunspell_destroy(pDictionary); + + NSFile::CFileBinary::SaveToFile(sFileDst, sResult, true); + } + + return 0; +} diff --git a/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt b/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt new file mode 100644 index 00000000000..4d97adce042 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt @@ -0,0 +1,213 @@ +A +qocalmaq +Alderaan'ın +hamısı +həmçinin +Və +cavab +dir +incəsənət +kimi +da +uzaq +körpə +zirzəmi +ol +olub +doğuldu +bulvar +fasilə +nəsllər +gəlin +lakin +al +ilə +Kaliforniya +Kalifornikasiya +bilər +kartlar +şans +Çin +çənə +klublar +Cobain +bürc +nəzarət +qiymət +edə bilməzdim +yaratmaq +lənət +rəqs +saziş +sövdələşmələr +dağıdıcı +almazlar +etməz +etməyərik +arzu +xülyalar +Şərq +kənar +kənarları +məmnunluq +hamının +uzaq +peri +solğun +üz +son +tap +ilk +üçün +-dan +sərhəd +qız +qızın +yaxşı +gitara +əl +hardcore +var +yoxdur +o +eşitmək +ürək +O'nun +ona +gizli +yüksək +ona +onun +Hollivud +Mən +Mənəm +əgər +içində +məlumat +içində +dir +bu +jack +sadəcə +kral +qohum +bilmək +qoyulmuş +qanun +yerləşdirilmək +qurğuşun +aparmaq +yerləşdirilmə +məkan +sevmək +şans +edilmiş +adam +çox +Evlənmək +maska +o bilər +bəlkə də +mənası +mən +meditasiya +xatirə +ağılın +pul +mənim +heç vaxt +deyil +heç nə +nömrələr +of +of +üstündə +bir +yalnız +və ya +nəticə +öz +Ödə +Şəftəli +yerlər +oynayır +oynamaq +əhali +porno +tərifləmək +ehtimal ki +ehtimal +psixik +kraliça +qaldırmaq +qalan +hörmət +qalxmaq +yol +xam +müqəddəs +Xilas et +elmi +çığırmaq +satılır +şəkil +xəstələnmək +gümüşçü +dəri +əsgər +bir şey +Mahnı +mahnılar +qılınclar +büyü +casuslar +ulduz +Stansiya +oğurlamaq +daşlar +günəş +şübhəli +İsveç +qılınclar +yeniyetmə +test +dandan +bu ki +bu ki +bu +onların +bu +onlar +düşünmək +bu +onlar +gel-git +üçün +deyilmişəm +çox +cəhd et +başa düşdüm +qilin +titrəmək +mübarizə aparır? +istəyirəm +müharibə +idi +dalğalar +geymək +silahlar +yaxşı +idarə olunan +Qərbi +nə +arasında +qalib gəlmək +qalib gəlir +ilə +qadın +dünya +səhv +siz +sizə +sənsən +sənin diff --git a/Common/3dParty/hunspell/test/src/bg_BG.txt b/Common/3dParty/hunspell/test/src/bg_BG.txt new file mode 100644 index 00000000000..a09b554067d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/bg_BG.txt @@ -0,0 +1,212 @@ +A +остаряване +Алдераан +всичко +също +и +отговор +са +изкуство +като +в +далеч +бебе +мазе +бъда +било +роден +булевард +почивка +породи +невеста +но +купувам +от +Калифорния +Калифорникация +може +карти +шанс +Китай +брадичка +клубове +Кобейн +съзвездие +контрол +цена +не можех +създаване +проклятие +танц +сделка +сделки +унищожение +диаманти +не прави +не правим +мечта +мечти +Изток +ръб +ръбове +екстаз +всеки +далеч +приказка +избледнява +лица +краен +намирам +първи +за +от +предел +момиче +момичето +добре +китара +ръка +хардкор +има +няма +той +чуя +сърце +той е +нейни +скрит +висок +него +негов +Холивуд +аз +аз съм +ако +в +информация +вътре +е +това е +вале +просто +крал +родственик +знам +определен +закон +поставям +водя +води +местоположение +обичам +късмет +направен +човек +много +Ожени се +маска +май +може би +означава +аз +медитация +спомен +ума +пари +моя +никога +не +нищо +числа +от +изключен +на +един +само +или +изход +свой +Плати +праскова +места +играе +играя +население +порно +похвала +вероятно +вероятен +психичен +кралица +въздигам +останал +почит +възход +път +груб +светия +Спасявам +наука +крясък +продава +форма +по-болен +златар +кожа +войник +някаква +Песен +песни +пикове +заклинание +шпиони +звезда +стация +крада +камъни +слънце +подозрителен +Швеция +мечове +тийнейджър +тест +отколкото +това +това е +на +техни +тези +те с +мисли +този +той +прилив +до +каза +също +опитайте +разбрано +еднорог +вибрация +водене? +искам +война +беше +вълни +носете +оръжия +Ами +бяха +Западна +какво +докато +победа +победи +със +жена +свят +грешка +ти +ти би +ти си +вашият diff --git a/Common/3dParty/hunspell/test/src/ca_ES.txt b/Common/3dParty/hunspell/test/src/ca_ES.txt new file mode 100644 index 00000000000..3fd8739062a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ca_ES.txt @@ -0,0 +1,112 @@ +amor +llum +lluum +esperança +espirança +llibertat +força +forrça +pau +somni +llibre +mar +amistat +cançó +flor +cel +estrella +temps +camí +vent +muntanya +mumntanya +riu +soroll +silenci +viatge +foc +gel +paraula +vida +dia +nit +tarda +matí +lluna +sol +llac +marbre +ferro +sal +mel +sucre +peix +ocell +oceoll +joc +ritme +melodia +pintura +pentura +teatre +dansa +poema +història +llegenda +mitologia +festa +música +vi +cervesa +cervessa +formatge +pa +ciutat +poble +natura +camp +bosc +platja +sorra +sorrà +pedra +ànima +cos +ment +cor +somriure +somriàre +abraçada +bes +parla +oida +vista +tacte +gust +olfacte +color +forma +número +lletra +sistema +regla +escola +universitat +univversitat +mestre +estudiant +sabiduria +lliçó +pregunta +resposta +risposta +dubte +certesa +veritat +mentida +promesa +secret +descoberta +descaberta +aventura +destinació \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt b/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt new file mode 100644 index 00000000000..8b31af1a394 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt @@ -0,0 +1,212 @@ +A +envellir +Alderaan +tot +també +I +resposta +és +art +com +a +lluny +nadó +celler +ser +ha estat +nat +bulevard +pausa +generacions +núvia +però +comprar +amb +Califòrnia +Californication +pot +cartes +oportunitat +Xina +mentó +clubs +Cobain +signe del zodíac +control +preu +no podria +crear +maleït +ballar +acord +negocis +destructiu +diamants +no fer +no fem +desitjar +somnis +Est +vora +voreres +satisfacció +tots +llunyà +fada +pallid +cara +final +trobar +primer +per +de +frontera +noia +la noia +bé +guitarra +mà +hardcore +hi ha +no hi ha +ell +sentir +cor +ell és +seva +secret +alt +ell +seu +Hollywood +jo +sóc +si +en +informació +interior +és +és +jack +només +rei +parent +saber +fixat +llei +col·locar +plom +portar +col·locació +lloc +estimar +oportunitat +fet +home +molts +casar-se +màscara +podria +potser +sentit +jo +meditació +memòria +ment +diners +meu +mai +no +res +números +de +fora +sobre +un +només +o +resultat +seu +pagar +préssec +llocs +jugar +joc +població +porno +elogiar +probablement +probable +psíquic +reina +elevar +restant +respecte +pujar +camí +cru +sant +salvar +ciència +crit +vendre’s +figura +malalt +joier +pell +soldat +alguna cosa +cançó +cançons +cims +encanteri +espies +estrella +estació +robar +pedres +sol +sospitós +Suècia +espases +adolescent +prova +que +que +això +seu +aqueixos +ells +pensar +aqueix +ells +marees +per +no he estat +molt +intentar +entendre +fer +tremolar +lluitar +desitjar +guerra +va ser +ones +portar +armes +bé +administrat +Oest +què +entre +guanyar +guanya +amb +dona +món +equivocat +tu +vostè +tu ets +teu diff --git a/Common/3dParty/hunspell/test/src/cs_CZ.txt b/Common/3dParty/hunspell/test/src/cs_CZ.txt new file mode 100644 index 00000000000..a76fe6803e8 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/cs_CZ.txt @@ -0,0 +1,206 @@ +pomaliý +šťstný +smuutný +horcký +studiený +záludnast +náhodillost +úpěnlevý +rozspačitý +svéhllavý +jablko +slunce +voda +dům +pták +káva +chleba +květina +kniha +pes +kočka +město +zelený +modrý +červený +bílý +černý +velký +malý +rychlý +pomalý +šťastný +smutný +horký +studený +nový +starý +hezký +ošklivý +dobrý +špatný +zdravý +nemocný +silný +slabý +chytrý +hloupý +pracovat +jíst +pít +spát +číst +psát +mluvit +smát se +plakat +zpívat +hrát +tančit +učit se +nakupovat +vařit +telefonovat +dívat se +poslouchat +chodit +běžet +létat +plavat +psát +učit se +dělat +mít +být +jít +přijít +odejít +dát +vzít +říct +vidět +slyšet +cítit +myslet +chtít +moct +muset +rád +nerad +ano +ne +prosím +děkuji +na shledanou +omlouvám se +sbohem +ahoj +čau +hej +jo +fakt +super +blbost +paráda +no jo +jasně +takže +vlastně +třeba +snad +leštěnka +pochmurný +živelný +ponaučení +záhada +pochybnost +nádhera +soucit +záludnost +náhodilost +úpěnlivý +rozpačitý +svéhlavý +marnivost +blahodar +rozčarování +odchylka +přelud +vytrvalost +neústupnost +lehkost +souznění +rozmarnost +roztržitost +úskočnost +rozkoš +marasmus +rozpolcenost +neúprosnost +ztřeštěnost +chmurnost +okouzlení +zářivost +vyrovnanost +neochvějnost +neúcta +bizarnost +rozmařilost +nepochopení +nevýslovný +pomíjivost +beznaděj +úzkost +odtažitost +rozerv +rozervanost +vyčerpanost +bezcitnost +záludnost +nezdolnost +rozkošátnost +nezdolatelnost +rozmarnost +živelnost +bezútěšnost +záhadnost +neposkvrnitelnost +rozkošnělost +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +rozervanost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +bezbřehost \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/da_DK.txt b/Common/3dParty/hunspell/test/src/da_DK.txt new file mode 100644 index 00000000000..1581a616601 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/da_DK.txt @@ -0,0 +1,129 @@ +Hej +Goddag +Tak +Ja +Nej +Måske +Mad +Vand +Hus +Bil +Tog +Cykel +Skole +Børn +Far +Mor +Søster +Bror +Hund +Kat +Fisk +Fugl +Træ +Blomst +Græs +Sol +Måne +Himmel +Regn +Sne +Sommer +Vinter +Forår +Efterår +Aften +Nat +Dag +Uge +Måned +År +Læse +Skrive +Tale +Lære +Arbejde +Sove +Vågne +Løbe +Gå +Sidde +Stå +Lytte +Se +Høre +Spise +Drikke +Kød +Frugt +Grøntsager +Ost +Brød +Vand +Juice +Kaffe +Te +Mælk +Smør +Æg +Salt +Peber +Sukker +Bolle +Smørrebrød +Køkken +Stue +Soveværelse +Badeværelse +Toilet +Bord +Stol +Sofa +Lampe +Vindue +Dør +Gulv +Loft +Væg +Sofa +Pude +Tæppe +Badekar +Håndvask +Spejl +Håndklæde +Seng +Dyne +Dynee +Pude +Pudee +Alarm +Alarmm +Skrivebord +Stol +Hus +Hund +Kat +Katt +Bil +Skole +Skolee +Sol +Soll +Vand +Vandd +Mad +Madd +By +Barn +Barnn +Tørklæde +Skæbne +Uafhængighed +Kærlighed +Kærligheed +overbelastning +Modstandsbevægelsen +Uafhængighedserklæringen +Forårssommertemperaturen +Stabiliseringsperioden diff --git a/Common/3dParty/hunspell/test/src/de_AT.txt b/Common/3dParty/hunspell/test/src/de_AT.txt new file mode 100644 index 00000000000..fccb06c4319 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_AT.txt @@ -0,0 +1,131 @@ +Ägyptologie +Ährenamt +Ängstlichkeit +Äquatoria +Abarbeiten +Abbild +Abbilden +Abbildungs +Abbreviatur +Abbrüche +Abfassen +Abfertigen +Abfolge +Abfuhr +Ableugnen +Ablichten +Ablöse +Absätze +Abschnitts +Abwechseln +Abwehren +Aktiv +Britannia +Browserfenster +Budgetieren +Bugpartie +Bukarester +Burgundersoße +Butterkrem +Button +Cabriolet +Campanile +Canapé +Caprice +Celsius +Chamäleon +Charakteristik +Chronometer +Chronometrie +Cölln +Connectzustände +Cursorspur +Däne +Dachs +Dahindämmern +Darbringen +Daten +Datenbankserver +Desktopsystem +Detektivfilm +Dichtertum +Dinosaurier +Direktion +Diskantgambe +Diskothek +Druckereicode +Kapsel +Karausche +Katzen +Klinge +Klinke +Kohlrabi +Koinzidenz +Kolleg +Komplott +Meereis +Mehrphasigkeit +Memorieren +Messen +Methode +Metrowaggon +Meute +Migräne +Milieuforschung +Mindern +Mineralien +Mitternacht +Mobiliar +Mohrrübe +Mühelosigkeit +Normativität +Notifikation +Ökonomie +Orangeton +Osten +Subjekt +Subsidiarität +Subsumieren +Tagfalter +Speicher +Spielzeugsammlung +Zahler + +Сложные слова +Zurückgezogenheit +Äquipotentialfläche +Äußerungsbedeutung +Abfassungszeitraum +Abgeschlossenheits +Adjunktionsbeseitigung +Anknüpfungsgrundsätze +Chiffrierschlüssel +Knochenmarktransplantation +Bundeskaderathlet +Carbonsäurechlorid +Cardiazoltherapie +Chancenungleichheit +Charakterisierungsmöglichkeit +Chlorophyllkonzentration +Computerspielemarkt +Deindustrialisieren +Dekodierungsmöglichkeit +Kartoffelschälmesser +Kernspinresonanztomographie +Merkmalskombination +Nachbarschaftszentren +Opportunitätsprinzip +Tiefenstaffelung +Tourismusfachmann +Sequenzbetrachtung + +Слова с ошибками +Dechifrierprogramm +Administratorkenwort +Spigeln +Tätigkeite +Draufgangertum +Abschnit +Komunikation +Drackereicode +Bumeln \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/de_CH.txt b/Common/3dParty/hunspell/test/src/de_CH.txt new file mode 100644 index 00000000000..12c46630805 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_CH.txt @@ -0,0 +1,116 @@ +Alpinist +Alteration +Alternative +Alumne +Amateurfilmer +Ambulanz +Amtmänner +Analogie +Analytik +Ananas +Angabe +Ankünfte +Dynastie +Ebenbürtigkeit +Echtheitszertifikat +Editionspläne +Editor +Ehrenamtlichkeit +Eigentümerschaft +Einbau +Eindringling +Eingabequittungsbetrieb +Einhüllen +Einkommen +Einloggen +Einschließen +Einsortier +Elaboration +Elementar +Entertainer +Entkuppeln +Entschädigungs +Enumerator +Erbringen +Erdichten +Erfahrenheit +Erhalt +Erleichtern +Ersparnis +Erstatten +Erzählliteratur +Helikopter +Helpdesk +Herunterladen +Hindeuten +Hinterlassenschaft +Hiob +Landesprache +flexibilität +floristisch +flugbillet +heroben +herrichten +herstellen +herübereilen +herunterzubücken +hie +hieraus +hilfe +himbeere +justiz +kältebeständig +kärtchen +känguru +kaktusgewächs +kalligrafie +kamel +kampagnendirektor +kapazitär +kapitalist +karamell +kardieren +karpfen +katalogdaten +lyzeum +mahagonirot +makkaroni +malerausbildung +management +mangel +maniküre +manneskraft +mansarde +mark +marketingpraktiker +maschinell +massage +massengutschifffahrt +materie +medaille +medizinalshampoo +meeresfrüchte +quotient +salonwagen +satzeinleitend +trilateral +tristesse +tropen +vereisen +verfahren +verfügungs +verhindern +verkäufer + +Слова с ошибками +Anbindungsystem +Anglistikdocent +Ecco +Economclass +Einverstandnis +Electrik +Historique +herüberzurucken +kartofel +salade +sanddornbere \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/de_DE.txt b/Common/3dParty/hunspell/test/src/de_DE.txt new file mode 100644 index 00000000000..3ab503f810a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_DE.txt @@ -0,0 +1,211 @@ +Hallo +Guten Morgen +Danke +Bitte +Ja +Nein +Entschuldigung +Tschüss +Liebe +Freund +Familie +Glück +Gesundheit +Schule +Arbeit +Essen +Trinken +Wasser +Brot +Käse +Fleisch +Gemüse +Obst +Kaffee +Tee +Milch +Zucker +Salz +Pfeffer +Haus +Wohnung +Bett +Stuhl +Tisch +Sofa +Fernseher +Telefon +Computer +Buch +Zeitung +Schreiben +Lesen +Hören +Sehen +Fühlen +Laufen +Springen +Schwimmen +Tanzen +Singen +Lachen +Weinen +Freude +Trauer +Angst +Mut +Liebe +Hass +Freundschaft +Beziehung +Familie +Eltern +Kinder +Geschwister +Großeltern +Onkel +Tante +Cousin +Cousine +Ehemann +Ehefrau +Verlobung +Hochzeit +Scheidung +Geburt +Tod +Krankheit +Arzt +Krankenhaus +Medikament +Apotheke +Gesundheit +Wohlbefinden +Fitness +Diät +Schlaf +Ruhe +Entspannung +Sport +Fußball +Tennis +Schwimmen +Laufen +Radfahren +Wandern +Reisen +Urlaub +Strand +Sonne +Meer +Komplementär +Perspektive +Konsens +Integrität +Konsequenz +Authentizität +Korrelation +Charakteristik +Akzeptanz +Flexibilität +Assoziation +Dekomposition +Komplexität +Positivismus +Universalität +Stabilität +Individualität +Konsistenz +Konformität +Dezentralisierung +Kollaboration +Partizipation +Präzision +Transformation +Konkurrenz +Paradoxie +Redundanz +Regeneration +Integration +Isolation +Asymmetrie +Aggregation +Disziplin +Resilienz +Relevanz +Konfusion +Komplikation +Koordination +Harmonie +Ineffizienz +Konstruktion +Konversion +Kollusion +Gerontologie +Differenzierung +Dimensionalität +Inferenz +Fluktuation +Kontraktion +Rezession +Inflation +Dekontamination +Exzellenz +Innovation +Isomorphie +Konnotation +Insuffizienz +Konversion +Kompensation +Koalition +Inkongruenz +Inkontinenz +Kontrahent +Konfiskation +Konjunktur +Aggression +Konfrontation +Kompatibilität +Prognose +Akzeleration +Konstruktion +Diversifikation +Prävention +Sanktion +Indikation +Reduktion +Konkurrenz +Konfiguration +Konnotation +Rezession +Transformation +Interaktion +Kooperation +Innovation +Kollision +Proklamation +Konnotation +Konfrontation +Disposition +Konkordanz +Deklamation +Kollaboration +Isolation +Inflation +Diversifikation +Konnotation +Kompensation +Diffusion +Dekadenz +Konserve +Deklomotion +Kolaboration +Isollation +Infllation +Divirsifikation +Konotation +Kompenssation +Difusion +Dekadens +Kanzerve + diff --git a/Common/3dParty/hunspell/test/src/el_GR.txt b/Common/3dParty/hunspell/test/src/el_GR.txt new file mode 100644 index 00000000000..badd16854fe --- /dev/null +++ b/Common/3dParty/hunspell/test/src/el_GR.txt @@ -0,0 +1,123 @@ +Αβαντάζ +Αβασταγά +Αβγάτισες +αβέβαιο +αβέλτερο +αβέλτεροι +αβίαστους +άβλαβοι +αβοκάντο +αβράδιαστης +άβραστη +αβράχυντου +άβρεχτα +αβρή +αβρότης +άβυσσον +αγαθόν +αγαθούς +αγάλακτο +αγγούρι +αγελαδινού +αγέρα +αγεωμέτρητων +αγίνωτοι +άγκυρες +αγορεύσεις +αγόρευσή +αγορίνα +Αγοριού +Αγροληψία +Αρμόνια +βγαίνοντας +βεβαιώσεων +διάθεση +διαίρεση +Διαιρέσου +Διαιτολογίου +διαψεύσουν +διδασκάλισσας +ενασκήσεις +ενασχόληση +ενασχόλησή +ενδείξεις +ενδεχόμενον +ενδιαμέσου +Επιστήθιες +Επιστημο +Επιστολές +Επιστολή +εύπορους +ευρέα +ευρημάτων +ευρύτητά +ευσταθών +εύστροφα +ευσυνειδησία +εύτακτε +ευτελείς +ευτελίζουν +ιδρυτικό +ιεροψάλτες +Ιζόλα +Ιθαγένειάς +ικανότατος +ιλαρότης +κεφαλής +κεφαλιάτικες +κεφαλωτές +κήπε +κήπευση +Κήρυξής +Λεξικογραφιών +Λεξιλογικός +λεοντή +λεοντής +ολιγοχρόνιου +ολικέ +ολικές +ολική +πελαγώνω +πελατών +πελάων +προστατεύει +προστασίας +σούρουπου +σουρούπωμα +σούρτης +Σούρωνα +Σπαγέτα +Σφάλμα +Σφάλματά +σφικτά +σφικτέ +σφοδρότητας +σφοδρού +σφραγίσω +σχεδιάζουμε +σχεδιάζουν +σχηματίσου +σχηματίσουμε +σχολιάζεσαι +Σχολιάζεστε +Ενδιαφέροντα + +Слова с ошибками +Αβασiλευτου +αγαπούσαv +βeβαιωμένοι +εvασxόλησης +επιoτολικέ +ιδιωτικοποιήσειc +λεπταίσθnτη +πρoστιμάρισμα +σφάλμαtα +προστάτεuε +κεxριμπαριού +διαισθnτικότητες +αγκιστpώσουv +αγαθoεργiας +αβεβαιoτητά +αγέρεc +διδαxθούμε +εuσταθειώv \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_AU.txt b/Common/3dParty/hunspell/test/src/en_AU.txt new file mode 100644 index 00000000000..f9404bce0d3 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_AU.txt @@ -0,0 +1,116 @@ +Acknowledge +acrophobia +adventurousness +aeronautics +algal +Alligator +allegation +alphabetise +Analogy +appropriable +assembly +attempt +Average +barbecue +bathtub +begun +belongingness +Better +binary +blackberry +boatswain +bow-tie +brambly +bright-eyed +bubble +Calender +cancellous +cantankerousness +carefree +categorized +cellular +chaos +cheerfulise +childlike +circumstance +close-mouthed +Cocoa +coherent +co-located +Colours +controversial +cottage +creditworthiness +cut-down +dedicated +deep-freeze +Definitive +Designs +digital +distensible +dollar +dyslexia +Egyptian +effectively +etiquette +excess +exotica +fairly +feedback +features +figure's +fjord +forty-seven +government +haematomata +helpless +homologous +implant +Indemnify +inexpert +interior +localises +loquaciousness +maelstrom +mechanizable +melodious +mezzo-soprano +mozzie +municipalisation +mystifier +Neoclassicism +newsletter +non-professional +officiation +orientalisation +palaeoanthropography +parrot +pickpocket +pioneer +cryptanalytic +simplifying +sommelier +spicy +steward +subcontinental +swimwear +Technical +trajectory +wholesomeness +Advantageously +interindustry +red-eye +sub-group + +Слова с ошибками +Acredited +agressive +appreciativiness +aritmetical +biosyntesized +lisense +paranoa +fotoelectronic +semi transparent +synonymus +wordprocessing \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_CA.txt b/Common/3dParty/hunspell/test/src/en_CA.txt new file mode 100644 index 00000000000..f3bf6608a78 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_CA.txt @@ -0,0 +1,125 @@ +admire +admittance +aggrandizement +Airmen +Albatross +amateur +angling +apparatus +Architecture +assessment +attempt's +awakening +backgrounder +Balance's +barometric +bashfulness +beautiful +belletristic +blatancy +bonbon +border +Bottom +bountifulness +breakpoints +bulkiness +businesslike +can't +cash +castle +Casual +cauliflower +celebrity +childish +chokecherry +choreographically +chronological +classification +clearheaded +coalesce +Coexistence +collaborative +coloured's +concentration +draconian +drainpipe +demonstrativeness +dependence +dependency +dream +duplication +epidemiological +equitable +Essence +Exemption +exonerate +fainthearted +falsification +ferromagnetic +flammable +fraternization +French +frontier +gadget +galleria +Gallery +gateaux +geocache +ginger +glace +glacier +globalization +hockey +holiday +housemate +intensifier +joystick +Language +leaseholder +non-breakable +northerly +o'clock +oeuvre +openhandedness +oscillation +outface +outlaw +overladen +package +palazzo +panama +Paragraphs +Parliament +particular +pasteurization +pathogen +perception +phenomena +philanthropically +physical +populations +repugnance +request +resplendence +retroactive +rigidity +schedule's +School +scintillation +sensibility +settlement +taxiway +bereft + +Слова с ошибками +acomplishment +anihilate +caprise +chambre +etnographically +horsmanship +innundation +lemongras +omelete +retorical +shepishness \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_GB.txt b/Common/3dParty/hunspell/test/src/en_GB.txt new file mode 100644 index 00000000000..f50273dd01d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_GB.txt @@ -0,0 +1,122 @@ +Abbreviation +Acceptability +acquirable +Addressee +afterthought +airworthiness +all-powerful +amateurishness +amorphousness +anthology +Auspiciousness +Bibliographer +Bilberry +birthday +bodyguard +broadleaved +brontosaurus +bumptiousness +Cabaret +Californian +calumny +cancellation +cantonal +capitalize +careful +carry-on +casino +clown +co-ordinate +cockleshell +decennial +deckchair +decryption +deep-freeze +Democracy +financial +fish-plate +Flamenco +housing +Hybrid +hydroelectricity +iceboat +ichthyology +idiomatic +ill-humoured +imperatrix +individuality +interocular +intrasectoral +ironwoods +Jolliness +Jurisprudent +knowledgable +kopeks +labour-intensive +laboratory +lake +language +larynx +latching +leakiness +License +licensed +licensee +life-threatening +linguistics +long-lived +machinable +mainsheet +Major +malleability +man-hour +Mango +ninety-five +nobody +non-blocking +non-judicial +nonconforming +north-Western +nutritiousness +quasi-synchronous +question +racoon +radish +Railway +Rarity +saucer +Save +Saying +supplely +tallish +target +Taxi +teach-in +technician +ultramodern +umbrae +uncertainness +unconstitutionality +washing +wasn't +waxen +weather +well-formed +what's-his-name +whereupon +Wi-Fi +Wikipedia + +Слова с ошибками +Abstractnes +advantageusness +arhythmical +autosuggestibility +kaptor +coldshouldering +humaneneses +imaginativness +knight-erantry +magasine +night-wachman +qualifidly \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_US.txt b/Common/3dParty/hunspell/test/src/en_US.txt new file mode 100644 index 00000000000..a806686cdab --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_US.txt @@ -0,0 +1,213 @@ +apple +banana +cat +dog +egg +fish +gold +house +ice +juice +kite +lion +mouse +night +orange +pencil +queen +rabbit +sun +tea +umbrella +vase +watch +xylophone +yellow +zebra +arrow +book +cake +car +day +elephant +flower +hat +island +jelly +king +lamp +moon +nose +owl +pink +quilt +radio +sunflower +tree +unicorn +violin +water +xylophone +yellow +zoo +apple juice +blue +calculator +desk +elephant +fire +goat +hat +ice cream +jacket +key +lemon +map +notebook +owl +pear +quilt +rose +soccer +table +umbrella +vegetable +whale +xylophone +yellow +zebra +apple pie +beach +computer +drum +elephant +goat cheese +hat +ice skate +juice box +kite festival +lemonade +mountain +notebook paper +orange juice +pizza +queen bee +rainbow +snow +turtle +umbrella hat +valley +Aberration +Absolution +Acquiesce +Adumbrate +Aesthete +Altruistic +Ambivalent +Anomalous +Antediluvian +Antipathy +Aphorism +Apocryphal +Apostasy +Apparition +Arduous +Assiduous +Audacious +Austere +Autonomy +Avaricious +Axiomatic +Baleful +Bellicose +Belligerent +Bereft +Bilious +Bombastic +Cacophony +Capricious +Cartography +Castigate +Clandestine +Coalesce +Cogent +Cognizant +Colloquy +Concomitant +Confabulate +Congenial +Conundrum +Copious +Corpulent +Coven +Credulous +Culpable +Dearth +Debilitate +Deleterious +Denigrate +Despondent +Diatribe +Dilapidated +Disparage +Dissemble +Dissonance +Duplicity +Ebullient +Egregious +Ephemeral +Equanimity +Esoteric +Euphemism +Evanescent +Exacerbate +Exhort +Expatriate +Extol +Facetious +Fatuous +Feckless +Felicitous +Feral +Fervent +Fetter +Flummox +Fractious +Garrulous +Hegemony +Iconoclast +Idiosyncrasy +Ignominious +Impecunious +Ineffable +Inexorable +Inscrutable +Insidious +Intrepid +Intransigent +Invective +Irascible +Juxtapose +Kowtow +Languid +Lassitude +Lurid +Malinger +Maudlin +Mawkish +Mendacious +Metaphysical +Antransigent +Inwective +Iracible +Juxtopose +Kovtow +Langued +Lasitude +Larid +Mallinger +Haudlin +Mavkish +Mendocious +Mitaphysical + diff --git a/Common/3dParty/hunspell/test/src/en_ZA.txt b/Common/3dParty/hunspell/test/src/en_ZA.txt new file mode 100644 index 00000000000..f509809717c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_ZA.txt @@ -0,0 +1,114 @@ +Acceptably +Achievement +administrate +all-day +amount +average +bilayer +blasé +boutique +breezy +byers +cabdriver +carefree +categorised +Chameleon +cheerful +chronology +cliché +cooling-off +courage +crudités +decorates +dooryard +débâcle +electromotive +equalled +Exotica +fellow-traveller +forests +full-timer +graded +habitué +haven't +hide-and-seek +home-building +interaxial +kingdom +largeness +long-distance +Majority +manoeuvre +Matrix +metier +mightn't +multidisciplinary +night-time +officio +old-style +organize +overaggressive +packing +parenthesis +pince-nez +Plaint +play-act +policy-making +Preheat +prohibit +puzzle +queue +quite +re-enact +reason +ready-made +renewal +resize +rooihout +scampi +schoolteacher +sea-green +shop-boy +sidebar +skyscraper +soundless +spelling +stakeout +synchronizing +take-off +Thereof +Trademark +transportable +treatment +tweeness +under-age +unmake +Variate +Visitant +volume +webmaster +well-prepared +window +yesteryear +first-aid +Hydrant +inconstant +network +northernmost +nowhere +souvenir +telecommunicate + +Слова с ошибками +afordable +anthropologie +bagage +comparatif +flammeble +indivizible +jetlag +lettrebox +panoramma +posessor +selfdoubt +abandonner \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/es_ES.txt b/Common/3dParty/hunspell/test/src/es_ES.txt new file mode 100644 index 00000000000..05520c2d2f1 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/es_ES.txt @@ -0,0 +1,208 @@ +nosotros +vosotros +ellos +ellas +aquí +allí +ahora +antes +después +siempre +nunca +también +solamente +verdad +mentira +bien +mal +grande +pequeño +rápido +lento +nuevo +viejo +bueno +malo +feliz +triste +bonito +feo +caliente +frío +dulce +amargo +fuerte +débil +cerca +lejos +fácil +difícil +cierto +falso +caro +barato +limpio +sucio +fuerte +débil +alto +bajo +claro +oscuro +abierto +cerrado +joven +viejo +corto +largo +alegre +tranquilo +nervioso +amable +grosero +conocido +desconocido +cortés +rudo +agradable +desagradable +sabroso +insípido +difícil +fácil +cansado +descansado +moderno +antiguo +último +primero +posible +imposible +rápido +lento +sencillo +complicado +propio +ajeno +abierto +cerrado +amable +desagradable +seguro +inseguro +correcto +incorrecto +dulce +amargo +Anacoreta +Sobrentender +Embriaguez +Inquebrantable +Empedernido +Derramamiento +Despotricar +Escafandra +Aletargamiento +Estancamiento +Descarado +Exégesis +Contrariedad +Espeluznante +Conspiración +Impedimenta +Deglutir +Engreído +Enmascarado +Exterminio +Embelesar +Permutación +Desesperanza +Impenetrable +Enarbolamiento +Errabundo +Deslinde +Inefable +Soliviantar +Embriaguez +Perdurable +Opulencia +Trémulo +Desembolso +Empedernido +Anquilosar +Enigmático +Inquebrantable +Contrincante +Desmesurado +Vanagloriar +Exasperar +Desvanecer +Perpetuidad +Desbaratar +Ineficaz +Zozobra +Elucubración +Ineludible +Desgarramiento +Atestiguar +Encascarar +Desembozar +Irreverente +Soslayar +Despiadado +Embaucar +Moflete +Endilgar +Desfalco +Embelesamiento +Desestimar +Enajenación +Desavenencia +Inexorable +Atolladero +Egrégoro +Desafiar +Afable +Enervar +Belicoso +Enervar +Descacharrante +Entramado +Inigualable +Perplejidad +Descabellado +Diligencia +Enaltecimiento +Desvergonzado +Arrebato +Empatía +Endiosar +Peripecia +Desidia +Subversión +Desfachatado +Desfalco +Desvirtuar +Errático +Desahuciar +Envilecimiento +Empecinado +Estolidez +Despropósito +Engatusar +Culminante +Sobrentender +Enseñorear +Desacato +segguro +insseguro +correcto +incarrecto +dalce +amergo +Anasoreta +Sobrententter +Embreagues +Inquebranttable +Empidernedo + diff --git a/Common/3dParty/hunspell/test/src/eu_ES.txt b/Common/3dParty/hunspell/test/src/eu_ES.txt new file mode 100644 index 00000000000..9cbd124e59f --- /dev/null +++ b/Common/3dParty/hunspell/test/src/eu_ES.txt @@ -0,0 +1,132 @@ +Abantza +ñabar +abasto +abegikortasun +aberaskeria +aberetzar +abezedario +abialdi +Abiatzaile +abizari +Aboli +abonatu +absenta +absolutibo +accelerando +adabegitsu +adberbio +adiaka +adierazle +adierazkizun +adikuntza +adin +adinaro +adineratu +adin-txikitasun +administratzaile +adoleszentzia +adopzio +adostu +aerolabangailu +Aeroplano +afalordu +agente +agertezin +agiantza +agoran +arradatze +arrakasta +Batata +baterakuntza +baterakor +Bateri +batuar +baud-abiadura +batzuenganako +batzuengandik +batzuengan +batzuengatik +batzuen +baxera +berezi +berezikeria +beritzete +beroa +Beroate +beroatza +berorri +berrabiatu +berra +berresgarri +berripaper +chap +dabilzkidake +dabilzkie +dagitza +dagokik +dagozkieke +erdiondu +galdera +galtzada +garaitiar +garantia +Garaztaketa +garbitasun +gastronomiko +Gaurgero +gaurgoitik +legizkie +legokizue +legozkidake +lehenbizi +nindoakio +publikotasun +publizitate +subsidiario +substantibo +sugestio +superbalorazio +taidun +taldeburu +Talent +Teknografia +xantxa +xerbitor +xerokopia +zabaldura +Zabalkor +Zabaltza +zabilzkieken +zabilzkio +zaharkote +zeneritzeketen +zenerra +zenezagu +zengozkigute +zeniharduke +zenioke +zenioketez +zeniraute +zenizkien +zenizkiguke +Zintut +Zintuzkedan +isiltasun + +Слова с ошибками +abriсot +absenzia +addikzio +administraziozerbizu +bat-bates +bermagari +cataluniar +dakarza +erdemin +garatienetarikoa +ishil +nindezaguane +nintzainaken +summa +technologiko +charmant \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/fr_FR.txt b/Common/3dParty/hunspell/test/src/fr_FR.txt new file mode 100644 index 00000000000..5ab592e094c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/fr_FR.txt @@ -0,0 +1,211 @@ +Bonjour +Merci +Oui +Non +S'il +Excusez-moi +Pardon +Bien +Mal +Grosse +Petit +Beau +Moche +Fort +Faible +Chaud +Froid +Vite +Lent +Haut +Bas +Loin +Près +Heureux +Triste +Facile +Difficile +Simple +Compliqué +Bon +Mauvais +Nouveau +Vieux +Jeune +Âgé +Bienvenue +Amitié +Amour +Famille +Travail +Maison +Voiture +Manger +Boire +Courir +Marcher +Nager +Chanter +Dormir +Jouer +Parler +Écouter +Regarder +Lire +Écrire +Acheter +Vendre +Aller +Venir +Faire +Dire +Voir +Savoir +Apprendre +Aimer +Détester +Partir +Rester +Arriver +Revenir +Partager +Aider +Aimer +Ouvrir +Fermer +Manger +Boire +Avoir +Être +Pouvoir +Vouloir +Devoir +Parler +Écouter +Rire +Pleurer +Danse +Étudier +Travailler +Voyager +Vivre +Connaître +Reconnaître +Voyager +Exister +Choisir +Donner +Recevoir +Aimer +Oser +Phénoménologie +Électroencéphalographie +Parallélépipède +Anticonstitutionnellement +Transsubstantiation +Éclectisme +Anachronisme +Catéchuménat +Démagogie +Fructueux +Ineffable +Hypothèque +Propriété +Procrastination +Complaisance +Réminiscence +Éthique +Équinoxe +Exponentiel +Hétérogénéité +Imbroglio +Incorrigible +Maelström +Métaphysique +Protagoniste +Subliminal +Verrouillage +Volumétrique +Énigmatique +Époustouflant +Immatériel +Infini +Polyglotte +Recrudescence +Prophylactique +Symbiotique +Vestibulaire +Épistémologie +Faramineux +Géopolitique +Hypnotique +Inamovible +Intemporel +Labyrinthe +Pacifiste +Quémandeur +Soporifique +Ubuesque +Volumineux +Effervescence +Électrophorèse +Paradoxe +Prorata +Quadrupède +Sarcophage +Trigonométrie +Vaccinologie +Xenophobe +Zéphyr +Génétique +Labyrintique +Mégalo +Nostalgie +Omniprésent +Pangramme +Périlleux +Quinquennat +Rémunération +Scolopendre +Tautologique +Utopiste +Vexatoire +Wolof +Xanthine +Yacht +Zanzibar +Axiomatique +Chronométrer +Dilettante +Énervement +Facétieux +Générique +Harmonique +Illusoire +Juridique +Kabbaliste +Longetivité +Médiane +Néologisme +Oxygène +Patronymique +Quotidien +Rétorique +Sémantique +Tautologie +Utopique +Vaccinologie +Xénophobie +Yachting +Zoroastrisme +Voager +Exisster +Chaiser +Doner +Resevoir +Aimmer +Osero +Phénoménollogie +Électraencéphallographie +Parallélépepède + diff --git a/Common/3dParty/hunspell/test/src/gl_ES.txt b/Common/3dParty/hunspell/test/src/gl_ES.txt new file mode 100644 index 00000000000..1fa4436b773 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/gl_ES.txt @@ -0,0 +1,120 @@ +ola +tipo +Si +non +nonnr +comida +comidaa +auga +augaa +casa +coche +cochee +un tren +bicicleta +escola +escolaa +niños +pai +paii +nai +naii +irmá +irmán +cachorro +gato +gatoo +peixe +peixee +aves +avess +árbore +flor +herba +o sol +lúa +o ceo +chuvia +neve +vexa +inverno +primavera +outono +noite +noite +día +unha semana +mes +ano +para ler +escribir +fala +ensinar +traballo +durmir +durmir +correr +vai +senta +estado +para escoitar +vexa +escoita +hai +beber +carne +furtas +verduras +queixo +pan +auga +zume +café +té +leite +aceite +ovo +sal +impacienta +azucre +un bocadillo +cociña +sala de estar +dormitorio +baño +batela +sofá +lámpada +fiestra +a porta +piso +teito +parede +sofá +alfombra +baño +afundir +espello +toalla +cama +manta +almofada +reloxo de alarma +escritorio +cadeira +marabilloso +adverbio +obviamente +Dominante +residenciais +convidado +perigo +cuestión +deporte +mina +cordeiro +cabeza +tratar +avogado +intelixente +guapo diff --git a/Common/3dParty/hunspell/test/src/hr_HR.txt b/Common/3dParty/hunspell/test/src/hr_HR.txt new file mode 100644 index 00000000000..6fbcfb98f7c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/hr_HR.txt @@ -0,0 +1,215 @@ +boliestan +jyak +slaby +pameetan +gllup +bezuspješhno +besimeni +bezuzban +blagastanje +bljeskovica +jabuka +sunce +voda +kuća +ptica +kava +kruh +cvijet +knjiga +pas +mačka +grad +zelen +plav +crven +bijel +crn +velik +malen +brz +spor +sretan +tužan +vruć +hladan +nov +star +lijep +ružan +dobar +loš +zdrav +bolestan +jak +slab +pametan +glup +raditi +jesti +piti +spavati +čitati +pisati +govoriti +smijati se +plakati +pjevati +igrati +plesati +učiti se +kupovati +kuhati +telefonirati +gledati +slušati +hodati +trčati +letjeti +plivati +čitati +pisati +raditi +imati +biti +ići +doći +otići +dati +uzeti +reći +vidjeti +čuti +osjetiti +misliti +htjeti +moći +morati +rado +nerado +da +ne +molim +hvala +doviđenja +oprosti +zbogom +zdravo +čau +ej +da +baš +super +glupost +fantastično +jasno +tako +zapravo +možda +lako +teško +prozračnost +usplahirenost +neoblomivost +prezir +proigranost +uznemirenost +besprijekornost +besprizornost +nepredvidivost +beznadnost +promašenost +protivljenje +neizreciv +bezizlaznost +neuspjelost +zbunjenost +neodlučnost +protivština +nepovratnost +bezduhovitost +ravnodušnost +prolaznost +neobaveznost +bezbrižnost +nepovratnost +promašenost +neprepoznatljivost +neukrotivost +bezobzirnost +nevinost +nestalnost +nepostojanost +bezizlaznost +nepovratnost +prolaznost +neodgovornost +bezbrižnost +nevolja +nezadovoljstvo +prolaznost +bezuspješno +bezimeni +bezuzdan +blagostanje +bljeskavica +boren +carovnija +crpeža +dostojanstvo +duhovitost +egzaltacija +gorkoća +histerija +idila +ironija +izdaja +janjetina +kajanje +kavana +krhotina +ljepljivost +lukavstvo +magnutizam +melankolija +misticizam +naivnost +nelagoda +neraspoloženje +obmana +okrutnost +opojenost +prezir +propast +ravnodušnost +sjenka +skitnica +spletka +stid +sudbina +susret +sudbina +šapat +tišina +trepet +utopija +uzaludnost +veličanstvo +zaborav +zanesenost +zanos +zavjera +zbunjenost +zluradost +zloslutnost +žargon +žártva +šaptanje +čarobnost +dileme +hodočasće +lebdjeti +iznimka +preobilje +probuditi se +surov \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/hu_HU.txt b/Common/3dParty/hunspell/test/src/hu_HU.txt new file mode 100644 index 00000000000..aae52a65b73 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/hu_HU.txt @@ -0,0 +1,114 @@ +Szorzótábla +Réges-régen +normálméret +nemeslelkűség +mindegyik +milliós +Mikroflóra +Mezőgazdaságigép +meséskönyv +mennyiség +Memória +kártya +kuráre +Kurzor +jégkorong +jellemesség +Javak +irányzás +iromány +Inkluzíve +hűtőedény +hőmérséklet +hír +hétszázas +hátrány +háromszáz +Hintó +generátor +gavallérság +explozíva +eső +esdeklés +epilógus +Energia +Előélet +előterjesztés +előnézet +elvonás +elszigetelés +ellátmány +Elevátor +egynémelykor +egyenlőség +eddzenek +dzsungel +ananász +akvárium +Szépül +Sztorizik +szobroz +szimbolizál +szemlélődik +sugdolózik +majmol +Macskáz +Létesít +Lokalizálódik +litografál +levelesedik +lepet +közömbösít +kételkedik +kivirágoz +kerekez +kedvez +járkál +jegyzőkönyvez +iskolázik +individualizál +csendesít +borsoz +billentet +bajmolódik +anyagozik +alkonyodik +Aktualizál +színes +szemelt +lassú +hatékony +hasznos +gyúlékony +gyári +abszurd +örökjog +öregkor +ömlő +Zászlaj +Zseblámpa +regényirodalom +realitás +raktárhelyiség +pötty +pótlék +pótdíj +pályafutás +Promóció +Processzus +poloska +pernye +pediáter +parancsnoklás + +Слова с ошибками +sponzorálás +mihamarábiak +idohatár +hypnotizmus +departement +légiesul +kutagat +költségtakkarékos +redukzió +pilanatfelvétel \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/id_ID.txt b/Common/3dParty/hunspell/test/src/id_ID.txt new file mode 100644 index 00000000000..dff2ed986ef --- /dev/null +++ b/Common/3dParty/hunspell/test/src/id_ID.txt @@ -0,0 +1,121 @@ +acang-acang +Adiksi +Adventisius +Advokat +afirmatif +agroindustry +agrisilvikultur +akhir-akhir +akomodatif +aksi +aljabar +anggul +anotasi +antusiasme +apoteker +bahagia +bakat +bangkang +Bankir +Barikade +bebaru +belar +beleid +bencana +bentangur +beritawan +besuk +bilingualisme +Cecak +Celempong +cencawan +cengkar +ceremai +cermin +cudang +Dampal +dampan +dansa +datung +debitur +defensi +defisit +demper +dendang +Derivasi +Desember +deskripsi +diskotek +diskusi +distansi +dragon +dramatisasi +Eksamen +Eksistensi +eksperimen +ekstensifikasi +ekuitas +elektron +gelut +Geofisikawan +Gerbang +gerempang +influenza +Informasi +Inisiator +insekta +institusional +instruksional +jelajah +Kamrad +Kapilaritas +kapster +kardiovaskular +karismatik +keranjingan +komunal +Limitatif +Linguistik +lintang +masabodoh +matematikus +medisinal +Melankolia +Memorabilia +nasional +nasionisme +Panen +pangkek +peranti +perian +persekusi +perunjung +regenerasi +reglementer +robotika +runjang +Sabtu +Simbang +simpati +tebing +topi +Unggal +unsuri +urbanisasi +variabel +wahana +warganegara + +Слова с ошибками +Abonement +Abcente +ambivalan +bakteriostatic +cekaw +darmavisata +declarasi +duplex +ecozona +gempur-mengempur +jejengok +transitive \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/it_IT.txt b/Common/3dParty/hunspell/test/src/it_IT.txt new file mode 100644 index 00000000000..02852a870c7 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/it_IT.txt @@ -0,0 +1,200 @@ +Ciao +Ciaoo +Buongiorno +Buonasera +Buonassera +Grazie +Prego +Arrivederci +Buonanotte +Scusa +Per favore +Amore +Amico +Famiglia +Casa +Città +Strada +Montagna +Montaga +Mare +Sole +Luna +Stelle +Giorno +Notte +Colazione +Clazione +Pranzo +Cena +Acqua +Vino +Caffè +Pane +Formaggio +Pasta +Pizza +Gelato +Dolce +Salato +Frutta +Verdura +Carne +Pesce +Pollo +Uovo +Sale +Pepe +Olio +Burro +Zucchero +Latte +Yogurt +Insalata +Zuppa +Bistecca +Prosciutto +Parmigiano +Biscotti +Cioccolato +Spagggrhetti +Spaghetti +Lasagne +Risotto +Gnocchi +Penne +Ravioli +Cannelloni +Pesto +Caprese +Limoncello +Espresso +Cappuccino +Tiramisù +Panna cotta +Cannoli +Panettone +Brioche +Focaccia +Foacdccia +Crostini +Arancini +Antipasto +Primo piatto +Secondo piatto +Contorno +Pane tostato +Marmellata +Accoglienza +Affascinante +Aggressività +Alleviare +Appassionato +Armonioso +Autonomia +Autovfnomia +Barbarie +Beneficiare +Bizzarro +Burocrazia +Cambiamento +Capriccioso +Cautela +Commemorare +Comportamento +Conseguenza +Controverso +Coraggioso +Debolezza +Decisivo +Delizioso +Desiderare +Destrezza +Determinato +Determin +Difficoltà +Disponibilità +Divertimento +Eccentrico +Efficienza +Elettrizzante +Emergere +Empatia +Energia +Equilibrio +Esperienza +Fantastico +Fenomenale +Generosità +Gratitudine +Immaginazione +Impressionante +Impressiante +Indipendenza +Ingenuità +Innovazione +Intelligenza +Intensità +Intrigante +Ispirazione +Instabilità +Irresistibile +Leggenda +Libertà +Luminoso +Magistrale +Malinconia +Meraviglioso +Metamorfosi +Miracolo +Misterioso +Nostalgia +Opportunità +Originalità +Passione +Pericoloso +Prestigioso +Prodigioso +Prospettiva +Raffinato +Rafinato +Ricchezza +Rispettoso +Sensibilità +Sorprendente +Spontaneità +Spontaneita +Stravagante +Suggestivo +Surreale +Tenerezza +Trasformazione +Unicità +Vibrante +Vittoria +Volontà +Amicizia +Avventura +Bellezza +Calma +Danza +Eleganza +Felicità +Gioia +Incanto +Magia +Natura +Odore +Passatempo +Quotidiano +Relax +Serenità +Tesoro +Umorismo +Vacanza +Zelo +Avventuriero +Speranza +Risate +Armonia +Incanto diff --git a/Common/3dParty/hunspell/test/src/kk_KZ.txt b/Common/3dParty/hunspell/test/src/kk_KZ.txt new file mode 100644 index 00000000000..69010faa9b5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/kk_KZ.txt @@ -0,0 +1,209 @@ +сөз +адам +қала +тау +ауа +су +аспан +жер +бала +ата +ана +тамақ +кітап +ұстаз +оқу +тұтыну +тыныш +тұз +ауру +денсаулық +топ +маусым +төс +көз +жүрек +сарғыш +көп +аз +ертең +түн +түс +жас +қара +ақ +көк +қызыл +шай +салт +ыстық +суық +қазақ +жеті +он +жүз +мың +бір +екі +үш +төрт +бес +алты +жеті +сегіз +тоғыз +он +бақша +бұлақ +қиыр +досым +ақша +патша +таң +кеш +тауар +күн +апат +риза +ауырсыну +орман +жаңбыр +бауыр +жел +тұман +үй +бұлақ +көше +айнала +шайыр +тағам +сусын +топ +бас +әрекет +тіл +кеме +сиыр +қой +ешкі +шөп +ит +тұқым +қарындаш +апа +ана +әке +дала +тарлау +дәуір +таңдай +жыл +басқарушылар +басқарушшылар +жауапкер +ерекшеліктерімендерге +тұмылдырықтатқыздан +білімділігінге +білімдарды +алалықсыздар +айырмашылықтарын +тұрақтандырып +сылтауратқандарыңызды +қолдар +байланысқадан +жетілдірілген +зарарсыздандырады +ескеріп +ескеріпп +міндеттемелеріндерге +кезеңдердің +себепсіздік +біреудейлер +беделілерің +кездестіріңіз +шектердің +көңіл +көңл +мол +алайда +мәселе +мәселеу +сендің +келер +келерр +кәне +көпір +күндіз +сана +белгілер +дайын +ез +қайшы +саф +рең +шақ +үміткер +бақыт +бақытт +республика +консервациялау +мемлекеттік +тағатсыздан +адамда +бәрі +бең +беңр +жасағанда +жасағоанда +жабайылық +заманда +көшірдік +мерейі +Мерейій +мөлшерсіздікк +мөлшерсіздік +пенді +тылда +мәртебесімен +аппаратпен +тегінді +кездеме +ересектік +көңілсіздік +тәуекелсіздік +қанағатсыздық +ғаділетсіздік +сайдақы +басым +тәжікеден +тұрғын +қонақ +қауіпсіздік +қадірсіздік +білгішсінбейсіңдер +талқандас +кешікті +қоздырғышы +бас +емдейсіңдер +құқылы +тақылет +әдемі +көткеншектейсіңдер +әжет +қайтар +белсену +түсінбеймін +жағымсыздық +сыздар +мәртебесі +тұрғыны +мезгіл +әлбетте +барысын +оқылған +безге +жаса +аламаңдайсыңдар +кереметті +епетейсіздік diff --git a/Common/3dParty/hunspell/test/src/ko_KR.txt b/Common/3dParty/hunspell/test/src/ko_KR.txt new file mode 100644 index 00000000000..3ef2abd2ce5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ko_KR.txt @@ -0,0 +1,157 @@ +안녕하세요 +감사합니다 +사랑해요 +미안합니다 +음식 +친구 +가방 +집 +학교 +컴퓨터 +물 +밥 +책 +산 +바다 +날씨 +일 +노래 +치킨 +반찬 +꽃 +숙제 +가족 +아이 +게임 +영화 +생일 +시간 +동물 +여행 +차 +쇼핑 +추천 +대화 +전화 +사진 +운동 +잠 +병원 +음료수 +능력 +주말 +전자기기 +고양이 +강아지 +바나나 +가을 +겨울 +봄 +여름 +옷 +신발 +지하철 +택시 +버스 +비행기 +샴푸 +브러시 +삼계탕 +국수 +불고기 +된장 +김치 +먹다 +마시다 +보다 +듣다 +놀다 +하다 +가다 +오다 +서다 +늦다 +일어나다 +자다 +빨갛다 +파랗다 +노랗다 +녹색 +보라색 +맛있다 +시원하다 +덥다 +추운 +기분 +슬프다 +즐겁다 +정신이 +바쁘다 +참새 +나비 +병아리 +돌 +물고기 +향신료 +시장 +기차 +공원 +해변 +지갑 +병원 +대학 +교통 +공항 +천재 +연구 +일본 +중국 +사업 +지식 +성격 +자금 +기술 +정부 +전략 +협력 +혁신 +경제 +철학 +신체 +영감 +현상 +역사 +태양 +설명 +사회 +환경 +자연 +현실 +존경 +정확 +장애 +낙관 +발전 +절망 +일상 +소멸 +도전 +반복 +포기 +파괴 +혁혹 +소외 +식민지 +혐오 +출산 +행복 +불평 +판매 +위험 +안녕하ㅎ요 +감사합ㅅ다 +사랑ㄱ해요 +미안ㅎ합니다 +친ㅔ구 +가ㅎ방 + diff --git a/Common/3dParty/hunspell/test/src/lb_LU.txt b/Common/3dParty/hunspell/test/src/lb_LU.txt new file mode 100644 index 00000000000..e7dd0e3d594 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lb_LU.txt @@ -0,0 +1,118 @@ +Aarbecht +Aarbechtszäitorganisatioun +Aartgenoss +Abenteuer +abrëll +absence +Abusives +Abzebillercher +Acquéreur +Adjointeë +Affischéiertes +Airbussen +Alldeegleches +Angschtzoustä +Basketballspiller +Baufirme +bauren +bekanntes +Beleg +Berodung +Bewältegung +Datentransfer +Dateschutz +Decisives +Donneschden +Drangsaléiertes +Dränk +Giischtgen +Grondlag +grondreegel +Géies +Handelsdag +hausaufgab +hierschtdag +Häerzi +Industriell +Infrastrukturelles +Interessi +Internetfore +Intervall +Kamell +Kantoner +Karamell +Klenges +Nopeschhaus +Motors +Muer +Muerenter +Musek +Nettoverméige +niess +Protektioun +Prouf +Provisioun +Prozessor +Präis +Präsens +Sanitäres +Schauspiller +Schema +Taxatioun +Telefonsgespréich +termingrë +terrass +Textdatei +Textsprooch +Titulaire +Titel +erausféieren +erausjoe +gëeicht +onglécklecherweis +unzesammelen +unzespille +Approvisionnement + +Сложные слова +Aktiegesellschaft +Aktivitéitsdéclaratioun +Alarmstëmmung +Allgemengverständleches +Bankenoperatioun +Bensinsreserven +Besteierungsofkommes +Diskriminéierungsmoossnam +Dokumentatiounsaarbecht +Haaptrecommandatioun +Héchstgeschwindegkeet +Héichproblematesches +Hëllefsdéngscht +Integratiounsméisseges +Iwwersetzungsprogramm +Kapitaliséierungsdimensioun +Museksinstrument +Publicitéitsmarché +Transportproblem + +Слова с ошибками +Abonnnement +Accomodéiertes +Agrarcenter +Begrennung +Berodunszentren +Deeluung +Dialogue +Dictaten +Inspektor +Iwereileges +Pedagogik +Televisionschaîn +Bechäftegungsméiglechkeet +Gläicheetspolitik +Musekheichschoul +Satelliten +Addressbichelchen +Aarbechtsfield + + diff --git a/Common/3dParty/hunspell/test/src/lt_LT.txt b/Common/3dParty/hunspell/test/src/lt_LT.txt new file mode 100644 index 00000000000..1f04ae6ce1d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lt_LT.txt @@ -0,0 +1,127 @@ +Abstraktus +šachmatai +žadintoja +agurkas +Aikštė +Akinukai +akmuo +šakoti +aktualinti +aktorius +šalinis +šaltinis +bernystė +beskuo +būgnelis +Bilietas +bilingvizmas +daržavietė +Darbadienis +Darbas +darbuotoja +dargi +daržinė +daugintoja +Daugiaveiksmis +delnė +įdelnis +detalizuoti +šerdelė +erdvėti +šeriškas +šeštadienis +etiketas +Evoliucija +fabrikantė +Fantastika +Fenomenas +fikusas +gaudinėti +gausėja +gūbrinti +geležis +geležtė +gelsvis +geranoris +Gertys +gerviukas +giesmininkė +Gikas +Goža +griaustinis +grįžinys +gėrioja +griozdas +grizijo +gryčia +grožėja +grįžti +grupė +gąstauti +Jaukas +jodinėjo +jodyti +keturnagis +Kiaušina +Kiaurymė +kiausta +kietakaktis +ūkiškas +kilimėlis +kilometrinis +ūkininkaitė +ūkinis +krykti +lapuotis +laukas +laupti +laužtė +Maudulys +Maumedis +mažutėlis +mazgotuvė +mechanikė +medeinė +medikamentinis +meduolinis +Nūdien +nebrendėlė +Negu +neiginys +parudenys +pasakotojas +pasausė +pasieninis +paskyriui +paslapčiom +Pasodas +Pat +Pataikūniškas +patarška +patentinis +proskyna +protekiniais +provizoriškas +rėkčioti +rūmas +rodyklinis +Romanistas +Skylmatis +Skyriklis +skolininkas +skraidžioja +skruzdėda +skėtrus + +Слова с ошибками +Abbreviatūra +alpinismas +amortizacia +daugiamžis +deziderativinis +generazija +keturiasdešimtūkstantas +krivuluoja +Šnaukstai +pazintinis +progresa \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/lv_LV.txt b/Common/3dParty/hunspell/test/src/lv_LV.txt new file mode 100644 index 00000000000..51984047594 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lv_LV.txt @@ -0,0 +1,205 @@ +Sveiks +Sveikks +Labrīt +Lbrīt +Paldies +Paldiess +Lūdzu +Luzu +Atvainojiet +Atvainvfojiet +Prieks +Perieks +Draugs +Dravfugs +Ģimene +Gimene +Māja +Maja +Pilsēta +Pilseta +Ceļš +Ceļšs +Kalns +Jūra +Sauls +Mēness +Zvaigznes +Diena +Nakts +Brokastis +Pusdienas +Vakariņas +Vīns +Kafija +Maize +Siers +Makaroni +Pica +Saldējums +Deserts +Sāļš +Augļi +Dārzeņi +Gaļa +Zivis +Vistas +Ola +Sāls +Pipari +Eļļa +Sviests +Cukurs +Piens +Jogurts +Salāti +Zupa +Salds +Šokolāde +Spageti +Rīsi +Kakao +Biezpiens +Kūka +Tēja +Karalis +Zelts +Ezis +Tulpe +Lācis +Kaķis +Suns +Putns +Vārna +Zaķis +Pele +Ābols +Aita +Zirgs +Lauva +Pūķis +Lasis +Vilks +Vējš +Uguns +Ūdens +Zeme +Debesis +Saule +Rūpniecība +Aizkustinošs +Izdzīvošana +Nepieciešamība +Atbildība +Lieliski +Apmierināts +Neparasts +Izglītība +Sarežģīts +Atsevišķs +Pamatots +Organizācija +Sadarbība +Efektīvs +Daudzveidīgs +Novērtēt +Pārsteidzošs +Inovatīvs +Vērtība +Aizraujošs +Nopietns +Komunikācija +Māksla +Dzīvība +Ekskluzīvs +Tehnoloģijas +Rezultāts +Atbalsts +Nodrošinātība +Pārbaudīt +Radošs +Sociāls +Izteiksmīgs +Brīvība +Pieredze +Ietekme +Pārmaiņas +Drosmīgs +Racionāls +Empātija +Izpratne +Risinājums +Iespējas +Atklāts +Vadošais +Eksperimentāls +Neatkarība +Tīrība +Samierināšanās +Motivācija +Harmonija +Dinamisks +Iedvesma +Izglītojošs +Komplicēts +Pieejamība +Sadarbība +Tūlītējs +Saprotams +Neizsakāms +Lieliskums +Inovācijas +Aizrautība +Pārdomas +Sapratne +Rezultatīvs +Iespējams +Pārbaude +Sociālais +Izteiksme +Brīvība +Pieredzējis +Ietekmīgs +Pārmaiņu +Racionāla +Izpratni +Risinājumi +Iespējams +Atklāta +Vadošā +Eksperimentāla +Neatkarība +Tīra +Motivējošs +Harmonisks +Dinamika +Iedvesmojošs +Spēks +Mīlestība +Pasaule +Daba +Skaistums +Miers +Sapnis +Prieks +Rītausma +Brīnums +Izcils +Saikne +Dzirksts +Pārmaiņas +Atbalsts +Izcilība +Satriecošs +Dzīvīgums +Pārveidošana +Uzdrīkstēšanās +Uzticamība +Ieguldījums +Vērtība +Līdzsvars +Saskaņa +Izsmalcinātība +Pateicība +Atzinība +Pārsteigums diff --git a/Common/3dParty/hunspell/test/src/mn_MN.txt b/Common/3dParty/hunspell/test/src/mn_MN.txt new file mode 100644 index 00000000000..ac86b087ab0 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/mn_MN.txt @@ -0,0 +1,103 @@ +Баатар +Багаа +Базар +Барра +Бат-Очир +Баттуул +Батхэсэн +Баярмаа +Билгэх +Бор +Бөөнцагаан +Бүрэнхайрхан +Бямбагар +Бэх +Гарам +Гантиг +Гурвантэс +Гүр +Гэрэлтуяа +Давст +Дангаа +Дансран +Дарь-Эх +Дөргөн +Дундбүрд +Дэмүүл +Дэлгэрцэцэг +Жавзан +Жарантай +Заглул +Зүүнхөвөө +Кир +Корона +Лүн +Лха +Лхаваан +Майхан +Манлай +Мөндөөхөө +Мөнхөт +Мөрөн +Мөнххаан +Мөст +Мэгэд +Мухар +Найдалмаа +Найтингейл +Налайх +Нарантуул +Намтай +Насантогтох +Номин +Нямсамбуу +Нэүдэй +Орог +Очир +Өнөржаргал +Өөдөс +Өргөн +Паган +Пас +Пүрэвдорж +Пүрэвхүү +Сайнаа +Сайхандулаан +Сундуй +Сэлх +Сүүж +Сээр +Тайван +Тарав +Тогтуун +Төрболд +Төхөм +Төмөр +Түргэн +Түшиг +Түгтөмөр +Түшиг +Удвал +Улиастай +Улаандэл +гүедэцгээчих +дэвхэрлүүлсхийчих +дэвхэлцгээчих +дэвшигдүүлгэчих +дэвшилцчих +дэвээ +дэггүйчүүд +наламгардуулалц +налбаруулзна + +Слова с ошибками +Батарчулуун +Баруунхарааа +Даважаргал +Дөрволжин +Мягмараран +Оюунтулхуур +оторчилсхилгэ +Асрамжлулгацгаачих +гүентүүлгэцгэээ +наладаадуулга \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nb_NO.txt b/Common/3dParty/hunspell/test/src/nb_NO.txt new file mode 100644 index 00000000000..7218490a618 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nb_NO.txt @@ -0,0 +1,113 @@ +Bahamasøyene +Festarrangement +Festarrangemang +Festival +festligheta +festnummer +forhandlernett +forgylle +fotballstyre +Fotgå +fotoamatørene +Fotogalleri +fotokopiere +generalkostnadene +generaltabbe +generøs +Generell +genmodifisertst +handlingsresymeet +hardhet +Harmfull +hastighetsregulering +havbanke +havforskningsundersøkelsene +informasjonsutveksling +Infrarødest +kaffeautomat +kaldslig +kalenderåra +kjekk +kjendisstoffa +kjærlighetslyrikk +kjøkken +Kontantautomat +kontantlån +kontrahere +kontraheringsplikt +Låskasse +læregutt +læreprosess +Museums +museumssamling +musikkorps +myggstikka +myndighetsaldere +omløpstider +omregn +områdeplan +omriss +omsetningsgjeld +omsjaltning +omsetningsvolumer +omslutning +omslyngning +omsonst +omstendeligheta +Omstart +Omstreifende +Omsyn +omtåketheta +oppdagelse +oppbygning +oppebære +oppfølgingsapparat +oppgjørsbank +oppgjørsblankett +opphøringene +partisipere +randverdi +rapportskriver +rasjonalisering +Rate +selsak +selskapsinntekt +selskapsoverskudd +selvbetjeningene +snabbingene +Snadderene +Sytti +søkekriterium +søkemulighetene +søkeargumenter +søkingen +søkne +sølvlaga +sørlandsk +søtningene +tabellrad +Tabellkolonne +Takhalm +taksene +takseringssystema +tal +trolsk +trosinnholdene +utfoldelsesmuligheta +Utformingsmetode +Utgift +vekstfaktor +vekstforhold + +Слова с ошибками +Arbeidstagerorganisasion +festsprel +forhandlingsdirektor +handlingforløpa +kjempeflinktt +lanetilbud +omraming +omsvøpssfull +raportmateriale +serstilt +taksamst \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nl_NL.txt b/Common/3dParty/hunspell/test/src/nl_NL.txt new file mode 100644 index 00000000000..3efaf4df406 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nl_NL.txt @@ -0,0 +1,115 @@ +Advertentie +Advocate +affirmatie +afgevaardigd +afneemster +allerbekendst +alternatieveling +annulering +anticycloon +Backtrackroute +Bearbeiden +becijfer +bediening +bedrag +beduiden +beïnvloeding +benadeling +bepaaldelijk +Catalogiseer +Catering +cellulair +classificator +collaboreren +collectiviteit +comfortabel +complimenteus +contractant +correctionaliseren +daaraanvolgend +dagelijks +deelgenoot +degelijkheid +demarqueren +Denotative +deposant +dergelijken +detail +deugen +diakritisch +Directioneel +dusgenaamd +eendrachtigheid +Eenzaamheid +eersteklascoupé +Eigenschap +felicitatietelegram +centerkanaal +Chargeer +filiaal +klare +Klassikaal +kleinhandel +evolutie +exemplaar +exequiën +familiaal +fauteuil +luister +magistratelijk +perelaar +Permitteren +Perseveratie +persoonlijk +pictogram +pixel +sloten +sluimer +sneltoets +Soldij +Solliciteren +zegepraal +zelfbeeld +zevendaags +aangeslotene +meermaals +expedieert +jaargetijden +kaderleden +Kapitelen + +Сложные слова +avontuurlijkheid +bedrijfsmaatschappelijk +begrotingstechnisch +belangstellingssfeer +concurrentievoordeel +conferentieganger +democratisch-liberaal +discontoverhoging +doctoraatsverhandeling +dubbeldeksbus +economisch-financieel +energiezuinig +erkentelijkheid +evenwichtigheid +klimaatsverandering +koffiezetmachine +koopmansgebruik +maatschapsovereenkomst +personeelsconsulent +sociaalwetenschappelijk +zelfverzekerdheid +fondsenwervende + +Слова с ошибками +afficher +algorithme +beeindiging +client +consnteren +deactivieren +deblockering +electrisch +certificat +sovereiniteit \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nn_NO.txt b/Common/3dParty/hunspell/test/src/nn_NO.txt new file mode 100644 index 00000000000..6c0c1b48bc9 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nn_NO.txt @@ -0,0 +1,116 @@ +Ankeret +Anleggsbedrift +Annandag +annonseavis +annuell +ansats +ansvarsmedviten +Antibiotikai +apal +apoteki +apparattavlor +appetitt +Aprikos +arbeidsdokument +arbeidsmarknad +barndom +bastematte +bautingi +Bedriftsleiar +befolkningi +begynnarkurs +Beheld +belastningi +beredskapsnivå +beredskapsperiode +berglandskapi +berrfrost +beskjedi +beskrivingi +betalingsoppdrag +betalingsplikt +bevismateriale +bildeband +bildebruki +bildespråki +bildeteksti +bilingval +billettlukone +binær +bione +bjørkegreini +bjørnebæri +blenge +blokkeringi +blomsterbordi +blyerts +bogen +bokstavrekningi +bokstavteikni +Borddisk +effektevaluering +elgkalv +Elone +emballer +faktainformasjon +familiebedrifti +familieterapeut +fastbuande +Februar +feili +fisketom +hengelåsi +istandsetjingi +Item +jaguar +jamlig +janen +jarnbanestasjon +kjende +kjentfolki +kjæleri +kjøledisk +kjørety +midli +Mideftnar +midtstrek +multiplikasjonstabell +museumsdirektør +onsdag +operasjon +operasjonskode +opinionsskapingi +opningi +Personalkonsulent +Personligdom +persontryggleik +petroleumspris +redningsaksjon +reduksjon +refusnik +seinst +sekretær +seljande +sendeferd +Standpunkt +støyisolering +støytvis +terminoppgåve +tidløysone +tidsfølgjone +Tilbakebetalingstid +uprofesjonell +upåklageleg + +Слова с ошибками +Anlegsarbeid +anonse +ansversproblematikk +barneforteling +besoksliste +bilophoggingi +effektivitetskontrol +fakturaerklering +miljøbyrad +selskapskat +cement \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/oc_FR.txt b/Common/3dParty/hunspell/test/src/oc_FR.txt new file mode 100644 index 00000000000..23c82dafd0d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/oc_FR.txt @@ -0,0 +1,108 @@ +Ajustaira +alaguiar +alausièr +alberguèri +alcaloïdic +alègrament +alenament +algorisme +Alimentacion +allergologia +alpèstra +amaisament +amorteirar +analista +analogic +atucament +Audicion +auquièr +auscultacion +auscultar +ausèri +autenticament +brilhant +brumós +Burgada +cabelièira +cadeçar +Caducèu +çaicontra +calcièrs +Calmar +camarilha +cambièra +canalhariá +casse +cedar +cendrós +cèrca +cèrtes +cestòdes +chantièr +chartrós +Chassís +dimensionar +diptèrs +dirèctament +discrecionària +discriminar +Distraire +dòler +Enòrme +enqueriái +espicifòrme +esquelèt +Esquèrra +estetic +innocéncia +innocentàs +Maniquèu +mantelejar +Nauchièr +natièr +oxigèn +pacanariá +pagés +pagesiá +Primièirament +requereguèri +requisitòria +saumelèri +S'autodeterminar +sautarèl +scientament +scientologia +secador +secretèri +sècta +sectorial +s'efarcimar +s'endeven +s'engarrar +sentimental +s'entrepausar +shampó +sextant +sòli +Solidament +soquèla +subrejornada +suedés +utilitària +Utilizaire +vacàs +vaisselèri +valiái +validament + +Слова с ошибками +albatros +amistanza +brunonièr +carpentier +centrifugation +estelhad +primaria +s'embractar +sosembrançament +vascularisacion \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pl_PL.txt b/Common/3dParty/hunspell/test/src/pl_PL.txt new file mode 100644 index 00000000000..81c4afafce5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pl_PL.txt @@ -0,0 +1,225 @@ +dom +pies +kot +auto +drzewo +książka +szkoła +przyjaciel +mama +tata +dziecko +jabłko +czekolada +kawa +herbata +telefon +telewizor +komputer +muzyka +sport +zdrowie +piękno +praca +miłość +szczęście +czas +pieniądze +język +kraj +miasto +zima +lato +jesień +wiosna +morze +góry +jezioro +rzeka +park +zwierzę +ptak +ryba +drewno +złoto +srebro +metal +szkło +buty +sukienka +spodnie +koszula +czapka +płaszcz +ręka +noga +oko +ucho +nos +usta +ząb +głowa +serce +mózg +król +królowa +książę +księżniczka +chłopak +dziewczyna +mężczyzna +kobieta +staruszek +staruszka +lekarz +pielęgniarka +nauczyciel +uczennica +student +studentka +kucharz +kelner +wojna +pokój +mapa +flaga +śmiech +płacz +sen +marzenie +praca +nauka +sztuka +teatr +kino +muzeum +kaplica +kościół +zamek +most +droga + +Сложные слова на польском языке + +1. konstantynopolitańczykowianeczka +2. niezadogłębienieńskujący +3. antykontraatakujący +4. supersamoobsługiwalnymi +5. rozpierduchlanoculka +6. nieodezwawiałobyś +7. przystawieniowy +8. nieprzeżyciowakościami +9. nieprzekazywających +10. przeciwzakwaszeniowych +11. nieszczęściodrapańskiego +12. społeczno-wychowawczyniami +13. seledynowo-fioletowymi +14. przeciwdeszczową +15. mikroelektroniczno-kwalitacyjną +16. nieokreślonościowo-losowo-obiektywnie +17. zagubieniecioburakowatej +18. antyneuroleptyzanckim +19. nieupubliczniającymi +20. splądrowałbyś +21. konserwowano-spożywczymi +22. ożelośćiowo-miłosnej +23. nieprzyzwoitolicjią +24. nieodporowościę +25. rzeszołkofiołkowatymi +26. niezakapiactwuja +27. nieoszczędniewczelnianków +28. przekształconowaczkołępów +29. rozwińczywianiu +30. nieprzeskakiwalnościami +31. modernizująco-rewolucyjnego +32. nadzwyczajnieuzdolnionymi +33. przemocno-wsparciański +34. przepyszno-peltzerowskiego +35. kwestionowano-wzmocnieniami +36. nieodczynieństwującą +37. niezasłużonowypasionego +38. likwidującego/zarządzającego +39. szeszcześtoplutowanych +40. niewpadkowościowi +41. antynazizhownemu +42. nieuchronnieprzekroczeniowym +43. niezatrawialnieprzyjemnego +44. kardiopulmonologiczno-angiologów +45. gorączkowointensywnościowego +46. antykonstytucyjnorozpadowego +47. nieobawiamysię/źródleni +48. prerewolucyjnolphillipsowi +49. szóstkaniewygranych +50. nieupadkokogeneracyjnymi +51. społeczno-humanitarnarządzaniami +52. nieodziewowiędzy +53. przemocnochamować +54. społecznosensacyjnosądowym +55. przerażającorzymskiego +56. nieprzemontowanych/zamuzowych +57. referendumkonstytucyjno-reformujące +58. niezniesłowiałszymi +59. niebohaterystycznymi +60. produktodenarodowomenopauzalem +61. odrywającopierdolca +62. niegotowożywione +63. niepostronnynarodzonemu +64. przedniaautochtonicznym +65. nadciągniono-wchodzących +66. promocjostworczym +67. niezapowiadającychkoalicji +68. bezgłupinczłapie +69. wyomjaził +70. wagotonizacyjno-radiofonizowanego +71. gospodarczo-zasadotwórczej +72. skrupulatno-rzeźniczobardziej +73. samokiedy-konstytucyjnej +74. niedomętnością +75. nieoszustamiwykorzystana +76. przeprowadzonoświeckie +77. nieuniknionaobowiązkowo-plastycznej +78. poduszkowo-nicościowych +79. niepowodzeńbutmizeryjewego +80. skojarzeniowocolorowymi +81. przytułkamiwciągarkowych +82. wchodziłoprzeciwniepowszechny +83. karaublicznociągana +84. przedpolitycznilubelskim +85. niezapowiedziano-date-expanded +86. licznościłodziennej +87. niezawinieniomatołek +88. pakujączwobilardowego +89. rewersdopisek +90. przeprosinoworadosną +91. nieakceptacyjnoprospekcyjnymi +92. jedniżużytym +93. ainikopciksemilitechnikowany +94. motszynopiszącym +95. nieprzerejestrowanasezonowanie +96. słupotartackimoblikiem +97. nieodbieraniemniedostępności +98. dorozwinięcówkobiet +99. szybopojabytesłowickiego +100. przystępnoracjmujacych + +Слова с ошибками + +jedniiżużytym + +wiomjaził + +niezzniesłoowiałszymi + +superrsammoobsługiwalnymi + +przemoocnochamować + +staruszzka + +tiatr + +woina + +teleffon + +zołoto \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pt_BR.txt b/Common/3dParty/hunspell/test/src/pt_BR.txt new file mode 100644 index 00000000000..6f39dbef644 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pt_BR.txt @@ -0,0 +1,108 @@ +que +eu +não +de +você +para +ele +se +é +um +sim +por +isso +em +uma +uuma +está +como +com +bem +na +me +mas +do +era +quando +então +tudo +tydo +aqui +disse +estava +esâtava +lá +fazer +vai +sobre +vamos +homem +hollmem +bom +ok +agora +coisa +coissa +quero +foi +meu +seu +só +eles +as +posso +pocso +estou +mais +mim +certo +dizer +dizdizerr +os +no +sei +ela +vocês +sua +todos +sabe +minha +alguma +algyyma +casa +muito +oh +quallquer +qualquer +da +estamos +até +onde +onede +ao +tenho +nós +tem +tinha +tiinha +quê +ir +ou +pode +quer +vou +seus +dia +estão +nos +cabeça +quem +anos +depois +sou +vez +vá +fez +irmão +câmera +câmeara \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pt_PT.txt b/Common/3dParty/hunspell/test/src/pt_PT.txt new file mode 100644 index 00000000000..ed038092d09 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pt_PT.txt @@ -0,0 +1,135 @@ +pan +manteiga +menteiga +queijo +salchichón +saуlchichón +óleo +pimenta +pimmenta +sal +baga +mel +geléia +cogumelo +cebola +cóbola +banana +cenoura +pêra +beterraba +frutas +melão +melancia +bolo +chocolate +carne +batatas +salada +salóda +tomate +pepino +pipino +col +mingau +sopa +sanduíche +refrigerante +refrigarante +água +café +chá +leite +suco +scuco +maçã +uvas +laranja +abacaxi +adacaxi +damasco +demasco +açucar +arroz +macarrão +res +porco +frango +costeleta +cãsteleta +limão +ervilha +pão +peixe +caramelo +sorvete +nogueira +ovo +pêssego +xícara +xíícara +vidro +prato +colher +garfo +faca +pires +garrafa +guardanapo +café da manhã +almoço +jantar +avião +carro +bonde +ônibus +trem +bicicleta +janeiro +fevereiro +fevíreiro +março +abril +maio +junho +julho +agosto +setembro +setembra +outubro +novembro +dezembro +desembro +caneta +livro +xadrez +telefone +relógio +pente +televisão +ferro +sabão +rádio +bolsa +cartão +mala +presente +câmera +computador +camputador +filme +flor +vaso +quadro +lenço +bola +balão +brinquedo +brinqueedo +conta +sobre +papel +pepel +jornal +letra +bilhete \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/ro_RO.txt b/Common/3dParty/hunspell/test/src/ro_RO.txt new file mode 100644 index 00000000000..2cd141c9418 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ro_RO.txt @@ -0,0 +1,210 @@ +casă +copil +carte +masă +școală +lumină +apă +munte +soare +lună +pâine +fruct +floare +stradă +mașină +aer +timp +zi +noapte +nor +vânt +ochi +gură +nas +mână +picior +inimă +sânge +cap +ureche +voce +melodie +culoare +formă +linie +cerc +dreptunghi +cercetare +știință +limbă +frază +literă +cifră +număr +sunet +zgomot +telefon +internet +computer +program +ecran +tastatură +mouse +joc +sport +muzică +artă +film +televizor +radio +planetă +stea +univers +galaxie +atom +moleculă +substanță +energie +lumină +căldură +frig +aparat +instrument +mașinărie +unelte +hrană +băutură +haine +pantofi +păr +piele +ochelari +ceas +bijuterie +pământ +apă +aer +foc +metal +lemn +piatră +hârtie +cerneală +pix +carte +cadru +tablou +sculptură +model +formă +anticonstituționalitate +dezvoltare +inexpugnabil +nefast +concomitent +antiseptic +recalcitrant +perseverență +extravagant +inexorabil +colosal +plauzibil +efervescent +perspicacitate +superfluu +subversiv +incoruptibil +inefabil +hiperbolic +indefectibil +peremptoriu +ambivalent +paradoxal +heterogen +indiferent +periferic +subliminal +ultraviolet +indeferent +conglomerație +circumstanțial +contraproducător +conglomerat +insurmontabil +intransigent +insidios +inerent +consternant +ambiguitate +inerție +inconsolabil +oniric +remarcabil +repudiat +subiectiv +periculos +infatigabil +abnegare +exuberant +facet +represiune +implacabil +indiferent +infatigabil +insolit +intempestiv +incandescent +letargic +magistral +magnanim +nefast +oblivial +oportun +periculos +plutitor +propice +reprobabil +risipitor +robust +salutar +simetric +solicitant +stringent +sufocant +superficial +tranzitoriu +tributar +trivial +umilitor +unic +vehement +vernal +vicios +victorios +vindicativ +virtuos +vizibil +volatil +vorace +vulnerabil +xenofob +xerofil +yonder +yang +yodel +zonal +zodiac +zoon +zoomorf +zurbagiu +Caaă +Soaare +Cartr +Appă +Coopil +Frumoss +Feriсire +Prietenn +Muziică +Exeplu diff --git a/Common/3dParty/hunspell/test/src/ru_RU.txt b/Common/3dParty/hunspell/test/src/ru_RU.txt new file mode 100644 index 00000000000..28d99377fcf --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ru_RU.txt @@ -0,0 +1,197 @@ +должен +доллжен +наш +думаю +думмаю +свою +сам +всем +ни +нас +пока +этом +этой +ваша +всеми +возьми +моей +сама +вся +день +само +всей +бывает +себе +пойду +куда +ими +твоей +всю +своего +твой +пусть +ним +про +точно +иметь +которые +тогда +сюда +наше +самой +взять +наверное +домой +совсем +те +тобой +наверно +что-то +будто +твои +пути +дома +такие +тех +такое +его +самой +вашей +наверное +мои +например +типа +значит +люблю +минут +пор +случае +искусство +лучше +того +такому +ждать +видеть +мною +ждал +имя +важно +чего-то +самому +обычно +представляет +мечтать +стало +помните +взять +моих +самим +своим +вообще +самими +здесь +обратно +сразу +таким +ежели +наоборот +куда +таков +мечтает +значит +покажи +такими +кстати +почти +всякий +научит +вдоль +тогдашний +толком +занимает +Аквапланирование +Барокамера +Библиографирование +Биосинтез +Взаимодействующий +Вибраторный +Виртуальность +Вооруженность +Господствующий +Десантно-штурмовой +Диагностировать +Дипломатический +Дисгармония +Дискриминационный +Достопримечательный +Жизнеустройство +Интернациональный +Инфицированный +Кальцинировать +Ключичный +Коннотация +Лиловатый +Люминесцентный +Метрополитен +Многоплановый +Модернизировать +Наивысший +Наименее +Неопределенный +Нераскрытый +Неоднократный +Неохотно +Непостижимый +Неусыпный +Обезьяноподобный +Обзавестись +Оптический +Оптимизировать +Осуществиться +Очистительный +Парафинировать +Переключатель +Пограничный +Подготовительный +Подрядчик +Полиморфный +Почитать +Преисполниться +Преподаватель +Преследователь +Прирожденный +Проектирование +Профанация +Разграничительный +Распоряжающийся +Реконструктивный +Революционный +Рентгенологический +Рискованный +Роскошествовать +Самоунижение +Сверхъестественный +Светочувствительный +Семантика +Сингулярность +Совершенствовать +Соединительный +Сосуществование +Спорообразующий +Стационарный +Столовая +Сторицей +Сцепной +Трансформирующий +Триумвират +Укротитель +Универсальный +Федеративный +Хронометраж +Целостность +Криумвират +Укратитель +Универссальный +Фидиративный +Хранометраж +Целосность diff --git a/Common/3dParty/hunspell/test/src/sk_SK.txt b/Common/3dParty/hunspell/test/src/sk_SK.txt new file mode 100644 index 00000000000..1bc44a6dda5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sk_SK.txt @@ -0,0 +1,205 @@ +hiša +pes +mačka +avto +drevo +knjiga +šola +prijatelj +mama +oče +otrok +jabolko +čokolada +kava +čaj +telefon +televizija +računalnik +glasba +šport +zdravje +lepota +delo +ljubezen +sreča +čas +denar +jezik +država +mesto +zima +poletje +jesen +pomlad +morje +gore +jezero +reka +park +žival +ptica +riba +les +zlato +srebro +kovina +steklo +čevlji +obleka +hlače +srajca +kapa +plašč +roka +noga +oko +uho +nos +ustnice +zob +glava +srce +možgani +kralj +kraljica +princ +princesa +fant +dekle +moški +ženska +starec +starka +zdravnik +medicinska sestra +učitelj +učenka +študent +študentka +kuhar +natakar +vojna +mir +zemljevid +zastava +smeh +jok +spanje +sanje +delo +učenje +umetnost +gledališče +kino +muzej +kapela +cerkev +grad +most +cesta + +Сложные слова + +1. Neparlamentarna +2. Samozadosten +3. Nepristranski +4. Pretirano +5. Nepredušno +6. Nesreča +7. Razpršeno +8. Nesprejemljiv +9. Prekomeren +10. Prostovoljstvo +11. Izolirati +12. Trmast +13. Brezpogojno +14. Neodvisnost +15. Skupnost +16. Neizvedljiv +17. Nelegitimen +18. Nevzdržen +19. Preobremenjenost +20. Ogrevalni sistem +21. Preoblikovati +22. Nezaslišano +23. Neugoden +24. Prezasedenost +25. Nesreča +26. Neupravičeno +27. Mednaroden +28. Kompatibilnost +29. Neuspeh +30. Neobvladljiv +31. Neskončen +32. Neprimeren +33. Amortizacija +34. Koncentracija +35. Cirkulacija +36. Obremenitev +37. Gromozanski +38. Simbol +39. Vinjeta +40. Digitalizacija +41. Funkcionalnost +42. Rentabilnost +43. Ekshibicionizem +44. Frustracija +45. Neprilagodljiv +46. Severnoameriški +47. Ekskluzivnost +48. Preverjanje +49. Celoživljenjsko +50. Privlačnost +51. Periferija +52. Sokrivda +53. Kompromis +54. Strpnost +55. Racionalizacija +56. Birokracija +57. Odraslost +58. Stabilnost +59. Nepredvidljivost +60. Razkošje +61. Smrtnost +62. Obveščenost +63. Produktivnost +64. Neugodje +65. Zapletenost +66. Hegemonija +67. Umetnost +68. Tranzicija +69. Individualnost +70. Kontaminacija +71. Inkubacija +72. Prikrito +73. Etnični +74. Sovražnost +75. Atraktivnost +76. Nestrpnost +77. Divergenca +78. Digitalna pismenost +79. Stabilizacija +80. Raznolikost + +Слова с ошибками + + Kontamenacija + + Grommozanski + + Neobvladlliv + + Neparlametarna + + Nevrzdržen + + voina + + muzei + + ryba + + serebro + + televiziia \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sl_SI.txt b/Common/3dParty/hunspell/test/src/sl_SI.txt new file mode 100644 index 00000000000..3a2674932d2 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sl_SI.txt @@ -0,0 +1,210 @@ +Hiša +Sonce +Miza +Stol +Ptica +Trava +Drevo +Noč +Luna +Morje +Gora +Cvet +Riba +Rdeča +Modra +Zelena +Rumena +Bela +Črna +Kamen +Pes +Mačka +Roka +Noga +Glava +Oči +Uho +Nos +Usta +Jabolko +Hruška +Sliva +Jagoda +Malina +Lubenica +Kruh +Mleko +Sir +Mesnica +Sadje +Zelenjava +Voda +Zrak +Ogenj +Sneg +Dež +Oblak +Veter +Zima +Poletje +Jesen +Pomlad +Zajec +Lisica +Volk +Medved +Lev +Tigrica +Slon +Konj +Krava +Ovca +Piščanec +Jajce +Mleko +Kava +Čaj +Sok +Vino +Pivo +Hrana +Pecivo +Testo +Marmelada +Kruh +Sir +Olje +Sol +Poper +Sladkor +Kava +Čaj +Vino +Pivo +Šola +Učitelj +Učenec +Knjiga +Pisarna +Računalnik +Telefon +Glasba +Slika +Film +Gledališče +Mesto +Vas +Trg +Cesta +Reka +Avtomatizacija +Razvoj +Komunikacija +Kompjuter +Programiranje +Elektronski +Inženiring +Elektrifikacija +Kombinacija +Sistem +Informacija +Univerza +Biblioteka +Univerzitetni +Laboratorij +Raziskava +Razvojna +Inovacija +Intelektualni +Integriteta +Izobraževanje +Izvajanje +Preverjanje +Tehnologija +Implementacija +Program +Sodelovanje +Proizvodnja +Industrija +Organizacija +Administracija +Proaktivnost +Kreativnost +Projektni +Razumevanje +Kvaliteta +Upravljanje +Ocenjevanje +Statistika +Kompetentnost +Konsolidacija +Realizacija +Kapaciteta +Distribucija +Kompatibilnost +Konceptualizacija +Povezava +Posodobitev +Fleksibilnost +Ekonomija +Organiziranje +Konkurenca +Stabilnost +Ekologija +Osebnost +Zavzetost +Entuziazem +Motivacija +Avtorizacija +Kreacija +Akumulacija +Monotonija +Diferenciacija +Transformacija +Koncentracija +Inovativnost +Aktivnost +Vzpostavljanje +Reorganizacija +Kategorizacija +Partikularnost +Homogenost +Izjemenost +Generalizacija +Hierarhija +Koordinacija +Inspiracija +Evaluacija +Ustvarjalnost +Oblikovanje +Kompatibilnost +Konkretizacija +Proaktivnost +Identifikacija +Kapaciteta +Intervencija +Konsolidacija +Realizacija +Eksplozivnost +Abstrakcija +Individualnost +Integracija +Segmentacija +Asimilacija +Artikulacija +Kolaboracija +Asociacija +Stabilizacija +Kooperacija +Transformacija +Hšza +Kmojnikacija +Progrramiranjee +Elektornkski +Inženeirrng +Izzobraževanjee +Infomracija +Razvoojnaa +Proizvdonja +Akitvnostt \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt b/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt new file mode 100644 index 00000000000..9002894db69 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt @@ -0,0 +1,227 @@ +кућа +пас +мачка +аутомобил +дрво +књига +школа +пријатељ +мама +тата +дете +јабука +чоколада +кафа +чај +телефон +телевизија +рачунар +музика +спорт +здравље +лепота +посао +љубав +срећа +време +новац +језик +земља +град +зима +лето +јесен +пролеће +море +планине +језеро +река +парк +животиња +птица +риба +дрво +злато +сребро +метал +стакло +ципеле +одећа +панталоне +кошуља +капа +капут +рука +нога +око +уво +нос +усне +зуб +глава +срце +мозак +краљ +краљица +принц +принцеза +дечак +девојчица +мушкарац +жена +старац +старица +доктор +медицинска сестра +наставник +ученик +студент +студенткиња +кувар +конобар +рат +мир +мапа +застава +смех +плач +сан +сањарење +посао +учење +уметност +позориште +биоскоп +музеј +црква +дворац +мост +улица +пут + +Сложные слова + +Конечно! Вот сто сложных слов на сербском языке на кириллице: + +1. Контраст +2. Компликација +3. Конструкција +4. Диспропорција +5. Корелација +6. Колаборација +7. Консервативан +8. Диференцијација +9. Експерименталан +10. Инвалидитет +11. Легитиман +12. Оптимизација +13. Компетентан +14. Документација +15. Персистентан +16. Апроксимација +17. Екстраваганција +18. Катастрафалан +19. Резервација +20. Прогресиван +21. Идентификација +22. Генерација +23. Криминалистички +24. Дестабилизација +25. Корумпиран +26. Конфронтација +27. Експлозиван +28. Функционалан +29. Релевантан +30. Квалификација +31. Акредитација +32. Петиција +33. Каустичан +34. Периодичан +35. Контроверзан +36. Гигантски +37. Принципијалан +38. Управоливост +39. Имунизација +40. Магнетичан +41. Оперативан +42. Десант +43. Хиерархија +44. Феминистички +45. Сегментација +46. Колоритан +47. Деградација +48. Диверзификација +49. Казуистички +50. Реципрочан +51. Манипулативан +52. Екстензиван +53. Колективни +54. Каузалитет +55. Синхронизација +56. Кампања +57. Товарни +58. Хируршки +59. Шампионат +60. Геостационаран +61. Опустошан +62. Клема +63. Стационарни +64. Секуларни +65. Исегментација +66. Дебелина +67. Прецизан +68. Рафиниран +69. Психолошки +70. Турбулентан +71. Интегритет +72. Идеолошки +73. Манифестација +74. Имплицитан +75. Хомогеност +76. Изолација +77. Хетерогеност +78. Спекулативан +79. Вагу +80. Математички +81. Гематолошки +82. Психијатријски +83. Блокада +84. Заплена +85. Монопол +86. Дисидент +87. Екстрадиција +88. Ревизија +89. Ваидан +90. Колонизација +91. Мотивација +92. Просек +93. Ресурс +94. Хуманизам +95. Дравски +96. Коалиција +97. Картеля +98. Резолуција +99. Менталитет +100. Епидемиологија + +С ошибками + + Колонизакаија + + Епидемиогија + + Казуистикаки + + Хуманкзам + + Манитулативан + + сањваење + + утење + + автомобил + + мекицинска сестра + + стукло \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt b/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt new file mode 100644 index 00000000000..48cd99d072a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt @@ -0,0 +1,173 @@ +ananas +anarhistički +antidepresiv +Anđeo +avion +banana +banka +belina +bespomoćnost +bibliotekar +bibliaoteikar +brod +citat +crkva +cvet +cveće +demokratija +demackratija +demokratizacija +Dobrota +dom +Dragi +ekran +eksperimentalni +eksplozija +epidemiologija +farmakologija +filantropija +flaša +frizura +fudbal +garaža +generalitet +geografski +globalizam +gnezdo +grad +građanstvo +grlo +hamburger +Harmonija +himalaji +hiperbola +hipotermija +hleb +Hrabrost +hrana +Hvala +igra +igračka +individualnost +infrastruktura +internet +inmternet +jabuka +jahač +jastuk +jednakost +jubilej +jurisprudencija +kafa +krevet +kriminalisticki +kriminalistika +kuća +kvantitativni +lampa +latiaratura +Lepota +lingvistika +literatura +ljubav +Ljubavi +ljubavnica +Ljubazan +Ljubim +lubenica +majica +majka +mašina +mikroorganizama +mikroskopija +Milost +Mir +Mirno +nacionalizam +nedopustiv +neurologija +novčanik +noć +nož +oktobar +okultizam +optimističan +optimističnost +ormar +Osoba +oči +pas +peškir +planina +poniženje +Porodica +Prijatelj +psihologija +psihoterapija +Radost +računar +reka +rekonvalescencija +reumatologija +revolucija +sendvič +Slatko +Sloboda +Slobodan +Snaga +socijalizacija +socijalizam +Spreman +Sreća +Srećan +Srećno +sunce +superiornost +Svetlost +tata +tehnologija +telefon +telekomunikacije +top +tradicionalni +ulica +univerzalnost +univerzitet +univirzdalnost +Usmena +Znanje +usta +Vedar +vegetarijanstvo +velikodušnost +voda +voz +Zabava +zavisnost +Zdravlje +zemlja +Zima +zjmlja +zločinački +zoološki +Zvezda +ćilim +čarapa +čarobnjak +časopis +čizme +đak +đevrek +đumbir +šešir +šišmiš +škola +šljiva +šuma +žaba +ženskara +žirafa +život +životinjski +žurka + diff --git a/Common/3dParty/hunspell/test/src/sv_SE.txt b/Common/3dParty/hunspell/test/src/sv_SE.txt new file mode 100644 index 00000000000..99b61d15766 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sv_SE.txt @@ -0,0 +1,210 @@ +Hus +Sol +Mjölk +Vatten +Fisk +Stol +Grön +Blomma +Träd +Katt +Hund +Bok +Cykel +Kaffe +Frukt +Kött +Fönster +Dörr +Säng +Lampa +Bord +Hår +Ögon +Hand +Fötter +Näsa +Mun +Öra +Huvud +Arm +Ben +Kläder +Hatt +Skor +Väska +Papper +Penna +Skrivbord +Telefon +Radio +Musik +Film +Teater +Konst +Sport +Spel +Resa +Bil +Tåg +Buss +Flygplan +Båt +Stad +Land +Hav +Sjö +Flod +Berg +Dal +Park +Skog +Sjukhus +Apotek +Skola +Universitet +Affär +Restaurang +Café +Hotell +Turist +Vän +Familj +Mamma +Pappa +Bror +Syster +Barn +Morfar +Mormor +Vänster +Höger +Framåt +Bakåt +Upp +Ner +Snäll +Osnäll +Glad +Ledsen +Trött +Stark +Svag +Tyst +Bullrig +Ren +Smutsig +Vacker +Ful +Liten +Stor +Komplexitet +Oproportionerlig +Ovillkorlig +Efterklokhet +Komplicerad +Desorientering +Konstellation +Otillgänglighet +Irreversibel +Förlåtelse +Overksamhet +Indifferent +Hierarki +Kombinatorik +Inkompatibilitet +Absorption +Konsekvens +Verklighetsfrånvänd +Retrospektiv +Förändringsbarhet +Ambivalens +Besvikenhet +Ineffektivitet +Intrikat +Dilemma +Hesitation +Absurditet +Kompromisslös +Konsolidering +Föresats +Tillfredsställelse +Delegering +Rekommendation +Detaljrikedom +Oanvändbar +Stagnation +Nostalgi +Hemlighetsfull +Avsaknad +Perseverans +Existentialism +Repetitivitet +Intolerans +Anonymitet +Obetydlig +Paradox +Förvirring +Juxtaposition +Reflektion +Självständighet +Kollision +Kreativitet +Djupgående +Abstraktion +Eufori +Autentisk +Insinuation +Omöjlig +Pessimism +Inkonsekvens +Revisionism +Sensationell +Obeveklig +Subjektivitet +Universalitet +Entropi +Omvälvande +Infiltration +Konservativ +Atypisk +Provokation +Konfrontation +Anarki +Konkurrenskraft +Defensivitet +Nihilism +Konklusion +Apori +Korrespondens +Prioritering +Exponentiell +Fragmentering +Aversion +Harmoni +Vanmakt +Signifikans +Katalysator +Förlust +Enhällighet +Ambition +Tendens +Alienation +Artificiell +Uppfyllelse +Psykosomatisk +Virtuos +Egensinnig +Anpassning +Hållbarhet +Konstitution +Kompleksitet +Oproporsjonerlig +Uvilkorlig +Etterklokhed +Komplisert +Desorientering +Konstelasjon +Utilgjengelighet +Irreversibel +Forlatelse diff --git a/Common/3dParty/hunspell/test/src/tr_TR.txt b/Common/3dParty/hunspell/test/src/tr_TR.txt new file mode 100644 index 00000000000..9ad60f3664a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/tr_TR.txt @@ -0,0 +1,205 @@ +Akşam +Almak +Altın +Anahtar +Anlamak +Araba +Atmak +Ayakkabı +Açmak +Ağaç +Bahçe +Bakır +Bakkal +Bakmak +Balık +Beyaz +Bilgisayar +Bilmek +Binmek +Bulmak +Ceket +Cevaplamak +Deniz +Dinlemek +Doktor +Duyurulmamış +Düzenleştirme +Düşmek +Düşünmek +Ekmek +Elbise +Eldiven +Elma +Erkek +Etek +Etmek +Ev +Eşarp +Gelgit +Geliştiricilikle +Geliştirilebilir +Geliştirme +Gerçekleştirme +Gezmek +Geçmek +Gitar +Gitmek +Giymek +Gri +Gömlek +Görülebilirlik +Görünümlü +Görünüşlü +Gözlük +Gümüş +Günaydın +Hareketlendi +Hareketlilik +Hava +Hayalperest +Hüzün +Kahve +Kahverengi +Kalabalıklar +Kalem +Kalkmak +Kalmak +Kapatmak +Kararlılık +Kararlılıkla +Kararsızlık +Kararsızlıkla +Karpuz +Kedi +Kemer +Kemdkcer +Kırmızı +Kitap +Kız +Kızgınmak +Koklamak +Koalye +Kolye +Konservatuvar +Konuşmak +Korkmak +Koymak +Koşmak +Kravat +Kullanılabilir +Kullanılmış +Kullanılmışlık +Kullanışlılık +Kurumsallaşma +Köpek +Küpe +Kütüphane +Mavi +Mazbut +Melankoli +Merdiven +Merhaba +Merhabalar +Meurhaba +Meydan +Meyhane +Meyve +Mor +Muhafazakar +Muhteşem +Mukadderatlarınızdanmışçasına +Muvaffak +Muzaffer +Muzafferiyet +Muzip +Mükemmeldik +Münasebet +Münzevi +Müsrif +Mütevazi +Müteessir +Mütercim +Mütereddit +Mütevazı +Müzmin +Okul +Okumak +Otobüs +Otoriterlik +Oynamak +Pantolon +Pasta +Pembe +Pembei +Plaj +Platin +Saat +Sandalye +Sarı +Satmak +Sevinmek +Sevmek +Sıcak +Sıradaymışız +Siyah +Sormak +Soymak +Soğuk +Su +Sükûnet +Sürrealist +Süt +Tabak +Tadına bakmak +Tatlı +Tavuk +Telefoncu +Televizyon +Temizlemek +Teşekkürler +Türkuaz +Tuirkuazu +Turuncu +Tutmak +Ulaştırılabilir +Uygulanabilir +Uyumak +Uçak +Yapmak +Yatak +Yazmak +Yemek +Yeşil +Yıkanmak +Yıldız +Yol +Yöneltilmezken +Yüzme +Yüzük +Zenginleştirmek +Çalışamamıştı +Çalışmak +Çalışmamıştır +Çanta +Çay +Çıkarmak +Çiçek +Çorap +Özelleştirilmiş +Özelleştirme +Özgürleştirme +Üzülmek +İnmek +İsteksizlik +İsteksizlikle +İstikrarlı +İstikrarlılık +İstisnai +İslamiyetle +İzlemek +İçmek +İşbirliği +İşitmek +Şapka +Şemsiye diff --git a/Common/3dParty/hunspell/test/src/uk_UA.txt b/Common/3dParty/hunspell/test/src/uk_UA.txt new file mode 100644 index 00000000000..b139dedfbd8 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uk_UA.txt @@ -0,0 +1,210 @@ +абдукція +абіогенез +амбівалентнасть +амбівалентність +анахранізм +анахронізм +антропогенез +антропологія +антропоморфізм +апатія +археологія +архетип +аскетизм +астрономія +афект +бачити +бігти +білий +біллий +біологія +бувай +будинок +будь ласка +бути +важко +велиикий +великий +веселка +взяти +вибачте +відчувати +вода +волюнтаризм +втаємниченість +вчитися +гарний +гарячий +гегемонія +географія +герменевтика +герменевтика +гештальт +говорити +гойдалка +готувати +грати +дати +дедукція +деконструктивізм +деконструкція +демаркація +детермінізм +дзвіночок +дивитися +дисгарммонія +дисгармонія +дисфункція +дисфункця +дихотомія +до побачення +добрий +доктрина +думати +дурний +дурня +дякую +евфемізм +езотерика +ей +екзистенціалізм +екзистенціалізм +екзистенцілізм +екзистенція +економіка +емерджентність +ентелехія +епістемологія +ефемерність +ефемерність +занепадництво +звісно +здоровий +зелений +йти +ілюзорність +ілюзорність +імплікація +інвектива +індукція +інтроспекціїя +їсти +історія +каблучка +кава +казус +калюжа +катарсис +каченя +каштани +квітка +кішка +класно +книга +когнітивістика +комаха +консенсус +космогенез +купувати +легко +лінгвістика +літати +маленький +марнослів'я +математика +мати +метаморфоза +метелик +метелиця +містифікація +місто +могти +можливо +мусити +насправді +не радий +незворушність +ні +нігілізм +новий +нонсенс +ностальгія +павучок +парадокс +пес +писати +пити +піти +плавати +плакати +повільний +поганий +політологія +постмодернізм +потворний +працювати +привіт +прийти +психоаналіз +птах +радий +ремінісценція +рефлексія +робити +розбурхання +розумний +сильний +сингулярність +синестезія +синій +синішй +синкретизм +сказати +скатертина +слабкий +слухати +сміятися +сніг +соліпсизм +соломинка +сонечко +сонце +соціологія +спати +співати +справді +старий +структуралізм +сумний +так +так +танцювати +телефонувати +тож +трансцендентність +фантастично +фаталізм +фемінізм +феномен +феноменологія +фізика +філософія +фрактал +хворий +хімія +хліб +хліб +ходити +холодний +хотіти +чао +червонй +червоний +черевики +читати +чорнй +чорний +чути +швидкий +щасливий +яблуко diff --git a/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt b/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt new file mode 100644 index 00000000000..b92bea172f4 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt @@ -0,0 +1,262 @@ +Mарт +Ёз +Ём +Ёхуд +Август +Адвакат +Адреси +айтган-лирангиз +айқин +амалга +анча +Апрел +арзонроқ +аҳамият +аҳднома +бажарилади +бажарилди +баланд +ихтисослан +банкрот +баҳона +Баҳор +бераман +берасизми +беринг +бериш +бешинчи +биз +Бизга +Бизнинг +билан +Бирор +Бозорнинг +бор +бошқа +Бу +Бугун +будингиз +бунга +бундай +Бухгалтерлик +бўлади +бўладими +бўлиши +бўлмаган +бўлса +бўш +бўшайди +бўшатасиз +вазифасига +вазият +вариант +вақт +газетадаги +газетадан +даромад +Декабрь +Душанба +Эрталаб +Етказиб +Жисмоний +Жуда +Жума +зарур +зиёфат +Ижара +ижарага +икки +Илтимос +Индинга +информатизациялари +Иситгич +иши +ишлатсак +Ишхона +Июль +Июнь +Йўқ +йил +йилдан +кам +Шинамгина +кампанияси +келдим +келишимдан +келмоқчи +келсам +келтириш +керак +керакдир +керакми +кета-ди +кеч +Кеча +кечага +Кечаси +Кечир +Кечирдинг +кирла +кирадими +кондиционер +коррупциядир +кран +Куз +Кун +куни +кўрмоқчи +кўчиб +лойиҳа +Май +маълумоти +маълумотларни +Маъмурият +маъруза +Мен +музлатгич +мумкин +муфмкин +мутахассис +мушовир +муҳим +нарса +нархи +Нархини +нақд +ўшанақасини +неча +Номардлик +Ноябри +интернетдаги +ойнаси +ойнинг +Октябри +олдин +олдиндан +олмаймиз +олмоқчи +орқали +шоти +шорти +Оқшом +пайдо +Панжшанба +пулини +Раҳмат +резюме +реклама +Салом +Сармоядор +Сентябрь +Сешанба +Сиз +сизга +сизда +Сизнинг +синган +сифатида +совуқ +софвуқ +Солиқларни +Статистик +сўм +тажрибали +тайёргарлик +тайёрладик +тайёрладингизми +таклиф +талафот +талафоти +таъминловчилардан +танишинг +таржимон +тарржимон +тахминан +ташкил +Телефонни +технология +Безантирани +тозалан +тозалигига +Тонгда +топширишимиз +топшириқ +турли +турмоқчи +тутсак +Тушлик +ўладиганингиз +тўлай +тўлаймиз +тилдиришинг +тўлиқ +уйингиз +уйни +уч +учун +ўқидим +фақат +Феврал +хабар +Хайрли кун +Мотамхонаси +хонлик +Чек +Чоршанба +Шанба +шарт-номани +шартини +шартлар +шартлари +шартни +шартнома +шахс +шовқин +Шом +Шу +эди +Эртага +Эртадан сўнг +Эшитишимга +эълон +эълонингиз +эълонингизни +эътироф +Юклаш +Якшанба +Январи +Ярим кеча +яхши +қабул +қаерда +Қанақа +қаноатманда +қанча +қачон +қизиқарлидир +қиламиз +қилганим +қилдим +қилинг +қилинди +қилишди +қиммат +қиммати +Қимматидан +қирқ +Қиш +қувонарлими +қўнғироқ +Қўшимча +ҳайвонини +ҳам +ҳамза +Ҳар +ҳафтага +ҳақиқатан +ҳисоблаб +Ҳозир +ҳужжатни +Ўтган кун + + diff --git a/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt b/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt new file mode 100644 index 00000000000..ee6a1d93567 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt @@ -0,0 +1,200 @@ +Salom +Sallom +Rahmat +Rhmat +Iltimos +Iltimo +Kattalar +Kattalarvf +Yaxshi +Yashi +Kelajak +Keljajak +Oilaviy +Oilaaviy +Qarindosh +Qarinndosh +Shahar +Shaha +Dengiz +Dengizzz +Quyosh +Quyyosh +Yulduz +Oyim +Kechqurun +Tushun +Suvchi +Sharob +Choyxona +Nonushta +Tushlik +Muzqaymoq +Desert +Tuzluq +Mevalar +Sabzavot +Baliq +Tuxumli +Sabza +Sariq +Salatlar +Shirinlik +Shokolad +Rishta +Kakao +Pishloq +Tort +Qaymoq +Sutli +Qatiq +Salomatlik +Temir +Zahar +Oqimli +Shamol +Olov +Yer +Osmon +Shanba +Dushanba +Seshanba +Chorshanba +Payshanba +Juma +Yakshanba +Oltin +Tong +Bomdod +Asr +Shom +Kun +Oqsoqol +Shoshqaloq +Kulgili +Muxlislilar +Tavsiflash +Tuzilishga +Mustaqillik +Tushuntirish +Boshqarish +Mashhurlik +Tarkibiy +Tahlil +Ishchi +Xalqaro +Tarjima +Mustahkamlik +Chaqaloq +Istiqbol +Tasvir +Taklif +Tasavvur +Jiddiy +Majburiyat +Asosiy +Tahdid +Tushunmovchilik +Ishonch +Maqomi +Ijodkor +Tadbirkor +Hayotiy +Mashhur +Bemorlik +Tadbir +Jismoniy +Madaniyat +Xavfsizlik +Sifatli +Suvli +Sotuvchi +Chetel +Tashqi +Sotuv +Tarbiyalanish +Murabbo +Sariqcha +Qovun +Shaharlik +Muhimlik +Tarbiyachilik +Xatolik +Balandlik +Yuzaki +Kuyov +Qiziquvchan +Orzular +Mashq +Qalampir +Muammo +Sadoqatli +Yovuzlik +Fikr-mulohaza +Boylik +Tushuncha +Zanjir +Eslatma +Tabassum +Ishonuvchi +Chidamlilik +Ilova +Birodarlik +Oqilona +Ijodiyot +Tayanch +Hurmat +Baxtli +Tajriba +Samimiylik +Shifokor +Ishrat +Baho +Namoyish +Qiyinchilik +Bolalar +Ishonchli +Taqdir +Shovqinli +Xalqaro +Baxt +Fursat +Hurmatli +Qulaylik +Zamonaviy +Sadoqat +Sabr +Nikoh +Jasorat +Barkamollik +Dunyoqarash +Omadli +Foydali +Yorqin +Mehribonlik +Fazilatli +Kutubxona +Istiqomatli +Fido +Bahor +Shafqatsizlik +Tafakkur +Fazilat +Qochish +Laziz +Uzoq +Ilhom +Omad +Hurmatli +Tandir +Sherzod +Bahoriy +Dilshod +Baxtli +Shonli +Nurli +Shafqatsizlik +Oqqush +Boylik +Toza +Sabrli diff --git a/Common/3dParty/hunspell/test/src/vi_VN.txt b/Common/3dParty/hunspell/test/src/vi_VN.txt new file mode 100644 index 00000000000..2982e9eb45c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/vi_VN.txt @@ -0,0 +1,128 @@ +Bánh +Bang +bênh +bướng +bậy +Chanh +chum +chuyện +chép +Chùng +chắp +chệnh +chới +chữ +công +cạc +cột +cứu +Doanh +duyên +dùng +dể +dọng +gia +giày +giêng +Giảng +giềng +hon +Hoẳn +Hài +hôm +hước +hấu +hớt +hữu +Khiển +Khoào +khuya +khuyến +khách +khén +khẩn +khắp +khựng +kẻo +lang +liền +Loàng +Luỗng +lình +lương +lấp +lệnh +lịnh +lốn +lời +lựng +Muộn +Mãnh +mại +mạn +mổ +mởn +nghiễm +nghều +Ngoáy +Nguyên +ngóp +người +ngỏ +ngớp +ngụa +ngửng +nhiếp +nhu +nhà +nhân +Nhóm +nhưỡng +nhắm +nhổn +nhứt +ninh +noi +nãy +nạn +nốt +ong +pao +phiên +phiêu +Phên +Phương tiện +phẩm chất +phố đi bộ +quan trọng +quyền lợi +quán cà phê +quảng cáo +Quốc +Quốc tế +riêng biệt +rưỡi +Rải +Rẻng +rộng rãi +siễn +sum +Sõng +Sưu +sưu tập +sử dụng +Thiệt thòi +Thuộc về +thuộc tính + +Слова с ошибками +thiệte +quốq tế +nguên +khoao +chenh +chhùng +man +doah +khien +ngoay \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/test.pro b/Common/3dParty/hunspell/test/test.pro new file mode 100644 index 00000000000..2dee3f69709 --- /dev/null +++ b/Common/3dParty/hunspell/test/test.pro @@ -0,0 +1,29 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-07-21T18:28:42 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +DEFINES += KERNEL_USE_DYNAMIC_LIBRARY + +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +ADD_DEPENDENCY(UnicodeConverter kernel hunspell) + +core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32 +core_linux:LIBS += -lz + +SOURCES += main.cpp + +DESTDIR = $$PWD/build From 9c2e696710010271b9d332551711d6d317b2e74d Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 29 Feb 2024 19:59:39 +0300 Subject: [PATCH 365/794] Add words --- Common/3dParty/hunspell/test/src/en_US.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Common/3dParty/hunspell/test/src/en_US.txt b/Common/3dParty/hunspell/test/src/en_US.txt index a806686cdab..f910ca76ce8 100644 --- a/Common/3dParty/hunspell/test/src/en_US.txt +++ b/Common/3dParty/hunspell/test/src/en_US.txt @@ -210,4 +210,7 @@ Haudlin Mavkish Mendocious Mitaphysical - +timeline +rollout +workshopped +deliverables From b71ed594da18ce1f2a330f4aa9f31bca340cd2e2 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 29 Feb 2024 20:03:36 +0300 Subject: [PATCH 366/794] Add tests result --- .../3dParty/hunspell/test/dst/az_Latn_AZ.txt | 213 ++++++++++++++ Common/3dParty/hunspell/test/dst/bg_BG.txt | 212 ++++++++++++++ Common/3dParty/hunspell/test/dst/ca_ES.txt | 112 ++++++++ .../hunspell/test/dst/ca_ES_valencia.txt | 212 ++++++++++++++ Common/3dParty/hunspell/test/dst/cs_CZ.txt | 206 ++++++++++++++ Common/3dParty/hunspell/test/dst/da_DK.txt | 129 +++++++++ Common/3dParty/hunspell/test/dst/de_AT.txt | 131 +++++++++ Common/3dParty/hunspell/test/dst/de_CH.txt | 116 ++++++++ Common/3dParty/hunspell/test/dst/de_DE.txt | 211 ++++++++++++++ Common/3dParty/hunspell/test/dst/el_GR.txt | 123 ++++++++ Common/3dParty/hunspell/test/dst/en_AU.txt | 116 ++++++++ Common/3dParty/hunspell/test/dst/en_CA.txt | 125 +++++++++ Common/3dParty/hunspell/test/dst/en_GB.txt | 122 ++++++++ Common/3dParty/hunspell/test/dst/en_US.txt | 218 +++++++++++++++ Common/3dParty/hunspell/test/dst/en_ZA.txt | 114 ++++++++ Common/3dParty/hunspell/test/dst/es_ES.txt | 208 ++++++++++++++ Common/3dParty/hunspell/test/dst/eu_ES.txt | 132 +++++++++ Common/3dParty/hunspell/test/dst/fr_FR.txt | 211 ++++++++++++++ Common/3dParty/hunspell/test/dst/gl_ES.txt | 120 ++++++++ Common/3dParty/hunspell/test/dst/hr_HR.txt | 215 ++++++++++++++ Common/3dParty/hunspell/test/dst/hu_HU.txt | 114 ++++++++ Common/3dParty/hunspell/test/dst/id_ID.txt | 121 ++++++++ Common/3dParty/hunspell/test/dst/it_IT.txt | 200 +++++++++++++ Common/3dParty/hunspell/test/dst/kk_KZ.txt | 209 ++++++++++++++ Common/3dParty/hunspell/test/dst/ko_KR.txt | 157 +++++++++++ Common/3dParty/hunspell/test/dst/lb_LU.txt | 118 ++++++++ Common/3dParty/hunspell/test/dst/lt_LT.txt | 127 +++++++++ Common/3dParty/hunspell/test/dst/lv_LV.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/dst/mn_MN.txt | 103 +++++++ Common/3dParty/hunspell/test/dst/nb_NO.txt | 113 ++++++++ Common/3dParty/hunspell/test/dst/nl_NL.txt | 115 ++++++++ Common/3dParty/hunspell/test/dst/nn_NO.txt | 116 ++++++++ Common/3dParty/hunspell/test/dst/oc_FR.txt | 108 ++++++++ Common/3dParty/hunspell/test/dst/pl_PL.txt | 225 +++++++++++++++ Common/3dParty/hunspell/test/dst/pt_BR.txt | 108 ++++++++ Common/3dParty/hunspell/test/dst/pt_PT.txt | 135 +++++++++ Common/3dParty/hunspell/test/dst/ro_RO.txt | 210 ++++++++++++++ Common/3dParty/hunspell/test/dst/ru_RU.txt | 197 +++++++++++++ Common/3dParty/hunspell/test/dst/sk_SK.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/dst/sl_SI.txt | 210 ++++++++++++++ .../3dParty/hunspell/test/dst/sr_Cyrl_RS.txt | 227 +++++++++++++++ .../3dParty/hunspell/test/dst/sr_Latn_RS.txt | 173 ++++++++++++ Common/3dParty/hunspell/test/dst/sv_SE.txt | 210 ++++++++++++++ Common/3dParty/hunspell/test/dst/tr_TR.txt | 205 ++++++++++++++ Common/3dParty/hunspell/test/dst/uk_UA.txt | 210 ++++++++++++++ .../3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt | 262 ++++++++++++++++++ .../3dParty/hunspell/test/dst/uz_Latn_UZ.txt | 200 +++++++++++++ Common/3dParty/hunspell/test/dst/vi_VN.txt | 128 +++++++++ 48 files changed, 7957 insertions(+) create mode 100644 Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt create mode 100644 Common/3dParty/hunspell/test/dst/bg_BG.txt create mode 100644 Common/3dParty/hunspell/test/dst/ca_ES.txt create mode 100644 Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt create mode 100644 Common/3dParty/hunspell/test/dst/cs_CZ.txt create mode 100644 Common/3dParty/hunspell/test/dst/da_DK.txt create mode 100644 Common/3dParty/hunspell/test/dst/de_AT.txt create mode 100644 Common/3dParty/hunspell/test/dst/de_CH.txt create mode 100644 Common/3dParty/hunspell/test/dst/de_DE.txt create mode 100644 Common/3dParty/hunspell/test/dst/el_GR.txt create mode 100644 Common/3dParty/hunspell/test/dst/en_AU.txt create mode 100644 Common/3dParty/hunspell/test/dst/en_CA.txt create mode 100644 Common/3dParty/hunspell/test/dst/en_GB.txt create mode 100644 Common/3dParty/hunspell/test/dst/en_US.txt create mode 100644 Common/3dParty/hunspell/test/dst/en_ZA.txt create mode 100644 Common/3dParty/hunspell/test/dst/es_ES.txt create mode 100644 Common/3dParty/hunspell/test/dst/eu_ES.txt create mode 100644 Common/3dParty/hunspell/test/dst/fr_FR.txt create mode 100644 Common/3dParty/hunspell/test/dst/gl_ES.txt create mode 100644 Common/3dParty/hunspell/test/dst/hr_HR.txt create mode 100644 Common/3dParty/hunspell/test/dst/hu_HU.txt create mode 100644 Common/3dParty/hunspell/test/dst/id_ID.txt create mode 100644 Common/3dParty/hunspell/test/dst/it_IT.txt create mode 100644 Common/3dParty/hunspell/test/dst/kk_KZ.txt create mode 100644 Common/3dParty/hunspell/test/dst/ko_KR.txt create mode 100644 Common/3dParty/hunspell/test/dst/lb_LU.txt create mode 100644 Common/3dParty/hunspell/test/dst/lt_LT.txt create mode 100644 Common/3dParty/hunspell/test/dst/lv_LV.txt create mode 100644 Common/3dParty/hunspell/test/dst/mn_MN.txt create mode 100644 Common/3dParty/hunspell/test/dst/nb_NO.txt create mode 100644 Common/3dParty/hunspell/test/dst/nl_NL.txt create mode 100644 Common/3dParty/hunspell/test/dst/nn_NO.txt create mode 100644 Common/3dParty/hunspell/test/dst/oc_FR.txt create mode 100644 Common/3dParty/hunspell/test/dst/pl_PL.txt create mode 100644 Common/3dParty/hunspell/test/dst/pt_BR.txt create mode 100644 Common/3dParty/hunspell/test/dst/pt_PT.txt create mode 100644 Common/3dParty/hunspell/test/dst/ro_RO.txt create mode 100644 Common/3dParty/hunspell/test/dst/ru_RU.txt create mode 100644 Common/3dParty/hunspell/test/dst/sk_SK.txt create mode 100644 Common/3dParty/hunspell/test/dst/sl_SI.txt create mode 100644 Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt create mode 100644 Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt create mode 100644 Common/3dParty/hunspell/test/dst/sv_SE.txt create mode 100644 Common/3dParty/hunspell/test/dst/tr_TR.txt create mode 100644 Common/3dParty/hunspell/test/dst/uk_UA.txt create mode 100644 Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt create mode 100644 Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt create mode 100644 Common/3dParty/hunspell/test/dst/vi_VN.txt diff --git a/Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt b/Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt new file mode 100644 index 00000000000..5365bb7974d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt @@ -0,0 +1,213 @@ +A [Ü, Ha, Ağ, Ac, Ad, Da, Fa, Ah, Ka, Al, An, Na, Qa] +qocalmaq [almayacaq, almamaq] +Alderaan'ın [Federasiyanın] +hamısı +həmçinin +Və +cavab +dir +incəsənət +kimi +da +uzaq +körpə +zirzəmi [zəmində] +ol +olub +doğuldu [doğulduğu, doğurduğu] +bulvar [bunlar] +fasilə +nəsllər [nəsillər, nəsnələri, nəslə, nələrlə, səslər] +gəlin +lakin +al +ilə +Kaliforniya [Kanalizasiya] +Kalifornikasiya [Kommunikasiya] +bilər +kartlar +şans +Çin +çənə [dənə, çəkə, mənə, nənə, sənə, tənə, çənəyə] +klublar +Cobain [] +bürc [borc, gürcü] +nəzarət +qiymət +edə bilməzdim [bilməzdim] +yaratmaq +lənət +rəqs +saziş +sövdələşmələr [məsləhətləşmələr] +dağıdıcı +almazlar [almanlar, almaz lar, almaz-lar, almaları, marallar, mallara] +etməz +etməyərik [etmərik, etmədikləri] +arzu +xülyalar [yalanlar] +Şərq +kənar +kənarları [kənar ları, kənar-ları, kənarına, kənarında, kəlamları, aparılarkən] +məmnunluq +hamının +uzaq +peri [şeri, geri, meri, yeri] +solğun [dolğun] +üz +son +tap +ilk +üçün +-dan [-dam, -da, -an, -dana, -adan, -nda, -daş, -dən, -dağ, -can, -dad, -din, -lan, -don, -qan, adan, andan] +sərhəd +qız +qızın +yaxşı +gitara [artaraq] +əl +hardcore [hardadır] +var +yoxdur +o [od, ol, on, ot, ov, ox, ü, ı] +eşitmək +ürək +O'nun [Onun, Oyununu] +ona +gizli +yüksək +ona +onun +Hollivud [Holland] +Mən +Mənəm +əgər +içində +məlumat +içində +dir +bu +jack [janra] +sadəcə +kral +qohum +bilmək +qoyulmuş +qanun +yerləşdirilmək [yerləşdirilməsi, yerləşdirilmiş, yerləşdirilib, yerləşdirildiyini] +qurğuşun [quruluşunun] +aparmaq +yerləşdirilmə [yerləşdirilməsi, yerləşdirilmiş, yerləşdirilib, yerləşdirildiyini] +məkan +sevmək +şans +edilmiş +adam +çox +Evlənmək +maska [masa, marka] +o bilər [bilərlər, bilər] +bəlkə də [bəlkə] +mənası +mən +meditasiya [dissertasiya] +xatirə +ağılın +pul +mənim +heç vaxt [vaxtsa] +deyil +heç nə [heçə] +nömrələr [nömrələri, nömrə lər, nömrə-lər, nömrəli, nömrə] +of [od, əf, ol, on, ot, ov, ox, ofis] +of [od, əf, ol, on, ot, ov, ox, ofis] +üstündə +bir +yalnız +və ya [vəla] +nəticə +öz +Ödə [Də, Ədə, Adə, Edə, Idə, Öndə, Ölə, Önə] +Şəftəli [Həftəlik] +yerlər +oynayır +oynamaq +əhali +porno [sponsor] +tərifləmək [təriflər, təklifləri, təkliflərlə, təkliflərə] +ehtimal ki [ehtimal] +ehtimal +psixik [psixi, psixoloji] +kraliça [kralı] +qaldırmaq +qalan +hörmət +qalxmaq +yol +xam +müqəddəs +Xilas et [Xilası] +elmi +çığırmaq [çağırmaq, çıxarmaq] +satılır +şəkil +xəstələnmək [xəstələnməyi, dəstəklənməsi] +gümüşçü [gümüş] +dəri +əsgər +bir şey [şeydir] +Mahnı +mahnılar +qılınclar [qılınc lar, qılınc-lar, qılıncı] +büyü [böyüyü] +casuslar [ruslar] +ulduz +Stansiya +oğurlamaq [vurğulamaq] +daşlar +günəş +şübhəli +İsveç +qılınclar [qılınc lar, qılınc-lar, qılıncı] +yeniyetmə +test +dandan [andan, candan, qandan, yandan, danışanda, adından, yanından, canından] +bu ki [builki] +bu ki [builki] +bu +onların +bu +onlar +düşünmək +bu +onlar +gel-git [get-gedə] +üçün +deyilmişəm [deyilmiş əm, deyilmiş-əm, deyilmişdi, deyilmiş, deyilmi, deyiləm] +çox +cəhd et [cəhdlər] +başa düşdüm [] +qilin [ilin, bilin, dilin] +titrəmək [itirməmək, itirmək] +mübarizə aparır? [] +istəyirəm +müharibə +idi +dalğalar [qadağalar, dağlarda, adalar, dağlar] +geymək [getmək, getməmək] +silahlar +yaxşı +idarə olunan [olunanlardan] +Qərbi [Hərbi, Qəbri, Qərb, Qərbin, Qəbir, Qərbə, Qəlbi] +nə +arasında +qalib gəlmək [qaliblərin] +qalib gəlir [qalibləri] +ilə +qadın +dünya +səhv +siz +sizə +sənsən [səndən, sən sən, sən-sən, nədənsə, mənsə, sənə, səslənən] +sənin diff --git a/Common/3dParty/hunspell/test/dst/bg_BG.txt b/Common/3dParty/hunspell/test/dst/bg_BG.txt new file mode 100644 index 00000000000..57cc73c5c72 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/bg_BG.txt @@ -0,0 +1,212 @@ +A [А, Е, О, И, В, С, Я, У] +остаряване +Алдераан [Дерайлиран] +всичко +също +и +отговор +са +изкуство +като +в +далеч +бебе +мазе +бъда +било +роден +булевард +почивка +породи +невеста +но +купувам +от +Калифорния +Калифорникация [Калифорнийския, Калифорнийка, Калифорния] +може +карти +шанс +Китай +брадичка +клубове +Кобейн [Кобен] +съзвездие +контрол +цена +не можех [можехме] +създаване +проклятие +танц +сделка +сделки +унищожение +диаманти +не прави [неправи, неуправии, неправдиви] +не правим [непоправим] +мечта +мечти +Изток +ръб +ръбове +екстаз +всеки +далеч +приказка +избледнява +лица +краен +намирам +първи +за +от +предел +момиче +момичето +добре +китара +ръка +хардкор [хардуер] +има +няма +той +чуя +сърце +той е [той] +нейни +скрит +висок +него +негов +Холивуд +аз +аз съм [разсъмна] +ако +в +информация +вътре +е +това е [товарен] +вале +просто +крал +родственик +знам +определен +закон +поставям +водя +води +местоположение +обичам +късмет +направен +човек +много +Ожени се [Брожение] +маска +май +може би [можещи] +означава +аз +медитация +спомен +ума +пари +моя +никога +не +нищо +числа +от +изключен +на +един +само +или +изход +свой +Плати +праскова +места +играе +играя +население +порно [бурно, орно, порено, опорно, спорно, упорно, порна, парно, порне, поено, порни, потно, торно, морно, горно] +похвала +вероятно +вероятен +психичен +кралица +въздигам +останал +почит +възход +път +груб +светия +Спасявам +наука +крясък +продава +форма +по-болен +златар +кожа +войник +някаква +Песен +песни +пикове +заклинание +шпиони +звезда +стация [станция, стария, статия, стадия, атестация, стагнация] +крада +камъни +слънце +подозрителен +Швеция +мечове +тийнейджър [тинейджър, пейджър] +тест +отколкото +това +това е [товарен] +на +техни +тези +те с [тесте] +мисли +този +той +прилив +до +каза +също +опитайте +разбрано +еднорог [едно рог, еднороден] +вибрация +водене? [водене, неводен, воден] +искам +война +беше +вълни +носете +оръжия +Ами +бяха +Западна +какво +докато +победа +победи +със +жена +свят +грешка +ти +ти би [табиети] +ти си [тифуси] +вашият diff --git a/Common/3dParty/hunspell/test/dst/ca_ES.txt b/Common/3dParty/hunspell/test/dst/ca_ES.txt new file mode 100644 index 00000000000..be726d0d8a2 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ca_ES.txt @@ -0,0 +1,112 @@ +amor +llum +lluum [lluu, llum, lluus, lluïm, lluu m] +esperança +espirança [esperança, espirant, espinçadora, espinça, espira] +llibertat +força +forrça [forra, força, forçar] +pau +somni +llibre +mar +amistat +cançó +flor +cel +estrella +temps +camí +vent +muntanya +mumntanya [muntanya, muntanyà, muntant] +riu +soroll +silenci +viatge +foc +gel +paraula +vida +dia +nit +tarda +matí +lluna +sol +llac +marbre +ferro +sal +mel +sucre +peix +ocell +oceoll [ocell] +joc +ritme +melodia +pintura +pentura [puntera, entura, pintura, puntura, ventura, penetrant, apertura, parapent] +teatre +dansa +poema +història +llegenda +mitologia +festa +música +vi +cervesa +cervessa [cervesa, cer vessa, cer-vessa, cerves sa, cerves-sa, cervesera, cerveseria, cerveser, cessava] +formatge +pa +ciutat +poble +natura +camp +bosc +platja +sorra +sorrà +pedra +ànima +cos +ment +cor +somriure +somriàre [somriure, somrient] +abraçada +bes +parla +oida [oidà, oïda, ioda, odia, aido, oia, oda, oiada, oxida, aida, sida, onda, mida, dida, vida] +vista +tacte +gust +olfacte +color +forma +número +lletra +sistema +regla +escola +universitat +univversitat [universitat, universitari, universalitat, universalitzat, universalista] +mestre +estudiant +sabiduria [sabuderia] +lliçó +pregunta +resposta +risposta [resposta, disposta, ris posta, ris-posta, risp osta, risp-osta, trasposta, posteritat, riosta, polvorista] +dubte +certesa +veritat +mentida +promesa +secret +descoberta +descaberta [descoberta, desca berta, desca-berta, descabestrat, descartable, descabota, descarta] +aventura +destinació diff --git a/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt b/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt new file mode 100644 index 00000000000..87fc1cc63ba --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt @@ -0,0 +1,212 @@ +A +envellir +Alderaan [Aldebaran, Aldebrand, Aldeana, Anedera] +tot +també +I +resposta +és +art +com +a +lluny +nadó +celler +ser +ha estat [hastat] +nat +bulevard +pausa +generacions +núvia +però +comprar +amb +Califòrnia +Californication [Californiana, Californita] +pot +cartes +oportunitat +Xina +mentó +clubs +Cobain [Cobai, Cobais, Cobrin, Cob ain, Cob-ain, Cobalamina] +signe del zodíac [signé del zodíac, signè del zodíac, sígne del zodíac, sïgne del zodíac, signE del zodíac, Signe del zodíac, sIgne del zodíac, sigNe del zodíac, siGne del zodíac] +control +preu +no podria [nodriria, podriria, nodria] +crear +maleït +ballar +acord +negocis +destructiu +diamants +no fer [noosfera] +no fem [nomenem] +desitjar +somnis +Est +vora +voreres +satisfacció +tots +llunyà +fada +pallid [pallis, palli, pallin, pali] +cara +final +trobar +primer +per +de +frontera +noia +la noia [la noïa, la Noia] +bé +guitarra +mà +hardcore [recordar] +hi ha [hifa] +no hi ha [nó hi ha, nò hi ha, nO hi ha, No hi ha] +ell +sentir +cor +ell és [estellés] +seva +secret +alt +ell +seu +Hollywood +jo +sóc +si +en +informació +interior +és +és +jack +només +rei +parent +saber +fixat +llei +col·locar +plom +portar +col·locació +lloc +estimar +oportunitat +fet +home +molts +casar-se +màscara +podria +potser +sentit +jo +meditació +memòria +ment +diners +meu +mai +no +res +números +de +fora +sobre +un +només +o +resultat +seu +pagar +préssec +llocs +jugar +joc +població +porno +elogiar +probablement +probable +psíquic +reina +elevar +restant +respecte +pujar +camí +cru +sant +salvar +ciència +crit +vendre’s [vendre's, vendre] +figura +malalt +joier +pell +soldat +alguna cosa [glucosamina] +cançó +cançons +cims +encanteri +espies +estrella +estació +robar +pedres +sol +sospitós +Suècia +espases +adolescent +prova +que +que +això +seu +aqueixos +ells +pensar +aqueix +ells +marees +per +no he estat [nó he estat, nò he estat, nO he estat, No he estat] +molt +intentar +entendre +fer +tremolar +lluitar +desitjar +guerra +va ser [vaser, serva] +ones +portar +armes +bé +administrat +Oest +què +entre +guanyar +guanya +amb +dona +món +equivocat +tu +vostè +tu ets [tubets] +teu diff --git a/Common/3dParty/hunspell/test/dst/cs_CZ.txt b/Common/3dParty/hunspell/test/dst/cs_CZ.txt new file mode 100644 index 00000000000..916cc8419c4 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/cs_CZ.txt @@ -0,0 +1,206 @@ +pomaliý [pomalý, pomaličku] +šťstný [šťastný] +smuutný [smutný, smutnu] +horcký [horký, horácký, horecký, horský, hornický, horňácký] +studiený [studený, studie] +záludnast [záludnost, záludný] +náhodillost [nahodilost, náhodnost] +úpěnlevý [úpěnlivý, úpletový] +rozspačitý [rozpačitý, rozpačitěný] +svéhllavý [svéhlavý, svéhlavička] +jablko +slunce +voda +dům +pták +káva +chleba +květina +kniha +pes +kočka +město +zelený +modrý +červený +bílý +černý +velký +malý +rychlý +pomalý +šťastný +smutný +horký +studený +nový +starý +hezký +ošklivý +dobrý +špatný +zdravý +nemocný +silný +slabý +chytrý +hloupý +pracovat +jíst +pít +spát +číst +psát +mluvit +smát se [smát] +plakat +zpívat +hrát +tančit +učit se [učitele] +nakupovat +vařit +telefonovat +dívat se [sedívat] +poslouchat +chodit +běžet +létat +plavat +psát +učit se [učitele] +dělat +mít +být +jít +přijít +odejít +dát +vzít +říct +vidět +slyšet +cítit +myslet +chtít +moct +muset +rád +nerad +ano +ne +prosím +děkuji +na shledanou [shledanou, dohledanou, shledávanou, ohledanou] +omlouvám se [omlouvání] +sbohem +ahoj +čau +hej +jo +fakt +super +blbost +paráda +no jo [nojo] +jasně +takže +vlastně +třeba +snad +leštěnka +pochmurný +živelný +ponaučení +záhada +pochybnost +nádhera +soucit +záludnost +náhodilost [nahodilost, náhodnost] +úpěnlivý +rozpačitý +svéhlavý +marnivost +blahodar [blaho dar, blaho-dar, lahoda] +rozčarování +odchylka +přelud +vytrvalost +neústupnost +lehkost +souznění +rozmarnost +roztržitost +úskočnost +rozkoš +marasmus +rozpolcenost +neúprosnost +ztřeštěnost +chmurnost +okouzlení +zářivost +vyrovnanost +neochvějnost +neúcta +bizarnost +rozmařilost +nepochopení +nevýslovný +pomíjivost +beznaděj +úzkost +odtažitost +rozerv [rozerve, rozervi, rozervu, rezerv, rozervat] +rozervanost +vyčerpanost +bezcitnost +záludnost +nezdolnost +rozkošátnost [rozkošnost, rozkošatěnost, rozkošnickost, rozkoktanost] +nezdolatelnost +rozmarnost +živelnost +bezútěšnost +záhadnost +neposkvrnitelnost [nepotiskovatelnost, nepopisovatelnost, nepřemostitelnost, nezvratitelnost] +rozkošnělost [rozkošatělost, rozkošnost, rozkošnickost, rozkošatěnost] +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +rozervanost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +bezbřehost diff --git a/Common/3dParty/hunspell/test/dst/da_DK.txt b/Common/3dParty/hunspell/test/dst/da_DK.txt new file mode 100644 index 00000000000..b7a362e12d2 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/da_DK.txt @@ -0,0 +1,129 @@ +Hej +Goddag +Tak +Ja +Nej +Måske +Mad +Vand +Hus +Bil +Tog +Cykel +Skole +Børn +Far +Mor +Søster +Bror +Hund +Kat +Fisk +Fugl +Træ +Blomst +Græs +Sol +Måne +Himmel +Regn +Sne +Sommer +Vinter +Forår +Efterår +Aften +Nat +Dag +Uge +Måned +År +Læse +Skrive +Tale +Lære [Lære, Læres, Lærer, Læren, Læreø, Læreå, læreå] +Arbejde +Sove +Vågne +Løbe +Gå +Sidde +Stå +Lytte +Se +Høre [Høre, Høres, Hører, Høreø, Høreå, høreå] +Spise +Drikke +Kød +Frugt +Grøntsager +Ost +Brød +Vand +Juice +Kaffe +Te +Mælk +Smør [Smør, Smøre, Smørs, Smør'] +Æg +Salt +Peber +Sukker +Bolle +Smørrebrød +Køkken +Stue +Soveværelse +Badeværelse +Toilet +Bord +Stol +Sofa +Lampe +Vindue +Dør +Gulv +Loft +Væg +Sofa +Pude +Tæppe +Badekar +Håndvask +Spejl +Håndklæde +Seng +Dyne +Dynee [Dynes, Dyner, Dyne, Dynen, Dynge, Dynees, Dynete, Dyneel, Dynele, Dyneed, Dyneeg, Dyneem, Dynefe, Dyneve] +Pude +Pudee [Pudene, Pudre, Puder, Pude, Pudes, Pudse, Puden, Pudet, Pudel] +Alarm +Alarmm [Alarm, Alarms] +Skrivebord +Stol +Hus +Hund +Kat +Katt [Kett, Katy, Katty, Kate, Kitt, Kata, Kato, Matt, Watt, Kat, Kast, Kats, Takt, Kart, Katte] +Bil +Skole +Skolee [Skolie, Skolede, Skoler, Skole, Skoles, Skolen, Skolet, Skolde] +Sol +Soll [Sol, Sole, Sols, Soli, Sola, Sall, Sold, Solo, Soul] +Vand +Vandd [Vanda, Vandy, Vandt, Vand, Vands, Vande, Vandr] +Mad +Madd [Mads, Maud, Mad, Made, Mand] +By +Barn +Barnn [Barni, Baran, Barny, Barn, Baren, Barns, Baron] +Tørklæde +Skæbne +Uafhængighed +Kærlighed +Kærligheed [Kærlighed, Ærlighed, Hæderlighed, Herlighed, Liderlighed] +overbelastning +Modstandsbevægelsen +Uafhængighedserklæringen +Forårssommertemperaturen +Stabiliseringsperioden diff --git a/Common/3dParty/hunspell/test/dst/de_AT.txt b/Common/3dParty/hunspell/test/dst/de_AT.txt new file mode 100644 index 00000000000..060081d0113 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_AT.txt @@ -0,0 +1,131 @@ +Ägyptologie +Ährenamt [Ährensamt, Ährenast, Ährenart, Ährenact, Ährenabt, Ährenakt, Ährenaxt, Ehrenamt, Ohrenamt, -ährenamt, Ährenartig] +Ängstlichkeit +Äquatoria +Abarbeiten +Abbild +Abbilden +Abbildungs [Abbildung, Abbildungs-, Bildungsnah, Unbildung] +Abbreviatur +Abbrüche +Abfassen +Abfertigen +Abfolge +Abfuhr +Ableugnen +Ablichten +Ablöse +Absätze +Abschnitts +Abwechseln +Abwehren +Aktiv +Britannia +Browserfenster +Budgetieren +Bugpartie +Bukarester +Burgundersoße +Butterkrem +Button +Cabriolet +Campanile +Canapé +Caprice +Celsius +Chamäleon +Charakteristik +Chronometer +Chronometrie +Cölln +Connectzustände +Cursorspur +Däne +Dachs +Dahindämmern +Darbringen +Daten +Datenbankserver +Desktopsystem +Detektivfilm +Dichtertum +Dinosaurier +Direktion +Diskantgambe +Diskothek +Druckereicode +Kapsel +Karausche +Katzen +Klinge +Klinke +Kohlrabi +Koinzidenz +Kolleg +Komplott +Meereis +Mehrphasigkeit +Memorieren +Messen +Methode +Metrowaggon +Meute +Migräne +Milieuforschung +Mindern +Mineralien +Mitternacht +Mobiliar +Mohrrübe +Mühelosigkeit +Normativität +Notifikation +Ökonomie +Orangeton +Osten +Subjekt +Subsidiarität +Subsumieren +Tagfalter +Speicher +Spielzeugsammlung +Zahler + +Сложные слова [] +Zurückgezogenheit +Äquipotentialfläche +Äußerungsbedeutung +Abfassungszeitraum +Abgeschlossenheits [Abgeschlossenheit, Abgeschlossenheits-, Unabgeschlossenheit, Aufgeschlossenheit, Abgeschlagenheit, Geschlossenheit] +Adjunktionsbeseitigung +Anknüpfungsgrundsätze +Chiffrierschlüssel +Knochenmarktransplantation +Bundeskaderathlet +Carbonsäurechlorid +Cardiazoltherapie +Chancenungleichheit +Charakterisierungsmöglichkeit +Chlorophyllkonzentration +Computerspielemarkt +Deindustrialisieren +Dekodierungsmöglichkeit +Kartoffelschälmesser +Kernspinresonanztomographie +Merkmalskombination +Nachbarschaftszentren +Opportunitätsprinzip +Tiefenstaffelung +Tourismusfachmann +Sequenzbetrachtung + +Слова с ошибками [] +Dechifrierprogramm [Dechiffrierprogramm, Liederprogramm] +Administratorkenwort [Administratorkennwort, Administratorkonto, Administratorrecht, Distriktadministrator, Distriktsadministrator] +Spigeln [Spiegeln] +Tätigkeite [Tätigkeit, Tätigkeiten, Untätigkeit, Nagetätigkeit, Mildtätigkeit, Regietätigkeit] +Draufgangertum [Draufgängertum, Draufgänger] +Abschnit [Abschnitt, Abschritt] +Komunikation [Kommunikation, Exkommunikation, Kommunikativ, Kommunikator, Komplikation] +Drackereicode [Druckereicode, Dreidecker] +Bumeln [Baumeln, Bummeln, Blumen, Brummeln, Bummel] diff --git a/Common/3dParty/hunspell/test/dst/de_CH.txt b/Common/3dParty/hunspell/test/dst/de_CH.txt new file mode 100644 index 00000000000..196e03636bf --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_CH.txt @@ -0,0 +1,116 @@ +Alpinist +Alteration +Alternative +Alumne +Amateurfilmer +Ambulanz +Amtmänner +Analogie +Analytik +Ananas +Angabe +Ankünfte +Dynastie +Ebenbürtigkeit +Echtheitszertifikat +Editionspläne +Editor +Ehrenamtlichkeit +Eigentümerschaft +Einbau +Eindringling +Eingabequittungsbetrieb +Einhüllen +Einkommen +Einloggen +Einschließen [Einschliessen, Einschliefen] +Einsortier [Einsortier-, Einsorter, Eintortier, Einportier, Einvortier, Einsortiere, Einsortiert, Unsortierter, Unsortiert, Einzusortieren, Sortieren] +Elaboration +Elementar +Entertainer +Entkuppeln +Entschädigungs [Entschädigung, Entschädigungs-, Entschädigungslos, Entschädigens, Entschädigen] +Enumerator +Erbringen +Erdichten +Erfahrenheit +Erhalt +Erleichtern +Ersparnis +Erstatten +Erzählliteratur +Helikopter +Helpdesk +Herunterladen +Hindeuten +Hinterlassenschaft +Hiob +Landesprache [Landessprache, Landesrache, Landsprache, Ladesprache, -landesprache] +flexibilität [Flexibilität, -flexibilität, flexibilisiert] +floristisch +flugbillet [Flugbillet, -flugbillet, flugbereit] +heroben +herrichten +herstellen +herübereilen +herunterzubücken +hie +hieraus +hilfe [Hilfe, hilf, hilfe-, -hilfe, helfe, hilft, hälfe] +himbeere [Himbeere, -himbeere, himbeer-, himbeerrot] +justiz [Justiz, justiz-, -justiz, justiziell] +kältebeständig +kärtchen [Kärtchen, -kärtchen, Gärtchen, Bärtchen, kärglichen] +känguru [Känguru, -känguru] +kaktusgewächs [Kaktusgewächs, -kaktusgewächs, ausgewechselt] +kalligrafie [Kalligrafie, -kalligrafie, kalligrafiere, kalligrafische, kalligrafisch] +kamel [Kamel, kamel-, -kamel, kamen, rammel] +kampagnendirektor [Kampagnendirektor, -kampagnendirektor, kampagnenartig] +kapazitär +kapitalist [Kapitalist, -kapitalist, kapital ist, kapital-ist, kapitalistisch, kapitalisierst, kapitalisiert, kapitalstark] +karamell [Karamell, karamell-, -karamell, lamellar] +kardieren +karpfen [Karpfen, -karpfen, krampfen] +katalogdaten [Katalogdaten, -katalogdaten, katalogartigen] +lyzeum [Lyzeum, -lyzeum] +mahagonirot +makkaroni [Makkaroni, -makkaroni, marokkanisch] +malerausbildung [Malerausbildung, -malerausbildung, ausbildungsreif] +management [Management, -management, managen, gemanagt, angemahnt] +mangel +maniküre +manneskraft [Manneskraft, -manneskraft, maskenhaft] +mansarde [Mansarde, -mansarde, ansparende] +mark [Mark, -mark, merk, park, Sark, Park, Bark, markig] +marketingpraktiker [Marketingpraktiker, -marketingpraktiker, marketingorientiert, marketingwirksamer] +maschinell +massage [Massage, massage-, -massage, massige, Passage, Gassage, passagere] +massengutschifffahrt [Massengutschifffahrt, -massengutschifffahrt, maschinenschriftlich] +materie [Materie, -materie, materiell, materiefrei, maturiere, mattier] +medaille [Medaille, -medaille, medaillenlos] +medizinalshampoo [Medizinalshampoo, -medizinalshampoo, sozialmedizinisch] +meeresfrüchte [Meeresfrüchte, -meeresfrüchte, Heeresfrüchte, meeresfeuchte, meeresfeucht, früchtereiche, früchtereich] +quotient [Quotient, -quotient, quotiert, quotieren, quotiere, quotisieren] +salonwagen [Salonwagen, -salonwagen, lossagen] +satzeinleitend +trilateral +tristesse [Tristesse, -tristesse, tristeste, trist esse, trist-esse, triste, rissfeste, stresse, rissfest] +tropen [Tropen, tropfen, tropen-, -tropen, trogen, tropenfest] +vereisen +verfahren +verfügungs [verfügungs-, verfügen] +verhindern +verkäufer [Verkäufer, -verkäufer, verkämpfe, verkaufe, verkupfer] + +Слова с ошибками [] +Anbindungsystem [Anbindungssystem] +Anglistikdocent [Anglistikdozent, Anglistikstudent, Linguistikdozent] +Ecco [Echo, Codec] +Economclass [Economyclass, Economyklasse] +Einverstandnis [Einverständnis, Einverstandanis, Einverstandnils, Einverstandeis, Einverstandnil, Einverstanden, Seinsverständnis, Koranverständnis, Unverständnis] +Electrik [Elektrik, Electrabel] +Historique [Historisiere, Historie] +herüberzurucken [herüberzugucken, herüberzurücken, herüberzulocken, herüberzustrecken, herüberzublicken, herüberzuschicken] +kartofel [kartoniere] +salade [malade, lade] +sanddornbere [versandbereite] diff --git a/Common/3dParty/hunspell/test/dst/de_DE.txt b/Common/3dParty/hunspell/test/dst/de_DE.txt new file mode 100644 index 00000000000..36cde4a624e --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_DE.txt @@ -0,0 +1,211 @@ +Hallo +Guten Morgen [Morgenläuten, Morgenröten] +Danke +Bitte +Ja +Nein +Entschuldigung +Tschüss +Liebe +Freund +Familie +Glück +Gesundheit +Schule +Arbeit +Essen +Trinken +Wasser +Brot +Käse +Fleisch +Gemüse +Obst +Kaffee +Tee +Milch +Zucker +Salz +Pfeffer +Haus +Wohnung +Bett +Stuhl +Tisch +Sofa +Fernseher +Telefon +Computer +Buch +Zeitung +Schreiben +Lesen +Hören +Sehen +Fühlen +Laufen +Springen +Schwimmen +Tanzen +Singen +Lachen +Weinen +Freude +Trauer +Angst +Mut +Liebe +Hass +Freundschaft +Beziehung +Familie +Eltern +Kinder +Geschwister +Großeltern +Onkel +Tante +Cousin +Cousine +Ehemann +Ehefrau +Verlobung +Hochzeit +Scheidung +Geburt +Tod +Krankheit +Arzt +Krankenhaus +Medikament +Apotheke +Gesundheit +Wohlbefinden +Fitness +Diät +Schlaf +Ruhe +Entspannung +Sport +Fußball +Tennis +Schwimmen +Laufen +Radfahren +Wandern +Reisen +Urlaub +Strand +Sonne +Meer +Komplementär +Perspektive +Konsens +Integrität +Konsequenz +Authentizität +Korrelation +Charakteristik +Akzeptanz +Flexibilität +Assoziation +Dekomposition +Komplexität +Positivismus +Universalität +Stabilität +Individualität +Konsistenz +Konformität +Dezentralisierung +Kollaboration +Partizipation +Präzision +Transformation +Konkurrenz +Paradoxie +Redundanz +Regeneration +Integration +Isolation +Asymmetrie +Aggregation +Disziplin +Resilienz +Relevanz +Konfusion +Komplikation +Koordination +Harmonie +Ineffizienz +Konstruktion +Konversion +Kollusion +Gerontologie +Differenzierung +Dimensionalität +Inferenz +Fluktuation +Kontraktion +Rezession +Inflation +Dekontamination +Exzellenz +Innovation +Isomorphie +Konnotation +Insuffizienz +Konversion +Kompensation +Koalition +Inkongruenz +Inkontinenz +Kontrahent +Konfiskation +Konjunktur +Aggression +Konfrontation +Kompatibilität +Prognose +Akzeleration +Konstruktion +Diversifikation +Prävention +Sanktion +Indikation +Reduktion +Konkurrenz +Konfiguration +Konnotation +Rezession +Transformation +Interaktion +Kooperation +Innovation +Kollision +Proklamation +Konnotation +Konfrontation +Disposition +Konkordanz +Deklamation +Kollaboration +Isolation +Inflation +Diversifikation +Konnotation +Kompensation +Diffusion +Dekadenz +Konserve +Deklomotion [Deklamation, Deklination, Deletionsklon] +Kolaboration [Kollaboration, Kollaborativ, Elaboration, Korporation, Inkorporation] +Isollation [Isolation, Installation, Kollation, Solmisation, Spallation] +Infllation [Inflation, Inflationär, Inflammation, Inflationiere, Installation] +Divirsifikation [Diversifikation, Ossifikation, Kodifikation, Ratifikation] +Konotation [Konnotation, Korotation, Kinotation, Kontotation, Ökonotation, Konnotativ, Annotation, Notation, Konfrontation] +Kompenssation [Kompensation] +Difusion [Diffusion, Gasdiffusion, Infusion, Diskussion, Fusion] +Dekadens [Dekaden, Dekadenz, Dekadent, Dekade, Dekans, Dekagons, Dekkans] +Kanzerve [Verwanze] + diff --git a/Common/3dParty/hunspell/test/dst/el_GR.txt b/Common/3dParty/hunspell/test/dst/el_GR.txt new file mode 100644 index 00000000000..cc8cf011f27 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/el_GR.txt @@ -0,0 +1,123 @@ +Αβαντάζ +Αβασταγά +Αβγάτισες +αβέβαιο +αβέλτερο +αβέλτεροι +αβίαστους +άβλαβοι +αβοκάντο +αβράδιαστης +άβραστη +αβράχυντου +άβρεχτα +αβρή +αβρότης +άβυσσον +αγαθόν +αγαθούς +αγάλακτο +αγγούρι +αγελαδινού +αγέρα +αγεωμέτρητων +αγίνωτοι +άγκυρες +αγορεύσεις +αγόρευσή +αγορίνα +Αγοριού +Αγροληψία +Αρμόνια +βγαίνοντας +βεβαιώσεων +διάθεση +διαίρεση +Διαιρέσου +Διαιτολογίου +διαψεύσουν +διδασκάλισσας +ενασκήσεις +ενασχόληση +ενασχόλησή +ενδείξεις +ενδεχόμενον +ενδιαμέσου +Επιστήθιες +Επιστημο [Επιστημοσύνη] +Επιστολές +Επιστολή +εύπορους +ευρέα +ευρημάτων +ευρύτητά +ευσταθών +εύστροφα +ευσυνειδησία +εύτακτε +ευτελείς +ευτελίζουν +ιδρυτικό +ιεροψάλτες +Ιζόλα +Ιθαγένειάς +ικανότατος +ιλαρότης +κεφαλής +κεφαλιάτικες +κεφαλωτές +κήπε +κήπευση +Κήρυξής +Λεξικογραφιών +Λεξιλογικός +λεοντή +λεοντής +ολιγοχρόνιου +ολικέ +ολικές +ολική +πελαγώνω +πελατών +πελάων +προστατεύει +προστασίας +σούρουπου +σουρούπωμα +σούρτης +Σούρωνα +Σπαγέτα +Σφάλμα +Σφάλματά +σφικτά +σφικτέ +σφοδρότητας +σφοδρού +σφραγίσω +σχεδιάζουμε +σχεδιάζουν +σχηματίσου +σχηματίσουμε +σχολιάζεσαι +Σχολιάζεστε +Ενδιαφέροντα + +Слова с ошибками [] +Αβασiλευτου [Αβασίλευτου, Αβασίλευτο, Αβόλευτου] +αγαπούσαv [αγαπούσα, αγαπούσαν, αγαπούσε] +βeβαιωμένοι [βεβαιωμένοι, βεβαιωμένο] +εvασxόλησης [ενασχόλησης] +επιoτολικέ [επιστολικέ, επιστολικό] +ιδιωτικοποιήσειc [ιδιωτικοποιήσει, ιδιωτικοποιήσεις, ιδιωτικοποιήσετε, ιδιωτικοποιήσεως, ιδιωτικοποιήσεων, ιδιωτικοποιήστε] +λεπταίσθnτη [λεπταίσθητη, λεπταίσθητα, λεπταίσθητε, λεπταίσθητο] +πρoστιμάρισμα [προστιμάρισμα, στιμάρισμα] +σφάλμαtα [σφάλματα, σφάλμα] +προστάτεuε [προστάτευε, προστάτεψε, προστάτευσε, προστάτες, προστάτευα, προστάτευσα] +κεxριμπαριού [κεχριμπαριού, κεχριμπαρένιο] +διαισθnτικότητες [διαισθητικότητες, διαισθητικότητας, διαισθητικότητα, διαισθητικότης, αισθητικότητες] +αγκιστpώσουv [αγκιστρώσουν] +αγαθoεργiας [αγαθοεργίας] +αβεβαιoτητά [αβεβαιότητά, βεβαιότητά] +αγέρεc [αγέρες] +διδαxθούμε [διδαχθούμε, διδαχτούμε] +εuσταθειώv [ευσταθειών] diff --git a/Common/3dParty/hunspell/test/dst/en_AU.txt b/Common/3dParty/hunspell/test/dst/en_AU.txt new file mode 100644 index 00000000000..55691a415f1 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_AU.txt @@ -0,0 +1,116 @@ +Acknowledge +acrophobia +adventurousness +aeronautics +algal +Alligator +allegation +alphabetise +Analogy +appropriable +assembly +attempt +Average +barbecue +bathtub +begun +belongingness +Better +binary +blackberry +boatswain +bow-tie +brambly +bright-eyed +bubble +Calender +cancellous +cantankerousness +carefree +categorized [categorised, categorise, categorisation, category, decorticated, cauterised, avant-grist] +cellular +chaos +cheerfulise +childlike +circumstance +close-mouthed +Cocoa +coherent +co-located +Colours +controversial +cottage +creditworthiness +cut-down +dedicated +deep-freeze +Definitive +Designs +digital +distensible +dollar +dyslexia +Egyptian +effectively +etiquette +excess +exotica +fairly +feedback +features +figure's +fjord +forty-seven +government +haematomata +helpless +homologous +implant +Indemnify +inexpert +interior +localises +loquaciousness +maelstrom +mechanizable +melodious +mezzo-soprano +mozzie +municipalisation +mystifier +Neoclassicism +newsletter +non-professional +officiation +orientalisation +palaeoanthropography +parrot +pickpocket +pioneer +cryptanalytic +simplifying +sommelier +spicy +steward +subcontinental +swimwear +Technical +trajectory +wholesomeness +Advantageously +interindustry +red-eye +sub-group + +Слова с ошибками [] +Acredited [Credited, A credited, Accredited, Accredit, Accreted, Creditable, Discredit, Acridity, Aegritude] +agressive [aggressive, regressive, digressive, progressive, transgressive, aggressor, expressive] +appreciativiness [appreciativeness, appreciatively, appreciative, appreciation, apprehensiveness, operativeness, provocativeness] +aritmetical [arithmetical, arithmetica, arithmetic, hermetical, antithetical, paramedical, grammatical] +biosyntesized [biosynthesized, nonsynthesised, synthesised, amniocenteses, amniocentesis] +lisense [license, senilise, linenise, sensualise, sensise, licence, licensable] +paranoa [paranoia, paranoid, paranormal, paragon, panorama, Paringa, parental] +fotoelectronic [photoelectronic] +semi transparent [semitransparent, transparentise, non-transparent, transparency, semi-permanent, transpiration, superintendence] +synonymus [synonyms, synonymous, synonym's, synonym us, synonym-us, synonym, anonymous, synchronous, synoecious, anonymise, unanimous] +wordprocessing [word-processing] diff --git a/Common/3dParty/hunspell/test/dst/en_CA.txt b/Common/3dParty/hunspell/test/dst/en_CA.txt new file mode 100644 index 00000000000..a23012fcfa4 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_CA.txt @@ -0,0 +1,125 @@ +admire +admittance +aggrandizement +Airmen +Albatross +amateur +angling +apparatus +Architecture +assessment +attempt's +awakening +backgrounder +Balance's +barometric +bashfulness +beautiful +belletristic +blatancy +bonbon +border +Bottom +bountifulness +breakpoints +bulkiness +businesslike +can't +cash +castle +Casual +cauliflower +celebrity +childish +chokecherry +choreographically +chronological +classification +clearheaded +coalesce +Coexistence +collaborative +coloured's +concentration +draconian +drainpipe +demonstrativeness +dependence +dependency +dream +duplication +epidemiological +equitable +Essence +Exemption +exonerate +fainthearted +falsification +ferromagnetic +flammable +fraternization +French +frontier +gadget +galleria +Gallery +gateaux +geocache +ginger +glace +glacier +globalization +hockey +holiday +housemate +intensifier +joystick +Language +leaseholder +non-breakable +northerly +o'clock +oeuvre +openhandedness +oscillation +outface +outlaw +overladen +package +palazzo +panama +Paragraphs +Parliament +particular +pasteurization +pathogen +perception +phenomena +philanthropically +physical +populations +repugnance +request +resplendence +retroactive +rigidity +schedule's +School +scintillation +sensibility +settlement +taxiway +bereft + +Слова с ошибками [] +acomplishment [accomplishment, accomplish, compliment] +anihilate [annihilate, annihilator, annihilation] +caprise [caprice, cap rise, cap-rise, apprise] +chambre [chamber, chambray] +etnographically [ethnographically, pornographically, photographically, typographically, topographically] +horsmanship [horsemanship, sportsmanship, swordsmanship, marksmanship, showmanship] +innundation [inundation, foundation, annunciation, insinuation, intimidation] +lemongras [lemongrass, lemonades] +omelete [omelette, telemeter] +retorical [rhetorical, oratorical, categorical, theoretical, reportorial] +shepishness [sheepishness, snappishness, waspishness, impishness, foppishness] diff --git a/Common/3dParty/hunspell/test/dst/en_GB.txt b/Common/3dParty/hunspell/test/dst/en_GB.txt new file mode 100644 index 00000000000..3b8b7a1426f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_GB.txt @@ -0,0 +1,122 @@ +Abbreviation +Acceptability +acquirable +Addressee +afterthought +airworthiness +all-powerful +amateurishness +amorphousness +anthology +Auspiciousness +Bibliographer +Bilberry +birthday +bodyguard +broadleaved +brontosaurus +bumptiousness +Cabaret +Californian +calumny +cancellation +cantonal +capitalize +careful +carry-on +casino +clown +co-ordinate +cockleshell +decennial +deckchair +decryption +deep-freeze +Democracy +financial +fish-plate +Flamenco +housing +Hybrid +hydroelectricity +iceboat +ichthyology +idiomatic +ill-humoured +imperatrix +individuality +interocular +intrasectoral +ironwoods +Jolliness +Jurisprudent +knowledgable +kopeks +labour-intensive +laboratory +lake +language +larynx +latching +leakiness +License +licensed +licensee +life-threatening +linguistics +long-lived +machinable +mainsheet +Major +malleability +man-hour +Mango +ninety-five +nobody +non-blocking +non-judicial +nonconforming +north-Western +nutritiousness +quasi-synchronous +question +racoon [raccoon, racoon's, contra] +radish +Railway +Rarity +saucer +Save +Saying +supplely +tallish +target +Taxi +teach-in +technician +ultramodern +umbrae +uncertainness +unconstitutionality +washing +wasn't +waxen +weather +well-formed +what's-his-name +whereupon +Wi-Fi +Wikipedia + +Слова с ошибками [] +Abstractnes [Abstractness, Abstractedness, Abstracter, Abstraction, Abstracted] +advantageusness [advantageousness, advantageous] +arhythmical [rhythmical, arrhythmical, a rhythmical, arrhythmic, arrhythmia] +autosuggestibility [auto-suggestibility] +kaptor [captor] +coldshouldering [cold-shouldering] +humaneneses [humaneness, humanenesses, humannesses, humanness, humanises, humblenesses] +imaginativness [imaginativeness, imaginative, imaginableness, imitativeness] +knight-erantry [knight-errantry, straight-eight] +magasine [magazine, magnesia, imagine] +night-wachman [night-watchman, nightmarish] +qualifidly [qualifiedly, qualified, squalidly] diff --git a/Common/3dParty/hunspell/test/dst/en_US.txt b/Common/3dParty/hunspell/test/dst/en_US.txt new file mode 100644 index 00000000000..a1cd136a72b --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_US.txt @@ -0,0 +1,218 @@ +apple +banana +cat +dog +egg +fish +gold +house +ice +juice +kite +lion +mouse +night +orange +pencil +queen +rabbit +sun +tea +umbrella +vase +watch +xylophone +yellow +zebra +arrow +book +cake +car +day +elephant +flower +hat +island +jelly +king +lamp +moon +nose +owl +pink +quilt +radio +sunflower +tree +unicorn +violin +water +xylophone +yellow +zoo +apple juice [applesauce] +blue +calculator +desk +elephant +fire +goat +hat +ice cream [creamer] +jacket +key +lemon +map +notebook +owl +pear +quilt +rose +soccer +table +umbrella +vegetable +whale +xylophone +yellow +zebra +apple pie [pineapple] +beach +computer +drum +elephant +goat cheese [headcheese] +hat +ice skate [cheapskate] +juice box [jukebox] +kite festival [quite festival] +lemonade +mountain +notebook paper [] +orange juice [orangeade] +pizza +queen bee [quin bee, queen bi, keen bee, ween bee] +rainbow +snow +turtle +umbrella hat [umbrella] +valley +Aberration +Absolution +Acquiesce +Adumbrate +Aesthete +Altruistic +Ambivalent +Anomalous +Antediluvian +Antipathy +Aphorism +Apocryphal +Apostasy +Apparition +Arduous +Assiduous +Audacious +Austere +Autonomy +Avaricious +Axiomatic +Baleful +Bellicose +Belligerent +Bereft +Bilious +Bombastic +Cacophony +Capricious +Cartography +Castigate +Clandestine +Coalesce +Cogent +Cognizant +Colloquy +Concomitant +Confabulate +Congenial +Conundrum +Copious +Corpulent +Coven +Credulous +Culpable +Dearth +Debilitate +Deleterious +Denigrate +Despondent +Diatribe +Dilapidated +Disparage +Dissemble +Dissonance +Duplicity +Ebullient +Egregious +Ephemeral +Equanimity +Esoteric +Euphemism +Evanescent +Exacerbate +Exhort +Expatriate +Extol +Facetious +Fatuous +Feckless +Felicitous +Feral +Fervent +Fetter +Flummox +Fractious +Garrulous +Hegemony +Iconoclast +Idiosyncrasy +Ignominious +Impecunious +Ineffable +Inexorable +Inscrutable +Insidious +Intrepid +Intransigent +Invective +Irascible +Juxtapose +Kowtow +Languid +Lassitude +Lurid +Malinger +Maudlin +Mawkish +Mendacious +Metaphysical +Antransigent [Intransigent, Intransigence, Transient, Intransitive, Transcendent] +Inwective [Infective, Invective, Ineffective, Instinctive, Inactive] +Iracible [Irascible, Acquirable] +Juxtopose [Juxtapose, Juxtaposition] +Kovtow [Kowtow, Kowloon] +Langued [Languid, Languished] +Lasitude [Lassitude, Latitude] +Larid [Arid, L arid, La rid, La-rid, Laird, Lard, Laid, Lurid] +Mallinger [Malinger, Salinger, Lingering, Lingerer, Germinal] +Haudlin [Maudlin, Handling] +Mavkish [Mawkish, Mavis] +Mendocious [Mendacious, Mendocino] +Mitaphysical [Metaphysical, Physicality, Physical] +timeline [time line, time-line, timberline] +rollout [roll out, roll-out, rollover] +workshopped [work shopped, work-shopped, works hopped, works-hopped, workshop] +deliverables [deliverable, deliverable s, deliverers, deliberative, desirable] + + diff --git a/Common/3dParty/hunspell/test/dst/en_ZA.txt b/Common/3dParty/hunspell/test/dst/en_ZA.txt new file mode 100644 index 00000000000..89bb91d321f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_ZA.txt @@ -0,0 +1,114 @@ +Acceptably +Achievement +administrate +all-day +amount +average +bilayer +blasé +boutique +breezy +byers +cabdriver +carefree +categorised +Chameleon +cheerful +chronology +cliché +cooling-off +courage +crudités +decorates +dooryard +débâcle +electromotive +equalled +Exotica +fellow-traveller +forests +full-timer +graded +habitué +haven't +hide-and-seek +home-building +interaxial +kingdom +largeness +long-distance +Majority +manoeuvre +Matrix +metier +mightn't +multidisciplinary +night-time +officio +old-style +organize +overaggressive +packing +parenthesis +pince-nez +Plaint +play-act +policy-making +Preheat +prohibit +puzzle +queue +quite +re-enact +reason +ready-made +renewal +resize +rooihout +scampi +schoolteacher +sea-green +shop-boy +sidebar +skyscraper +soundless +spelling +stakeout +synchronizing +take-off +Thereof +Trademark +transportable +treatment +tweeness +under-age +unmake +Variate +Visitant +volume +webmaster +well-prepared +window +yesteryear +first-aid +Hydrant +inconstant +network +northernmost +nowhere +souvenir +telecommunicate + +Слова с ошибками [] +afordable [fordable, affordable, a fordable, formidable, recordable, foreseeable, adorable, avoidable, avoidably] +anthropologie [anthropology, anthropologies] +bagage [baggage, bag age, bag-age, Babbage, garbage, bagged, bagel, bakgat, ribcage] +comparatif [comparative, comparator, compatriot, comparable, comparability, comparably] +flammeble [flammable, flamelike, lamentable, blameless, flamed, flammability, flamboyance] +indivizible [indivisible, individualize, indiscernible, divisible, invincible, indefeasible, inadvisability] +jetlag [jet-lag] +lettrebox [letterbox, treble, storybook, legislature] +panoramma [panorama, Panorama, panoramic, paranormal, Panamanian, pentagram, paramagnet] +posessor [possessor, possess, assessor, processor, professor, poses, posses] +selfdoubt [self-doubt] +abandonner [abandoner, abandon, bandoleer, Ndondondwane, Bannerman, abundance, abundant] diff --git a/Common/3dParty/hunspell/test/dst/es_ES.txt b/Common/3dParty/hunspell/test/dst/es_ES.txt new file mode 100644 index 00000000000..c68b9446d3a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/es_ES.txt @@ -0,0 +1,208 @@ +nosotros +vosotros +ellos +ellas +aquí +allí +ahora +antes +después +siempre +nunca +también +solamente +verdad +mentira +bien +mal +grande +pequeño +rápido +lento +nuevo +viejo +bueno +malo +feliz +triste +bonito +feo +caliente +frío +dulce +amargo +fuerte +débil +cerca +lejos +fácil +difícil +cierto +falso +caro +barato +limpio +sucio +fuerte +débil +alto +bajo +claro +oscuro +abierto +cerrado +joven +viejo +corto +largo +alegre +tranquilo +nervioso +amable +grosero +conocido +desconocido +cortés +rudo +agradable +desagradable +sabroso +insípido +difícil +fácil +cansado +descansado +moderno +antiguo +último +primero +posible +imposible +rápido +lento +sencillo +complicado +propio +ajeno +abierto +cerrado +amable +desagradable +seguro +inseguro +correcto +incorrecto +dulce +amargo +Anacoreta +Sobrentender +Embriaguez +Inquebrantable +Empedernido +Derramamiento +Despotricar +Escafandra +Aletargamiento +Estancamiento +Descarado +Exégesis [Génesis] +Contrariedad +Espeluznante +Conspiración +Impedimenta +Deglutir +Engreído +Enmascarado +Exterminio +Embelesar +Permutación [Permutan] +Desesperanza +Impenetrable +Enarbolamiento [Enarbola miento, Enarbola-miento, Enrollamiento, Arrollamiento, Encarcelamiento, Eslabonamiento] +Errabundo +Deslinde +Inefable +Soliviantar +Embriaguez +Perdurable +Opulencia +Trémulo +Desembolso +Empedernido +Anquilosar +Enigmático +Inquebrantable +Contrincante +Desmesurado +Vanagloriar +Exasperar +Desvanecer +Perpetuidad +Desbaratar +Ineficaz +Zozobra +Elucubración +Ineludible +Desgarramiento +Atestiguar +Encascarar [Encascara, Encascaran, Encascaras, Enmascarar, Encascar, Encascar ar, Encascar-ar, Encascabelar, Encascotar, Enmascaran, Enmascara] +Desembozar +Irreverente +Soslayar +Despiadado +Embaucar +Moflete +Endilgar +Desfalco +Embelesamiento +Desestimar +Enajenación +Desavenencia +Inexorable +Atolladero +Egrégoro [Negror] +Desafiar +Afable +Enervar +Belicoso +Enervar +Descacharrante +Entramado +Inigualable +Perplejidad +Descabellado +Diligencia +Enaltecimiento +Desvergonzado +Arrebato +Empatía [Empata, Empate] +Endiosar +Peripecia +Desidia +Subversión +Desfachatado +Desfalco +Desvirtuar +Errático +Desahuciar +Envilecimiento +Empecinado +Estolidez +Despropósito +Engatusar +Culminante +Sobrentender +Enseñorear +Desacato +segguro [seguro, seg guro, seg-guro, seguiros, segur] +insseguro [inseguro, insegura] +correcto +incarrecto [incorrecto, insurrecto] +dalce [salce, dale, alce, dance, calce, dalle, dulce, d alce, cendal, cebadal, celda] +amergo [amero, mergo, amargo, amelgo, a mergo, amorgone] +Anasoreta [Anacoreta, Masoreta, Trasfretana, Asotanas, Asotanara] +Sobrententter [Sobrestante, Soberanamente, Sobriamente, Soberbiamente] +Embreagues [Embregues, Embragues, Embriagues, Embriaguemos, Embragares, Embrague, Embriague] +Inquebranttable [Inquebrantable, Quebrantable, Infranqueable, Intransitable] +Empidernedo [Empedernido, Empedernecer, Empedernir] + diff --git a/Common/3dParty/hunspell/test/dst/eu_ES.txt b/Common/3dParty/hunspell/test/dst/eu_ES.txt new file mode 100644 index 00000000000..a0335c41c03 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/eu_ES.txt @@ -0,0 +1,132 @@ +Abantza +ñabar +abasto +abegikortasun +aberaskeria +aberetzar +abezedario +abialdi +Abiatzaile +abizari +Aboli +abonatu +absenta +absolutibo +accelerando +adabegitsu +adberbio +adiaka +adierazle +adierazkizun +adikuntza +adin +adinaro +adineratu +adin-txikitasun +administratzaile +adoleszentzia +adopzio +adostu +aerolabangailu +Aeroplano +afalordu +agente +agertezin +agiantza +agoran +arradatze +arrakasta +Batata +baterakuntza +baterakor +Bateri +batuar +baud-abiadura +batzuenganako +batzuengandik +batzuengan +batzuengatik +batzuen +baxera +berezi +berezikeria +beritzete +beroa +Beroate +beroatza +berorri +berrabiatu +berra +berresgarri +berripaper +chap +dabilzkidake +dabilzkie +dagitza +dagokik +dagozkieke +erdiondu +galdera +galtzada +garaitiar +garantia +Garaztaketa +garbitasun +gastronomiko +Gaurgero +gaurgoitik +legizkie +legokizue +legozkidake +lehenbizi +nindoakio +publikotasun +publizitate +subsidiario +substantibo +sugestio +superbalorazio +taidun +taldeburu +Talent +Teknografia +xantxa +xerbitor +xerokopia +zabaldura +Zabalkor +Zabaltza +zabilzkieken +zabilzkio +zaharkote +zeneritzeketen +zenerra +zenezagu +zengozkigute +zeniharduke +zenioke +zenioketez +zeniraute +zenizkien +zenizkiguke +Zintut +Zintuzkedan +isiltasun + +Слова с ошибками [] +abriсot [abrikot, abrigo] +absenzia [absentzia] +addikzio [adikzio, dikzio, adukzio, adizio] +administraziozerbizu [administrazio-zerbitzu, administrazio-zuzenbide, administraziopean] +bat-bates [bat-batez] +bermagari [bermagarri, bermagailuari, bermagailuri, armagaberi, bermaguneari] +cataluniar [kataluniar, catalunyar, kataluniera] +dakarza [dakartza, dakarna, dakarzu] +erdemin [erremin, erdimin, iminerdi] +garatienetarikoa [garatuenetarikoa, ugarienetarikoa, gogoratuenetarikoa, argienetarikoa, aberatsenetarikoa] +ishil [isil, istil] +nindezaguane [nindezaguena, nindezaguan, nindezaguanez, nindezaguanek, nindezaguanen, nindezaguanei, nindezaguana, nindezagunan, nindezagutean, nindezagutenan, nindezaguzue] +nintzainaken [nintzainanek, nintzainake, nintzainakeen, nintzainanen, nintzaiakeenen, nintzaiakeen, nintzakenanen, nintzaiekenan] +summa [suma, susma, sumoa] +technologiko [teknologikoko, teknologiko, terminologiko, etnologikoko] +charmant [charmat, xarmant] diff --git a/Common/3dParty/hunspell/test/dst/fr_FR.txt b/Common/3dParty/hunspell/test/dst/fr_FR.txt new file mode 100644 index 00000000000..9b4428ca524 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/fr_FR.txt @@ -0,0 +1,211 @@ +Bonjour +Merci +Oui +Non +S'il +Excusez-moi +Pardon +Bien +Mal +Grosse +Petit +Beau +Moche +Fort +Faible +Chaud +Froid +Vite +Lent +Haut +Bas +Loin +Près +Heureux +Triste +Facile +Difficile +Simple +Compliqué +Bon +Mauvais +Nouveau +Vieux +Jeune +Âgé +Bienvenue +Amitié +Amour +Famille +Travail +Maison +Voiture +Manger +Boire +Courir +Marcher +Nager +Chanter +Dormir +Jouer +Parler +Écouter +Regarder +Lire +Écrire +Acheter +Vendre +Aller +Venir +Faire +Dire +Voir +Savoir +Apprendre +Aimer +Détester +Partir +Rester +Arriver +Revenir +Partager +Aider +Aimer +Ouvrir +Fermer +Manger +Boire +Avoir +Être +Pouvoir +Vouloir +Devoir +Parler +Écouter +Rire +Pleurer +Danse +Étudier +Travailler +Voyager +Vivre +Connaître +Reconnaître +Voyager +Exister +Choisir +Donner +Recevoir +Aimer +Oser +Phénoménologie +Électroencéphalographie +Parallélépipède +Anticonstitutionnellement +Transsubstantiation +Éclectisme +Anachronisme +Catéchuménat +Démagogie +Fructueux +Ineffable +Hypothèque +Propriété +Procrastination +Complaisance +Réminiscence +Éthique +Équinoxe +Exponentiel +Hétérogénéité +Imbroglio +Incorrigible +Maelström +Métaphysique +Protagoniste +Subliminal +Verrouillage +Volumétrique +Énigmatique +Époustouflant +Immatériel +Infini +Polyglotte +Recrudescence +Prophylactique +Symbiotique +Vestibulaire +Épistémologie +Faramineux +Géopolitique +Hypnotique +Inamovible +Intemporel +Labyrinthe +Pacifiste +Quémandeur +Soporifique +Ubuesque +Volumineux +Effervescence +Électrophorèse +Paradoxe +Prorata +Quadrupède +Sarcophage +Trigonométrie +Vaccinologie [Carcinologie, Actinologie, Vaccinogène, Accidentologie] +Xenophobe [Xénophobe, Technophobe] +Zéphyr +Génétique +Labyrintique [Labyrinthique] +Mégalo +Nostalgie +Omniprésent +Pangramme +Périlleux +Quinquennat +Rémunération +Scolopendre +Tautologique +Utopiste +Vexatoire +Wolof +Xanthine +Yacht +Zanzibar +Axiomatique +Chronométrer +Dilettante +Énervement +Facétieux +Générique +Harmonique +Illusoire +Juridique +Kabbaliste +Longetivité [Longévité] +Médiane +Néologisme +Oxygène +Patronymique +Quotidien +Rétorique [Rétorque, Rhétorique, Rotorique, Ré torique, Ré-torique, Météorique, Torique, Théorétique, Théorique] +Sémantique +Tautologie +Utopique +Vaccinologie [Carcinologie, Actinologie, Vaccinogène, Accidentologie] +Xénophobie +Yachting +Zoroastrisme +Voager [Viager, Voyager, Ouvrager] +Exisster [Exister] +Chaiser [Chaires, Chaise, Chaisier, Chaises, Chasser, Chaise r, Chamoiser, Tchadiser] +Doner [Toner, Zoner, Donner, Drone, Doser, Doter, Dorer, Douer, Doler, Doper, Dîner] +Resevoir [Redevoir, Recevoir, Revoir, Reversoir, Ivoire, Voire] +Aimmer [Aimer] +Osero [Oser, Osera, Oser o, Rosser, Roeser, Rose] +Phénoménollogie [Phénoménologie] +Électraencéphallographie [] +Parallélépepède [Parallélépipède] + diff --git a/Common/3dParty/hunspell/test/dst/gl_ES.txt b/Common/3dParty/hunspell/test/dst/gl_ES.txt new file mode 100644 index 00000000000..74cc6886333 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/gl_ES.txt @@ -0,0 +1,120 @@ +ola +tipo +Si +non +nonnr [nono] +comida +comidaa [comídaa, comidas, comida, comidan] +auga +augaa [áugaa, augas, auga, augaba, augada, augala, augara, augar] +casa +coche +cochee [coches, coche, chochee, cachee, checo] +un tren [oin tren] +bicicleta +escola +escolaa [escóraa, escoala, escolas, escola, escálaa, escolla, escolma, escolar, escolta] +niños +pai +paii [paio, pai, pii, aii, pali, pais] +nai +naii [nai, nii, aii, naif, nais, nazi] +irmá +irmán +cachorro +gato +gatoo [gato, atoo, gateo, gatos] +peixe +peixee [peidee, peixes, peixe, peitee] +aves +avess [aveas, avesa, aves, avesas, avesos, vesas, aveso, aveces, escave] +árbore +flor +herba +o sol [ou sol] +lúa +o ceo [ou ceo, o ceou] +chuvia +neve +vexa +inverno +primavera +outono +noite +noite +día +unha semana [semanalmente] +mes +ano +para ler [parable] +escribir +fala +ensinar +traballo +durmir +durmir +correr +vai +senta +estado +para escoitar [parasitario] +vexa +escoita +hai +beber +carne +furtas +verduras +queixo +pan +auga +zume +café +té +leite +aceite +ovo +sal +impacienta +azucre +un bocadillo [oin bocadillo] +cociña +sala de estar [sala dei estar] +dormitorio +baño +batela +sofá +lámpada +fiestra +a porta [aporta, portara, portador, porta] +piso +teito +parede +sofá +alfombra +baño +afundir +espello +toalla +cama +manta +almofada +reloxo de alarma [riloxo de alarma, ríloxo de alarma, reiloxo de alarma, reloxo dei alarma, relouxo de alarma, reloxou de alarma, relollo de alarma] +escritorio +cadeira +marabilloso +adverbio +obviamente +Dominante +residenciais +convidado +perigo +cuestión +deporte +mina +cordeiro +cabeza +tratar +avogado +intelixente +guapo diff --git a/Common/3dParty/hunspell/test/dst/hr_HR.txt b/Common/3dParty/hunspell/test/dst/hr_HR.txt new file mode 100644 index 00000000000..6ce3b0a0715 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/hr_HR.txt @@ -0,0 +1,215 @@ +boliestan [bolestan, obijestan] +jyak [jak] +slaby [slabu, slab, slaba, slabe, slabi, slabo] +pameetan [pametan, pametna, napamet] +gllup [glup] +bezuspješhno [bezuspješno, bezuspješnih, bezuspješan, bezuspješna] +besimeni [besi meni, besi-meni, bezimeni, besanim] +bezuzban [bezuman, bezuba] +blagastanje [blagostanje, blaga stanje, blaga-stanje, blagostanja, blistanje, oblaganje] +bljeskovica [bljeskovima, bljeskovi, bljeskova, bljeskalica, bljeskavi] +jabuka +sunce +voda +kuća +ptica +kava +kruh +cvijet +knjiga +pas +mačka +grad +zelen +plav +crven +bijel +crn +velik +malen +brz +spor +sretan +tužan +vruć +hladan +nov +star +lijep +ružan +dobar +loš +zdrav +bolestan +jak +slab +pametan +glup +raditi +jesti +piti +spavati +čitati +pisati +govoriti +smijati se [smijati] +plakati +pjevati +igrati +plesati +učiti se [učiti] +kupovati +kuhati +telefonirati +gledati +slušati +hodati +trčati +letjeti +plivati +čitati +pisati +raditi +imati +biti +ići +doći +otići +dati +uzeti +reći +vidjeti +čuti +osjetiti +misliti +htjeti +moći +morati +rado +nerado +da +ne +molim +hvala +doviđenja +oprosti +zbogom +zdravo +čau [ča, ču, čađu, čaju, čamu, času, čađ, čaj, čak, čar, čas, ča u] +ej +da +baš +super +glupost +fantastično +jasno +tako +zapravo +možda +lako +teško +prozračnost +usplahirenost +neoblomivost [neslomivom] +prezir +proigranost [prostranost, programiranosti, razigranosti, pristranost] +uznemirenost +besprijekornost +besprizornost [besprizornom, besprizornoj, besprijekornost, besprizorni] +nepredvidivost +beznadnost +promašenost [promašenosti, promašen, osiromašenom, raspršenost] +protivljenje +neizreciv +bezizlaznost +neuspjelost [neuspjeloj, neuspješnost, neuspjelog, neuspjelom] +zbunjenost +neodlučnost +protivština +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +bezduhovitost [bez duhovitost, bez-duhovitost, duhovitostu, duhovitosti, duhovitosta, duhovitost] +ravnodušnost +prolaznost +neobaveznost [neobaveznosti, neobaveznom, neobaveznoj, neobavezna, neobavezni] +bezbrižnost +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +promašenost [promašenosti, promašen, osiromašenom, raspršenost] +neprepoznatljivost [neprepoznatljivosti, ne prepoznatljivost, ne-prepoznatljivost, prepoznatljivosti, prepoznatljivost, neprepoznatljiva, neraspoznatljivosti] +neukrotivost [neukrotivog, neukrotiv, neučtivost, neotuđivosti] +bezobzirnost +nevinost +nestalnost +nepostojanost +bezizlaznost +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +prolaznost +neodgovornost +bezbrižnost +nevolja +nezadovoljstvo +prolaznost +bezuspješno +bezimeni +bezuzdan [bez uzdan, bez-uzdan, bezdan, bezdušan, beznadan] +blagostanje +bljeskavica [bljeskalica, bljeskavima, bljeska vica, bljeska-vica, bljeskavi, bljeskalici, bljeskava, bljeskalicu] +boren [borne, obrne, bore, oboren, borbena] +carovnija [otrovnija, darovnica] +crpeža [crteža] +dostojanstvo +duhovitost +egzaltacija +gorkoća [gorkoga, gorkošću] +histerija +idila +ironija +izdaja +janjetina +kajanje +kavana +krhotina +ljepljivost +lukavstvo +magnutizam [zategnutima, zamahnutima, izdignutima, vagnutima] +melankolija +misticizam +naivnost +nelagoda +neraspoloženje +obmana +okrutnost +opojenost [opojnost, obojenost, opojenoj, popunjenost, podvojenost, opčinjenost] +prezir +propast +ravnodušnost +sjenka +skitnica +spletka +stid +sudbina +susret +sudbina +šapat +tišina +trepet +utopija +uzaludnost +veličanstvo +zaborav +zanesenost +zanos +zavjera +zbunjenost +zluradost [zluradosti, zlu radost, zlu-radost, zlurad] +zloslutnost [zloslutnoj, zloslutnom, zloslutnu, zloslutna] +žargon +žártva [žrtva] +šaptanje +čarobnost +dileme +hodočasće [hodočaste, hodočašće] +lebdjeti +iznimka +preobilje [preobilne, preoblikuje] +probuditi se [probuditi] +surov diff --git a/Common/3dParty/hunspell/test/dst/hu_HU.txt b/Common/3dParty/hunspell/test/dst/hu_HU.txt new file mode 100644 index 00000000000..c925ed03d03 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/hu_HU.txt @@ -0,0 +1,114 @@ +Szorzótábla +Réges-régen +normálméret +nemeslelkűség +mindegyik +milliós +Mikroflóra +Mezőgazdaságigép +meséskönyv +mennyiség +Memória +kártya +kuráre +Kurzor +jégkorong +jellemesség +Javak +irányzás +iromány +Inkluzíve +hűtőedény +hőmérséklet +hír +hétszázas +hátrány +háromszáz +Hintó +generátor +gavallérság +explozíva +eső +esdeklés +epilógus +Energia +Előélet +előterjesztés +előnézet +elvonás +elszigetelés +ellátmány +Elevátor +egynémelykor +egyenlőség +eddzenek +dzsungel +ananász +akvárium +Szépül +Sztorizik +szobroz +szimbolizál +szemlélődik +sugdolózik +majmol +Macskáz +Létesít +Lokalizálódik +litografál +levelesedik +lepet +közömbösít +kételkedik +kivirágoz +kerekez +kedvez +járkál +jegyzőkönyvez +iskolázik +individualizál +csendesít +borsoz +billentet +bajmolódik +anyagozik +alkonyodik +Aktualizál +színes +szemelt +lassú +hatékony +hasznos +gyúlékony +gyári +abszurd +örökjog +öregkor +ömlő +Zászlaj [Zászlajú, Zászlaja, Zászlai, Zászlóalj] +Zseblámpa +regényirodalom +realitás +raktárhelyiség +pötty +pótlék +pótdíj +pályafutás +Promóció +Processzus +poloska +pernye +pediáter +parancsnoklás + +Слова с ошибками [] +sponzorálás [szponzorálás, szponzorál, zongorálás] +mihamarábiak [mihamarábbiak, mihamarabbiak, mihamarábbi, hamarábbiak, mihamarább] +idohatár [időhatár] +hypnotizmus [hipnotizmus, nepotizmus] +departement [département] +légiesul [légiesül, légiósul] +kutagat [kutatgat, kutazgat, kutasat, kutakat, kutadat, kutamat, kútagát, kútágat, kútágát, kutat] +költségtakkarékos [költségtakarékos, költségtakarékkos, költséghatékony] +redukzió [redukció, redukáló] +pilanatfelvétel [pillanatfelvétel, pialantfelvétel, adatfelvétel] diff --git a/Common/3dParty/hunspell/test/dst/id_ID.txt b/Common/3dParty/hunspell/test/dst/id_ID.txt new file mode 100644 index 00000000000..2d95d3b7404 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/id_ID.txt @@ -0,0 +1,121 @@ +acang-acang +Adiksi +Adventisius +Advokat +afirmatif +agroindustry [agroindustri, nonindustri] +agrisilvikultur +akhir-akhir +akomodatif +aksi +aljabar +anggul +anotasi +antusiasme +apoteker +bahagia +bakat +bangkang +Bankir +Barikade +bebaru +belar +beleid +bencana +bentangur +beritawan +besuk +bilingualisme +Cecak +Celempong +cencawan +cengkar +ceremai +cermin +cudang +Dampal +dampan +dansa +datung +debitur +defensi +defisit +demper +dendang +Derivasi +Desember +deskripsi +diskotek +diskusi +distansi +dragon +dramatisasi +Eksamen +Eksistensi +eksperimen +ekstensifikasi +ekuitas +elektron +gelut +Geofisikawan +Gerbang +gerempang +influenza +Informasi +Inisiator +insekta +institusional +instruksional +jelajah +Kamrad +Kapilaritas +kapster +kardiovaskular +karismatik +keranjingan +komunal +Limitatif +Linguistik +lintang +masabodoh [masa bodoh, masa-bodoh, mastodon] +matematikus +medisinal +Melankolia +Memorabilia +nasional +nasionisme +Panen +pangkek +peranti +perian +persekusi +perunjung +regenerasi +reglementer +robotika +runjang +Sabtu +Simbang +simpati +tebing +topi +Unggal +unsuri +urbanisasi +variabel +wahana +warganegara [warga negara, warga-negara, negarawan, antarnegara, mancanegara, waranggana] + +Слова с ошибками [] +Abonement [Abonemen, Bombardemen] +Abcente [Absente, Centet] +ambivalan [ambivalen, ambilan, ambalan] +bakteriostatic [bakteriostatik, bakteriolisis] +cekaw [cekat, cekak, cekau, cekam, cekal, cekah, kacek] +darmavisata [darmawisata, darmatirta, mandataris] +declarasi [deklarasi, deflagrasi] +duplex [dupleks] +ecozona [ekozona, eco zona, eco-zona] +gempur-mengempur [gempur-menggempur, gempul-gempul] +jejengok [jejengkok, jengkeng] +transitive [transitif, transvetisme, transit, transisi] diff --git a/Common/3dParty/hunspell/test/dst/it_IT.txt b/Common/3dParty/hunspell/test/dst/it_IT.txt new file mode 100644 index 00000000000..5b9d3363bd9 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/it_IT.txt @@ -0,0 +1,200 @@ +Ciao +Ciaoo [Ciao, Ciano, Ciao o, Ciocia] +Buongiorno +Buonasera +Buonassera [Buonasera, Buon assera, Buon-assera, Buonalbergo] +Grazie +Prego +Arrivederci +Buonanotte +Scusa +Per favore [Favorevole] +Amore +Amico +Famiglia +Casa +Città +Strada +Montagna +Montaga [Montagna, Montata, Montana, Montala, Montava, Montaggi, Montaguto, Montano, Montato] +Mare +Sole +Luna +Stelle +Giorno +Notte +Colazione +Clazione [Colazione, Coazione, Cl azione, Cl-azione, Clonazione, Collazione, Clorazione, Chelazione] +Pranzo +Cena +Acqua +Vino +Caffè +Pane +Formaggio +Pasta +Pizza +Gelato +Dolce +Salato +Frutta +Verdura +Carne +Pesce +Pollo +Uovo +Sale +Pepe +Olio +Burro +Zucchero +Latte +Yogurt +Insalata +Zuppa +Bistecca +Prosciutto +Parmigiano +Biscotti +Cioccolato +Spagggrhetti [Spaghetti, Spaghetteria] +Spaghetti +Lasagne +Risotto +Gnocchi +Penne +Ravioli +Cannelloni +Pesto +Caprese +Limoncello +Espresso +Cappuccino +Tiramisù +Panna cotta [Panbiscotto] +Cannoli +Panettone +Brioche +Focaccia +Foacdccia [Focaccia] +Crostini +Arancini +Antipasto +Primo piatto [Rimpiattato, Primariato, Rimpiatto, Rimpatriato] +Secondo piatto [Attosecondo] +Contorno +Pane tostato [Tostapane] +Marmellata +Accoglienza +Affascinante +Aggressività +Alleviare +Appassionato +Armonioso +Autonomia +Autovfnomia [Autonomia, Autotomia] +Barbarie +Beneficiare +Bizzarro +Burocrazia +Cambiamento +Capriccioso +Cautela +Commemorare +Comportamento +Conseguenza +Controverso +Coraggioso +Debolezza +Decisivo +Delizioso +Desiderare +Destrezza +Determinato +Determin [Determina, Determini, Determino, Determinò, Termine] +Difficoltà +Disponibilità +Divertimento +Eccentrico +Efficienza +Elettrizzante +Emergere +Empatia +Energia +Equilibrio +Esperienza +Fantastico +Fenomenale +Generosità +Gratitudine +Immaginazione +Impressionante +Impressiante [Impressi ante, Impressi-ante, Impressionante, Impressionate, Imprestante, Impressioniste] +Indipendenza +Ingenuità +Innovazione +Intelligenza +Intensità +Intrigante +Ispirazione +Instabilità +Irresistibile +Leggenda +Libertà +Luminoso +Magistrale +Malinconia +Meraviglioso +Metamorfosi +Miracolo +Misterioso +Nostalgia +Opportunità +Originalità +Passione +Pericoloso +Prestigioso +Prodigioso +Prospettiva +Raffinato +Rafinato [Raffinato, Rapinato, Affinato, Trainato, Raffrenato, Raffilato] +Ricchezza +Rispettoso +Sensibilità +Sorprendente +Spontaneità +Spontaneita [Spontaneità, Spontaneista] +Stravagante +Suggestivo +Surreale +Tenerezza +Trasformazione +Unicità +Vibrante +Vittoria +Volontà +Amicizia +Avventura +Bellezza +Calma +Danza +Eleganza +Felicità +Gioia +Incanto +Magia +Natura +Odore +Passatempo +Quotidiano +Relax +Serenità +Tesoro +Umorismo +Vacanza +Zelo +Avventuriero +Speranza +Risate +Armonia +Incanto diff --git a/Common/3dParty/hunspell/test/dst/kk_KZ.txt b/Common/3dParty/hunspell/test/dst/kk_KZ.txt new file mode 100644 index 00000000000..3547d29f053 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/kk_KZ.txt @@ -0,0 +1,209 @@ +сөз +адам +қала +тау +ауа +су +аспан +жер +бала +ата +ана +тамақ +кітап +ұстаз +оқу +тұтыну +тыныш +тұз +ауру +денсаулық +топ +маусым +төс +көз +жүрек +сарғыш +көп +аз +ертең +түн +түс +жас +қара +ақ +көк +қызыл +шай +салт +ыстық +суық +қазақ +жеті +он +жүз +мың +бір +екі +үш +төрт +бес +алты +жеті +сегіз +тоғыз +он +бақша +бұлақ +қиыр +досым +ақша +патша +таң +кеш +тауар +күн +апат +риза +ауырсыну +орман +жаңбыр +бауыр +жел +тұман +үй +бұлақ +көше +айнала +шайыр +тағам +сусын +топ +бас +әрекет +тіл +кеме +сиыр +қой +ешкі +шөп +ит +тұқым +қарындаш +апа +ана +әке +дала +тарлау +дәуір +таңдай +жыл +басқарушылар +басқарушшылар [басқарушылар, басқарушы, басқармасылар, басқаруғалар, бақылаушыларлар] +жауапкер +ерекшеліктерімендерге +тұмылдырықтатқыздан +білімділігінге +білімдарды +алалықсыздар +айырмашылықтарын +тұрақтандырып +сылтауратқандарыңызды +қолдар +байланысқадан +жетілдірілген +зарарсыздандырады +ескеріп +ескеріпп [ескеріп, ескеріпі, ескеріле] +міндеттемелеріндерге +кезеңдердің +себепсіздік +біреудейлер +беделілерің +кездестіріңіз +шектердің +көңіл +көңл [көң, көл, көңіл, көңі] +мол +алайда +мәселе +мәселеу [мәселе, мәселең, мәселен, мәселес, мәпелеу, мәуелеу, мәселем, мә селеу, селеу] +сендің +келер +келерр [келер, керлер, келері, кереле, еркеле, кермеле, келекеле] +кәне +көпір +күндіз +сана +белгілер +дайын +ез +қайшы +саф +рең +шақ +үміткер +бақыт +бақытт [бақыт, бақытта, бақытты, бақырт, бақыты] +республика +консервациялау +мемлекеттік +тағатсыздан +адамда +бәрі +бең +беңр [бең, бер] +жасағанда +жасағоанда [жасағанда, жасалғанда, жасасқанда, жасаманда, жасақанда] +жабайылық +заманда +көшірдік +мерейі +Мерейій [Мерейі, Мерейің, Мерейім, Мерейлі, Мерей, Мейір] +мөлшерсіздікк [мөлшерсіздік, өлшемсіздік, мөлшерсіз, өлшеусіздік] +мөлшерсіздік +пенді +тылда +мәртебесімен +аппаратпен +тегінді +кездеме +ересектік +көңілсіздік +тәуекелсіздік +қанағатсыздық +ғаділетсіздік +сайдақы +басым +тәжікеден +тұрғын +қонақ +қауіпсіздік +қадірсіздік +білгішсінбейсіңдер +талқандас +кешікті +қоздырғышы +бас +емдейсіңдер +құқылы +тақылет +әдемі +көткеншектейсіңдер +әжет +қайтар +белсену +түсінбеймін +жағымсыздық +сыздар +мәртебесі +тұрғыны +мезгіл +әлбетте +барысын +оқылған +безге +жаса +аламаңдайсыңдар +кереметті +епетейсіздік diff --git a/Common/3dParty/hunspell/test/dst/ko_KR.txt b/Common/3dParty/hunspell/test/dst/ko_KR.txt new file mode 100644 index 00000000000..5d30797f0cc --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ko_KR.txt @@ -0,0 +1,157 @@ +안녕하세요 +감사합니다 +사랑해요 +미안합니다 +음식 +친구 +가방 +집 +학교 +컴퓨터 +물 +밥 +책 +산 +바다 +날씨 +일 +노래 +치킨 +반찬 +꽃 +숙제 +가족 +아이 +게임 +영화 +생일 +시간 +동물 +여행 +차 +쇼핑 +추천 +대화 +전화 +사진 +운동 +잠 +병원 +음료수 +능력 +주말 +전자기기 +고양이 +강아지 +바나나 +가을 +겨울 +봄 +여름 +옷 +신발 +지하철 +택시 +버스 +비행기 +샴푸 +브러시 +삼계탕 +국수 +불고기 +된장 +김치 +먹다 +마시다 +보다 +듣다 +놀다 +하다 +가다 +오다 +서다 +늦다 +일어나다 +자다 +빨갛다 +파랗다 +노랗다 +녹색 +보라색 +맛있다 +시원하다 +덥다 +추운 +기분 +슬프다 +즐겁다 +정신이 +바쁘다 +참새 +나비 +병아리 +돌 +물고기 +향신료 +시장 +기차 +공원 +해변 +지갑 +병원 +대학 +교통 +공항 +천재 +연구 +일본 +중국 +사업 +지식 +성격 +자금 +기술 +정부 +전략 +협력 +혁신 +경제 +철학 +신체 +영감 +현상 +역사 +태양 +설명 +사회 +환경 +자연 +현실 +존경 +정확 +장애 +낙관 +발전 +절망 +일상 +소멸 +도전 +반복 +포기 +파괴 +혁혹 [현혹, 혈족] +소외 [쇠오, 소아, 시외, 소오, 소에, 소의, 소와, 소요, 소유, 소위, 소야, 소되, 소뇌, 소 외, 소외감] +식민지 +혐오 +출산 +행복 +불평 +판매 +위험 +안녕하ㅎ요 [안녕하다] +감사합ㅅ다 [감사하다, 감사하여가다, 감사해가다] +사랑ㄱ해요 [사랑해요, 사랑해내요] +미안ㅎ합니다 [미안합니다, 미안한체합니다, 미안할만합니다, 미안해갑니다, 미안하여갑니다] +친ㅔ구 [친구] +가ㅎ방 [가방, 감방] + diff --git a/Common/3dParty/hunspell/test/dst/lb_LU.txt b/Common/3dParty/hunspell/test/dst/lb_LU.txt new file mode 100644 index 00000000000..37c698dbc9c --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lb_LU.txt @@ -0,0 +1,118 @@ +Aarbecht +Aarbechtszäitorganisatioun +Aartgenoss +Abenteuer +abrëll [Abrëll, brëll] +absence [Absence] +Abusives +Abzebillercher +Acquéreur +Adjointeë +Affischéiertes +Airbussen +Alldeegleches +Angschtzoustä +Basketballspiller +Baufirme +bauren [Bauren, bauen, brauen] +bekanntes +Beleg +Berodung +Bewältegung +Datentransfer +Dateschutz +Decisives +Donneschden +Drangsaléiertes +Dränk +Giischtgen +Grondlag +grondreegel [Grondreegel, grondleeënd] +Géies +Handelsdag +hausaufgab [Hausaufgab, ausbaufäheg] +hierschtdag [Hierschtdag, hierarchescht] +Häerzi +Industriell +Infrastrukturelles +Interessi +Internetfore +Intervall +Kamell +Kantoner +Karamell +Klenges +Nopeschhaus +Motors +Muer +Muerenter +Musek +Nettoverméige +niess [miess, Niess, iess, giess, Siess, Fiess] +Protektioun +Prouf +Provisioun +Prozessor +Präis +Präsens +Sanitäres +Schauspiller +Schema +Taxatioun +Telefonsgespréich +termingrë [Termingrë, verminnte] +terrass [Terrass, zerrass] +Textdatei +Textsprooch +Titulaire +Titel +erausféieren +erausjoe +gëeicht +onglécklecherweis +unzesammelen +unzespille +Approvisionnement + +Сложные слова [] +Aktiegesellschaft +Aktivitéitsdéclaratioun +Alarmstëmmung +Allgemengverständleches +Bankenoperatioun +Bensinsreserven +Besteierungsofkommes +Diskriminéierungsmoossnam +Dokumentatiounsaarbecht +Haaptrecommandatioun +Héchstgeschwindegkeet +Héichproblematesches +Hëllefsdéngscht +Integratiounsméisseges +Iwwersetzungsprogramm +Kapitaliséierungsdimensioun +Museksinstrument +Publicitéitsmarché +Transportproblem + +Слова с ошибками [] +Abonnnement [Abonnement, Joresabonnement, Abonnenti, Abonnent, Agebonnent] +Accomodéiertes [Accommodéiertes, Accommodéiert, Accordéiertes, Accommodéiers] +Agrarcenter [Agrarzenter, Agrozenter] +Begrennung [Begrënnung, Begrenzung, Benennung, Verbrennung, Begrenzen, Trennung] +Berodunszentren [Berodungszentren, Berodungszentre, Berodungszentr, Berodungszenter] +Deeluung [Deelung, Andeelung, Opdeelung, Verdeelung, Zelldeelung] +Dialogue [Dialoge, Dialog] +Dictaten [Diktaten, Dichten] +Inspektor +Iwereileges [Iwwereileges, Iwwereilegtes, Iwwereileg, Iwwerfälleges] +Pedagogik +Televisionschaîn [Televisiounschaîn, Televisiounsgeschäft] +Bechäftegungsméiglechkeet [Beschäftegungsméiglechkeet] +Gläicheetspolitik [Gläichheetspolitik, Sécherheetspolitik, Gesondheetspolitik, Geschäftspolitik, Dechetspolitik] +Musekheichschoul [Musekhéichschoul, Museksschoul] +Satelliten [Satellitten, Satellitte, Satellit] +Addressbichelchen [Adressbichelchen, Reklammbichelchen] +Aarbechtsfield [Aarbechtsfeld, Aarbechtsgefier, Aarbechtsblieder, Aarbechtsatelier, Aarbechtsalldag] + + diff --git a/Common/3dParty/hunspell/test/dst/lt_LT.txt b/Common/3dParty/hunspell/test/dst/lt_LT.txt new file mode 100644 index 00000000000..09068f6d859 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lt_LT.txt @@ -0,0 +1,127 @@ +Abstraktus +šachmatai +žadintoja +agurkas +Aikštė +Akinukai +akmuo +šakoti +aktualinti +aktorius +šalinis +šaltinis +bernystė +beskuo +būgnelis +Bilietas +bilingvizmas +daržavietė +Darbadienis +Darbas +darbuotoja +dargi +daržinė +daugintoja +Daugiaveiksmis +delnė +įdelnis +detalizuoti +šerdelė +erdvėti +šeriškas +šeštadienis +etiketas +Evoliucija +fabrikantė +Fantastika +Fenomenas +fikusas +gaudinėti +gausėja +gūbrinti +geležis +geležtė +gelsvis +geranoris +Gertys +gerviukas +giesmininkė +Gikas +Goža +griaustinis +grįžinys +gėrioja +griozdas +grizijo +gryčia +grožėja +grįžti +grupė +gąstauti +Jaukas +jodinėjo +jodyti +keturnagis +Kiaušina +Kiaurymė +kiausta +kietakaktis +ūkiškas +kilimėlis +kilometrinis +ūkininkaitė +ūkinis +krykti +lapuotis +laukas +laupti +laužtė +Maudulys +Maumedis +mažutėlis +mazgotuvė +mechanikė +medeinė +medikamentinis +meduolinis +Nūdien +nebrendėlė +Negu +neiginys +parudenys +pasakotojas +pasausė +pasieninis +paskyriui +paslapčiom +Pasodas +Pat +Pataikūniškas +patarška +patentinis +proskyna +protekiniais +provizoriškas +rėkčioti +rūmas +rodyklinis +Romanistas +Skylmatis +Skyriklis +skolininkas +skraidžioja +skruzdėda +skėtrus + +Слова с ошибками [] +Abbreviatūra [Abreviatūra, Klaviatūra] +alpinismas [alpinsimas, alpinimas, alpinistas, alpinizmas, alpinistinis, alpinistini, alpinamas, alpinariumas] +amortizacia [amortizacija, amortizacini, amortizavo, amortizuoti] +daugiamžis [daugiaamžis, daugiaamži, daugiamatis, daugiametis, daugiažiedis] +deziderativinis [dezideratyvinis, dezideratyvini, prezidentinis, rezidentinis] +generazija [generacija, energija] +keturiasdešimtūkstantas [keturiasdešimttūkstantas, keturiasdešimttūkstanta, aštuoniasdešimttūkstantas, šešiasdešimttūkstantas, aštuoniasdešimttūkstanta] +krivuluoja [krivuliuoja, kreivuliuoja, kultivuoja] +Šnaukstai [Šnaukštai, Niaukstai, Šniauktai, Šniaukštai, Auksintai] +pazintinis [pažintinis, parazitinis, pantinis, patentinis, panteistinis] +progresa [progresai, progresas, progreso, progrese, progresu, progresą, progresų, progresavo, progresija] diff --git a/Common/3dParty/hunspell/test/dst/lv_LV.txt b/Common/3dParty/hunspell/test/dst/lv_LV.txt new file mode 100644 index 00000000000..6cd9ccc2a0d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lv_LV.txt @@ -0,0 +1,205 @@ +Sveiks +Sveikks [Sveiks, Sveikas, Sveikās, Sveikts, Sveikus, Sveikos, Sveikt, Saveiks, Ieveiks, Veiks] +Labrīt +Lbrīt [Larīt, Lorīt, Labrīt] +Paldies +Paldiess [Paldies, Paliess, Palaidies] +Lūdzu +Luzu [Lizu, Ludzu, Auzu, Zuzu, Guzu, Lauzu, Lupu, Lubu, Lugu, Lūzu, Luču] +Atvainojiet +Atvainvfojiet [Atvaimanājiet] +Prieks +Perieks [Peries, Prieks, Persiks] +Draugs +Dravfugs [Draugs] +Ģimene +Gimene [Ķimene, Ģimene] +Māja +Maja [Maija, Paja, Raja, Laja, Maža, Maka, Mija, Mana, Masa, Māja, Mata, Maša, Maza, Mala] +Pilsēta +Pilseta [Pilsēta, Pil seta, Pil-seta, Piebilsta] +Ceļš +Ceļšs [Ceļš, Ceļošs, Ceļas, Ceļus, Ceļos] +Kalns +Jūra +Sauls [Auls, Kauls, Rauls, Pauls, Salus, Sauks, Sals, Saules, Sakuls, Saulēs, Saguls, Sulas, Salsu, Sauli, Sauss] +Mēness +Zvaigznes +Diena +Nakts +Brokastis +Pusdienas +Vakariņas +Vīns +Kafija +Maize +Siers +Makaroni +Pica +Saldējums +Deserts +Sāļš +Augļi +Dārzeņi +Gaļa +Zivis +Vistas +Ola +Sāls +Pipari +Eļļa +Sviests +Cukurs +Piens +Jogurts +Salāti +Zupa +Salds +Šokolāde +Spageti +Rīsi +Kakao +Biezpiens +Kūka +Tēja +Karalis +Zelts +Ezis +Tulpe +Lācis +Kaķis +Suns +Putns +Vārna +Zaķis +Pele +Ābols +Aita +Zirgs +Lauva +Pūķis +Lasis +Vilks +Vējš +Uguns +Ūdens +Zeme +Debesis +Saule +Rūpniecība +Aizkustinošs +Izdzīvošana +Nepieciešamība +Atbildība +Lieliski +Apmierināts +Neparasts +Izglītība +Sarežģīts +Atsevišķs +Pamatots +Organizācija +Sadarbība +Efektīvs +Daudzveidīgs +Novērtēt +Pārsteidzošs +Inovatīvs +Vērtība +Aizraujošs +Nopietns +Komunikācija +Māksla +Dzīvība +Ekskluzīvs +Tehnoloģijas +Rezultāts +Atbalsts +Nodrošinātība +Pārbaudīt +Radošs +Sociāls +Izteiksmīgs +Brīvība +Pieredze +Ietekme +Pārmaiņas +Drosmīgs +Racionāls +Empātija +Izpratne +Risinājums +Iespējas +Atklāts +Vadošais +Eksperimentāls +Neatkarība +Tīrība +Samierināšanās +Motivācija +Harmonija +Dinamisks +Iedvesma +Izglītojošs +Komplicēts +Pieejamība +Sadarbība +Tūlītējs +Saprotams +Neizsakāms +Lieliskums +Inovācijas +Aizrautība +Pārdomas +Sapratne +Rezultatīvs +Iespējams +Pārbaude +Sociālais +Izteiksme +Brīvība +Pieredzējis +Ietekmīgs +Pārmaiņu +Racionāla +Izpratni +Risinājumi +Iespējams +Atklāta +Vadošā +Eksperimentāla +Neatkarība +Tīra +Motivējošs +Harmonisks +Dinamika +Iedvesmojošs +Spēks +Mīlestība +Pasaule +Daba +Skaistums +Miers +Sapnis +Prieks +Rītausma +Brīnums +Izcils +Saikne +Dzirksts +Pārmaiņas +Atbalsts +Izcilība +Satriecošs +Dzīvīgums +Pārveidošana +Uzdrīkstēšanās +Uzticamība +Ieguldījums +Vērtība +Līdzsvars +Saskaņa +Izsmalcinātība +Pateicība +Atzinība +Pārsteigums diff --git a/Common/3dParty/hunspell/test/dst/mn_MN.txt b/Common/3dParty/hunspell/test/dst/mn_MN.txt new file mode 100644 index 00000000000..b590811bfcd --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/mn_MN.txt @@ -0,0 +1,103 @@ +Баатар +Багаа +Базар +Барра +Бат-Очир +Баттуул +Батхэсэн +Баярмаа +Билгэх +Бор +Бөөнцагаан +Бүрэнхайрхан +Бямбагар +Бэх +Гарам +Гантиг +Гурвантэс +Гүр +Гэрэлтуяа +Давст +Дангаа +Дансран +Дарь-Эх +Дөргөн +Дундбүрд +Дэмүүл +Дэлгэрцэцэг +Жавзан +Жарантай +Заглул +Зүүнхөвөө +Кир +Корона +Лүн +Лха +Лхаваан +Майхан +Манлай +Мөндөөхөө +Мөнхөт +Мөрөн +Мөнххаан +Мөст +Мэгэд +Мухар +Найдалмаа +Найтингейл +Налайх +Нарантуул +Намтай +Насантогтох +Номин +Нямсамбуу +Нэүдэй +Орог +Очир +Өнөржаргал +Өөдөс +Өргөн +Паган +Пас +Пүрэвдорж +Пүрэвхүү +Сайнаа +Сайхандулаан +Сундуй +Сэлх +Сүүж +Сээр +Тайван +Тарав +Тогтуун +Төрболд +Төхөм +Төмөр +Түргэн +Түшиг +Түгтөмөр +Түшиг +Удвал +Улиастай +Улаандэл +гүедэцгээчих +дэвхэрлүүлсхийчих +дэвхэлцгээчих +дэвшигдүүлгэчих +дэвшилцчих +дэвээ +дэггүйчүүд +наламгардуулалц +налбаруулзна + +Слова с ошибками [] +Батарчулуун [Баатарчулуун, Батар чулуун, Батарч улуун] +Баруунхарааа [Баруунхарааг, Баруунхараа, Баруунхараагаа, Баруунхараад] +Даважаргал [Даваажаргал] +Дөрволжин [Дөрвөлжин] +Мягмараран [Мягмараар, Мягмарнаран] +Оюунтулхуур [Унтуурхуул] +оторчилсхилгэ [оторчилсхийлгэ, оторчилсхийчих, оторчилсхий, отогчилсхийлгэ, хорчилсхийлгэ] +Асрамжлулгацгаачих [Асрамжлуулгацгаачих] +гүентүүлгэцгэээ [гүентүүлгэцгээе, гүентүүлгэцгээ, гүентүүлгэцгээгээ, гүентүүлгэцгээж, гүентүүлгэцгээн, гүентүүлгэцгээнэ, гүентүүлгэцгээв, гүентүүлгэцгээг, гүентүүлгэцгээх, гүентүүлгэцгээм] +наладаадуулга [налдаадуулга, наадалдуулгаа, наадалдуулга, налдаадуулцгаа, наадамдуулгаа] diff --git a/Common/3dParty/hunspell/test/dst/nb_NO.txt b/Common/3dParty/hunspell/test/dst/nb_NO.txt new file mode 100644 index 00000000000..37cb4b46e62 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nb_NO.txt @@ -0,0 +1,113 @@ +Bahamasøyene +Festarrangement +Festarrangemang [Festarrangement, Festarrangør, Fellesarrangement, Storarrangementa] +Festival +festligheta +festnummer +forhandlernett +forgylle +fotballstyre +Fotgå +fotoamatørene +Fotogalleri +fotokopiere +generalkostnadene +generaltabbe +generøs +Generell +genmodifisertst +handlingsresymeet +hardhet +Harmfull +hastighetsregulering +havbanke +havforskningsundersøkelsene +informasjonsutveksling +Infrarødest +kaffeautomat +kaldslig +kalenderåra +kjekk +kjendisstoffa +kjærlighetslyrikk +kjøkken +Kontantautomat +kontantlån +kontrahere +kontraheringsplikt +Låskasse +læregutt +læreprosess +Museums +museumssamling +musikkorps +myggstikka +myndighetsaldere +omløpstider +omregn +områdeplan +omriss +omsetningsgjeld +omsjaltning +omsetningsvolumer +omslutning +omslyngning +omsonst +omstendeligheta +Omstart +Omstreifende +Omsyn +omtåketheta +oppdagelse +oppbygning +oppebære +oppfølgingsapparat +oppgjørsbank +oppgjørsblankett +opphøringene +partisipere +randverdi +rapportskriver +rasjonalisering +Rate +selsak +selskapsinntekt +selskapsoverskudd +selvbetjeningene +snabbingene +Snadderene +Sytti +søkekriterium +søkemulighetene +søkeargumenter +søkingen +søkne +sølvlaga +sørlandsk +søtningene +tabellrad +Tabellkolonne +Takhalm +taksene +takseringssystema +tal +trolsk +trosinnholdene +utfoldelsesmuligheta +Utformingsmetode +Utgift +vekstfaktor +vekstforhold + +Слова с ошибками [] +Arbeidstagerorganisasion [Arbeidstagerorganisasjon, Arbeidstakerorganisasjon, Arbeidsgiverorganisasjon, Sosialarbeiderorganisasjon, Arbeiderorganisasjon] +festsprel [festsprell, festsprek, festsprelt, festspell, feltprest, fengselsprest] +forhandlingsdirektor [forhandlingsdirektør, forhandlingssekretær, forhandlingstekniskere, forhandlingstaktiskere, forhandlingskontor] +handlingforløpa [handlingsforløpa, handling forløpa, handling-forløpa, handlingsforløp, lønnsforhandlinga, lønnsforhandling, forhandlingspart] +kjempeflinktt [kjempeflinkt, kjempeflinkest, kjempeflink, kjempeflott, kjempefint] +lanetilbud [lånetilbud, langetilbud, landetilbud, linetilbud, laketilbud, langtilbud, lagetilbud, landtilbud, danetilbud, lunetilbud, vanetilbud, fanetilbud, banetilbud, hanetilbud, kantinetilbud] +omraming [omramming, omringing, omringning, ramming, omring] +omsvøpssfull [omsvøpsfull, omsvøpslaus] +raportmateriale [rapportmateriale, kartmaterialer, kartmateriale, programmateriale, skrapmateriale] +serstilt [særstilt, ser stilt, ser-stilt, seerstilt, tverrstilt, storstilt, lederstil, stiliser] +taksamst [takksamst, takksamt, takksam, samletakst, samstav] diff --git a/Common/3dParty/hunspell/test/dst/nl_NL.txt b/Common/3dParty/hunspell/test/dst/nl_NL.txt new file mode 100644 index 00000000000..ce7cdbafcca --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nl_NL.txt @@ -0,0 +1,115 @@ +Advertentie +Advocate +affirmatie +afgevaardigd +afneemster +allerbekendst +alternatieveling +annulering +anticycloon +Backtrackroute [Jacktrackroute, Backtrackrouten, Baktrackroute, Backtrackroute-, Backtrack-route, Back-trackroute, Backtrackroutes] +Bearbeiden +becijfer +bediening +bedrag +beduiden +beïnvloeding +benadeling +bepaaldelijk +Catalogiseer +Catering +cellulair +classificator +collaboreren +collectiviteit +comfortabel +complimenteus +contractant +correctionaliseren +daaraanvolgend +dagelijks +deelgenoot +degelijkheid +demarqueren +Denotative [Denotatie, Denominatieve] +deposant +dergelijken +detail +deugen +diakritisch +Directioneel +dusgenaamd +eendrachtigheid +Eenzaamheid +eersteklascoupé +Eigenschap +felicitatietelegram +centerkanaal [centerkabaal, enterkanaal, centerkanaal-, center-kanaal, callcenter] +Chargeer +filiaal +klare +Klassikaal +kleinhandel +evolutie +exemplaar +exequiën +familiaal +fauteuil +luister +magistratelijk +perelaar +Permitteren +Perseveratie +persoonlijk +pictogram +pixel +sloten +sluimer +sneltoets +Soldij +Solliciteren +zegepraal +zelfbeeld +zevendaags +aangeslotene +meermaals +expedieert +jaargetijden +kaderleden +Kapitelen + +Сложные слова [] +avontuurlijkheid +bedrijfsmaatschappelijk +begrotingstechnisch +belangstellingssfeer +concurrentievoordeel +conferentieganger +democratisch-liberaal +discontoverhoging +doctoraatsverhandeling +dubbeldeksbus +economisch-financieel +energiezuinig +erkentelijkheid +evenwichtigheid +klimaatsverandering +koffiezetmachine +koopmansgebruik +maatschapsovereenkomst +personeelsconsulent +sociaalwetenschappelijk +zelfverzekerdheid +fondsenwervende + +Слова с ошибками [] +afficher [affiche, afficheer, affiche-, affiches] +algorithme [algoritme, algoritmiek] +beeindiging [beëindiging] +client [cliënt] +consnteren [consenteren, contesteren, constateren, consulteren, confronteren] +deactivieren [deactiveren, deactiveerde, reactiveren, deactiveert, geactiveerden] +deblockering [deblokkering] +electrisch [elektrisch] +certificat [certificaat, certificatie, certificeert, certificeer, certificeren] +sovereiniteit [soevereiniteit, suzereiniteit, sereniteit, universiteit] diff --git a/Common/3dParty/hunspell/test/dst/nn_NO.txt b/Common/3dParty/hunspell/test/dst/nn_NO.txt new file mode 100644 index 00000000000..90d328d8e3a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nn_NO.txt @@ -0,0 +1,116 @@ +Ankeret +Anleggsbedrift +Annandag +annonseavis +annuell +ansats +ansvarsmedviten +Antibiotikai +apal +apoteki +apparattavlor +appetitt +Aprikos +arbeidsdokument +arbeidsmarknad +barndom +bastematte +bautingi +Bedriftsleiar +befolkningi +begynnarkurs +Beheld +belastningi +beredskapsnivå +beredskapsperiode +berglandskapi +berrfrost +beskjedi +beskrivingi +betalingsoppdrag +betalingsplikt +bevismateriale +bildeband +bildebruki +bildespråki +bildeteksti +bilingval +billettlukone +binær +bione +bjørkegreini +bjørnebæri +blenge +blokkeringi +blomsterbordi +blyerts +bogen +bokstavrekningi +bokstavteikni +Borddisk +effektevaluering +elgkalv +Elone +emballer +faktainformasjon +familiebedrifti +familieterapeut +fastbuande +Februar +feili +fisketom +hengelåsi +istandsetjingi +Item +jaguar +jamlig +janen +jarnbanestasjon +kjende +kjentfolki +kjæleri +kjøledisk +kjørety +midli +Mideftnar +midtstrek +multiplikasjonstabell +museumsdirektør +onsdag +operasjon +operasjonskode +opinionsskapingi +opningi +Personalkonsulent +Personligdom +persontryggleik +petroleumspris +redningsaksjon +reduksjon +refusnik +seinst +sekretær +seljande +sendeferd +Standpunkt +støyisolering +støytvis +terminoppgåve +tidløysone +tidsfølgjone +Tilbakebetalingstid +uprofesjonell +upåklageleg + +Слова с ошибками [] +Anlegsarbeid [Anleggsarbeid, Tvangsarbeid, Grunnlagsarbeid, Føregangsarbeid, Bergingsarbeid] +anonse [annonse, nonsens, anse] +ansversproblematikk [ansvarsproblematikk, vurderingsproblematikk, ventelisteproblematikk, valdsproblematikk, drivhusproblematikk] +barneforteling [barneforteljing, barnefordeling, barneforsking, barnefarforelegg, barnebefolkning, barnebortføring] +besoksliste [besøksliste, sortsliste] +bilophoggingi [bilopphoggingi, bilopphogging, opphogging] +effektivitetskontrol [effektivitetskontroll, effektivitetsforskjell, effektivitetsproblem, effektivitetsnøytral, effektivitetsforbetring] +fakturaerklering [fakturaerklæring, faktureringsliste, overfakturering] +miljøbyrad [miljøbyråd, miljøby rad, miljøby-rad, miljøbragd] +selskapskat [selskap skat, selskap-skat, selskaps kat, selskaps-kat, selskapsskatt, selskapskapital, selskapsrett, selskapstype] +cement [sement, dement, centime, cent] diff --git a/Common/3dParty/hunspell/test/dst/oc_FR.txt b/Common/3dParty/hunspell/test/dst/oc_FR.txt new file mode 100644 index 00000000000..26c580cdf5f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/oc_FR.txt @@ -0,0 +1,108 @@ +Ajustaira +alaguiar +alausièr +alberguèri +alcaloïdic +alègrament +alenament +algorisme +Alimentacion +allergologia +alpèstra +amaisament +amorteirar +analista +analogic +atucament +Audicion +auquièr +auscultacion +auscultar +ausèri +autenticament +brilhant +brumós +Burgada +cabelièira +cadeçar +Caducèu +çaicontra +calcièrs +Calmar +camarilha +cambièra +canalhariá +casse +cedar +cendrós +cèrca +cèrtes +cestòdes +chantièr +chartrós +Chassís +dimensionar +diptèrs +dirèctament +discrecionària +discriminar +Distraire +dòler +Enòrme +enqueriái +espicifòrme +esquelèt +Esquèrra +estetic +innocéncia +innocentàs +Maniquèu +mantelejar +Nauchièr +natièr +oxigèn +pacanariá +pagés +pagesiá +Primièirament +requereguèri +requisitòria +saumelèri +S'autodeterminar +sautarèl +scientament +scientologia +secador +secretèri +sècta +sectorial +s'efarcimar +s'endeven +s'engarrar +sentimental +s'entrepausar +shampó +sextant +sòli +Solidament +soquèla [soquèla, roquèla] +subrejornada +suedés +utilitària +Utilizaire +vacàs +vaisselèri +valiái +validament + +Слова с ошибками [] +albatros [albatròs] +amistanza [amistança, amistat, animista] +brunonièr [brunhonièr, prunhonièr] +carpentier [carpentièr] +centrifugation [centrifugacion, centrifugadoira, centrifugador, centrifugar, centrifuga] +estelhad [estelhas, estelha, estelhada, estelhar, estelhan, estelhat, estelham, estrelhada, estervelhada, estenalhada, estendalha] +primaria [primariá, primària, primarai, primaris, primari, primariam, primacia, primarga] +s'embractar [s'embracetar, s'embraceta, s'embodracar, s'embarrassar, embracetar] +sosembrançament [sosembrancament, embraçament, asombrament] +vascularisacion [vascularizacion, secularizacion, cardiovascular] diff --git a/Common/3dParty/hunspell/test/dst/pl_PL.txt b/Common/3dParty/hunspell/test/dst/pl_PL.txt new file mode 100644 index 00000000000..3cb6dba99fe --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pl_PL.txt @@ -0,0 +1,225 @@ +dom +pies +kot +auto +drzewo +książka +szkoła +przyjaciel +mama +tata +dziecko +jabłko +czekolada +kawa +herbata +telefon +telewizor +komputer +muzyka +sport +zdrowie +piękno +praca +miłość +szczęście +czas +pieniądze +język +kraj +miasto +zima +lato +jesień +wiosna +morze +góry +jezioro +rzeka +park +zwierzę +ptak +ryba +drewno +złoto +srebro +metal +szkło +buty +sukienka +spodnie +koszula +czapka +płaszcz +ręka +noga +oko +ucho +nos +usta +ząb +głowa +serce +mózg +król +królowa +książę +księżniczka +chłopak +dziewczyna +mężczyzna +kobieta +staruszek +staruszka +lekarz +pielęgniarka +nauczyciel +uczennica +student +studentka +kucharz +kelner +wojna +pokój +mapa +flaga +śmiech +płacz +sen +marzenie +praca +nauka +sztuka +teatr +kino +muzeum +kaplica +kościół +zamek +most +droga + +Сложные слова на польском языке [] + +1. konstantynopolitańczykowianeczka [nicejsko-konstantynopolitańskiego] +2. niezadogłębienieńskujący [] +3. antykontraatakujący [finansująco-kontraktujący] +4. supersamoobsługiwalnymi [kancelaryjno-archiwalnymi] +5. rozpierduchlanoculka [nieporozpierdzielanie] +6. nieodezwawiałobyś [nieodprzedmiotawiany] +7. przystawieniowy [przedstawieniowy, nieprzystawienie, niepoprzystawianie, nieprzystawianie] +8. nieprzeżyciowakościami [nieprzewartościowywaniami, nieprzewartościowaniami] +9. nieprzekazywających [nieprzekrzywiających, nieprzejednywających, nieprzywdziewających, nieprzepoczwarzających] +10. przeciwzakwaszeniowych [zatokowo-przedsionkowych] +11. nieszczęściodrapańskiego [ogrodniczo-pszczelarskiego] +12. społeczno-wychowawczyniami [socjalizacyjno-wychowawczymi] +13. seledynowo-fioletowymi [mięśniowo-szkieletowymi] +14. przeciwdeszczową [przeciwdeszczową, przeciwdeszczowy] +15. mikroelektroniczno-kwalitacyjną [reumatologiczno-rehabilitacyjną] +16. nieokreślonościowo-losowo-obiektywnie [] +17. zagubieniecioburakowatej [] +18. antyneuroleptyzanckim [] +19. nieupubliczniającymi [nieuwieloznaczniającymi] +20. splądrowałbyś [wyeksplorowałbyś] +21. konserwowano-spożywczymi [konserwiarsko-zamrażalniczymi] +22. ożelośćiowo-miłosnej [] +23. nieprzyzwoitolicjią [nieprzypieczętowującą] +24. nieodporowościę [nieodpoliturowanie] +25. rzeszołkofiołkowatymi [] +26. niezakapiactwuja [niezakatrupiająca] +27. nieoszczędniewczelnianków [oszczędnościowo-rozliczeniowa] +28. przekształconowaczkołępów [] +29. rozwińczywianiu [nieporozwiązywaniu] +30. nieprzeskakiwalnościami [nieprzewartościowywaniami] +31. modernizująco-rewolucyjnego [reumatologiczno-rehabilitacyjnego] +32. nadzwyczajnieuzdolnionymi [] +33. przemocno-wsparciański [warciańsko-odrzańskiemu] +34. przepyszno-peltzerowskiego [faszystowsko-hitlerowskiego] +35. kwestionowano-wzmocnieniami [] +36. nieodczynieństwującą [nieodrzeczywistniającą] +37. niezasłużonowypasionego [] +38. likwidującego/zarządzającego [odchudzająco-oczyszczającego] +39. szeszcześtoplutowanych [nieprzeinstrumentowanych] +40. niewpadkowościowi [wielonarodowościowi] +41. antynazizhownemu [niebizantynizowanemu] +42. nieuchronnieprzekroczeniowym [oszczędnościowo-rozliczeniowym] +43. niezatrawialnieprzyjemnego [] +44. kardiopulmonologiczno-angiologów [endokrynologiczno-ginekologicznemu] +45. gorączkowointensywnościowego [wydolnościowo-sprawnościowego] +46. antykonstytucyjnorozpadowego [konstytucyjno-monarchicznego] +47. nieobawiamysię/źródleni [] +48. prerewolucyjnolphillipsowi [] +49. szóstkaniewygranych [niewykrystalizowywanych] +50. nieupadkokogeneracyjnymi [korekcyjno-kompensacyjnymi] +51. społeczno-humanitarnarządzaniami [] +52. nieodziewowiędzy [nieumiędzynarodowienie] +53. przemocnochamować [] +54. społecznosensacyjnosądowym [kompensacyjno-wyrównawczymi] +55. przerażającorzymskiego [kobylińsko-borzymskiego] +56. nieprzemontowanych/zamuzowych [] +57. referendumkonstytucyjno-reformujące [] +58. niezniesłowiałszymi [niezesłowiańszczonymi] +59. niebohaterystycznymi [charakterystyczniejszymi] +60. produktodenarodowomenopauzalem [] +61. odrywającopierdolca [niedopierdzielająca] +62. niegotowożywione [żywieniowo-noclegowi] +63. niepostronnynarodzonemu [kilkudziesięciostronicowemu] +64. przedniaautochtonicznym [urbanistyczno-architektonicznym] +65. nadciągniono-wchodzących [] +66. promocjostworczym [czteromocarstwowym] +67. niezapowiadającychkoalicji [] +68. bezgłupinczłapie [] +69. wyomjaził [] +70. wagotonizacyjno-radiofonizowanego [] +71. gospodarczo-zasadotwórczej [organizacyjno-gospodarczej] +72. skrupulatno-rzeźniczobardziej [] +73. samokiedy-konstytucyjnej [konstytucyjno-monarchicznej] +74. niedomętnością [nieumiejętnością] +75. nieoszustamiwykorzystana [] +76. przeprowadzonoświeckie [nieprzeprojektowywanie] +77. nieuniknionaobowiązkowo-plastycznej [] +78. poduszkowo-nicościowych [porządkowo-czystościowych] +79. niepowodzeńbutmizeryjewego [] +80. skojarzeniowocolorowymi [wypoczynkowo-szkoleniowymi] +81. przytułkamiwciągarkowych [] +82. wchodziłoprzeciwniepowszechny [] +83. karaublicznociągana [publiczno-prywatnego] +84. przedpolitycznilubelskim [hemolityczno-mocznicowemu] +85. niezapowiedziano-date-expanded [] +86. licznościłodziennej [termiczno-wilgotnościowej] +87. niezawinieniomatołek [] +88. pakujączwobilardowego [] +89. rewersdopisek [] +90. przeprosinoworadosną [nieprzeprojektowywaną] +91. nieakceptacyjnoprospekcyjnymi [adaptacyjno-rehabilitacyjnymi] +92. jedniżużytym [nienadużytymi] +93. ainikopciksemilitechnikowany [] +94. motszynopiszącym [niewspółtowarzyszącym] +95. nieprzerejestrowanasezonowanie [] +96. słupotartackimoblikiem [] +97. nieodbieraniemniedostępności [] +98. dorozwinięcówkobiet [] +99. szybopojabytesłowickiego [] +100. przystępnoracjmujacych [] + +Слова с ошибками [] + +jedniiżużytym [nienadużytymi] + +wiomjaził [jaziowy] + +niezzniesłoowiałszymi [niezesłowiańszczonymi, niezesłowiańszczanymi, niezesłowiańszczającymi, najniesłowniejszymi] + +superrsammoobsługiwalnymi [muzealno-archiwalnymi] + +przemoocnochamować [przeprogramować] + +staruszzka [staruszka, staruszeczka, staruszek, staroruska, starszaka] + +tiatr [tiar, titr, tatr, teatr, wiatr, otiatra, otiatria, tristia] + +woina [wpina, wona, wina, wozina, dwoina, wolina, wonna, wcina, toina, wodna, doina, wolna, wojna, wgina, woźna] + +teleffon [telefon, telef fon, telef-fon, telefoto] + +zołoto [złoto, gołoto, hołoto, Gołoto, Hołoto, zołotnik] diff --git a/Common/3dParty/hunspell/test/dst/pt_BR.txt b/Common/3dParty/hunspell/test/dst/pt_BR.txt new file mode 100644 index 00000000000..1f66fc5565d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pt_BR.txt @@ -0,0 +1,108 @@ +que +eu +não +de +você +para +ele +se +é +um +sim +por +isso +em +uma +uuma [u uma, uma, usma, suma, numa, ruma, duma, puma, fuma, juma] +está +como +com +bem +na +me +mas +do +era +quando +então +tudo +tydo [tudo, tido, todo] +aqui +disse +estava +esâtava [estava, tavares] +lá +fazer +vai +sobre +vamos +homem +hollmem [homem-gol] +bom +ok [o k, o, k, oó, os, oi, oc, ou, om, oh] +agora +coisa +coissa [coisca, coiça, coisas, coisa, cossa, comissa, cisosa, cissoa, cossai] +quero +foi +meu +seu +só +eles +as +posso +pocso [posso, poco, poso, psoco, poiso, pouso, pocho] +estou +mais +mim +certo +dizer +dizdizerr [dizer] +os +no +sei +ela +vocês +sua +todos +sabe +minha +alguma +algyyma [amalgama] +casa +muito +oh +quallquer [qualquer, alquerque, malquerer, alqueria, alquermes] +qualquer +da +estamos +até +onde +onede [enode, onde, monede, neode, onere, olede, nedendo] +ao +tenho +nós +tem +tinha +tiinha [tinão ha, tiazinha, toinha, tinha, tirinha, tidinha, tipinha, tianha, tainha] +quê +ir +ou +pode +quer +vou +seus +dia +estão +nos +cabeça +quem +anos +depois +sou +vez +vá +fez +irmão +câmera +câmeara [cameara, cameará, câmera, câmara, acâmera, comeara] diff --git a/Common/3dParty/hunspell/test/dst/pt_PT.txt b/Common/3dParty/hunspell/test/dst/pt_PT.txt new file mode 100644 index 00000000000..9477e3d006d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pt_PT.txt @@ -0,0 +1,135 @@ +pan [pana, pane, pano, pen, par, pai, pau, paz, San, Van, Dan, pança] +manteiga +menteiga [manteiga, antigamente] +queijo +salchichón [salsicha] +saуlchichón [] +óleo +pimenta +pimmenta [pimenta, pigmenta, pimenteira, pavimenta, implementa, impiamente] +sal +baga +mel +geléia [geleia] +cogumelo +cebola +cóbola [cebola] +banana +cenoura +pêra [pera, para, pira, pura] +beterraba +frutas +melão +melancia +bolo +chocolate +carne +batatas +salada +salóda [salda, salada, salsada] +tomate +pepino +pipino [pepino, pi pino, pi-pino, pipi no, pipi-no, filipino, pino] +col [cola, cole, colo, coa, cal, coe, cor, rol, sol, coo, com] +mingau [mingua, mingai, minga, mingar, mingas, mingou, mingam] +sopa +sanduíche +refrigerante +refrigarante [refrigerante, refrigerar, intrigante] +água +café +chá +leite +suco +scuco [suco, cuco, cucos] +maçã +uvas +laranja +abacaxi +adacaxi [abacaxi, cacada] +damasco +demasco [damasco, demarco, remasco, de masco, de-masco, descasco] +açucar [açúcar, açucara, açucare, açucaro, açudar] +arroz +macarrão +res [rés, ser, ares, reis, ires, ores, dres, rei, ris, ses, rãs, rês] +porco +frango +costeleta +cãsteleta [costeleta, chapeleta] +limão +ervilha +pão +peixe +caramelo +sorvete +nogueira +ovo +pêssego +xícara +xíícara [xícara, caraíba] +vidro +prato +colher +garfo +faca +pires +garrafa +guardanapo +café da manhã [ssafé da manhã] +almoço +jantar +avião +carro +bonde +ônibus [ónibus] +trem +bicicleta +janeiro +fevereiro +fevíreiro [fevereiro, ferreiro] +março +abril +maio +junho +julho +agosto +setembro +setembra [setembro, seteara] +outubro +novembro +dezembro +desembro [desmembro, dezembro, deslumbro, setembro, desdobro] +caneta +livro +xadrez +telefone +relógio +pente +televisão +ferro +sabão +rádio +bolsa +cartão +mala +presente +câmera [câmara, comera] +computador +camputador [computador, captador] +filme +flor +vaso +quadro +lenço +bola +balão +brinquedo +brinqueedo [brinquedo, branqueado] +conta +sobre +papel +pepel [papel, repele, pele] +jornal +letra +bilhete diff --git a/Common/3dParty/hunspell/test/dst/ro_RO.txt b/Common/3dParty/hunspell/test/dst/ro_RO.txt new file mode 100644 index 00000000000..b1bd8929057 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ro_RO.txt @@ -0,0 +1,210 @@ +casă +copil +carte +masă +școală +lumină +apă +munte +soare +lună +pâine +fruct +floare +stradă +mașină +aer +timp +zi +noapte +nor +vânt +ochi +gură +nas +mână +picior +inimă +sânge +cap +ureche +voce +melodie +culoare +formă +linie +cerc +dreptunghi +cercetare +știință +limbă +frază +literă +cifră +număr +sunet +zgomot +telefon +internet +computer +program +ecran +tastatură +mouse +joc +sport +muzică +artă +film +televizor +radio +planetă +stea +univers +galaxie +atom +moleculă +substanță +energie +lumină +căldură +frig +aparat +instrument +mașinărie +unelte +hrană +băutură +haine +pantofi +păr +piele +ochelari +ceas +bijuterie +pământ +apă +aer +foc +metal +lemn +piatră +hârtie +cerneală +pix +carte +cadru +tablou +sculptură +model +formă +anticonstituționalitate [anti constituționalitate, anti-constituționalitate, anticonstituționali tate, anticonstituționali-tate, anticonstituționale, neconstituționalitate, anticonstituțională, constituționalitate] +dezvoltare +inexpugnabil +nefast +concomitent +antiseptic +recalcitrant +perseverență +extravagant +inexorabil +colosal +plauzibil +efervescent +perspicacitate +superfluu [superfluă, superfulger] +subversiv +incoruptibil +inefabil +hiperbolic +indefectibil [indestructibil, indefinibil] +peremptoriu +ambivalent +paradoxal +heterogen [eterogen, heterogonie] +indiferent +periferic +subliminal +ultraviolet +indeferent [indiferent, interferent, deferent, inaderent, independent] +conglomerație +circumstanțial +contraproducător [contra producător, contra-producător, contraproductivă, contraproductiv, neproducător] +conglomerat +insurmontabil +intransigent +insidios +inerent +consternant +ambiguitate +inerție +inconsolabil +oniric +remarcabil +repudiat +subiectiv +periculos +infatigabil +abnegare +exuberant +facet [face, falet, facem] +represiune +implacabil +indiferent +infatigabil +insolit +intempestiv +incandescent +letargic +magistral +magnanim [magnaliu] +nefast +oblivial [bolivian] +oportun +periculos +plutitor +propice +reprobabil +risipitor +robust +salutar +simetric +solicitant +stringent +sufocant +superficial +tranzitoriu +tributar +trivial +umilitor +unic +vehement +vernal +vicios +victorios +vindicativ +virtuos +vizibil +volatil +vorace +vulnerabil +xenofob +xerofil +yonder [pondere] +yang +yodel [model] +zonal +zodiac +zoon [ozon, zono, zoom, zoo, zon, zobon, zovon, zvon, zoo n] +zoomorf +zurbagiu +Caaă [Casă, Cară, Cată, Cală, Cană, Cauă, Camă, Capă, Cadă, Cață, Cază, Cavă, Cașă] +Soaare [Soare, Sotare, Solare, Sonare, Somare, Soțioare] +Cartr [Carte, Cart, Carter, Carta, Carto, Cartu, Cartă] +Appă [Papă, Apă, Arpă, Aptă] +Coopil [Copil, Copilo, Copiilor] +Frumoss [Frumos, Frumos s, Frumoasă] +Feriсire [Fericire, Rereferire, Ferire] +Prietenn [Prieten, Prieteni, Prietena, Prietene, Prieteno, Prietenu, Prietenă, Prieten n, Prietinie, Prietin, Pretenție] +Muziică [Muzică, Muzic, Muică] +Exeplu [Exemplu] diff --git a/Common/3dParty/hunspell/test/dst/ru_RU.txt b/Common/3dParty/hunspell/test/dst/ru_RU.txt new file mode 100644 index 00000000000..938369e89b8 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ru_RU.txt @@ -0,0 +1,197 @@ +должен +доллжен [должен, доложен] +наш +думаю +думмаю [думаю] +свою +сам +всем +ни +нас +пока +этом +этой +ваша +всеми +возьми +моей +сама +вся +день +само +всей +бывает +себе +пойду +куда +ими +твоей +всю +своего +твой +пусть +ним +про +точно +иметь +которые +тогда +сюда +наше +самой +взять +наверное +домой +совсем +те +тобой +наверно +что-то +будто +твои +пути +дома +такие +тех +такое +его +самой +вашей +наверное +мои +например +типа +значит +люблю +минут +пор +случае +искусство +лучше +того +такому +ждать +видеть +мною +ждал +имя +важно +чего-то +самому +обычно +представляет +мечтать +стало +помните +взять +моих +самим +своим +вообще +самими +здесь +обратно +сразу +таким +ежели +наоборот +куда +таков +мечтает +значит +покажи +такими +кстати +почти +всякий +научит +вдоль +тогдашний +толком +занимает +Аквапланирование +Барокамера +Библиографирование +Биосинтез +Взаимодействующий +Вибраторный +Виртуальность +Вооруженность +Господствующий +Десантно-штурмовой +Диагностировать +Дипломатический +Дисгармония +Дискриминационный +Достопримечательный +Жизнеустройство +Интернациональный +Инфицированный +Кальцинировать +Ключичный +Коннотация +Лиловатый +Люминесцентный +Метрополитен +Многоплановый +Модернизировать +Наивысший +Наименее +Неопределенный +Нераскрытый +Неоднократный +Неохотно +Непостижимый +Неусыпный +Обезьяноподобный +Обзавестись +Оптический +Оптимизировать +Осуществиться +Очистительный +Парафинировать +Переключатель +Пограничный +Подготовительный +Подрядчик +Полиморфный +Почитать +Преисполниться +Преподаватель +Преследователь +Прирожденный +Проектирование +Профанация +Разграничительный +Распоряжающийся +Реконструктивный +Революционный +Рентгенологический +Рискованный +Роскошествовать +Самоунижение +Сверхъестественный +Светочувствительный +Семантика +Сингулярность +Совершенствовать +Соединительный +Сосуществование +Спорообразующий +Стационарный +Столовая +Сторицей +Сцепной +Трансформирующий +Триумвират +Укротитель +Универсальный +Федеративный +Хронометраж +Целостность +Криумвират [Триумвират] +Укратитель [Укротитель] +Универссальный [Универсальный] +Фидиративный [] +Хранометраж [Хронометраж] +Целосность [Целостность] diff --git a/Common/3dParty/hunspell/test/dst/sk_SK.txt b/Common/3dParty/hunspell/test/dst/sk_SK.txt new file mode 100644 index 00000000000..d8167476c95 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sk_SK.txt @@ -0,0 +1,205 @@ +hiša [šiša, Riša, Miša, hi ša, hi-ša] +pes +mačka +avto [atto, asto, auto, zavito] +drevo +knjiga [kvadriga] +šola [šila, šoka, šla, švola, škola, šosa, vola, šora, rola, kola, mola, dola, šopa, pola, hola] +prijatelj [prijatej, prijate, prijatie] +mama +oče [očne, otče, toče, očke, koče, moče, očeš, oči, one, ose, oke, oje, obe, očí, očú] +otrok +jabolko [jablko] +čokolada [čokoláda] +kava +čaj +telefon [telefón, telefot] +televizija [televízia] +računalnik [račianski] +glasba [glasnosť] +šport +zdravje [zdravej, zdravie, zdravte, zdravme, zdrav je, zdrav-je] +lepota [pelota, slepota, lopota, lehota, klepotať, epoleta, poleptať] +delo +ljubezen [lezeniu] +sreča [srnča, skeča, smeča] +čas +denar [denár, nedar] +jezik [veziko] +država [držiava, držala, dŕžava, dĺžava] +mesto +zima +poletje [polejte, poleje, poletuje, polje] +jesen [jeseň, jesne, nesej, jeden, jesene, jeseni, jesení] +pomlad [omlad, poklad, p omlad, pomlka] +morje [morke, more, moje, morte, morme, mor je, mor-je, morčej] +gore [hore, gofre, nore, kore, more, zore, bore, šore, Nore, Tore, Lore, Zore, gágore] +jezero [jazero, je zero, je-zero, zero] +reka [areka, rieka, rekta, repka, rezka, raka, roka, rekt, seka, reva, veka, deka, repa, reku, ruka] +park +žival [žuval, živa, živel, živil, rival, ži val, ži-val, živ al, živ-al, živa l, žičieval] +ptica [pica, pätica, psica, štica] +riba [rabi, roba, ria, iba, raba, ribi, ryba, rúba, róba, Tiba, r iba, babri] +les +zlato +srebro [rebro, s rebro, striebro] +kovina [okovina, krovina, ovinka, konina, novina, korina, rovina, kozina, košina, kofina, rakovina, kávovina] +steklo [šteklo, seklo, stekalo, stieklo, stenklo, streklo, stoklo, steblo, stĺklo] +čevlji [nevlhči] +obleka +hlače [hláče, tlače, hlase, hlave, hlade, plače] +srajca [rajca, krajca, s rajca] +kapa +plašč [plaš, plač, plaší, plaš č] +roka +noga [noha, nota, nosa, nova, nora, loga, koga, doga, joga, noža, noša, noxa, Toga, neogab] +oko +uho [ujo, ho, tuho, uhor, uhol, uhlo, ucho, uhoľ, uňho, hou, oho, uto, uhm, cho, uhú] +nos +ustnice [ustrice, kapustnice] +zob +glava [hlava, Ilava, Slava] +srce [drce, srnce, srdce, srne, srde, síce, súce] +možgani [moganie] +kralj [kraj, kraal] +kraljica [kraslica] +princ +princesa +fant +dekle [deke, dele, pekle, de kle, de-kle, debakle] +moški [košmi, kamoši] +ženska [ženská, ženiska, žensky, ženskí, ženský, ženskú, ženské] +starec +starka [starká, straka, statka, starla, stara, ostarka, staríka, starca, starkí, starký, starkú, starké] +zdravnik [zdrav nik, zdrav-nik, zdravenia] +medicinska sestra [medicínska sestra] +učitelj [učitelík] +učenka [učeníka, učenia, učenca, utečenka] +študent +študentka +kuhar [kurare] +natakar [katakana, katarakta, katarakt] +vojna +mir [mri, mor, mi, mira, mire, mier, emir, miri, miru, mar, air, mer, min, sir, mil] +zemljevid [zemediel] +zastava [zástava, zastáva, zastav, zastavia, zastaval, zastavaj, zastavať, zostava, zastala, zastaví] +smeh [sneh, smej, sme, steh, smer, smel, smeč, smeť, sme h] +jok [koj, kok, joj, jol, ojok, jak, jot, tok, sok, vok, rok, lok, mok, dok, job] +spanje [spanie] +sanje [sane, saje, sanuje, banje] +delo +učenje [učenej, učene, učenie] +umetnost [etnosti] +gledališče [nepojedali] +kino +muzej [mušej, muzeálnej] +kapela +cerkev +grad [grád, gard, hrad, graf, rad, grand, gram, gray, úrad, Arad] +most +cesta + +Сложные слова [] + +1. Neparlamentarna [parlamentarizmus] +2. Samozadosten [rozradostene] +3. Nepristranski [protistranícki] +4. Pretirano [pretrénovanosti] +5. Nepredušno [nepriedušnosť] +6. Nesreča [] +7. Razpršeno [zhoršenou] +8. Nesprejemljiv [nesprejazdňujeme] +9. Prekomeren [rekompenzovať] +10. Prostovoljstvo [sprostredkovateľstvo] +11. Izolirati [] +12. Trmast [] +13. Brezpogojno [] +14. Neodvisnost [neodôvodnenosti] +15. Skupnost [ústupnosti] +16. Neizvedljiv [] +17. Nelegitimen [nelegitimizuje] +18. Nevzdržen [] +19. Preobremenjenost [] +20. Ogrevalni sistem [] +21. Preoblikovati [aplikovateľnosti] +22. Nezaslišano [nezasluhujúci] +23. Neugoden [] +24. Prezasedenost [prezamestnanosť] +25. Nesreča [] +26. Neupravičeno [nenapraviteľnosť] +27. Mednaroden [mŕtvonarodeným] +28. Kompatibilnost [najkompatibilnejšom] +29. Neuspeh [neusporte] +30. Neobvladljiv [] +31. Neskončen [neskončenej] +32. Neprimeren [neprimeranie] +33. Amortizacija [amortizovaných] +34. Koncentracija [dekoncentrácia] +35. Cirkulacija [recirkulácia] +36. Obremenitev [odbremenenie] +37. Gromozanski [] +38. Simbol [] +39. Vinjeta [] +40. Digitalizacija [digitalizovaný] +41. Funkcionalnost [funkcionalistické] +42. Rentabilnost [nerentabilnosti] +43. Ekshibicionizem [exhibicionizmus] +44. Frustracija [frustrujúci] +45. Neprilagodljiv [] +46. Severnoameriški [] +47. Ekskluzivnost [] +48. Preverjanje [preverovanej] +49. Celoživljenjsko [] +50. Privlačnost [neprivlastňovala] +51. Periferija [periferický] +52. Sokrivda [dokrivkať] +53. Kompromis [kompromisník] +54. Strpnost [ostrovtipnosť] +55. Racionalizacija [zracionalizovania] +56. Birokracija [gerontokracia] +57. Odraslost [odrastenými] +58. Stabilnost [nestabilnosti] +59. Nepredvidljivost [najnepredstaviteľnejšou] +60. Razkošje [] +61. Smrtnost [úmrtnostným] +62. Obveščenost [presvedčenosti] +63. Produktivnost [neproduktívnosti] +64. Neugodje [] +65. Zapletenost [zakrpatenosti] +66. Hegemonija [] +67. Umetnost [menostatikum] +68. Tranzicija [tranzitivita] +69. Individualnost [individualisticky] +70. Kontaminacija [kontaminantmi] +71. Inkubacija [] +72. Prikrito [prikrátko] +73. Etnični [Letničie] +74. Sovražnost [samovražednosť] +75. Atraktivnost [abstraktnosti] +76. Nestrpnost [nepriestupnosti] +77. Divergenca [divergencia] +78. Digitalna pismenost [] +79. Stabilizacija [autostabilizácia] +80. Raznolikost [] + +Слова с ошибками [] + + Kontamenacija [Kontaminácia] + + Grommozanski [Grobianski] + + Neobvladlliv [Neobkradli] + + Neparlametarna [Neparlamentný, Parlamentárnej, Parlamentne] + + Nevrzdržen [Združene, Zdražene] + + voina [vonia, vina, vojna, voľna, voština] + + muzei [muzeálni] + + ryba + + serebro [se rebro, se-rebro, rebro] + + televiziia [televízia] diff --git a/Common/3dParty/hunspell/test/dst/sl_SI.txt b/Common/3dParty/hunspell/test/dst/sl_SI.txt new file mode 100644 index 00000000000..6bd93841419 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sl_SI.txt @@ -0,0 +1,210 @@ +Hiša +Sonce +Miza +Stol +Ptica +Trava +Drevo +Noč +Luna +Morje +Gora +Cvet +Riba +Rdeča +Modra +Zelena +Rumena +Bela +Črna +Kamen +Pes +Mačka +Roka +Noga +Glava +Oči +Uho +Nos +Usta +Jabolko +Hruška +Sliva +Jagoda +Malina +Lubenica +Kruh +Mleko +Sir +Mesnica +Sadje +Zelenjava +Voda +Zrak +Ogenj +Sneg +Dež +Oblak +Veter +Zima +Poletje +Jesen +Pomlad +Zajec +Lisica +Volk +Medved +Lev +Tigrica +Slon +Konj +Krava +Ovca +Piščanec +Jajce +Mleko +Kava +Čaj +Sok +Vino +Pivo +Hrana +Pecivo +Testo +Marmelada +Kruh +Sir +Olje +Sol +Poper +Sladkor +Kava +Čaj +Vino +Pivo +Šola +Učitelj +Učenec +Knjiga +Pisarna +Računalnik +Telefon +Glasba +Slika +Film +Gledališče +Mesto +Vas +Trg +Cesta +Reka +Avtomatizacija +Razvoj +Komunikacija +Kompjuter [Juterškov] +Programiranje +Elektronski +Inženiring +Elektrifikacija +Kombinacija +Sistem +Informacija +Univerza +Biblioteka +Univerzitetni +Laboratorij +Raziskava +Razvojna +Inovacija +Intelektualni +Integriteta +Izobraževanje +Izvajanje +Preverjanje +Tehnologija +Implementacija +Program +Sodelovanje +Proizvodnja +Industrija +Organizacija +Administracija +Proaktivnost [Retroaktivnost, Produktivnosti, Produktivnost, Provokativnost] +Kreativnost +Projektni +Razumevanje +Kvaliteta +Upravljanje +Ocenjevanje +Statistika +Kompetentnost +Konsolidacija +Realizacija +Kapaciteta +Distribucija +Kompatibilnost +Konceptualizacija [Konceptualizem] +Povezava +Posodobitev +Fleksibilnost +Ekonomija +Organiziranje +Konkurenca +Stabilnost +Ekologija +Osebnost +Zavzetost +Entuziazem [Entuziast] +Motivacija +Avtorizacija +Kreacija +Akumulacija +Monotonija +Diferenciacija +Transformacija +Koncentracija +Inovativnost +Aktivnost +Vzpostavljanje +Reorganizacija +Kategorizacija +Partikularnost +Homogenost +Izjemenost [Izjemnost, Izjemen ost, Izjemen-ost, Zmenjenosti, Izrojenost, Izmišljenost, Izrinjenost] +Generalizacija +Hierarhija +Koordinacija +Inspiracija +Evaluacija +Ustvarjalnost +Oblikovanje +Kompatibilnost +Konkretizacija +Proaktivnost [Retroaktivnost, Produktivnosti, Produktivnost, Provokativnost] +Identifikacija +Kapaciteta +Intervencija +Konsolidacija +Realizacija +Eksplozivnost +Abstrakcija +Individualnost +Integracija +Segmentacija [Sedimentacija, Sedimentacij, Argumentacija, Alimentacija] +Asimilacija +Artikulacija [Artikuliranja, Artikulirala, Cirkulacija, Kalkulacija] +Kolaboracija +Asociacija +Stabilizacija +Kooperacija +Transformacija +Hšza [Hrza] +Kmojnikacija [Komunikacija] +Progrramiranjee [Programiranje, Reprogramiranj, Programiranega, Programiranj] +Elektornkski [Elektorski, Elektorkin, Elektronski, Elektorki] +Inženeirrng [Inženiring] +Izzobraževanjee [Izobraževanje, Izobraževanj, Izobraževanega, Izobraževane] +Infomracija [Informacija, Informacij, Rafinacijam] +Razvoojnaa [Razvojen] +Proizvdonja [Proizvodnja, Proizvajanja, Proizvajanj, Proizvaja] +Akitvnostt [Aktivnost] diff --git a/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt b/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt new file mode 100644 index 00000000000..ef1ecd7824b --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt @@ -0,0 +1,227 @@ +кућа +пас +мачка +аутомобил +дрво +књига +школа +пријатељ +мама +тата +дете +јабука +чоколада +кафа +чај +телефон +телевизија +рачунар +музика +спорт +здравље +лепота +посао +љубав +срећа +време +новац +језик +земља +град +зима +лето +јесен +пролеће +море +планине +језеро +река +парк +животиња +птица +риба +дрво +злато +сребро +метал +стакло +ципеле +одећа +панталоне +кошуља +капа +капут +рука +нога +око +уво +нос +усне +зуб +глава +срце +мозак +краљ +краљица +принц +принцеза +дечак +девојчица +мушкарац +жена +старац +старица +доктор +медицинска сестра [војномедицинска] +наставник +ученик +студент +студенткиња +кувар +конобар +рат +мир +мапа +застава +смех +плач +сан +сањарење +посао +учење +уметност +позориште +биоскоп +музеј +црква +дворац +мост +улица +пут + +Сложные слова [Словенства] + +Конечно! Вот сто сложных слов на сербском языке на кириллице: [] + +1. Контраст [контрастира, контраста, контрастно, контрастна] +2. Компликација [компликацијама, компликација, компликације] +3. Конструкција [реконструкција, конструкцијама, конструкција, конструкцију] +4. Диспропорција [пропорцијалном] +5. Корелација [корелацијама, корелација] +6. Колаборација [колаборација] +7. Консервативан [конзервативан] +8. Диференцијација [диференцијације, диференцијацијом, диференцијална, диференцијални] +9. Експерименталан [експерименталним, експериментална, експериментални, експерименталне] +10. Инвалидитет [инвалидитет] +11. Легитиман [нелегитиман] +12. Оптимизација [аклиматизација] +13. Компетентан [некомпетентан, компетентан] +14. Документација [документација, документацијом, документацију, документације] +15. Персистентан [асистенткиња] +16. Апроксимација [апроксимације] +17. Екстраваганција [екстравагантност] +18. Катастрафалан [катастрофалан] +19. Резервација [резервација] +20. Прогресиван [прогресиван] +21. Идентификација [идентификација, идентификације] +22. Генерација [регенерација, генерација] +23. Криминалистички [криминалистички, криминалистичка, криминалистичке] +24. Дестабилизација [индустријализација] +25. Корумпиран [корумпирана, корумпиран] +26. Конфронтација [контаминација] +27. Експлозиван [експлозиван] +28. Функционалан [функционалности] +29. Релевантан [релевантан] +30. Квалификација [квалификацијама, дисквалификација, квалификација] +31. Акредитација [рехабилитација] +32. Петиција [петицијама] +33. Каустичан [аутистичан] +34. Периодичан [периодичан] +35. Контроверзан [контроверзна] +36. Гигантски [гигантских] +37. Принципијалан [беспринципијелан] +38. Управоливост [расположивости] +39. Имунизација [имунизација] +40. Магнетичан [магнетично] +41. Оперативан [оперативан] +42. Десант [десантне] +43. Хиерархија [хијерархија] +44. Феминистички [феминистичког] +45. Сегментација [сегментацијом] +46. Колоритан [колорисан] +47. Деградација [деградација] +48. Диверзификација [диверсификацију] +49. Казуистички [карикатуристички] +50. Реципрочан [реципрочан] +51. Манипулативан [манипулативна] +52. Екстензиван [екстензивна] +53. Колективни [колективни] +54. Каузалитет [локалитету] +55. Синхронизација [синхронизација] +56. Кампања [кампањама] +57. Товарни [товарника] +58. Хируршки [хируршких] +59. Шампионат [шампионати] +60. Геостационаран [револуционарност] +61. Опустошан [опустошености] +62. Клема [] +63. Стационарни [стационарна] +64. Секуларни [секуларних] +65. Исегментација [сегментацијом] +66. Дебелина [дебелића] +67. Прецизан [непрецизан] +68. Рафиниран [рафинирани] +69. Психолошки [психолошких, психолошки] +70. Турбулентан [корпулентан] +71. Интегритет [интегритет] +72. Идеолошки [идеолошких] +73. Манифестација [манифестација] +74. Имплицитан [имплицитан] +75. Хомогеност [хомогеност] +76. Изолација [хидроизолација] +77. Хетерогеност [] +78. Спекулативан [спекулативна] +79. Вагу [превагу] +80. Математички [математичким, математички] +81. Гематолошки [стоматолошки] +82. Психијатријски [психијатријске] +83. Блокада [блокадама] +84. Заплена [заплетена] +85. Монопол [монополом] +86. Дисидент [дисидентски] +87. Екстрадиција [екстрадиција] +88. Ревизија [ревизијама] +89. Ваидан [] +90. Колонизација [колонизација] +91. Мотивација [мотивација] +92. Просек [просектор] +93. Ресурс [ресурсу] +94. Хуманизам [хуманизам] +95. Дравски [Подравских] +96. Коалиција [коалиција] +97. Картеля [картелима] +98. Резолуција [резолуција] +99. Менталитет [менталитет] +100. Епидемиологија [дијалектологија] + +С ошибками [] + + Колонизакаија [Колонизација, Колонизацији, Колонијализам, Колонијализма] + + Епидемиогија [Епидемија, Епидемијом, Демагогија] + + Казуистикаки [Казуистика, Казуистике, Статистика] + + Хуманкзам [Хуманизам, Хуманизма] + + Манитулативан [Манипулативна, Ултимативан, Ултимативни] + + сањваење [сањање] + + утење [хтење, утање, стење, умење, утеше, утече, учење, утехе, утеже, уђење, утезање] + + автомобил [аутомобил, обилатом] + + мекицинска сестра [војномедицинска] + + стукло [стукли, тукло, стукла, стакло, стекло, свукло] diff --git a/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt b/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt new file mode 100644 index 00000000000..8996675c198 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt @@ -0,0 +1,173 @@ +ananas +anarhistički +antidepresiv [depresivan, depresivna, represivan, depresivne] +Anđeo +avion +banana +banka +belina +bespomoćnost +bibliotekar +bibliaoteikar [bibliotekarka, bibliotekar, biblioteka] +brod +citat +crkva +cvet +cveće +demokratija +demackratija [demokratija, demokratizacija, demokratiji, demokratije] +demokratizacija +Dobrota +dom +Dragi +ekran +eksperimentalni +eksplozija +epidemiologija [epistemologija, ideologija] +farmakologija +filantropija +flaša +frizura +fudbal [fudbal, fudbala, fudbalu] +garaža +generalitet +geografski +globalizam +gnezdo +grad +građanstvo +grlo +hamburger +Harmonija +himalaji [Himalaji, malajski] +hiperbola +hipotermija [hidroterapija] +hleb +Hrabrost +hrana [hrana] +Hvala +igra +igračka +individualnost +infrastruktura +internet +inmternet [internet, interne] +jabuka +jahač +jastuk +jednakost +jubilej +jurisprudencija +kafa +krevet +kriminalisticki [kriminalistički, kriminalistika, kriminalistička, kriminalistiku, kriminalističke] +kriminalistika +kuća +kvantitativni +lampa +latiaratura [mlatarati, rasturati, maturirala, landarati] +Lepota +lingvistika +literatura +ljubav +Ljubavi +ljubavnica +Ljubazan +Ljubim +lubenica +majica +majka +mašina +mikroorganizama +mikroskopija [mikroskop ija, mikroskop-ija, mikroskopi ja, mikroskopi-ja, mikroskopi, mikroskopska, mikroskopa, mikroskopski] +Milost +Mir +Mirno +nacionalizam +nedopustiv +neurologija +novčanik +noć +nož +oktobar +okultizam +optimističan [optimistička, optimistički, optimističke, optimističku] +optimističnost [optimistički, optimističke, optimistička, optimističku] +ormar +Osoba +oči +pas +peškir +planina [planina, planinar, planinac, planinčina, planini, planinčini, planin] +poniženje +Porodica +Prijatelj +psihologija +psihoterapija +Radost +računar +reka +rekonvalescencija +reumatologija [dermatologija, hematologija, stomatologija] +revolucija +sendvič +Slatko +Sloboda +Slobodan +Snaga +socijalizacija [socijalizam, specijalizacija, specijalizacijom, socijalizma] +socijalizam +Spreman +Sreća +Srećan +Srećno +sunce +superiornost +Svetlost +tata +tehnologija +telefon +telekomunikacije +top +tradicionalni +ulica +univerzalnost +univerzitet +univirzdalnost [univerzalnost] +Usmena +Znanje +usta +Vedar +vegetarijanstvo +velikodušnost +voda +voz +Zabava +zavisnost +Zdravlje +zemlja +Zima +zjmlja [zemlja] +zločinački +zoološki +Zvezda +ćilim +čarapa +čarobnjak +časopis +čizme +đak +đevrek +đumbir +šešir +šišmiš +škola +šljiva +šuma +žaba +ženskara +žirafa +život +životinjski +žurka + diff --git a/Common/3dParty/hunspell/test/dst/sv_SE.txt b/Common/3dParty/hunspell/test/dst/sv_SE.txt new file mode 100644 index 00000000000..408fca774df --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sv_SE.txt @@ -0,0 +1,210 @@ +Hus +Sol +Mjölk +Vatten +Fisk +Stol +Grön +Blomma +Träd +Katt +Hund +Bok +Cykel +Kaffe +Frukt +Kött +Fönster +Dörr +Säng +Lampa +Bord +Hår +Ögon +Hand +Fötter +Näsa +Mun +Öra +Huvud +Arm +Ben +Kläder +Hatt +Skor +Väska +Papper +Penna +Skrivbord +Telefon +Radio +Musik +Film +Teater +Konst +Sport +Spel +Resa +Bil +Tåg +Buss +Flygplan +Båt +Stad +Land +Hav +Sjö +Flod +Berg +Dal +Park +Skog +Sjukhus +Apotek +Skola +Universitet +Affär +Restaurang +Café +Hotell +Turist +Vän +Familj +Mamma +Pappa +Bror +Syster +Barn +Morfar +Mormor +Vänster +Höger +Framåt +Bakåt +Upp +Ner +Snäll +Osnäll [Snäll, Osäll] +Glad +Ledsen +Trött +Stark +Svag +Tyst +Bullrig +Ren +Smutsig +Vacker +Ful +Liten +Stor +Komplexitet +Oproportionerlig +Ovillkorlig +Efterklokhet +Komplicerad +Desorientering +Konstellation +Otillgänglighet +Irreversibel +Förlåtelse +Overksamhet +Indifferent +Hierarki +Kombinatorik [Kombinatorisk, Kombination] +Inkompatibilitet +Absorption +Konsekvens +Verklighetsfrånvänd +Retrospektiv +Förändringsbarhet [Förändringsbarnet, Förhandlingsbart, Förhandlingsbar] +Ambivalens +Besvikenhet [Besviken, Besviket] +Ineffektivitet +Intrikat +Dilemma +Hesitation +Absurditet +Kompromisslös +Konsolidering +Föresats +Tillfredsställelse +Delegering +Rekommendation +Detaljrikedom +Oanvändbar +Stagnation +Nostalgi +Hemlighetsfull +Avsaknad +Perseverans [Perseverera, Reverseras, Reversera] +Existentialism +Repetitivitet [Repetitivt, Receptivitet, Repetitiv, Representativitet] +Intolerans +Anonymitet +Obetydlig +Paradox +Förvirring +Juxtaposition +Reflektion +Självständighet +Kollision +Kreativitet +Djupgående +Abstraktion +Eufori +Autentisk +Insinuation +Omöjlig +Pessimism +Inkonsekvens +Revisionism +Sensationell +Obeveklig +Subjektivitet +Universalitet +Entropi +Omvälvande +Infiltration +Konservativ +Atypisk +Provokation +Konfrontation +Anarki +Konkurrenskraft +Defensivitet [Defensivt, Sensitivitet, Defensiv, Densitet] +Nihilism +Konklusion +Apori [Apor, Apors, Porig] +Korrespondens +Prioritering +Exponentiell +Fragmentering +Aversion +Harmoni +Vanmakt +Signifikans +Katalysator +Förlust +Enhällighet +Ambition +Tendens +Alienation +Artificiell +Uppfyllelse +Psykosomatisk +Virtuos +Egensinnig +Anpassning +Hållbarhet +Konstitution +Kompleksitet [Komplexitet, Komplementet] +Oproporsjonerlig [Oproportionerlig, Proportionerlig] +Uvilkorlig [Villkorlig] +Etterklokhed [Efterklok] +Komplisert [Komplicerat] +Desorientering +Konstelasjon [Konstellation] +Utilgjengelighet [Tillgänglighet] +Irreversibel +Forlatelse [Förlåtelse] diff --git a/Common/3dParty/hunspell/test/dst/tr_TR.txt b/Common/3dParty/hunspell/test/dst/tr_TR.txt new file mode 100644 index 00000000000..0ea601fe67a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/tr_TR.txt @@ -0,0 +1,205 @@ +Akşam +Almak +Altın +Anahtar +Anlamak +Araba +Atmak +Ayakkabı +Açmak +Ağaç +Bahçe +Bakır +Bakkal +Bakmak +Balık +Beyaz +Bilgisayar +Bilmek +Binmek +Bulmak +Ceket +Cevaplamak +Deniz +Dinlemek +Doktor +Duyurulmamış +Düzenleştirme +Düşmek +Düşünmek +Ekmek +Elbise +Eldiven +Elma +Erkek +Etek +Etmek +Ev +Eşarp +Gelgit +Geliştiricilikle +Geliştirilebilir +Geliştirme +Gerçekleştirme +Gezmek +Geçmek +Gitar +Gitmek +Giymek +Gri +Gömlek +Görülebilirlik +Görünümlü +Görünüşlü +Gözlük +Gümüş +Günaydın +Hareketlendi +Hareketlilik +Hava +Hayalperest +Hüzün +Kahve +Kahverengi +Kalabalıklar +Kalem +Kalkmak +Kalmak +Kapatmak +Kararlılık +Kararlılıkla +Kararsızlık +Kararsızlıkla +Karpuz +Kedi +Kemer +Kemdkcer [Kemerler] +Kırmızı +Kitap +Kız +Kızgınmak [Kızgın] +Koklamak +Koalye [Kolye, Kavalye] +Kolye +Konservatuvar +Konuşmak +Korkmak +Koymak +Koşmak +Kravat +Kullanılabilir +Kullanılmış +Kullanılmışlık +Kullanışlılık +Kurumsallaşma +Köpek +Küpe +Kütüphane +Mavi +Mazbut +Melankoli +Merdiven +Merhaba +Merhabalar +Meurhaba [Merhaba, Murabaha] +Meydan +Meyhane +Meyve +Mor +Muhafazakar +Muhteşem +Mukadderatlarınızdanmışçasına [] +Muvaffak +Muzaffer +Muzafferiyet +Muzip +Mükemmeldik +Münasebet +Münzevi +Müsrif +Mütevazi +Müteessir +Mütercim +Mütereddit +Mütevazı +Müzmin +Okul +Okumak +Otobüs +Otoriterlik +Oynamak +Pantolon +Pasta +Pembe +Pembei [Pembe, Pembeyi, Pembeli, Pembeci, Pembe i, Pembesi, Pemben] +Plaj +Platin +Saat +Sandalye +Sarı +Satmak +Sevinmek +Sevmek +Sıcak +Sıradaymışız +Siyah +Sormak +Soymak +Soğuk +Su +Sükûnet [Sükunet, Sünnet] +Sürrealist +Süt +Tabak +Tadına bakmak [Alınamamaktadır] +Tatlı +Tavuk +Telefoncu +Televizyon +Temizlemek +Teşekkürler +Türkuaz +Tuirkuazu [Türkuaz] +Turuncu +Tutmak +Ulaştırılabilir +Uygulanabilir +Uyumak +Uçak +Yapmak +Yatak +Yazmak +Yemek +Yeşil +Yıkanmak +Yıldız +Yol +Yöneltilmezken +Yüzme +Yüzük +Zenginleştirmek +Çalışamamıştı +Çalışmak +Çalışmamıştır +Çanta +Çay +Çıkarmak +Çiçek +Çorap +Özelleştirilmiş +Özelleştirme +Özgürleştirme +Üzülmek +İnmek +İsteksizlik +İsteksizlikle +İstikrarlı +İstikrarlılık +İstisnai +İslamiyetle +İzlemek +İçmek +İşbirliği +İşitmek +Şapka +Şemsiye diff --git a/Common/3dParty/hunspell/test/dst/uk_UA.txt b/Common/3dParty/hunspell/test/dst/uk_UA.txt new file mode 100644 index 00000000000..be4941540b1 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uk_UA.txt @@ -0,0 +1,210 @@ +абдукція +абіогенез +амбівалентнасть [амбівалентність, амбівалентний, бівалентність, біоеквівалентність, внівалентність] +амбівалентність +анахранізм [анахронізм, брахманізм, анархізм, нанізм] +анахронізм +антропогенез +антропологія +антропоморфізм +апатія +археологія +архетип +аскетизм +астрономія +афект +бачити +бігти +білий +біллий [білий, збілілий] +біологія +бувай +будинок +будь ласка [будь ласку] +бути +важко +велиикий [великий, великоокий] +великий +веселка +взяти +вибачте +відчувати +вода +волюнтаризм +втаємниченість +вчитися +гарний +гарячий +гегемонія +географія +герменевтика +герменевтика +гештальт [штатгальтер] +говорити +гойдалка +готувати +грати +дати +дедукція +деконструктивізм [де конструктивізм, де-конструктивізм, конструктивізм, неконструктивно] +деконструкція +демаркація +детермінізм +дзвіночок +дивитися +дисгарммонія [дисгармонія, дисгармоніям, дисгармонійний, фісгармонія] +дисгармонія +дисфункція +дисфункця [дисфункція, дистинкція] +дихотомія +до побачення [побачення] +добрий +доктрина +думати +дурний +дурня +дякую +евфемізм +езотерика +ей +екзистенціалізм +екзистенціалізм +екзистенцілізм [екзистенціалізм, екзистенціаліст, екзистенція] +екзистенція +економіка +емерджентність +ентелехія +епістемологія +ефемерність +ефемерність +занепадництво +звісно +здоровий +зелений +йти +ілюзорність +ілюзорність +імплікація +інвектива +індукція +інтроспекціїя [інтроспекції, інтроспекція, інтроспекції я, ретроспекція] +їсти +історія +каблучка +кава +казус +калюжа +катарсис +каченя +каштани +квітка +кішка +класно +книга +когнітивістика [когнітивність, когнітивна] +комаха +консенсус +космогенез [номогенез, екогенез] +купувати +легко +лінгвістика +літати +маленький +марнослів'я +математика +мати +метаморфоза +метелик +метелиця +містифікація +місто +могти +можливо +мусити +насправді +не радий [нерадий, незрадний] +незворушність +ні +нігілізм +новий +нонсенс +ностальгія +павучок +парадокс +пес +писати +пити +піти +плавати +плакати +повільний +поганий +політологія +постмодернізм +потворний +працювати +привіт +прийти +психоаналіз +птах +радий +ремінісценція +рефлексія +робити +розбурхання [розбухання, розбурханий, розпухання, бурхання] +розумний +сильний +сингулярність +синестезія [кінестезія, анестезія] +синій +синішй [синій, синішай, синішати] +синкретизм +сказати +скатертина +слабкий +слухати +сміятися +сніг +соліпсизм +соломинка +сонечко +сонце +соціологія +спати +співати +справді +старий +структуралізм +сумний +так +так +танцювати +телефонувати +тож +трансцендентність +фантастично +фаталізм +фемінізм +феномен +феноменологія +фізика +філософія +фрактал +хворий +хімія +хліб +хліб +ходити +холодний +хотіти +чао [чадо, чан, чат, чар, час, чад, дао, чаш, чай, чаї, чаю] +червонй [червоний, червоній, червоно, червона, червоні, червону, червоне, червоню, червонявий] +червоний +черевики +читати +чорнй [чорний, чорній, чорно, чорна, чорни, чорні, чорну, чорне, чорню] +чорний +чути +швидкий +щасливий +яблуко diff --git a/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt b/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt new file mode 100644 index 00000000000..7aee3099656 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt @@ -0,0 +1,262 @@ +Mарт [Арт, Ғарт, Қарт, Карт, Шарт, Фарт, Варт, Парт, Сарт, Март] +Ёз +Ём +Ёхуд +Август +Адвакат [Адвокат, Адэкват] +Адреси +айтган-лирангиз +айқин +амалга +анча +Апрел +арзонроқ +аҳамият [аҳамият, аҳамияти, ҳамият, ҳамжамият] +аҳднома +бажарилади +бажарилди +баланд +ихтисослан +банкрот +баҳона +Баҳор +бераман +берасизми +беринг +бериш +бешинчи +биз +Бизга +Бизнинг +билан [билан, биланг, билани] +Бирор +Бозорнинг +бор +бошқа +Бу +Бугун +будингиз +бунга +бундай +Бухгалтерлик +бўлади +бўладими +бўлиши +бўлмаган +бўлса +бўш +бўшайди +бўшатасиз +вазифасига +вазият +вариант +вақт +газетадаги +газетадан +даромад +Декабрь +Душанба +Эрталаб +Етказиб +Жисмоний +Жуда +Жума +зарур +зиёфат +Ижара +ижарага +икки +Илтимос +Индинга +информатизациялари +Иситгич +иши +ишлатсак +Ишхона +Июль +Июнь +Йўқ +йил +йилдан +кам +Шинамгина +кампанияси +келдим +келишимдан +келмоқчи +келсам +келтириш +керак +керакдир +керакми +кета-ди [кетади, кетарди, кета-чи, кета-кета, дискета] +кеч +Кеча +кечага +Кечаси +Кечир +Кечирдинг +кирла +кирадими +кондиционер +коррупциядир +кран +Куз +Кун +куни +кўрмоқчи +кўчиб +лойиҳа +Май +маълумоти +маълумотларни +Маъмурият +маъруза +Мен +музлатгич +мумкин +муфмкин [мумкин] +мутахассис +мушовир +муҳим +нарса +нархи +Нархини +нақд +ўшанақасини +неча +Номардлик +Ноябри +интернетдаги +ойнаси +ойнинг +Октябри +олдин +олдиндан +олмаймиз +олмоқчи +орқали +шоти +шорти [шоти, орти, ортиш, шотир, корти, форти, шарти, порти, сорти, ширти, торти, борти, шомурти] +Оқшом +пайдо +Панжшанба +пулини +Раҳмат +резюме +реклама +Салом +Сармоядор +Сентябрь +Сешанба +Сиз +сизга +сизда +Сизнинг +синган +сифатида +совуқ +софвуқ [совуқ] +Солиқларни +Статистик +сўм +тажрибали +тайёргарлик +тайёрладик +тайёрладингизми +таклиф +талафот +талафоти +таъминловчилардан +танишинг +таржимон +тарржимон [таржимон, тарраксимон] +тахминан +ташкил +Телефонни +технология +Безантирани +тозалан +тозалигига [тозалигига, газтозалагич] +Тонгда +топширишимиз +топшириқ +турли +турмоқчи +тутсак +Тушлик +ўладиганингиз +тўлай +тўлаймиз +тилдиришинг +тўлиқ +уйингиз +уйни +уч +учун +ўқидим +фақат +Феврал +хабар +Хайрли кун [Хайрли кўн] +Мотамхонаси +хонлик +Чек +Чоршанба +Шанба +шарт-номани +шартини +шартлар +шартлари +шартни +шартнома +шахс +шовқин +Шом +Шу +эди +Эртага +Эртадан сўнг [Эртасиганг] +Эшитишимга +эълон +эълонингиз +эълонингизни +эътироф +Юклаш +Якшанба +Январи +Ярим кеча [Яримкеча, Яримчиликча] +яхши +қабул +қаерда +Қанақа +қаноатманда +қанча +қачон +қизиқарлидир +қиламиз +қилганим [қилганим, қилганими, қилгандайин] +қилдим +қилинг +қилинди +қилишди +қиммат +қиммати +Қимматидан +қирқ +Қиш +қувонарлими +қўнғироқ +Қўшимча +ҳайвонини +ҳам +ҳамза +Ҳар +ҳафтага +ҳақиқатан +ҳисоблаб +Ҳозир +ҳужжатни +Ўтган кун [Ўтган кўн] + + diff --git a/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt b/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt new file mode 100644 index 00000000000..0b2717d0ce6 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt @@ -0,0 +1,200 @@ +Salom +Sallom [Slalom, Salom, Musallo, Alloma, Salo] +Rahmat +Rhmat [Rahmat, Marhamat] +Iltimos +Iltimo [Iltimos, Tilsimot, Timol] +Kattalar +Kattalarvf [Kattalashtir] +Yaxshi +Yashi [Ayshi, Tashi, Yash, Yasashi, Yarashish, Yalashish, Yaxshi] +Kelajak +Keljajak [Kelajak] +Oilaviy +Oilaaviy [Oilaviy, Hosilaviy] +Qarindosh +Qarinndosh [Qarindosh, Qayindoshlar, Oqarinish] +Shahar +Shaha [Shah, Shalha] +Dengiz +Dengizzz [Dengiz] +Quyosh +Quyyosh [Quyosh, Quysh] +Yulduz +Oyim +Kechqurun +Tushun +Suvchi +Sharob +Choyxona +Nonushta +Tushlik +Muzqaymoq +Desert +Tuzluq +Mevalar +Sabzavot +Baliq +Tuxumli +Sabza +Sariq +Salatlar +Shirinlik +Shokolad +Rishta +Kakao +Pishloq +Tort +Qaymoq +Sutli +Qatiq +Salomatlik +Temir +Zahar +Oqimli +Shamol +Olov +Yer +Osmon +Shanba +Dushanba +Seshanba +Chorshanba +Payshanba +Juma +Yakshanba +Oltin +Tong +Bomdod +Asr +Shom +Kun +Oqsoqol +Shoshqaloq +Kulgili +Muxlislilar +Tavsiflash +Tuzilishga +Mustaqillik +Tushuntirish +Boshqarish +Mashhurlik +Tarkibiy +Tahlil +Ishchi +Xalqaro +Tarjima +Mustahkamlik +Chaqaloq +Istiqbol +Tasvir +Taklif +Tasavvur +Jiddiy +Majburiyat +Asosiy +Tahdid +Tushunmovchilik +Ishonch +Maqomi +Ijodkor +Tadbirkor +Hayotiy +Mashhur +Bemorlik +Tadbir +Jismoniy +Madaniyat +Xavfsizlik +Sifatli +Suvli +Sotuvchi +Chetel +Tashqi +Sotuv +Tarbiyalanish +Murabbo +Sariqcha +Qovun +Shaharlik +Muhimlik +Tarbiyachilik +Xatolik +Balandlik +Yuzaki +Kuyov +Qiziquvchan +Orzular +Mashq +Qalampir +Muammo +Sadoqatli +Yovuzlik +Fikr-mulohaza +Boylik +Tushuncha +Zanjir +Eslatma +Tabassum +Ishonuvchi +Chidamlilik +Ilova +Birodarlik +Oqilona +Ijodiyot +Tayanch +Hurmat +Baxtli +Tajriba +Samimiylik +Shifokor +Ishrat +Baho +Namoyish +Qiyinchilik +Bolalar +Ishonchli +Taqdir +Shovqinli +Xalqaro +Baxt +Fursat +Hurmatli +Qulaylik +Zamonaviy +Sadoqat +Sabr +Nikoh +Jasorat +Barkamollik +Dunyoqarash +Omadli +Foydali +Yorqin +Mehribonlik +Fazilatli +Kutubxona +Istiqomatli +Fido +Bahor +Shafqatsizlik +Tafakkur +Fazilat +Qochish +Laziz +Uzoq +Ilhom +Omad +Hurmatli +Tandir +Sherzod +Bahoriy +Dilshod +Baxtli +Shonli +Nurli +Shafqatsizlik +Oqqush +Boylik +Toza +Sabrli diff --git a/Common/3dParty/hunspell/test/dst/vi_VN.txt b/Common/3dParty/hunspell/test/dst/vi_VN.txt new file mode 100644 index 00000000000..bcc3ab31505 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/vi_VN.txt @@ -0,0 +1,128 @@ +Bánh +Bang +bênh +bướng +bậy +Chanh +chum +chuyện +chép +Chùng +chắp +chệnh +chới +chữ +công +cạc +cột +cứu +Doanh +duyên +dùng +dể +dọng +gia +giày +giêng +Giảng +giềng +hon +Hoẳn +Hài +hôm +hước +hấu +hớt +hữu +Khiển +Khoào +khuya +khuyến +khách +khén +khẩn +khắp +khựng +kẻo +lang +liền +Loàng +Luỗng +lình +lương +lấp +lệnh +lịnh +lốn +lời +lựng +Muộn +Mãnh +mại +mạn +mổ +mởn +nghiễm +nghều +Ngoáy +Nguyên +ngóp +người +ngỏ +ngớp +ngụa +ngửng +nhiếp +nhu +nhà +nhân +Nhóm +nhưỡng +nhắm +nhổn +nhứt +ninh +noi +nãy +nạn +nốt +ong +pao +phiên +phiêu +Phên +Phương tiện [] +phẩm chất [] +phố đi bộ [phố đì bộ, phố đĩ bộ] +quan trọng [quàn trọng, quản trọng, quán trọng, quăn trọng, quằn trọng, quắn trọng, quặn trọng, quân trọng, quần trọng, quẩn trọng, quẫn trọng, quấn trọng, quận trọng] +quyền lợi [quyền] +quán cà phê [qùán cà phê, qủán cà phê, qũán cà phê, qúán cà phê, qụán cà phê, qưán cà phê, qừán cà phê, qửán cà phê, qữán cà phê, qứán cà phê, qựán cà phê] +quảng cáo [quảng] +Quốc +Quốc tế [Quốc] +riêng biệt [triêng] +rưỡi +Rải +Rẻng +rộng rãi [rộng] +siễn +sum +Sõng +Sưu +sưu tập [] +sử dụng [sử đụng] +Thiệt thòi [] +Thuộc về [Thuộc] +thuộc tính [] + +Слова с ошибками [] +thiệte [thiệt, thiệt e, thiện] +quốq tế [] +nguên [nguyên, nguồn] +khoao [khoào, khoai, khoa, khao, khoeo, khoèo, khoan] +chenh [chênh, chềnh, chểnh, chễnh, chếnh, chệnh, cheng, chen, chanh, chành, chảnh, chánh, chạnh, chinh, chình] +chhùng [chùng, chùn, hùng] +man +doah [doa, doanh, doan, doa h] +khien [khiên, khiền, khiển, khiến, khin, khen] +ngoay From 0476dedbac2269b8fdd4a2560bd2990226c36897 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 29 Feb 2024 21:54:50 +0300 Subject: [PATCH 367/794] fix bug #66656 --- OdfFile/Reader/Format/documentcontext.cpp | 2 +- OdfFile/Reader/Format/documentcontext.h | 1 + OdfFile/Reader/Format/styles.cpp | 31 +++++++++++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Format/documentcontext.cpp b/OdfFile/Reader/Format/documentcontext.cpp index a5549a30452..a74e4252058 100644 --- a/OdfFile/Reader/Format/documentcontext.cpp +++ b/OdfFile/Reader/Format/documentcontext.cpp @@ -36,7 +36,7 @@ namespace cpdoccore { namespace odf_reader { -document_context::document_context() : last_paragraph(NULL) +document_context::document_context() : last_paragraph(NULL), is_old_version(false) { } diff --git a/OdfFile/Reader/Format/documentcontext.h b/OdfFile/Reader/Format/documentcontext.h index 4e1bf4bcbb5..b37fde31630 100644 --- a/OdfFile/Reader/Format/documentcontext.h +++ b/OdfFile/Reader/Format/documentcontext.h @@ -49,6 +49,7 @@ class document_context office_element* get_last_element(); std::wstring office_class_; //openoffice xml 1.0 + bool is_old_version; //openoffice xml 1.0 std::vector levels; office_element* last_paragraph; diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index 6276981d8a3..75cdd7736f7 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -279,6 +279,8 @@ void style_content::add_child_element( xml::sax * Reader, const std::wstring & N } else if CP_CHECK_NAME(L"style", L"properties") { + Context->is_old_version = true; + office_element_ptr element; CP_CREATE_ELEMENT_SIMPLE(element); @@ -1775,16 +1777,41 @@ void style_master_page::pptx_convert(oox::pptx_conversion_context & Context) if (attlist_.draw_style_name_) { std::wstring style_name = attlist_.draw_style_name_.get(); - style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::DrawingPage, true); + graphic_format_properties* default_properties = NULL; + + if (getContext()->is_old_version) + { + style_instance* style_inst_def = Context.root()->odf_context().styleContainer().style_by_name(L"standard", style_family::Graphic, true); + if ((style_inst_def) && (style_inst_def->content())) + { + default_properties = style_inst_def->content()->get_graphic_properties(); + } + } + else + { + style_instance* style_inst_def = Context.root()->odf_context().styleContainer().style_default_by_type(odf_types::style_family::Graphic); + if ((style_inst_def) && (style_inst_def->content())) + { + default_properties = style_inst_def->content()->get_graphic_properties(); + } + } + style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::DrawingPage, true); if ((style_inst) && (style_inst->content())) { style_drawing_page_properties * properties = style_inst->content()->get_style_drawing_page_properties(); if (properties) { + odf_types::common_draw_fill_attlist calc_props; + if (default_properties) + { + calc_props.apply_from(default_properties->common_draw_fill_attlist_); + } + calc_props.apply_from(properties->content().common_draw_fill_attlist_); + oox::_oox_fill fill; - Compute_GraphicFill(properties->content().common_draw_fill_attlist_, office_element_ptr(), Context.root(), fill); + Compute_GraphicFill(calc_props, office_element_ptr(), Context.root(), fill); Context.get_slide_context().add_background(fill); } } From c649de088aa789056bcdf593c27fd72c77ebf198 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 29 Feb 2024 15:54:56 +0300 Subject: [PATCH 368/794] . (cherry picked from commit bba6d180dcbb95143a4b997054444f6feb7cd09f) --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 71ec17e9911..073c3f05a01 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -8020,26 +8020,26 @@ void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet: if (oUserProtectedRange.m_oName.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Name); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oName); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oName); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oSqref.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Sqref); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oSqref); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oSqref); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oText.IsInit()) { int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Text); - m_oBcw.m_oStream.WriteStringW(*oUserProtectedRange.m_oText); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oText); m_oBcw.WriteItemEnd(nCurPos); } if (oUserProtectedRange.m_oType.IsInit()) { - m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRange::Type); - m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Type); m_oBcw.m_oStream.WriteBYTE(oUserProtectedRange.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); } for (size_t i = 0; i < oUserProtectedRange.m_arUsers.size(); ++i) { From e2dc625b0aa878c9853f4e6ec58be206399316b2 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 1 Mar 2024 13:54:47 +0300 Subject: [PATCH 369/794] Fix bugs and refactoring --- .../html/css/src/CCssCalculator_Private.cpp | 5 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 7 -- HtmlFile2/htmlfile2.cpp | 102 +++++++++++++----- 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 1e75061a5c9..f127eb1fd2b 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -521,7 +521,10 @@ namespace NSCSS // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются if (L"table" == arSelectors[i].m_wsName) - oStyle.m_oFont.SetLineHeight(L"100%", 0, true); + { + oStyle.m_oFont.Clear(); + oStyle.m_oPadding.Clear(); + } CCompiledStyle oTempStyle; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 42fa4cd18d8..41e5f41ef90 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -304,13 +304,6 @@ namespace NSCSS if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) sSpacingValue += L" w:line=\"" + std::to_wstring(oStyle.m_oFont.GetLineHeight().ToInt(NSCSS::Twips, DEFAULT_LINEHEIGHT)) + L"\" w:lineRule=\"auto\""; -// else if (!oStyle.m_oBorder.Empty()) -// { -// sSpacingValue += L" w:line=\"" + std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Twips) * 2 * POINTCOEF + 0.5f)) + L"\" w:lineRule=\"auto\""; -// } - else if (!oStyle.m_oBorder.Empty()) - sSpacingValue += L" w:line=\"" + std::to_wstring(DEFAULT_LINEHEIGHT) + L"\" w:lineRule=\"auto\" "; - if (!sSpacingValue.empty()) { oXmlElement.AddPropertiesInP(PProperties::P_Spacing, sSpacingValue); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 200b6158964..78cfc12eeae 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -81,6 +81,20 @@ struct CTextSettings bBdo(oTS.bBdo), bPre(oTS.bPre), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} }; +//Необходимые стили таблицы +struct TTableStyles +{ + const NSCSS::NSProperties::CIndent* m_pPadding; + const NSCSS::NSProperties::CEnum* m_pCollapse; + + int m_nCellSpacing; + bool m_bHaveBorderAttribute; + + TTableStyles() + : m_pPadding(NULL), m_pCollapse(NULL), m_nCellSpacing(-1), m_bHaveBorderAttribute(false) + {} +}; + void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) { size_t pos = s.find(s1); @@ -839,6 +853,9 @@ class CHtmlFile2_Private else ReplaceSpaces(sText); + if (1 == sText.length() && std::iswspace(sText.front())) + sText = L"\u00A0"; + oXml->WriteEncodeXmlString(sText); oXml->WriteString(L""); @@ -945,18 +962,30 @@ class CHtmlFile2_Private else if(sAName == L"size") { int nSize = 3; - std::wstring sSize = m_oLightReader.GetText(); + const std::wstring sSize = m_oLightReader.GetText(); if(!sSize.empty()) { if(sSize.front() == L'+') - nSize += std::stoi(sSize.substr(1)); + nSize += NSStringFinder::ToInt(sSize.substr(1)); else if(sSize.front() == L'-') - nSize -= std::stoi(sSize.substr(1)); + nSize -= NSStringFinder::ToInt(sSize.substr(1)); else - nSize = std::stoi(sSize); + nSize = NSStringFinder::ToInt(sSize); } - sSize = nSize >= 1 && nSize <= 7 ? std::to_wstring(10 + nSize * 5) : L"22"; - sSelectors.back().m_wsStyle += L"; font-size: " + sSize; + + switch (nSize) + { + case 1: nSize = 10; break; + case 2: nSize = 12; break; + case 3: + default: nSize = 14; break; + case 4: nSize = 18; break; + case 5: nSize = 24; break; + case 6: nSize = 32; break; + case 7: nSize = 48; break; + } + + sSelectors.back().m_wsStyle += L"; font-size: " + std::to_wstring(nSize) + L"px"; } } m_oLightReader.MoveToElement(); @@ -1139,7 +1168,7 @@ class CHtmlFile2_Private else if(sName == L"pre" || sName == L"xmp") { CTextSettings oTSPre(oTS); - sSelectors.back().m_wsStyle += L" font-family:Consolas;"; + sSelectors.back().m_wsStyle += L"; font-family:Consolas"; oTSPre.bPre = true; readStream(oXml, sSelectors, oTSPre); } @@ -1217,18 +1246,18 @@ class CHtmlFile2_Private return L""; } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const NSCSS::CCompiledStyle& oTableStyle) + void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const TTableStyles& oTableStyles) { const std::wstring wsName = m_oLightReader.GetName(); std::vector mTable; int nDeath = m_oLightReader.GetDepth(); int i = 1; // Строка - + UINT unMaxColumns = 0; - + bool bTableHasBorderAttribute = false; - + for (std::vector::const_reverse_iterator oIter = sSelectors.crbegin(); oIter < sSelectors.crend(); ++oIter) { if (L"table" != oIter->m_wsName) @@ -1240,7 +1269,7 @@ class CHtmlFile2_Private break; } } - + while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) { // tr - строки в таблице @@ -1258,7 +1287,9 @@ class CHtmlFile2_Private if (L"thead" == wsName) wsTrPr += L""; - if (!bTableHasBorderAttribute && oTableStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + if (0 <= oTableStyles.m_nCellSpacing) + wsTrPr += L""; + else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) wsTrPr += L""; if (!wsTrPr.empty()) @@ -1342,16 +1373,16 @@ class CHtmlFile2_Private else wsTcPr += L""; - if (!oStyle.m_oPadding.Empty() && oStyle.m_oPadding != oTableStyle.m_oPadding) + if (NULL != oTableStyles.m_pPadding && !oStyle.m_oPadding.Empty() && oStyle.m_oPadding != *oTableStyles.m_pPadding) { - const int nTopPadding = std::max(oTableStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nLeftPadding = std::max(oTableStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), - oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - const int nBottomPadding = std::max(oTableStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - oStyle .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nRightPadding = std::max(oTableStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), - oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nTopPadding = std::max(oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nBottomPadding = std::max(oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + oStyle .m_oPadding.GetBottom() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); wsTcPr += L"" "" @@ -1445,11 +1476,17 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); - if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") - oXml->WriteString(L""); + TTableStyles oTableStyles; + + oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) + oTableStyles.m_bHaveBorderAttribute = true; + +// if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") +// oXml->WriteString(L""); m_bWasSpace = false; - + // Начало таблицы std::wstring wsTable = L""; @@ -1466,6 +1503,13 @@ class CHtmlFile2_Private else wsTable += L""; + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) + { + oTableStyles.m_nCellSpacing = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"]); + + wsTable += L""; + } + std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); if (wsAlign.empty()) @@ -1504,6 +1548,8 @@ class CHtmlFile2_Private "" "" ""; + + oTableStyles.m_pPadding = &oStyle.m_oPadding; } else wsTable += L""; @@ -1574,11 +1620,11 @@ class CHtmlFile2_Private CloseP(oXml, sSelectors); } if(sName == L"thead") - readTr(&oHead, sSelectors, oTS, oStyle); + readTr(&oHead, sSelectors, oTS, oTableStyles); else if(sName == L"tbody") - readTr(&oBody, sSelectors, oTS, oStyle); + readTr(&oBody, sSelectors, oTS, oTableStyles); else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS, oStyle); + readTr(&oFoot, sSelectors, oTS, oTableStyles); sSelectors.pop_back(); } From c9aad72ecc4f32dc35b4dbf9f260f1cbea954a16 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Mar 2024 18:00:36 +0600 Subject: [PATCH 370/794] Fix bug 66671 --- OOXML/XlsxFormat/Styles/Borders.cpp | 33 +++++++++++++++++++---------- OOXML/XlsxFormat/Styles/NumFmts.cpp | 4 ++++ OOXML/XlsxFormat/Styles/rPr.cpp | 1 + 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 5350fe6b444..f3d7e40e979 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -140,6 +140,13 @@ namespace OOX void CBorderProp::toBin(XLS::BiffStructure* obj) { auto ptr = static_cast(obj); + if(this == nullptr) + { + CColor color; + ptr->brtColor = color.GetDefaultColor(); + ptr->dg = 0x00; + return; + } if(m_oColor.IsInit()) ptr->brtColor = m_oColor->toColor(); else @@ -356,17 +363,21 @@ namespace OOX { auto ptr(new XLSB::Border); XLS::BaseObjectPtr objectPtr(ptr); - if(m_oBottom.IsInit()) - m_oBottom->toBin(&ptr->blxfBottom); - if(m_oDiagonal.IsInit()) - m_oDiagonal->toBin(&ptr->blxfDiag); - if(m_oTop.IsInit()) - m_oTop->toBin(&ptr->blxfTop); - if(m_oStart.IsInit()) - m_oStart->toBin(&ptr->blxfLeft); - if(m_oEnd.IsInit()) - m_oEnd->toBin(&ptr->blxfRight); - + + m_oBottom->toBin(&ptr->blxfBottom); + m_oDiagonal->toBin(&ptr->blxfDiag); + m_oTop->toBin(&ptr->blxfTop); + m_oStart->toBin(&ptr->blxfLeft); + m_oEnd->toBin(&ptr->blxfRight); + + if(m_oDiagonalDown.IsInit()) + ptr->fBdrDiagDown = m_oDiagonalDown->GetValue(); + else + ptr->fBdrDiagDown = false; + if(m_oDiagonalUp.IsInit()) + ptr->fBdrDiagUp = m_oDiagonalUp->GetValue(); + else + ptr->fBdrDiagUp = false; return objectPtr; } EElementType CBorder::getType () const diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index 9109cf6fe96..77a1f6b0b79 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -37,6 +37,7 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../XlsbFormat/Biff12_unions/FMTS.h" +#include "../../XlsbFormat/Biff12_records/BeginFmts.h" namespace OOX { @@ -202,12 +203,15 @@ namespace OOX XLS::BaseObjectPtr CNumFmts::toBin() { auto fmts(new XLSB::FMTS); + auto beginfmt(new XLSB::BeginFmts); + fmts->m_BrtBeginFmts = XLS::BaseObjectPtr{beginfmt}; XLS::BaseObjectPtr objectPtr(fmts); std::vector objectVector; for(auto i:m_arrItems) { fmts->m_arBrtFmt.push_back(i->toBin()); } + beginfmt->cfmts = fmts->m_arBrtFmt.size(); return objectPtr; } EElementType CNumFmts::getType () const diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 6c99fa3e12e..8fe1bf5a5ec 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -494,6 +494,7 @@ namespace OOX ptr.bBlue = m_oRgb->Get_B(); ptr.bGreen = m_oRgb->Get_G(); ptr.bRed = m_oRgb->Get_R(); + ptr.xColorType = 2; } From bb1d5401d216490f21331424319f48662ec3da43 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 1 Mar 2024 15:24:09 +0300 Subject: [PATCH 371/794] Refactoring --- HtmlFile2/htmlfile2.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 78cfc12eeae..07b28df1f4f 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -499,7 +499,36 @@ class CHtmlFile2_Private if(nFindEnd != std::string::npos) sFileContent.replace(nFind, nFindEnd - nFind, "1.0"); } + + // Так как для htmlToXhtml стили не нужны, а также их содержимое может пагубно повлиять на резьтат, + // то поэтому вырезаем их и вставляем уже после + size_t nFirstStyleFounded = sFileContent.find("", nStyleFounded); + + if (std::string::npos == nStyleEndFounded) + break; + + sStyles += sFileContent.substr(nStyleFounded + 7, nStyleEndFounded - nStyleFounded - 7) + " "; + sFileContent.erase(nStyleFounded, nStyleEndFounded - nStyleFounded + 8); + + nStyleFounded = sFileContent.find(""); + else + sRes.insert(nFirstStyleFounded, L""); + } // NSFile::CFileBinary oWriter; // if (oWriter.CreateFileW(m_sTmp + L"/res.html")) From 1ff92a8e7104c1a01da0714c261966c66dc3822e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Mar 2024 19:33:15 +0600 Subject: [PATCH 372/794] Fix def name conversion --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp | 2 +- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp index 6bf66b4a28e..cc3fad865b0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp @@ -80,7 +80,7 @@ void PtgName::writeFields(CFRecord& record) { record.reserveNunBytes(12); } - else + else if(record.getGlobalWorkbookInfo()->Version < 0x0800 ) { record.reserveNunBytes(2); } diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index e5e1ce607f3..bb0287e3910 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -73,6 +73,8 @@ namespace OOX return; m_oRef = oReader.GetText3(); + if(m_oName.IsInit()) + XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(m_oName.get()); } XLS::BaseObjectPtr CDefinedName::toBin() { From 1a86da3559101a0d3e71c5e8eec6eb862376b59b Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 1 Mar 2024 16:33:44 +0300 Subject: [PATCH 373/794] Fix bug #66670 --- .../html/css/src/CCssCalculator_Private.cpp | 4 +- HtmlFile2/htmlfile2.cpp | 53 +++++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index f127eb1fd2b..8c4170e1d70 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -85,7 +85,8 @@ namespace NSCSS } } - + + #ifdef CSS_CALCULATOR_WITH_XHTML std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) { if (m_arPageDatas.empty()) @@ -248,6 +249,7 @@ namespace NSCSS return arFindedElements; } + #endif void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles) { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 1acb5beb4c4..4cbc115e8ef 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1101,7 +1101,8 @@ class CHtmlFile2_Private else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) { wrP(oXml, sSelectors, oTS); - readSVG(oXml); + if (readSVG(m_oLightReader.GetOuterXml())) + ImageRels(oXml, -1, L"", L"png"); } else if(sName == L"input") readInput(oXml, sSelectors, oTS); @@ -1938,25 +1939,33 @@ class CHtmlFile2_Private if (nBase == std::wstring::npos) return bRes; - NSFile::CFileBinary oImageWriter; - std::wstring sImageName = std::to_wstring(m_arrImages.size()) + L'.' + sExtention; - if (oImageWriter.CreateFileW(m_sDst + L"/word/media/i" + sImageName)) + int nOffset = nBase + 7; + int nSrcLen = (int)(sSrcM.length() - nBase + 1); + int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); + if (nDecodeLen != 0) { - int nOffset = nBase + 7; - int nSrcLen = (int)(sSrcM.length() - nBase + 1); + BYTE* pImageData = new BYTE[nDecodeLen]; - int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); - if (nDecodeLen != 0) + if (!pImageData || FALSE == NSBase64::Base64Decode(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) + return bRes; + + if (L"svg" == sExtention || L"svg+xml" == sExtention) { - BYTE* pImageData = new BYTE[nDecodeLen]; - if (TRUE == NSBase64::Base64Decode(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) - { - oImageWriter.WriteFile(pImageData, (DWORD)nDecodeLen); - bRes = true; - } - RELEASEARRAYOBJECTS(pImageData); + std::wstring wsSvg(pImageData, pImageData + nDecodeLen); + bRes = readSVG(wsSvg); } - oImageWriter.CloseFile(); + else + { + NSFile::CFileBinary oImageWriter; + std::wstring sImageName = std::to_wstring(m_arrImages.size()) + L'.' + sExtention; + + if (oImageWriter.CreateFileW(m_sDst + L"/word/media/i" + sImageName)) + bRes = oImageWriter.WriteFile(pImageData, (DWORD)nDecodeLen); + + oImageWriter.CloseFile(); + } + + RELEASEARRAYOBJECTS(pImageData); } return bRes; @@ -2282,12 +2291,10 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L""); } - void readSVG (NSStringUtils::CStringBuilder* oXml) + bool readSVG (const std::wstring& wsSvg) { - const std::wstring wsSvg = m_oLightReader.GetOuterXml(); - if (wsSvg.empty()) - return; + return false; CSvgFile oSvgReader; @@ -2304,7 +2311,7 @@ class CHtmlFile2_Private { RELEASEINTERFACE(pFontManager); pFonts->Release(); - return; + return false; } NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create(); @@ -2350,7 +2357,7 @@ class CHtmlFile2_Private } if (!pBgraData) - return; + return false; unsigned int alfa = 0xffffff; //дефолтный тон должен быть прозрачным, а не белым @@ -2384,7 +2391,7 @@ class CHtmlFile2_Private pFonts->Release(); - ImageRels(oXml, -1, L"", L"png"); + return true; } }; From 3d1b8e64ac92a204ccab73919e13a183e7d6ce4b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Mar 2024 22:25:03 +0600 Subject: [PATCH 374/794] Fix shared formula conversion --- .../Biff_structures/SharedParsedFormula.cpp | 2 +- .../Logic/Biff_structures/StringPtgParser.cpp | 2 +- .../Worksheets/ConditionalFormatting.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 57 +++++++------------ OOXML/XlsxFormat/Worksheets/SheetData.h | 2 +- 5 files changed, 23 insertions(+), 42 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp index 066752eb2a5..14d90b2532f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp @@ -44,7 +44,7 @@ SharedParsedFormula::SharedParsedFormula(const bool is_part_of_a_revision, const SharedParsedFormula& SharedParsedFormula::operator=(const std::wstring& value) { - ParsedFormula::operator = (value); + parseStringFormula(value, L"SharedParsedFormula"); return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 03918299b10..d0405285065 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -341,7 +341,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(L"SharedParsedFormula" == tag_name || L"CFParsedFormulaNoCCE" == tag_name) { - found_operand = OperandPtgPtr(new PtgAreaN(operand_str, OperandPtg::ptg_VALUE, rgce.getLocation())); + found_operand = OperandPtgPtr(new PtgAreaN(operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation())); } else { diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 954ac25be5a..169bac34e40 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -2642,7 +2642,7 @@ XLS::BaseObjectPtr CConditionalFormatting::toBin() XLS::CellRef formatingfirstCell; if(m_oSqRef.IsInit()) { - auto conditionPtr(new XLSB::BeginConditionalFormatting);// + auto conditionPtr(new XLSB::BeginConditionalFormatting); ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; conditionPtr->ccf = m_arrItems.size(); conditionPtr->sqrfx.strValue = m_oSqRef.get(); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index fc00ce1b7aa..1e887b76672 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2183,53 +2183,34 @@ namespace OOX if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeShared) { - m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeNormal; - ptr->m_source = XLS::BaseObjectPtr{pFMLACELL}; + pSHRFMLACELL = new XLSB::SHRFMLACELL(0,0, refs); + ptr->m_source = XLS::BaseObjectPtr{pSHRFMLACELL}; pFMLACELL->m_source = XLS::BaseObjectPtr{pSource}; + pSHRFMLACELL->_fmlacell = XLS::BaseObjectPtr{pFMLACELL}; if(!m_oFormula->m_sText.empty()) { - m_oFormula->toBin(pFMLACELL->m_source); + auto shrFmla(new XLSB::ShrFmla(cellref)); + pSHRFMLACELL->m_source = XLS::BaseObjectPtr{shrFmla}; + m_oFormula->toBin(pSHRFMLACELL->m_source); - sharedFormulas.shrFmla.push_back(std::make_pair(cellref, m_oFormula->m_sText)); + sharedFormulas.shrFmla.push_back(cellref); } - else if(m_oFormula->m_oSi.IsInit() && sharedFormulas.shrFmla.size() > m_oFormula->m_oSi->GetValue() ) + if(m_oFormula->m_oSi.IsInit() && sharedFormulas.shrFmla.size() > m_oFormula->m_oSi->GetValue() ) { - - auto fmla = dynamic_cast(pSource); - - auto dataPair = sharedFormulas.shrFmla[m_oFormula->m_oSi->GetValue()]; - sourceCellRef = dataPair.first; - int coldiff = 0; - if(sourceCellRef.colRelative) - coldiff = cellref.column - dataPair.first.column; - int rowdiff = 0; - if(sourceCellRef.rowRelative) - rowdiff = cellref.row - dataPair.first.row; - fmla->formula = dataPair.second; - if(rowdiff || coldiff) - { - for(auto i:fmla->formula.rgce.sequence) - { - if(i->ptg_id.is_initialized() && i->ptg_id.get() == 37) - { - auto area(static_cast(i.get())); - area->areaXlsb.columnFirst += coldiff; - area->areaXlsb.columnLast += coldiff; - area->areaXlsb.rowFirst += rowdiff; - area->areaXlsb.rowLast += rowdiff; - } - else if(i->ptg_id.is_initialized() && i->ptg_id.get() == 36) - { - auto area(static_cast(i.get())); - area->loc_xlsb.column += coldiff; - area->loc_xlsb.row += rowdiff; - } - } - } - + sourceCellRef = sharedFormulas.shrFmla[m_oFormula->m_oSi->GetValue()]; } + + auto rowPos = new XLS::PtgExp; + rowPos->rowXlsb = sourceCellRef.row; + auto colPos = new XLS::PtgExtraCol; + colPos->col = sourceCellRef.column; + auto cellFmla = dynamic_cast(pSource); + cellFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + cellFmla->formula.rgcb.addPtg(PtgPtr{colPos}); + + } else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::cellformulatypeArray) { diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 1b18f455f17..ea9e1f145b7 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -128,7 +128,7 @@ namespace OOX struct sharedFormula { - std::vector> shrFmla; + std::vector shrFmla; std::vector> arrfmla; }; class CFormula : public WritingElement From 6bbf1190a7b0b543a50530d64d9ddaad10be5ea5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Mar 2024 22:25:33 +0600 Subject: [PATCH 375/794] Fix reference limits --- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp | 8 ++++---- .../XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index d1b3cbb4e72..4050d9f5417 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -130,9 +130,9 @@ const int str2column(std::wstring::const_iterator& str_begin, std::wstring::cons column = (column + 1) * radix + (symb - L'A'); } - if(column > 255) + if(column > 16384) { - column = 255; + column = 16384; } return column; @@ -152,9 +152,9 @@ const int str2row(std::wstring::const_iterator& str_begin, std::wstring::const_i row = row * 10 + (symb - L'0'); } --row; - if(row > 65535) + if(row > 1048576) { - row = 65535; + row = 1048576; } return row; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp index dd5354f3ce6..4de86dbffc3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp @@ -186,12 +186,16 @@ void CellRangeRef::fromString(const std::wstring& str) } rowFirst = 0; - rowLast = 65535; + rowLast = 1048576; + rowFirstRelative = false; + rowLastRelative = false; } if(-1 == columnFirst || -1 == columnLast) // no column specified - means whole row or range of rows { columnFirst = 0; - columnLast = 255; + columnLast = 16384; + columnFirstRelative = false; + columnLastRelative = false; } to_string_cache.clear(); } From aad25c3da835869201370c34af9d572e6ad33e88 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 2 Mar 2024 15:22:30 +0300 Subject: [PATCH 376/794] fix bug #66699 --- OdfFile/Reader/Format/draw_shapes_pptx.cpp | 5 +---- OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h | 3 ++- OdfFile/Writer/Format/draw_shapes.cpp | 1 + OdfFile/Writer/Format/draw_shapes.h | 3 ++- OdfFile/Writer/Format/odf_drawing_context.cpp | 12 +++++++----- OdfFile/Writer/Format/oox_shape_defines.h | 5 +++-- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/OdfFile/Reader/Format/draw_shapes_pptx.cpp b/OdfFile/Reader/Format/draw_shapes_pptx.cpp index e3e2cd70bad..04bc9eb8ed0 100644 --- a/OdfFile/Reader/Format/draw_shapes_pptx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_pptx.cpp @@ -397,10 +397,7 @@ void draw_connector::pptx_convert(oox::pptx_conversion_context & Context) } void draw_enhanced_geometry::pptx_convert(oox::pptx_conversion_context & Context) { - find_draw_type_oox(); - - bool set_shape = oox_convert(Context.get_slide_context().get_properties()); - + bool set_shape = oox_convert(Context.get_slide_context().get_properties()); if (!set_shape) { diff --git a/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h b/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h index 6845f5e1e94..0bce8878567 100644 --- a/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h +++ b/OdfFile/Writer/Format/Shapes/oox_shapeCallouts.h @@ -404,7 +404,8 @@ class oox_shape_WedgeRectCallout : public oox_shape view_box = L"0 0 21600 21600"; modifiers = L"6300 24300"; glue_points = L"?f40 ?f41"; - + glue_points_leaving_directions = L"180"; + add(L"f0", L"$0 -10800"); add(L"f1", L"$1 -10800"); add(L"f2", L"if(?f18 ,$0 ,0)"); diff --git a/OdfFile/Writer/Format/draw_shapes.cpp b/OdfFile/Writer/Format/draw_shapes.cpp index 7149a8fed2e..49b8c3dc913 100644 --- a/OdfFile/Writer/Format/draw_shapes.cpp +++ b/OdfFile/Writer/Format/draw_shapes.cpp @@ -428,6 +428,7 @@ void draw_enhanced_geometry_attlist::serialize(CP_ATTR_NODE) //CP_XML_ATTR_OPT(L"drawooo:enhanced-path", draw_enhanced_path_); CP_XML_ATTR_OPT(L"draw:enhanced-path", draw_enhanced_path_); CP_XML_ATTR_OPT(L"draw:glue-points", draw_glue_points_); + CP_XML_ATTR_OPT(L"draw:glue-point-leaving-directions", glue_points_leaving_directions_); CP_XML_ATTR_OPT(L"draw:mirror-vertical", draw_mirror_vertical_); CP_XML_ATTR_OPT(L"draw:mirror-horizontal", draw_mirror_horizontal_); diff --git a/OdfFile/Writer/Format/draw_shapes.h b/OdfFile/Writer/Format/draw_shapes.h index ba79801a85d..de272fb8e2d 100644 --- a/OdfFile/Writer/Format/draw_shapes.h +++ b/OdfFile/Writer/Format/draw_shapes.h @@ -311,7 +311,8 @@ class draw_enhanced_geometry_attlist _CP_OPT(std::wstring) draw_enhanced_path_; _CP_OPT(std::wstring) draw_text_areas_; _CP_OPT(std::wstring) draw_glue_points_; - + _CP_OPT(std::wstring) glue_points_leaving_directions_; + _CP_OPT(std::wstring) draw_sub_view_size_; _CP_OPT(odf_types::Bool) draw_mirror_vertical_; diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 6492c82691b..ead1b31063e 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -1178,15 +1178,17 @@ void odf_drawing_context::end_shape() enhanced->attlist_.draw_glue_points_ = shape_define->glue_points; enhanced->attlist_.draw_sub_view_size_ = shape_define->sub_view_size; + enhanced->attlist_.glue_points_leaving_directions_ = shape_define->glue_points_leaving_directions; enhanced->attlist_.draw_path_stretchpoint_x_ = shape_define->path_stretchpoint_x; enhanced->attlist_.draw_path_stretchpoint_y_ = shape_define->path_stretchpoint_y; - if (!shape_define->modifiers.empty()) - { - enhanced->attlist_.draw_modifiers_ = shape_define->modifiers; - } - else if (impl_->current_drawing_state_.oox_shape_ && !impl_->current_drawing_state_.oox_shape_->modifiers.empty()) + //if (!shape_define->modifiers.empty()) + //{ + // enhanced->attlist_.draw_modifiers_ = shape_define->modifiers; + //} + + if (impl_->current_drawing_state_.oox_shape_ && !impl_->current_drawing_state_.oox_shape_->modifiers.empty()) { enhanced->attlist_.draw_modifiers_ = impl_->current_drawing_state_.oox_shape_->modifiers; } diff --git a/OdfFile/Writer/Format/oox_shape_defines.h b/OdfFile/Writer/Format/oox_shape_defines.h index 01b987f8550..f281c352aa1 100644 --- a/OdfFile/Writer/Format/oox_shape_defines.h +++ b/OdfFile/Writer/Format/oox_shape_defines.h @@ -82,9 +82,10 @@ namespace cpdoccore _CP_OPT(std::wstring) view_box; _CP_OPT(std::wstring) sub_view_size; _CP_OPT(std::wstring) glue_points; + _CP_OPT(std::wstring) glue_points_leaving_directions; - std::wstring path_stretchpoint_x; - std::wstring path_stretchpoint_y; + _CP_OPT(std::wstring) path_stretchpoint_x; + _CP_OPT(std::wstring) path_stretchpoint_y; std::wstring odf_type_name; }; From d88fc239b8d446d18be402c443129fa89458f8d5 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 2 Mar 2024 15:42:11 +0300 Subject: [PATCH 377/794] fix convert to xlsb --- X2tConverter/src/lib/xlsx.h | 57 +++++++++++++------------------------ 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 396b6233c5e..fdd8a159e7d 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -157,41 +157,36 @@ namespace NExtractTools convertParams.m_bTempIsXmlOptions = false; return nRes; } - _UINT32 xlst_bin2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + _UINT32 xlsx_dir2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - _UINT32 nRes = 0; - - std::wstring sTargetBin; - if (params.getFromChanges()) - { - params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sTargetBin, params, convertParams); - } - else - sTargetBin = sFrom; + const OOX::CPath oox_path(sFrom); - BinXlsxRW::CXlsxSerializer oCXlsxSerializer; + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + oXlsb.Read(oox_path); - oCXlsxSerializer.setMacroEnabled(params.m_bMacro); - oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); - oCXlsxSerializer.setFontDir(params.getFontPath()); + OOX::CContentTypes oContentTypes; + _UINT32 nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - std::wstring sXmlOptions = params.getXmlOptions(); + return nRes; + } + _UINT32 xlst_bin2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); - std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method - std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method + _UINT32 nRes = 0; + + std::wstring sTempUnpackedXLSB = convertParams.m_sTempResultOOXMLDirectory; - oCXlsxSerializer.CreateXlsxFolders(sXmlOptions, convertParams.m_sTempResultOOXMLDirectory, sMediaPath, sEmbedPath); + convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSX; + nRes = xlst_bin2xlsx_dir(sFrom, sTempUnpackedXLSX, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = oCXlsxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sMediaPath, sEmbedPath); + convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSB; + nRes = xlsx_dir2xlsb_dir(sTempUnpackedXLSX, sTempUnpackedXLSB, params, convertParams); } - // удаляем EditorWithChanges, потому что он не в Temp - if (sFrom != sTargetBin) - NSFile::CFileBinary::Remove(sTargetBin); - - convertParams.m_sTempResultOOXMLDirectory = L""; return nRes; } _UINT32 xlst_bin2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) @@ -358,19 +353,7 @@ namespace NExtractTools } return nRes; } - _UINT32 xlsx_dir2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) - { - const OOX::CPath oox_path(sFrom); - - OOX::Spreadsheet::CXlsb oXlsb; - oXlsb.m_bWriteToXlsb = true; - oXlsb.Read(oox_path); - OOX::CContentTypes oContentTypes; - _UINT32 nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; - - return nRes; - } _UINT32 xlsx_dir2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xlsb", xlsx_dir2xlsb_dir); From 29852ddf2592ab912dfde1bffa1a8de4d5c6faf0 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 4 Mar 2024 10:31:02 +0300 Subject: [PATCH 378/794] Fix BeginShape to BeginMarkedContent --- PdfFile/PdfWriter.cpp | 3 +-- PdfFile/PdfWriter.h | 2 +- PdfFile/PdfWriter_empty.cpp | 2 +- PdfFile/SrcWriter/Document.cpp | 29 +++++++++++++++++++++-------- PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Pages.cpp | 14 +++++--------- PdfFile/SrcWriter/Pages.h | 2 +- 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 523b75cb236..114de87d179 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2345,10 +2345,9 @@ HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, { return m_pDocument->AddMetaData(sMetaName, pMetaData, nMetaLength) ? S_OK : S_FALSE; } -HRESULT CPdfWriter::AddShapeXML(const std::string& sXML) +void CPdfWriter::AddShapeXML(const std::string& sXML) { m_pDocument->AddShapeXML(sXML); - return S_OK; } void CPdfWriter::EndMarkedContent() { diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 810eeea82c6..45a3fff439e 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -198,7 +198,7 @@ class CPdfWriter HRESULT AddFormField (NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory); HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); - HRESULT AddShapeXML(const std::string& sXML); + void AddShapeXML(const std::string& sXML); void EndMarkedContent(); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера diff --git a/PdfFile/PdfWriter_empty.cpp b/PdfFile/PdfWriter_empty.cpp index 85033970f4b..1a8c4a69b42 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/PdfFile/PdfWriter_empty.cpp @@ -133,7 +133,6 @@ HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pInfo, const std::wstring& wsTempDirectory) { return 0; } HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { return 0; } HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) { return 0; } -HRESULT CPdfWriter::AddShapeXML(const std::string& sXML) { return 0; } HRESULT CPdfWriter::DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::EnableBrushRect(const LONG& lEnable) { return 0; } HRESULT CPdfWriter::SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2) { return 0; } @@ -161,6 +160,7 @@ bool CPdfWriter::IsValid() { return false; } bool CPdfWriter::IsPageValid() { return false; } void CPdfWriter::SetError() {} void CPdfWriter::EndMarkedContent() {} +void CPdfWriter::AddShapeXML(const std::string& sXML) {} void CPdfWriter::AddLink(PdfWriter::CPage* pPage, const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const unsigned int& unDestPage) {} unsigned char* CPdfWriter::EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs) { return NULL; } unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) { return NULL; } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 45067e93c6d..d8f6aa57beb 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1585,13 +1585,25 @@ namespace PdfWriter // Вторая часть идентификатора должна обновляться CObjectBase* pID = m_pTrailer->Get("ID"); - if (pID && pID->GetType() == object_type_ARRAY) + if ((pID && pID->GetType() == object_type_ARRAY) || !m_vMetaOForms.empty()) { BYTE arrId[16]; CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); - CObjectBase* pObject = ((CArrayObject*)pID)->Get(1, false); - ((CArrayObject*)pID)->Insert(pObject, new CBinaryObject(arrId, 16), true); + CArrayObject* pArrID = (CArrayObject*)pID; + if (pArrID) + { + CObjectBase* pObject = pArrID->Get(1, false); + pArrID->Insert(pObject, new CBinaryObject(arrId, 16), true); + } + else + { + pArrID = new CArrayObject(); + m_pTrailer->Add("ID", pArrID); + + pArrID->Add(new CBinaryObject(arrId, 16)); + pArrID->Add(new CBinaryObject(arrId, 16)); + } for (int i = 0; i < m_vMetaOForms.size(); ++i) m_vMetaOForms[i]->Add("ID", new CBinaryObject(arrId, 16)); @@ -1721,9 +1733,6 @@ namespace PdfWriter } void CDocument::AddShapeXML(const std::string& sXML) { - // TODO Revision++ - int nRevision = 0; - CObjectBase* pObj = m_pCurPage->Get("MetaOForm"); if (pObj && pObj->GetType() != object_type_DICT) { @@ -1736,7 +1745,6 @@ namespace PdfWriter pMetaOForm = new CDictObject(); m_pXref->Add(pMetaOForm); pMetaOForm->Add("Type", "MetaOForm"); - pMetaOForm->Add("Revision", nRevision); m_pCurPage->Add("MetaOForm", pMetaOForm); m_vMetaOForms.push_back(pMetaOForm); @@ -1767,10 +1775,15 @@ namespace PdfWriter } pArrayMeta->Add(new CStringObject(sXML.c_str())); - m_pCurPage->BeginShape(nRevision); + m_pCurPage->BeginShape(); } void CDocument::EndMarkedContent() { m_pCurPage->EndMarkedContent(); } + bool CDocument::HaveMetaOForm() + { + CObjectBase* pObj = m_pCurPage->Get("MetaOForm"); + return pObj && pObj->GetType() == object_type_DICT; + } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 6666c997553..f5149a7b4da 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -200,6 +200,7 @@ namespace PdfWriter const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); void EndMarkedContent(); + bool HaveMetaOForm(); private: char* GetTTFontTag(); diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 2ef4e523250..5eeead9f111 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1583,17 +1583,13 @@ namespace PdfWriter CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); return pRotate ? pRotate->Get() : 0; } - void CPage::BeginShape(int nRevision) + void CPage::BeginMarkedContent(const std::string& sName) { - // Operator : BDC - // Description: Начало маркированного контента MetaOForm + // Operator : BMC + // Description: Начало маркированного контента - m_pStream->WriteEscapeName("MetaOForm"); - m_pStream->WriteStr(" <<"); - m_pStream->WriteEscapeName("Revision"); - m_pStream->WriteChar(' '); - m_pStream->WriteInt(nRevision); - m_pStream->WriteStr(">> BDC\012"); + m_pStream->WriteEscapeName(sName.c_str()); + m_pStream->WriteStr(" BMC\012"); } void CPage::EndMarkedContent() { diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index d6e62dbb6b1..46e53b3c7a9 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -138,7 +138,7 @@ namespace PdfWriter void DrawShading(CShading* pShading); void SetStrokeAlpha(unsigned char unAlpha); void SetFillAlpha(unsigned char unAlpha); - void BeginShape(int nRevision); + void BeginMarkedContent(const std::string& sName); void EndMarkedContent(); void BeginText(); From f369715c55060d89da45876e9c2463ab2a704376 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 4 Mar 2024 18:12:00 +0600 Subject: [PATCH 379/794] Fix book view conversion --- OOXML/XlsxFormat/Workbook/BookViews.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index cc2cc8a740d..77c8a1a9aeb 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -76,18 +76,16 @@ namespace OOX } XLS::BaseObjectPtr CWorkbookView::toBin() { - auto ptr(new XLS::Window1); + auto ptr(new XLSB::BookView); XLS::BaseObjectPtr objectPtr(ptr); if (m_oActiveTab.IsInit()) { ptr->itabCur = m_oActiveTab->GetValue(); - ptr->ctabSel = m_oActiveTab->GetValue(); } else { ptr->itabCur = 0; - ptr->ctabSel = 0; } if (m_oAutoFilterDateGrouping.IsInit()) From 9e24a89fd4601f8a6dd5a765dcecc2d6e6aecbfe Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Mon, 4 Mar 2024 15:56:02 +0300 Subject: [PATCH 380/794] Fix bugs --- Common/3dParty/html/css/src/CCompiledStyle.cpp | 6 ++++++ Common/3dParty/html/css/src/CCompiledStyle.h | 2 ++ Common/3dParty/html/css/src/StyleProperties.cpp | 14 +++++++++----- .../3dParty/html/css/src/xhtml/CDocumentStyle.cpp | 2 +- HtmlFile2/htmlfile2.cpp | 15 ++++++++++----- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index a5ceaae0e62..b07f5cac784 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -424,6 +424,7 @@ namespace NSCSS break; } CASE(L"vertical-align"): + CASE(L"valign"): { m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode); break; @@ -503,4 +504,9 @@ namespace NSCSS { return m_sId; } + + bool CCompiledStyle::HaveThisParent(const std::wstring &wsParentName) const + { + return m_arParentsStyles.end() != m_arParentsStyles.find(wsParentName); + } } diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 2c789d0aac9..73cca6b0f62 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -52,6 +52,8 @@ namespace NSCSS void SetID(const std::wstring& sId); std::wstring GetId() const; + bool HaveThisParent(const std::wstring& wsParentName) const; + CCompiledStyle& operator+= (const CCompiledStyle& oElement); CCompiledStyle& operator= (const CCompiledStyle& oElement); bool operator== (const CCompiledStyle& oElement) const; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index d665a462416..16cb254e618 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -327,13 +327,15 @@ namespace NSCSS if (oDigit.Empty()) return *this; + else if (Empty()) + { + *this = oDigit; + return *this; + } else if (NSCSS::Percent == oDigit.m_enUnitMeasure && !Empty()) m_oValue *= oDigit.m_oValue / 100.; else - { - m_oValue = oDigit.m_oValue; - m_enUnitMeasure = oDigit.m_enUnitMeasure; - } + m_oValue += oDigit.ToDouble(m_enUnitMeasure); m_unLevel = oDigit.m_unLevel; m_bImportant = oDigit.m_bImportant; @@ -2251,7 +2253,9 @@ namespace NSCSS CFont &CFont::operator+=(const CFont &oFont) { - m_oSize += oFont.m_oSize; + if (!oFont.m_oSize.Empty()) + m_oSize = oFont.m_oSize; + m_oLineHeight += oFont.m_oLineHeight; m_oFamily += oFont.m_oFamily; m_oStretch += oFont.m_oStretch; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 41e5f41ef90..c2e9cd797f1 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -317,7 +317,7 @@ namespace NSCSS oXmlElement.AddPropertiesInP(PProperties::P_Shd, wsColor); } - if (!oStyle.m_oBorder.Empty()) + if (!oStyle.m_oBorder.Empty() && !oStyle.HaveThisParent(L"table")) { if (oStyle.m_oBorder.EqualSides()) { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 4cbc115e8ef..07dd4b9a8c5 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1423,15 +1423,19 @@ class CHtmlFile2_Private else wsTcPr += L""; - if (NULL != oTableStyles.m_pPadding && !oStyle.m_oPadding.Empty() && oStyle.m_oPadding != *oTableStyles.m_pPadding) + if (!oStyle.m_oPadding.Empty() && (NULL == oTableStyles.m_pPadding || oStyle.m_oPadding != *oTableStyles.m_pPadding)) { - const int nTopPadding = std::max(oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + const int nTopPadding = std::max((NULL != oTableStyles.m_pPadding) ? + oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nLeftPadding = std::max(oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + const int nLeftPadding = std::max((NULL != oTableStyles.m_pPadding) ? + oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - const int nBottomPadding = std::max(oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + const int nBottomPadding = std::max((NULL != oTableStyles.m_pPadding) ? + oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, oStyle .m_oPadding.GetBottom() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nRightPadding = std::max(oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ), + const int nRightPadding = std::max((NULL != oTableStyles.m_pPadding) ? + oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); wsTcPr += L"" @@ -1953,6 +1957,7 @@ class CHtmlFile2_Private { std::wstring wsSvg(pImageData, pImageData + nDecodeLen); bRes = readSVG(wsSvg); + sExtention = L"png"; } else { From 583f7b0d0ca6a2c200422aab2b989de5668d07dd Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 4 Mar 2024 17:08:42 +0300 Subject: [PATCH 381/794] Create CFile.prototype["getShapes"] --- .../graphics/pro/js/drawingfile.json | 1 + .../pro/js/wasm/js/drawingfile_base.js | 41 +++++++++++++++++++ .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 +- .../graphics/pro/js/wasm/src/drawingfile.h | 4 +- .../pro/js/wasm/src/drawingfile_test.cpp | 29 +++++++++++++ .../graphics/pro/js/wasm/src/metafile.cpp | 1 + PdfFile/PdfFile.cpp | 2 +- PdfFile/PdfFile.h | 2 +- PdfFile/PdfReader.cpp | 39 ++++++++++++++++-- PdfFile/SrcWriter/Document.cpp | 2 +- PdfFile/lib/xpdf/Gfx.cc | 17 +++----- 11 files changed, 121 insertions(+), 21 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index efdba26d0b0..3644f0c46df 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -36,6 +36,7 @@ "_GetButtonIcons", "_GetAnnotationsInfo", "_GetAnnotationsAP", + "_GetShapes", "_InitializeFontsBin", "_InitializeFontsBase64", "_InitializeFontsRanges", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 838e3c515ed..bfa98b4eb7a 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1498,6 +1498,47 @@ Module["_free"](ext); return res; }; + CFile.prototype["getShapes"] = function(pageIndex) + { + let res = []; + let ext = Module["_GetShapes"](this.nativeFile, pageIndex); + if (ext == 0) + return res; + + let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); + if (lenArray == null) + { + Module["_free"](ext); + return res; + } + + let len = lenArray[0]; + len -= 4; + if (len <= 0) + { + Module["_free"](ext); + return res; + } + + let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); + let reader = new CBinaryReader(buffer, 0, len); + + if (!reader.isValid()) + { + Module["_free"](ext); + return res; + } + + while (reader.isValid()) + { + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + res.push(reader.readString()); + } + + Module["_free"](ext); + return res; + }; CFile.prototype["getStructure"] = function() { let res = []; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index bb3e56f82a1..a7229e6ba52 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -243,9 +243,9 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) oRes.ClearWithoutAttack(); return bRes; } -WASM_EXPORT BYTE* GetShapesXML(CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* GetShapes(CGraphicsFileDrawing* pGraphics, int nPageIndex) { - return pGraphics->GetShapesXML(nPageIndex); + return pGraphics->GetShapes(nPageIndex); } WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index ca969e8beb0..531f44ba053 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -148,10 +148,10 @@ class CGraphicsFileDrawing return ((CPdfFile*)pReader)->GetAnnots(nPageIndex); return NULL; } - BYTE* GetShapesXML(int nPageIndex) + BYTE* GetShapes(int nPageIndex) { if (nType == 0) - return ((CPdfFile*)pReader)->GetShapesXML(nPageIndex); + return ((CPdfFile*)pReader)->GetShapes(nPageIndex); return NULL; } BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 1a80dd548c8..fcf3b8d42bd 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1717,6 +1717,35 @@ int main(int argc, char* argv[]) free(pAnnotAP); } + // SHAPES + if (true) + { + BYTE* pShapes = GetShapes(pGrFile, 0); + nLength = READ_INT(pShapes); + int i = 4; + nLength -= 4; + + std::cout << std::endl; + + while (i < nLength) + { + int nShapesLength = READ_INT(pShapes + i); + i += 4; + std::cout << "Shapes" << std::endl; + + for (int j = 0; j < nShapesLength; ++j) + { + int nPathLength = READ_INT(pShapes + i); + i += 4; + std::cout << std::string((char*)(pShapes + i), nPathLength) << std::endl; + i += nPathLength; + } + } + + if (pShapes) + free(pShapes); + } + Close(pGrFile); RELEASEARRAYOBJECTS(pCMapData); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e75..cf6435762ce 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,6 +39,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : IMetaFile(pAppFonts) {} virtual ~CMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 0739d2b63a2..91568833c8c 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1586,7 +1586,7 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) return NULL; return m_pInternal->pReader->GetAnnots(nPageIndex); } -BYTE* CPdfFile::GetShapesXML(int nPageIndex) +BYTE* CPdfFile::GetShapes(int nPageIndex) { if (!m_pInternal->pReader) return NULL; diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 0fa93e7fda5..b060246605c 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -135,7 +135,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer BYTE* GetWidgetEmbeddedFonts(); BYTE* GetWidgetStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); - BYTE* GetShapesXML (int nPageIndex); + BYTE* GetShapes (int nPageIndex); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index c300625ee98..782313e86a1 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1565,16 +1565,49 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) if (!pPageRef) return NULL; - Object oPageObj; + Object oPageObj, oMetaOForm, oID; XRef* xref = m_pPDFDocument->getXRef(); - if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict()) + if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict() || !oPageObj.dictLookup("MetaOForm", &oMetaOForm)->isDict("MetaOForm") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { - oPageObj.free(); + oPageObj.free(); oMetaOForm.free(); oID.free(); return NULL; } + oPageObj.free(); + + Object oTID, oID2; + Object* pTrailerDict = xref->getTrailerDict(); + if (!pTrailerDict || !pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString() || oID2.getString()->cmp(oID.getString()) != 0) + { + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); + return NULL; + } + oTID.free(); oID.free(); oID2.free(); + + Object oMetadata; + if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) + { + oMetaOForm.free(); oMetadata.free(); + return NULL; + } + oMetaOForm.free(); NSWasm::CData oRes; oRes.SkipLen(); + int nMetadataLength = oMetadata.arrayGetLength(); + oRes.AddInt(nMetadataLength); + + for (int i = 0; i < nMetadataLength; ++i) + { + Object oMetaStr; + std::string sStr; + if (oMetadata.arrayGet(i, &oMetaStr)->isString()) + { + TextString* s = new TextString(oMetaStr.getString()); + sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oRes.WriteString(sStr); + } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index d8f6aa57beb..d62d3e1614d 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1775,7 +1775,7 @@ namespace PdfWriter } pArrayMeta->Add(new CStringObject(sXML.c_str())); - m_pCurPage->BeginShape(); + m_pCurPage->BeginMarkedContent("MetaOForm"); } void CDocument::EndMarkedContent() { diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 655eb42de15..29f241de639 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,19 +5053,14 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); - } else if (args[0].isName("MetaOForm") && numArgs == 2 && args[1].isDict()) { - if (args[1].dictLookup("Revision", &obj)->isInt()) { - // TODO и совпадает с текущим в adaptor - Object obj2; - getContentObj(&obj2); - while (!obj2.isEOF() && !obj2.isCmd("EMC")) { - obj2.free(); - getContentObj(&obj2); - } - obj2.free(); obj.free(); - return; + } else if (args[0].isName("MetaOForm")) { + getContentObj(&obj); + while (!obj.isEOF() && !obj.isCmd("EMC")) { + obj.free(); + getContentObj(&obj); } obj.free(); + return; } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); From b88d303cebc8c7ecaa5ba39b6a1d1850886a5f3f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 4 Mar 2024 19:43:28 +0300 Subject: [PATCH 382/794] fix bug #66722 --- OdfFile/Reader/Format/styles_lite_container.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Format/styles_lite_container.cpp b/OdfFile/Reader/Format/styles_lite_container.cpp index 0b74c34cd94..0381d1d0160 100644 --- a/OdfFile/Reader/Format/styles_lite_container.cpp +++ b/OdfFile/Reader/Format/styles_lite_container.cpp @@ -114,16 +114,17 @@ std::wstring doc_props_container::dump_user_defined() CP_XML_WRITER(output) { + int pid = 2; for (std::map::iterator it = impl_->map_user_defineds.begin(); it != impl_->map_user_defineds.end(); ++it) { CP_XML_NODE(L"property") { CP_XML_ATTR(L"fmtid", L"{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"); - CP_XML_ATTR(L"name", it->first); - CP_XML_ATTR(L"pid", 2); + CP_XML_ATTR(L"pid", pid++); + CP_XML_ATTR(L"name", XmlUtils::EncodeXmlString(it->first)); CP_XML_NODE(L"vt:lpwstr") { - CP_XML_STREAM() << it->second; + CP_XML_STREAM() << XmlUtils::EncodeXmlString(it->second); } } } From 46fc80f423cee0e1501fc8d650e2a14ceeaade3e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 6 Mar 2024 10:15:20 +0300 Subject: [PATCH 383/794] fix bug #45218 --- .../Format/odf_number_styles_context.cpp | 37 ++++++++++++------- .../Writer/Format/odf_number_styles_context.h | 9 ++--- OdfFile/Writer/Format/ods_table_state.cpp | 24 +++++------- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/OdfFile/Writer/Format/odf_number_styles_context.cpp b/OdfFile/Writer/Format/odf_number_styles_context.cpp index e4c383a6eed..1520be6bedc 100644 --- a/OdfFile/Writer/Format/odf_number_styles_context.cpp +++ b/OdfFile/Writer/Format/odf_number_styles_context.cpp @@ -929,31 +929,42 @@ void odf_number_styles_context::detect_format(number_format_state & state) std::wstring strFormatCode = boost::regex_replace(state.format_code[0], re_unwanted, &replace_unwanted, boost::match_any | boost::format_all); //find [$-]. - boost::wregex re(L"(?=(\\[{1}\\${1}(\\w*)\\-(\\d*)\\]{1}))"); + boost::wregex re(L"(\\[\\$.*\-[\\w\\d]+\\])"); std::vector result; std::wstring tmp = strFormatCode; bool b = boost::regex_split(std::back_inserter(result), tmp, re); - if (b && result.size() >= 3) - { - state.currency_str = result[1]; - - int code = -1; - try + if (b && result.size() > 0) + {//split Currency String + tmp = result[0].substr(1, result[0].size() - 2); + size_t sep = tmp.find(L"-"); + if (sep != std::wstring::npos) + { + state.currency_str = tmp.substr(1, sep - 1); + + try + { + std::wstringstream ss; + ss << std::hex << tmp.substr(sep + 1); + ss >> state.language_code; + } + catch (...) {} + } + if (false == state.currency_str.empty()) { - std::wstringstream ss; - ss << std::hex << result[2]; - ss >> state.language_code; - }catch(...){} + size_t pos_digit = (std::min)(strFormatCode.find(L"0"), strFormatCode.find(L"#")); + size_t pos_currency = strFormatCode.find(state.currency_str); + if (pos_digit != std::wstring::npos) state.currency_pos = pos_digit < pos_currency ? 1 : 2; + } XmlUtils::replace_all(strFormatCode, result[0], L""); } if (state.format_code.size() > 0) //any { - boost::wregex re1(L"([mM]{2,}|[hH]{2,}|[sS]{2,})"); - boost::wregex re2(L"([mM]{1,}|[dD]{1,}|[yY]{2,})"); + boost::wregex re1(L"([mM]{2,}|[hH]{1,}|[sS]{2,})"); + boost::wregex re2(L"([M]{2,}|[m]{1,}|[dD]{1,}|[yY]{2,})"); tmp = strFormatCode; diff --git a/OdfFile/Writer/Format/odf_number_styles_context.h b/OdfFile/Writer/Format/odf_number_styles_context.h index 3dca3db10f8..0fffa3d735d 100644 --- a/OdfFile/Writer/Format/odf_number_styles_context.h +++ b/OdfFile/Writer/Format/odf_number_styles_context.h @@ -49,7 +49,7 @@ typedef shared_ptr::Type office_element_ptr; struct number_format_state { - int oox_num_fmt;//дефолтные (по документации - номера 0-163, за исключением некоторых) + int oox_num_fmt;//дефолтные odf_types::office_value_type::type ods_type; @@ -59,6 +59,7 @@ struct number_format_state unsigned int language_code; std::wstring currency_str; + unsigned int currency_pos = 0; }; class odf_number_styles_context @@ -67,7 +68,7 @@ class odf_number_styles_context odf_number_styles_context(); void set_odf_context(odf_conversion_context * Context); - number_format_state & add_or_find(int oox_num_fmt, std::wstring formatCode = L""); + number_format_state & add_or_find(int oox_num_fmt, std::wstring formatCode = L""); void process_styles(office_element_ptr root ); private: @@ -81,7 +82,7 @@ class odf_number_styles_context void detect_format(number_format_state & state); //////////////// - odf_conversion_context *odf_context_; + odf_conversion_context *odf_context_; std::vector styles_elments; ////////////////// @@ -94,8 +95,6 @@ class odf_number_styles_context void create_percentage_style(number_format_state & state, office_element_ptr & root_elm); void create_numbers(number_format_state & state, office_element_ptr & elm, office_element_ptr & root_elm); - - }; } } diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index e51324774f1..df7a0d1ad42 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -100,9 +100,9 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен } return convert_date(iDate); } - std::wstring convert_time(double dTime) + std::wstring convert_time(double dTime, bool bPT) { - //12H15M42S + //12H15M42S - pt int hours = 0, minutes = 0; double sec = 0; @@ -110,23 +110,20 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен double millisec = day.total_milliseconds() * dTime; - sec = millisec / 1000.; hours = (int)(sec / 60. / 60.); - minutes = (int)((sec - (hours * 60 * 60)) / 60.); - sec = sec - (hours * 60 + minutes) * 60.; + minutes = (int)((sec - (hours * (int)60 * (int)60)) / 60.); + sec = sec - (hours * (int)60 + minutes) * 60.; int sec1 = (int)sec; std::wstring time_str = (hours < 10 ? L"0" : L"") + boost::lexical_cast(hours) - //+ std::wstring(L"H") + - + std::wstring(L":") + + + (bPT ? std::wstring(L"H") : std::wstring(L":")) + (minutes < 10 ? L"0" : L"") + boost::lexical_cast(minutes) - //+ std::wstring(L"M") + - + std::wstring(L":") + - (sec1 < 10 ? L"0" : L"") + boost::lexical_cast(sec1); - //+ std::wstring(L"S"); + + (bPT ? std::wstring(L"M") : std::wstring(L":")) + + (sec1 < 10 ? L"0" : L"") + boost::lexical_cast(sec1) + + (bPT ? std::wstring(L"S") : std::wstring(L"")); return time_str; } @@ -148,7 +145,7 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен std::wstring sDate, sTime; if (dTime > 0) { - sTime = convert_time(dTime); + sTime = convert_time(dTime, false); } if (nDate > 0) { @@ -173,8 +170,7 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен { return oox_time; } - //PT12H15M42S - return std::wstring(L"PT") + convert_time(dTime); + return std::wstring(L"PT") + convert_time(dTime, true); } }; From f6713d751b29705a097ee07fa3168920b7bd8522 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 6 Mar 2024 11:41:39 +0300 Subject: [PATCH 384/794] fix bug #66750 --- OOXML/Common/SimpleTypes_Spreadsheet.h | 24 +++++++++++------------ OdfFile/Writer/Format/ods_table_state.cpp | 20 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.h b/OOXML/Common/SimpleTypes_Spreadsheet.h index 97c7808f93d..70de28e5933 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.h +++ b/OOXML/Common/SimpleTypes_Spreadsheet.h @@ -808,18 +808,18 @@ namespace SimpleTypes //---------------------------------------------------- // 18.18.82 ST_TimePeriod (Conditional Format Value Object Type) //---------------------------------------------------- - enum ETimePeriod - { - last7Days = 0, - lastMonth = 1, - lastWeek = 2, - nextMonth = 3, - nextWeek = 4, - thisMonth = 5, - thisWeek = 6, - today = 7, - tomorrow = 8, - yesterday = 9 + enum ETimePeriod + { + last7Days = 0, + lastMonth = 1, + lastWeek = 2, + nextMonth = 3, + nextWeek = 4, + thisMonth = 5, + thisWeek = 6, + today = 7, + tomorrow = 8, + yesterday = 9 }; DEFINE_SIMPLE_TYPE(ST_TimePeriod, ETimePeriod, last7Days) diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index df7a0d1ad42..eda40867063 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -2080,18 +2080,18 @@ void ods_table_state::set_conditional_time(int period) { switch (period) { - case 1: date_is->attr_.calcext_date_ = odf_types::time_period::yesterday; break; - case 2: date_is->attr_.calcext_date_ = odf_types::time_period::tomorrow; break; - case 3: date_is->attr_.calcext_date_ = odf_types::time_period::last7Days; break; - case 4: date_is->attr_.calcext_date_ = odf_types::time_period::thisMonth; break; - case 5: date_is->attr_.calcext_date_ = odf_types::time_period::lastMonth; break; - case 6: date_is->attr_.calcext_date_ = odf_types::time_period::nextMonth; break; - case 7: date_is->attr_.calcext_date_ = odf_types::time_period::thisWeek; break; - case 8: date_is->attr_.calcext_date_ = odf_types::time_period::lastWeek; break; - case 9: date_is->attr_.calcext_date_ = odf_types::time_period::nextWeek; break; + case 1: date_is->attr_.calcext_date_ = odf_types::time_period::lastMonth; break; + case 2: date_is->attr_.calcext_date_ = odf_types::time_period::lastWeek; break; + case 3: date_is->attr_.calcext_date_ = odf_types::time_period::nextMonth; break; + case 4: date_is->attr_.calcext_date_ = odf_types::time_period::nextWeek; break; + case 5: date_is->attr_.calcext_date_ = odf_types::time_period::thisMonth; break; + case 6: date_is->attr_.calcext_date_ = odf_types::time_period::thisWeek; break; + case 7: date_is->attr_.calcext_date_ = odf_types::time_period::today; break; + case 8: date_is->attr_.calcext_date_ = odf_types::time_period::tomorrow; break; + case 9: date_is->attr_.calcext_date_ = odf_types::time_period::yesterday; break; case 0: default: - date_is->attr_.calcext_date_ = odf_types::time_period::today; + date_is->attr_.calcext_date_ = odf_types::time_period::last7Days; } } } From 296383bd6f4658bd033c8d466cc0bb3b49a1afeb Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 6 Mar 2024 12:05:45 +0300 Subject: [PATCH 385/794] fix bug #66744 --- MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp b/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp index 29bf29e884b..036ac05124f 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/BulletsConverter.cpp @@ -111,7 +111,7 @@ void BulletsConverter::ConvertPFRun(PPTX::Logic::TextParagraphPr &oPPr, CTextPFR pLnSpc->m_name = L"a:lnSpc"; if (val > 0) - pLnSpc->spcPct = val * 12.5; + pLnSpc->spcPts = val * 12.5; else if (val < 0 && val > -13200) pLnSpc->spcPct = val * -1000; From 422f0736c44df096eb83b7e7ddd4d29af976996b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Mar 2024 17:45:57 +0600 Subject: [PATCH 386/794] Fix colot conversion --- OOXML/XlsxFormat/Styles/Fills.cpp | 26 +++++++++++--------------- OOXML/XlsxFormat/Styles/Fonts.cpp | 3 +++ OOXML/XlsxFormat/Styles/rPr.cpp | 6 +++++- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Fills.cpp b/OOXML/XlsxFormat/Styles/Fills.cpp index 242ef9b09cd..7b123660f51 100644 --- a/OOXML/XlsxFormat/Styles/Fills.cpp +++ b/OOXML/XlsxFormat/Styles/Fills.cpp @@ -163,26 +163,15 @@ namespace OOX if(m_oBgColor.IsInit()) ptr->brtColorBack = m_oBgColor->toColor(); else - { - ptr->brtColorBack.bAlpha = 255; - ptr->brtColorBack.bBlue = 0; - ptr->brtColorBack.bGreen = 0; - ptr->brtColorBack.bRed = 0; - ptr->brtColorBack.index = 64; - ptr->brtColorBack.nTintAndShade = 0; - ptr->brtColorBack.xColorType = 0; + { m_oBgColor.Init(); + ptr->brtColorBack = m_oBgColor->GetDefaultColor(); } if(m_oFgColor.IsInit()) ptr->brtColorFore = m_oFgColor->toColor(); else { - ptr->brtColorFore.bAlpha = 255; - ptr->brtColorFore.bBlue = 255; - ptr->brtColorFore.bGreen = 255; - ptr->brtColorFore.bRed = 255; - ptr->brtColorFore.index = 64; - ptr->brtColorFore.nTintAndShade = 0; - ptr->brtColorFore.xColorType = 0; + m_oFgColor.Init(); + ptr->brtColorFore = m_oFgColor->GetDefaultColor(); } } EElementType CPatternFill::getType () const @@ -530,6 +519,13 @@ namespace OOX { m_oPatternFill->toBin(objectPtr); } + else + { + CColor color; + ptr->fls = 0; + ptr->brtColorBack = color.GetDefaultColor(); + ptr->brtColorFore = color.GetDefaultColor(); + } if(m_oGradientFill.IsInit()) { diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index fd18d078e3b..0eb205ecf31 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -241,6 +241,8 @@ namespace OOX ptr->uls = 34; } } + else + ptr->uls = 0; if(m_oFamily.IsInit()) ptr->bFamily = m_oFamily->m_oFontFamily->GetValue(); @@ -252,6 +254,7 @@ namespace OOX ptr->brtColor = m_oColor->toColor(); else { + m_oColor.Init(); ptr->brtColor = m_oColor->GetDefaultColor(); } diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 8fe1bf5a5ec..63be11df16b 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -460,7 +460,7 @@ namespace OOX ptr.xColorType = 0; ptr.nTintAndShade = 0; ptr.index = 0; - ptr.fValidRGB = true; + ptr.fValidRGB = 0; return ptr; } @@ -472,6 +472,7 @@ namespace OOX ptr.bBlue = 0; ptr.bGreen = 0; ptr.bRed = 0; + ptr.fValidRGB = false; if(m_oAuto.IsInit()) { @@ -495,7 +496,10 @@ namespace OOX ptr.bGreen = m_oRgb->Get_G(); ptr.bRed = m_oRgb->Get_R(); ptr.xColorType = 2; + ptr.fValidRGB = true; } + else + ptr.xColorType = 0; if ( m_oTint.IsInit()) From e787102046f8406c44b774288f50d78f1bf789c9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 6 Mar 2024 18:47:52 +0600 Subject: [PATCH 387/794] Fix bug #27583 --- OOXML/Binary/Sheets/Reader/CSVReader.cpp | 3 ++ .../CellFormatController.cpp | 35 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/CSVReader.cpp b/OOXML/Binary/Sheets/Reader/CSVReader.cpp index e9f32647fce..29aba988e6d 100644 --- a/OOXML/Binary/Sheets/Reader/CSVReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CSVReader.cpp @@ -219,6 +219,8 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C smart_ptr pWorksheet(new OOX::Spreadsheet::CWorksheet(NULL)); pWorksheet->m_oSheetData.Init(); + pWorksheet->m_oSheetFormatPr.Init(); + pWorksheet->m_oSheetFormatPr->m_oBaseColWidth = 9; //----------------------------------------------------------------------------------- DWORD nFileSize = 0; @@ -311,6 +313,7 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C INT nIndexRow = 0; INT nIndexCol = 0; OOX::Spreadsheet::CRow *pRow = new OOX::Spreadsheet::CRow(); + pRow->m_oR.Init(); pRow->m_oR->SetValue(nIndexRow + 1); diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp index 265c6ae7f89..353c032162b 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp @@ -42,10 +42,21 @@ #include #include + const std::wstring DefaultDateFormat = L"dd.mm.yyyy"; const std::wstring DefaultPercentFormat = L"0.0%"; const std::wstring DefaultDollarFormat = L"#,##0.00$"; +std::map defaultDataFormats +{ + {DefaultDateFormat, 14}, + {L"d-mmm-yy", 15}, + {L"d-mmm", 16}, + {L"mmm-yy", 17}, + {L"m/d/yy h:mm", 22}, + {L"h:mm", 20} +}; + CellFormatController::CellFormatController(OOX::Spreadsheet::CStyles *styles): m_pStyles{styles} { @@ -170,23 +181,29 @@ void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const void CellFormatController::createFormatStyle(const std::wstring &format) { - if (!m_pStyles->m_oNumFmts.IsInit()) + auto prepareFormat = defaultDataFormats.find(format); + if(prepareFormat == defaultDataFormats.end()) { - m_pStyles->m_oNumFmts.Init(); + if (!m_pStyles->m_oNumFmts.IsInit()) + { + m_pStyles->m_oNumFmts.Init(); + } + m_pStyles->m_oNumFmts->m_arrItems.push_back(new OOX::Spreadsheet::CNumFmt()); + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oFormatCode = format; + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId.Init(); + m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->SetValue(164 + m_pStyles->m_oNumFmts->m_arrItems.size()); } - m_pStyles->m_oNumFmts->m_arrItems.push_back(new OOX::Spreadsheet::CNumFmt()); - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oFormatCode = format; - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId.Init(); - m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->SetValue(164 + m_pStyles->m_oNumFmts->m_arrItems.size()); - // Normal + data format OOX::Spreadsheet::CXfs* pXfs = new OOX::Spreadsheet::CXfs(); pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0); pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0); pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0); - pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->GetValue()); - + pXfs->m_oNumFmtId.Init(); + if(prepareFormat == defaultDataFormats.end()) + pXfs->m_oNumFmtId->SetValue(m_pStyles->m_oNumFmts->m_arrItems.back()->m_oNumFmtId->GetValue()); + else + pXfs->m_oNumFmtId->SetValue(prepareFormat->second); m_pStyles->m_oCellXfs->m_arrItems.push_back(pXfs); auto styleNum = (unsigned int)(m_pStyles->m_oCellXfs->m_arrItems.size() - 1); From 36dbd4f0e1d8bc338cda807fd1b46b2e64f477fd Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Wed, 6 Mar 2024 15:55:12 +0300 Subject: [PATCH 388/794] Refactoring --- Common/3dParty/html/htmltoxhtml.h | 17 +---- HtmlFile2/htmlfile2.cpp | 103 +++++++++++++++++++----------- HtmlFile2/src/StringFinder.h | 10 +-- 3 files changed, 70 insertions(+), 60 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 04cb2713f4f..41f3ab630da 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -35,23 +35,8 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } -static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) +static std::wstring htmlToXhtml(std::string& sFileContent) { - // Распознование кодировки - if (bNeedConvert) - { - std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"\"", "="}, {"\"", " "}, 0); - - if (sEncoding.empty()) - sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", "\"", "\""); - - if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding)) - { - NSUnicodeConverter::CUnicodeConverter oConverter; - sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); - } - } - // Избавление от size_t posA = sFileContent.find(""); - size_t nStyleFounded{nFirstStyleFounded}; - std::string sStyles; - - while (std::string::npos != nStyleFounded) - { - size_t nStyleEndFounded = sFileContent.find("", nStyleFounded); - - if (std::string::npos == nStyleEndFounded) - break; - - sStyles += sFileContent.substr(nStyleFounded + 7, nStyleEndFounded - nStyleFounded - 7) + " "; - sFileContent.erase(nStyleFounded, nStyleEndFounded - nStyleFounded + 8); - - nStyleFounded = sFileContent.find(""); - else - sRes.insert(nFirstStyleFounded, L""); - } + std::wstring sRes = htmlToXhtml(sFileContent); // NSFile::CFileBinary oWriter; // if (oWriter.CreateFileW(m_sTmp + L"/res.html")) @@ -736,17 +710,48 @@ class CHtmlFile2_Private } private: - bool NodeBelongToTable(const std::wstring& wsNodeName) + bool NodeBelongToTable(const std::wstring& wsNodeName) const { return L"table" == wsNodeName || L"tbody" == wsNodeName || L"th" == wsNodeName || L"td" == wsNodeName || L"tr" == wsNodeName || L"thead" == wsNodeName || L"tfoot" == wsNodeName; } + std::wstring GetArgumentValue(const std::wstring& wsArgumentName, const std::wstring& wsDefaultValue = L"") + { + if (!m_oLightReader.MoveToFirstAttribute()) + return wsDefaultValue; + + std::wstring wsValue{wsDefaultValue}; + + do + { + if (wsArgumentName == m_oLightReader.GetName()) + { + wsValue = m_oLightReader.GetText(); + break; + } + } while (m_oLightReader.MoveToNextAttribute()); + + m_oLightReader.MoveToElement(); + return wsValue; + } + + std::wstring ToUnicode(const std::string& sText) const + { + if (!m_sEncoding.empty() && !NSStringFinder::Equals("utf-8", m_sEncoding)) + { + NSUnicodeConverter::CUnicodeConverter oConverter; + return oConverter.toUnicode(sText, *m_sEncoding.c_str()); + } + + return UTF8_TO_U(sText); + } + // Так как CSS калькулятор не знает для какой ноды производится расчет стиля // и не знает, что некоторые стили предназначены только определенной ноде, // то проще пока обрабатывать это заранее // ! Используется для стилей, заданных через аргументы ! - bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring& wsStyleName) + bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring& wsStyleName) const { if (L"border" == wsStyleName && L"table" != wsNodeName) return false; @@ -754,6 +759,19 @@ class CHtmlFile2_Private return true; } + void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false) const + { + if (NULL == pXml) + return; + + pXml->WriteString(L""); + + if (bVahish) + pXml->WriteString(L""); + + pXml->WriteString(L""); + } + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) { m_bWasSpace = false; @@ -822,13 +840,20 @@ class CHtmlFile2_Private int nDeath = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nDeath)) { + const std::wstring wsName = m_oLightReader.GetName(); // Базовый адрес - if (m_oLightReader.GetName() == L"base") + if (L"base" == wsName) + m_sBase = GetArgumentValue(L"href"); + else if (L"meta" == wsName) { - while (m_oLightReader.MoveToNextAttribute()) - if (m_oLightReader.GetName() == L"href") - m_sBase = m_oLightReader.GetText(); - m_oLightReader.MoveToElement(); + m_sEncoding = GetArgumentValue(L"charset"); + if (m_sEncoding.empty()) + { + const std::wstring sContent = GetArgumentValue(L"content"); + + if (!sContent.empty()) + m_sEncoding = NSStringFinder::FindPropety(sContent, L"charset", {L"="}, {L";", L" ", L"\\n", L"\\t", L"\\f"}); + } } } } @@ -858,7 +883,7 @@ class CHtmlFile2_Private { if(sName == L"#text") { - std::wstring sText = m_oLightReader.GetText(); + std::wstring sText = ToUnicode(m_oLightReader.GetTextA()); size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) @@ -1536,8 +1561,8 @@ class CHtmlFile2_Private if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) oTableStyles.m_bHaveBorderAttribute = true; -// if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") -// oXml->WriteString(L""); + if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") + WriteEmptyParagraph(oXml, true); m_bWasSpace = false; diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index 6ac8ef4d3e9..f90027b8773 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -50,13 +50,13 @@ namespace NSStringFinder if (sString.length() < unStarting) return StringType(); - std::string sRegexValue = "(?i)" + sProperty; + std::string sRegexValue = "(?i)" + std::string(sProperty.begin(), sProperty.end()); if (!arDelimiters.empty()) { sRegexValue += "\\s*["; for (const StringType& sDelimiter : arDelimiters) - sRegexValue += sDelimiter + "|"; + sRegexValue += std::string(sDelimiter.begin(), sDelimiter.end()) + "|"; sRegexValue.pop_back(); sRegexValue += "]{1}"; } @@ -66,14 +66,14 @@ namespace NSStringFinder std::string sEndingValue; for (const StringType& sEnding : arEndings) - sEndingValue += sEnding + "|"; + sEndingValue += std::string(sEnding.begin(), sEnding.end()) + "|"; sEndingValue.pop_back(); - sRegexValue += "\\s*(.[^" + sEndingValue + "]*)\\s*[" + sEndingValue + "]{1}"; + sRegexValue += "\\s*(.[^" + sEndingValue + "]*)\\s*[" + sEndingValue + "]?"; } else - sRegexValue += "\\s*(.*)[\\n|\\r]{1}"; + sRegexValue += "\\s*(.*)[\\n|\\r]?"; boost::regex oRegex(sRegexValue); boost::match_results oResult; From d92ab67b21928085337e6bfcd372aae2eb554fe2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 6 Mar 2024 16:20:28 +0300 Subject: [PATCH 389/794] Fix validation --- PdfFile/PdfFile.cpp | 10 ++++++++-- PdfFile/PdfReader.cpp | 15 ++++++++------- PdfFile/PdfWriter.cpp | 8 -------- PdfFile/PdfWriter.h | 2 -- PdfFile/PdfWriter_empty.cpp | 2 -- PdfFile/SrcWriter/Document.cpp | 27 +++++++++++++++------------ PdfFile/SrcWriter/Document.h | 2 -- PdfFile/lib/xpdf/Gfx.cc | 18 ++++++++++++------ 8 files changed, 43 insertions(+), 41 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 91568833c8c..c263f5c1889 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -2378,12 +2378,18 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::ShapeStart: { CShapeStart* pCommand = (CShapeStart*)command; - m_pInternal->pWriter->AddShapeXML(pCommand->GetShapeXML()); +#ifndef BUILDING_WASM_MODULE + if (m_pInternal->bEdit && m_pInternal->bEditPage) + m_pInternal->pWriter->m_pDocument->AddShapeXML(pCommand->GetShapeXML()); +#endif return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { - m_pInternal->pWriter->EndMarkedContent(); +#ifndef BUILDING_WASM_MODULE + if (m_pInternal->bEdit && m_pInternal->bEditPage) + m_pInternal->pWriter->m_pPage->EndMarkedContent(); +#endif return S_OK; } default: diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 782313e86a1..ada8c303aac 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1561,18 +1561,18 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; - Ref* pPageRef = m_pPDFDocument->getCatalog()->getPageRef(nPageIndex + 1); - if (!pPageRef) + Dict* pResources = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1)->getResourceDict(); + if (!pResources) return NULL; - Object oPageObj, oMetaOForm, oID; + Object oProperties, oMetaOForm, oID; XRef* xref = m_pPDFDocument->getXRef(); - if (!xref->fetch(pPageRef->num, pPageRef->gen, &oPageObj)->isDict() || !oPageObj.dictLookup("MetaOForm", &oMetaOForm)->isDict("MetaOForm") || !oMetaOForm.dictLookup("ID", &oID)->isString()) + if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("MetaOForm", &oMetaOForm)->isDict("MetaOForm") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { - oPageObj.free(); oMetaOForm.free(); oID.free(); + oProperties.free(); oMetaOForm.free(); oID.free(); return NULL; } - oPageObj.free(); + oProperties.free(); Object oTID, oID2; Object* pTrailerDict = xref->getTrailerDict(); @@ -1581,7 +1581,7 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); return NULL; } - oTID.free(); oID.free(); oID2.free(); + oID.free(); oTID.free(); oID2.free(); Object oMetadata; if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) @@ -1608,6 +1608,7 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) } oRes.WriteString(sStr); } + oMetadata.free(); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 114de87d179..5ff8a24dc33 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2345,14 +2345,6 @@ HRESULT CPdfWriter::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, { return m_pDocument->AddMetaData(sMetaName, pMetaData, nMetaLength) ? S_OK : S_FALSE; } -void CPdfWriter::AddShapeXML(const std::string& sXML) -{ - m_pDocument->AddShapeXML(sXML); -} -void CPdfWriter::EndMarkedContent() -{ - m_pDocument->EndMarkedContent(); -} //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 45a3fff439e..ab64292c354 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -198,8 +198,6 @@ class CPdfWriter HRESULT AddFormField (NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory); HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); - void AddShapeXML(const std::string& sXML); - void EndMarkedContent(); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter_empty.cpp b/PdfFile/PdfWriter_empty.cpp index 1a8c4a69b42..0552f1f71dc 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/PdfFile/PdfWriter_empty.cpp @@ -159,8 +159,6 @@ void CPdfWriter::Reset() {} bool CPdfWriter::IsValid() { return false; } bool CPdfWriter::IsPageValid() { return false; } void CPdfWriter::SetError() {} -void CPdfWriter::EndMarkedContent() {} -void CPdfWriter::AddShapeXML(const std::string& sXML) {} void CPdfWriter::AddLink(PdfWriter::CPage* pPage, const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const unsigned int& unDestPage) {} unsigned char* CPdfWriter::EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs) { return NULL; } unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) { return NULL; } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index d62d3e1614d..09a6b5a3c9a 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1733,10 +1733,22 @@ namespace PdfWriter } void CDocument::AddShapeXML(const std::string& sXML) { - CObjectBase* pObj = m_pCurPage->Get("MetaOForm"); + CDictObject* pResources = (CDictObject*)m_pCurPage->Get("Resources"); + if (!pResources) + { + pResources = new CDictObject(); + m_pCurPage->Add("Resources", pResources); + } + CDictObject* pProperties = (CDictObject*)pResources->Get("Properties"); + if (!pProperties) + { + pProperties = new CDictObject(); + pResources->Add("Properties", pProperties); + } + CObjectBase* pObj = pProperties->Get("MetaOForm"); if (pObj && pObj->GetType() != object_type_DICT) { - m_pCurPage->Remove("MetaOForm"); + pProperties->Remove("MetaOForm"); pObj = NULL; } CDictObject* pMetaOForm = (CDictObject*)pObj; @@ -1745,7 +1757,7 @@ namespace PdfWriter pMetaOForm = new CDictObject(); m_pXref->Add(pMetaOForm); pMetaOForm->Add("Type", "MetaOForm"); - m_pCurPage->Add("MetaOForm", pMetaOForm); + pProperties->Add("MetaOForm", pMetaOForm); m_vMetaOForms.push_back(pMetaOForm); CBinaryObject* sID = NULL; @@ -1777,13 +1789,4 @@ namespace PdfWriter m_pCurPage->BeginMarkedContent("MetaOForm"); } - void CDocument::EndMarkedContent() - { - m_pCurPage->EndMarkedContent(); - } - bool CDocument::HaveMetaOForm() - { - CObjectBase* pObj = m_pCurPage->Get("MetaOForm"); - return pObj && pObj->GetType() == object_type_DICT; - } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index f5149a7b4da..35eecf5a8fd 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -199,8 +199,6 @@ namespace PdfWriter bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); - void EndMarkedContent(); - bool HaveMetaOForm(); private: char* GetTTFontTag(); diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 29f241de639..26c6c0aa1c4 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,14 +5053,20 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); - } else if (args[0].isName("MetaOForm")) { - getContentObj(&obj); - while (!obj.isEOF() && !obj.isCmd("EMC")) { - obj.free(); + } else if (args[0].isName("MetaOForm") && res->lookupPropertiesNF("MetaOForm", &obj)) { + Object oMetaOForm, oID, oTID, oID2; + if (obj.fetch(xref, &oMetaOForm)->isDict("MetaOForm") && oMetaOForm.dictLookup("ID", &oID)->isString() && xref->getTrailerDict()->dictLookup("ID", &oTID)->isArray() && + oTID.arrayGet(1, &oID2)->isString() && oID2.getString()->cmp(oID.getString()) == 0) { + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); obj.free(); getContentObj(&obj); + while (!obj.isEOF() && !obj.isCmd("EMC")) { + obj.free(); + getContentObj(&obj); + } + obj.free(); + return; } - obj.free(); - return; + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); obj.free(); } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); From 82cd32aa858bdb91838faefae1c97bc0b0f8926a Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 6 Mar 2024 19:38:20 +0300 Subject: [PATCH 390/794] fix bug #66772 --- .../Converter/xlsx_conditionalFormatting.cpp | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 8a1dada7bad..ecb0c857c8f 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -339,11 +339,13 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) } else if (0 <= (pos = f.find(L"is-between("))) { + val = f.substr(11, f.size() - 12); impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val); } else if (0 <= (pos = f.find(L"is-time("))) { + val = f.substr(8, f.size() - 9); impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val); } @@ -464,6 +466,28 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) { val = converter.convert_named_expr( f ); } + else if (0 <= (pos = f.find(L"between"))) + { + if (0 <= (pos = f.find(L"not-between"))) + { + impl_->conditionalFormattings_.back().rules.back().operator_ = L"notBetween"; + val = f.substr(12, f.length() - 13); + } + else + { + impl_->conditionalFormattings_.back().rules.back().operator_ = L"between"; + val = f.substr(8, f.length() - 9); + } + + XmlUtils::replace_all(val, L"(", L""); + XmlUtils::replace_all(val, L")", L""); + if (0 <= (pos = val.find(L","))) + { + impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr(val.substr(pos + 1)); + val = val.substr(0, pos); + } + val = converter.convert_named_expr(val); + } else if (0 <= (pos = f.find(L"!="))) { impl_->conditionalFormattings_.back().rules.back().operator_ = L"notEqual"; @@ -494,20 +518,6 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().operator_ = L"greaterThan"; val = converter.convert_named_expr( f.substr(1) ); } - else if (0 <= (pos = f.find(L"between"))) - { - impl_->conditionalFormattings_.back().rules.back().operator_ = L"between"; - val = f.substr(8, f.length() - 9); - - XmlUtils::replace_all(val, L"(", L""); - XmlUtils::replace_all(val, L")", L""); - if (0 <= (pos = val.find(L","))) - { - impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr( val.substr(pos + 1) ); - val = val.substr(0, pos); - } - val = converter.convert_named_expr( val ); - } else { val = converter.convert( f ); From 04480bb9eb06e3f7dd534821af89e5f2083cb94e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 6 Mar 2024 20:06:43 +0300 Subject: [PATCH 391/794] fix bug #66766 --- X2tConverter/src/ASCConverters.cpp | 39 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index bd83aeae93e..3e1e861c082 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -462,18 +462,26 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); if (true == NSDirectory::CreateDirectory(sDocxDir)) { - params.m_bMacro = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo; + params.m_bMacro = AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM == nFormatTo || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM == nFormatTo; convertParams.m_sTempResultOOXMLDirectory = sDocxDir; nRes = doct_bin2docx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromDocxDir(sDocxDir, sTo, nFormatTo, params, convertParams); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromDocxDir(sDocxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else @@ -832,7 +840,9 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { std::wstring sXlsxDir = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); if (true == NSDirectory::CreateDirectory(sXlsxDir)) @@ -842,8 +852,13 @@ namespace NExtractTools nRes = xlst_bin2xlsx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - std::wstring sXlsxFile; - nRes = fromXlsxDir(sXlsxDir, sTo, nFormatTo, params, convertParams); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromXlsxDir(sXlsxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else @@ -1158,7 +1173,9 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); } - else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatTo)) + else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo || + AVS_OFFICESTUDIO_FILE_OTHER_ODF == nFormatTo) { std::wstring sPptxDir = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); @@ -1172,7 +1189,13 @@ namespace NExtractTools nRes = pptt_bin2pptx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromPptxDir(sPptxDir, sTo, nFormatTo, params, convertParams); + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromPptxDir(sPptxDir, *params.m_sFileTo, nFormatTo, params, convertParams); } } else From 57e06222c723b94962865f1a98c3d21d31df74c8 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 7 Mar 2024 15:52:13 +0300 Subject: [PATCH 392/794] fix bug #66773 --- .../Converter/xlsx_conditionalFormatting.cpp | 30 +++++++++++++++++-- .../Converter/xlsx_conditionalFormatting.h | 1 + OdfFile/Reader/Format/calcext_elements.cpp | 4 +++ OdfFile/Reader/Format/calcext_elements.h | 2 +- OdfFile/Writer/Converter/XlsxConverter.cpp | 12 +++++--- OdfFile/Writer/Format/calcext_elements.cpp | 1 + OdfFile/Writer/Format/calcext_elements.h | 2 +- OdfFile/Writer/Format/ods_table_state.cpp | 15 ++++++++-- OdfFile/Writer/Format/ods_table_state.h | 2 +- 9 files changed, 57 insertions(+), 12 deletions(-) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index ecb0c857c8f..83d560e849b 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -90,6 +90,9 @@ namespace oox { _CP_OPT(std::wstring) formula2; _CP_OPT(int) rank; _CP_OPT(bool) bottom; + _CP_OPT(bool) equal; + _CP_OPT(bool) above; + _CP_OPT(int) stdDev; //color scale icon set data_bar std::vector<_cfvo> cfvo; //color scale data_bar(1 element) @@ -152,8 +155,10 @@ class xlsx_conditionalFormatting_context::Impl if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); - //CP_XML_ATTR(L"equalAverage" , 0); - //CP_XML_ATTR(L"aboveAverage" , 0); + if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage",*c.rules[j].above); + if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage",*c.rules[j].equal); + if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); + if (c.rules[j].type == 1) { if (c.rules[j].formula_type) @@ -324,6 +329,22 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; } + else if (f == L"below-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().above = false; + } + else if (f == L"above-equal-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().equal = true; + } + else if (f == L"below-equal-average") + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"aboveAverage"; + impl_->conditionalFormattings_.back().rules.back().above = false; + impl_->conditionalFormattings_.back().rules.back().equal = true; + } else if ( 0 <= (pos = f.find(L"formula-is("))) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression"; @@ -584,5 +605,10 @@ void xlsx_conditionalFormatting_context::set_time_period(int val) { impl_->conditionalFormattings_.back().rules.back().time_period = val; } +void xlsx_conditionalFormatting_context::set_stdDev(int val) +{ + impl_->conditionalFormattings_.back().rules.back().stdDev = val; +} + } } diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h index 91762255418..cfbbde04a1c 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h @@ -55,6 +55,7 @@ class xlsx_conditionalFormatting_context void set_dxf (int dxf_id); void set_showVal(bool val); void set_time_period(int val); + void set_stdDev(int val); void add_sfv (int type, std::wstring value); void add_color (std::wstring col); diff --git a/OdfFile/Reader/Format/calcext_elements.cpp b/OdfFile/Reader/Format/calcext_elements.cpp index d8b152833f0..0cf91a8721c 100644 --- a/OdfFile/Reader/Format/calcext_elements.cpp +++ b/OdfFile/Reader/Format/calcext_elements.cpp @@ -72,6 +72,7 @@ void calcext_condition_attr::add_attributes( const xml::attributes_wc_ptr & Attr CP_APPLY_ATTR(L"calcext:base-cell-address", base_cell_address_); CP_APPLY_ATTR(L"calcext:apply-style-name", apply_style_name_); CP_APPLY_ATTR(L"calcext:value", value_); + CP_APPLY_ATTR(L"loext:stdDev", loext_stdDev_); } void calcext_date_is_attr::add_attributes( const xml::attributes_wc_ptr & Attributes ) { @@ -309,6 +310,9 @@ void calcext_condition::xlsx_convert(oox::xlsx_conversion_context & Context) if (dxfId >= 0) Context.get_conditionalFormatting_context().set_dxf(dxfId); + + if (attr_.loext_stdDev_) + Context.get_conditionalFormatting_context().set_stdDev(*attr_.loext_stdDev_); } // calcext_condition //--------------------------------------------------------------------------------------------------------- diff --git a/OdfFile/Reader/Format/calcext_elements.h b/OdfFile/Reader/Format/calcext_elements.h index 987d9150f7e..146f8dd442c 100644 --- a/OdfFile/Reader/Format/calcext_elements.h +++ b/OdfFile/Reader/Format/calcext_elements.h @@ -69,6 +69,7 @@ class calcext_condition_attr _CP_OPT(std::wstring) base_cell_address_; _CP_OPT(std::wstring) apply_style_name_; _CP_OPT(std::wstring) value_; + _CP_OPT(int) loext_stdDev_; }; class calcext_icon_set_attr @@ -77,7 +78,6 @@ class calcext_icon_set_attr void add_attributes( const xml::attributes_wc_ptr & Attributes ); _CP_OPT(odf_types::iconset_type) icon_set_type_; - }; class calcext_date_is_attr diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 31edbefe002..330958e14e7 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -3431,13 +3431,17 @@ void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_co if (false == oox_cond_rule->m_oType.IsInit()) return; _CP_OPT(unsigned int) rank; - _CP_OPT(bool) bottom, percent; - + _CP_OPT(bool) bottom, percent, above, equal; + _CP_OPT(int) stdDev; + if (oox_cond_rule->m_oRank.IsInit()) rank = oox_cond_rule->m_oRank->GetValue(); if (oox_cond_rule->m_oBottom.IsInit()) bottom = oox_cond_rule->m_oBottom->ToBool(); if (oox_cond_rule->m_oPercent.IsInit()) percent = oox_cond_rule->m_oPercent->ToBool(); + if (oox_cond_rule->m_oAboveAverage.IsInit()) above = oox_cond_rule->m_oAboveAverage->ToBool(); + if (oox_cond_rule->m_oEqualAverage.IsInit()) equal = oox_cond_rule->m_oEqualAverage->ToBool(); + if (oox_cond_rule->m_oStdDev.IsInit()) stdDev = oox_cond_rule->m_oStdDev->GetValue(); - ods_context->current_table()->start_conditional_rule(oox_cond_rule->m_oType->GetValue(), rank, bottom, percent); + ods_context->current_table()->start_conditional_rule(oox_cond_rule->m_oType->GetValue(), rank, bottom, percent, above, equal, stdDev); { if (oox_cond_rule->m_oDxfId.IsInit()) { @@ -3460,7 +3464,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_co if (oox_cond_rule->m_oTimePeriod.IsInit()) ods_context->current_table()->set_conditional_time(oox_cond_rule->m_oTimePeriod->GetValue()); - + convert(oox_cond_rule->m_oIconSet.GetPointer()); convert(oox_cond_rule->m_oColorScale.GetPointer()); convert(oox_cond_rule->m_oDataBar.GetPointer()); diff --git a/OdfFile/Writer/Format/calcext_elements.cpp b/OdfFile/Writer/Format/calcext_elements.cpp index 406b4015436..57ffb5166ed 100644 --- a/OdfFile/Writer/Format/calcext_elements.cpp +++ b/OdfFile/Writer/Format/calcext_elements.cpp @@ -60,6 +60,7 @@ void calcext_condition_attr::serialize(CP_ATTR_NODE) CP_XML_ATTR_OPT_ENCODE_STRING(L"calcext:base-cell-address", calcext_base_cell_address_); CP_XML_ATTR_OPT(L"calcext:apply-style-name", calcext_apply_style_name_); CP_XML_ATTR_OPT_ENCODE_STRING(L"calcext:value", calcext_value_); + CP_XML_ATTR_OPT(L"loext:stdDev", loext_stdDev_); } void calcext_date_is_attr::serialize(CP_ATTR_NODE) { diff --git a/OdfFile/Writer/Format/calcext_elements.h b/OdfFile/Writer/Format/calcext_elements.h index 593e0a60185..45f30c80cbd 100644 --- a/OdfFile/Writer/Format/calcext_elements.h +++ b/OdfFile/Writer/Format/calcext_elements.h @@ -70,7 +70,7 @@ class calcext_condition_attr _CP_OPT(std::wstring) calcext_base_cell_address_; _CP_OPT(std::wstring) calcext_apply_style_name_; _CP_OPT(std::wstring) calcext_value_; - + _CP_OPT(int) loext_stdDev_; }; class calcext_icon_set_attr { diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index eda40867063..d0f7bafe5d6 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -1948,7 +1948,7 @@ void ods_table_state::end_conditional_format() { current_level_.pop_back(); } -void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent) +void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent, _CP_OPT(bool) above, _CP_OPT(bool) equal, _CP_OPT(int) stdDev) { office_element_ptr elm; @@ -1991,11 +1991,20 @@ void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int table = L"'" + table + L"'"; } } - condition->attr_.calcext_base_cell_address_ = table + col + row; + condition->attr_.calcext_base_cell_address_ = (table.empty() ? L"" : (table + L".")) + col + row; } switch(rule_type) { - case 0: condition->attr_.calcext_value_ = L"above-average"; break; + case 0: + { + if (equal) condition->attr_.calcext_value_ = above.get_value_or(true) ? L"above-equal-average" : L"below-equal-average"; + else condition->attr_.calcext_value_ = above.get_value_or(true) ? L"above-average" : L"below-average"; + + if (stdDev) + { + condition->attr_.loext_stdDev_ = *stdDev; + } + }break; case 1: condition->attr_.calcext_value_ = L"begins-with()"; break; case 4: condition->attr_.calcext_value_ = L"contains-text()"; break; case 5: condition->attr_.calcext_value_ = L"is-error"; break; diff --git a/OdfFile/Writer/Format/ods_table_state.h b/OdfFile/Writer/Format/ods_table_state.h index fccbe0efa1e..85a5f6a86b0 100644 --- a/OdfFile/Writer/Format/ods_table_state.h +++ b/OdfFile/Writer/Format/ods_table_state.h @@ -384,7 +384,7 @@ class ods_table_state void start_conditional_formats(); void start_conditional_format(const std::wstring& ref); - void start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent); + void start_conditional_rule(int rule_type, _CP_OPT(unsigned int) rank, _CP_OPT(bool) bottom, _CP_OPT(bool) percent, _CP_OPT(bool) above, _CP_OPT(bool) equal, _CP_OPT(int) stdDev); void set_conditional_formula(const std::wstring& formula); void set_conditional_value(int type, const std::wstring& value ); From e30c5fb79db66f0e33fa898bef7c5a6ee353a3ca Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 7 Mar 2024 15:59:01 +0300 Subject: [PATCH 393/794] fix bug #66777 --- OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 83d560e849b..189a9ec139f 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -405,7 +405,9 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) } else if (0 <= (pos = f.find(L"contains-text"))) { - impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsText"; + if (std::wstring::npos != f.find(L"not-contains-text")) + impl_->conditionalFormattings_.back().rules.back().formula_type = L"notContainsText"; + else impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsText"; std::wstring text = f.substr(pos + 14, f.length() - pos - 15); From f9cd49a756a73559d40aebe50ea5c3f917817a16 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 7 Mar 2024 16:05:31 +0300 Subject: [PATCH 394/794] Fix bugs --- Common/3dParty/html/css/src/ConstValues.h | 3 +- .../html/css/src/xhtml/CXmlElement.cpp | 41 ++++++++--------- HtmlFile2/htmlfile2.cpp | 44 ++++++++++++------- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index f92f8dd438a..ac03ac18fbe 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -86,7 +86,8 @@ namespace NSCSS R_Color = 4, R_U = 5, R_Highlight = 6, - R_SmallCaps = 7 + R_SmallCaps = 7, + R_Kern = 8 } RunnerProperties; typedef enum diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index fc49313ebd0..68689d3be29 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -55,7 +55,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"0"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"480\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h2") { @@ -66,7 +66,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"1"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"400\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h3") { @@ -77,7 +77,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"2"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"360\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h4") { @@ -88,7 +88,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"3"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"320\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h5") { @@ -99,7 +99,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"4"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"280\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h6") @@ -111,7 +111,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"5"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:after=\"0\" w:before=\"280\""); + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h1-c") { @@ -122,9 +122,9 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"44"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"48"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Kern, L"36"); } else if (sNameDefaultElement == L"h2-c") { @@ -136,9 +136,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"33"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"36"); } else if (sNameDefaultElement == L"h3-c") { @@ -150,9 +149,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"26"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"27"); } else if (sNameDefaultElement == L"h4-c") { @@ -164,9 +162,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"24"); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"22"); } else if (sNameDefaultElement == L"h5-c") { @@ -178,9 +175,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"20"); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"18"); } else if (sNameDefaultElement == L"h6-c") { @@ -192,9 +188,8 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); - AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"15"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); } else if (sNameDefaultElement == L"p-c") { @@ -203,8 +198,6 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Paragraph character"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"p"); - - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); } else if (sNameDefaultElement == L"p") { @@ -222,8 +215,6 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Div character"); AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"div"); - - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); } else if (sNameDefaultElement == L"div") { @@ -244,7 +235,6 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddPropertiesInR(CSSProperties::RunnerProperties::R_Color, L"0000FF"); AddPropertiesInR(CSSProperties::RunnerProperties::R_U, L"single"); - AddPropertiesInR(CSSProperties::RunnerProperties::R_RFonts, DEFAULTFONTNAME); } else if (sNameDefaultElement == L"a") { @@ -475,6 +465,11 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L""; break; } + case CSSProperties::RunnerProperties::R_Kern: + { + sRStyle += L""; + break; + } default: break; } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index b7a1ba8716c..79af26ffb22 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -193,7 +193,7 @@ class CHtmlFile2_Private m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) { m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); - m_oPageData.SetMargin(L"720tw 720tw 720tw 720tw", 0, true); + m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); m_oPageData.SetFooter(L"720tw", 0, true); m_oPageData.SetHeader(L"720tw", 0, true); } @@ -229,7 +229,7 @@ class CHtmlFile2_Private NSDirectory::CreateDirectory(m_sDst + L"/word/theme"); // theme1.xml - std::wstring sTheme = L""; + std::wstring sTheme = L""; NSFile::CFileBinary oThemeWriter; if (oThemeWriter.CreateFileW(m_sDst + L"/word/theme/theme1.xml")) { @@ -273,7 +273,7 @@ class CHtmlFile2_Private } // fontTable.xml - std::wstring sFontTable = L""; + std::wstring sFontTable = L""; NSFile::CFileBinary oFontTableWriter; if (oFontTableWriter.CreateFileW(m_sDst + L"/word/fontTable.xml")) { @@ -377,13 +377,13 @@ class CHtmlFile2_Private if(oParams && !oParams->m_sdocDefaults.empty()) m_oStylesXml += oParams->m_sdocDefaults; else - m_oStylesXml += L""; + m_oStylesXml += L""; // normal по умолчанию if(oParams && !oParams->m_sNormal.empty()) m_oStylesXml += oParams->m_sNormal; else - m_oStylesXml += L""; + m_oStylesXml += L""; // Маркированный список m_oStylesXml += L""; @@ -764,11 +764,11 @@ class CHtmlFile2_Private if (NULL == pXml) return; - pXml->WriteString(L""); - + pXml->WriteString(L""); + if (bVahish) pXml->WriteString(L""); - + pXml->WriteString(L""); } @@ -927,8 +927,13 @@ class CHtmlFile2_Private else ReplaceSpaces(sText); - if (1 == sText.length() && std::iswspace(sText.front())) - sText = L"\u00A0"; + if (std::iswspace(sText.front())) + { + if (1 == sText.length()) + sText = L"\u00A0"; + else if (m_bWasSpace) + sText.erase(0, 1); + } oXml->WriteEncodeXmlString(sText); oXml->WriteString(L""); @@ -983,13 +988,18 @@ class CHtmlFile2_Private // Перенос строки else if(sName == L"br") { - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - if(oStyle.m_oText.GetAlign() == L"both") - oXml->WriteString(L""); - oXml->WriteString(L""); - m_bWasSpace = false; + if (L"" == oXml->GetSubData(oXml->GetCurSize() - 6)) + { + oXml->WriteString(L""); + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); + if(oStyle.m_oText.GetAlign() == L"both") + oXml->WriteString(L""); + oXml->WriteString(L""); + } + else + WriteEmptyParagraph(oXml); + + m_bWasSpace = true; } else if(sName == L"center") { From e2ebe6a6d353172646d9d5cd2d54654721e53dd0 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 7 Mar 2024 16:39:55 +0300 Subject: [PATCH 395/794] fix bug #66783 --- OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp | 4 ++++ OdfFile/Writer/Format/ods_table_state.cpp | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 189a9ec139f..7ab8a319b85 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -375,6 +375,10 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().formula_type = L"containsErrors"; impl_->conditionalFormattings_.back().rules.back().formula = L"0"; } + else if (0 <= (pos = f.find(L"is-no-error"))) + { + impl_->conditionalFormattings_.back().rules.back().formula_type = L"notContainsErrors"; + } else if (0 <= (pos = f.find(L"duplicate"))) { impl_->conditionalFormattings_.back().rules.back().formula_type = L"duplicateValues"; diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index d0f7bafe5d6..497aca2ad67 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -2044,17 +2044,18 @@ void ods_table_state::end_conditional_rule() void ods_table_state::set_conditional_formula(const std::wstring& formula) { calcext_condition* condition = dynamic_cast (current_level_.back().get()); - if (!condition) return; std::wstring odfFormula = formulas_converter_table.convert_conditional_formula(formula); - std::wstring operator_; + std::wstring operator_ = condition->attr_.calcext_value_.get_value_or(L""); + + if (std::wstring::npos != operator_.find(L"is-no-error")) + return; + bool s = false; bool split = false; - operator_ = condition->attr_.calcext_value_.get_value_or(L""); - size_t f_start = operator_.find(L"("); size_t f_end = operator_.rfind(L")"); if (f_start != std::wstring::npos && f_end != std::wstring::npos) From 26658a71898fab291279cd844320375cb3299d28 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 9 Mar 2024 16:20:20 +0300 Subject: [PATCH 396/794] fix bug #66796 --- OdfFile/Writer/Format/ods_table_state.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index 497aca2ad67..2d45a6c37ef 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -2006,12 +2006,12 @@ void ods_table_state::start_conditional_rule(int rule_type, _CP_OPT(unsigned int } }break; case 1: condition->attr_.calcext_value_ = L"begins-with()"; break; - case 4: condition->attr_.calcext_value_ = L"contains-text()"; break; + case 4: condition->attr_.calcext_value_ = L"formula-is()"; break; case 5: condition->attr_.calcext_value_ = L"is-error"; break; case 6: condition->attr_.calcext_value_ = L"contains-text()"; break; case 8: condition->attr_.calcext_value_ = L"duplicate"; break; case 9: condition->attr_.calcext_value_ = L"formula-is()"; break; - case 11: condition->attr_.calcext_value_ = L"not-contains-text()"; break; + case 11: condition->attr_.calcext_value_ = L"formula-is()"; break; case 12: condition->attr_.calcext_value_ = L"is-no-error"; break; case 13: condition->attr_.calcext_value_ = L"not-contains-text()"; break; case 15: @@ -2050,7 +2050,8 @@ void ods_table_state::set_conditional_formula(const std::wstring& formula) std::wstring operator_ = condition->attr_.calcext_value_.get_value_or(L""); - if (std::wstring::npos != operator_.find(L"is-no-error")) + if (std::wstring::npos != operator_.find(L"is-no-error") || + std::wstring::npos != operator_.find(L"is-error")) return; bool s = false; From d81e70cfee7dc3976855dbb634a83f4b56dc94d3 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sun, 10 Mar 2024 14:37:48 +0300 Subject: [PATCH 397/794] fix bug #66798 --- .../DataTypes/custom_shape_types_convert.h | 1 + OdfFile/DataTypes/referenceformat.cpp | 104 +++++++++++++ OdfFile/DataTypes/referenceformat.h | 76 +++++++++ OdfFile/Projects/Linux/OdfFormatLib.pro | 6 +- OdfFile/Projects/Linux/odf_datatypes.cpp | 1 + OdfFile/Projects/Windows/cpcommon.vcxproj | 2 + .../Projects/Windows/cpcommon.vcxproj.filters | 146 ++++++++++++++++-- OdfFile/Reader/Format/paragraph_elements.cpp | 102 +++++++++--- OdfFile/Reader/Format/paragraph_elements.h | 43 ++++-- OdfFile/Writer/Format/odf_text_context.cpp | 12 ++ OdfFile/Writer/Format/odf_text_context.h | 1 + .../Writer/Format/odt_conversion_context.cpp | 27 ++++ OdfFile/Writer/Format/paragraph_elements.cpp | 36 +++++ OdfFile/Writer/Format/paragraph_elements.h | 36 ++++- 14 files changed, 536 insertions(+), 57 deletions(-) create mode 100644 OdfFile/DataTypes/referenceformat.cpp create mode 100644 OdfFile/DataTypes/referenceformat.h diff --git a/OdfFile/DataTypes/custom_shape_types_convert.h b/OdfFile/DataTypes/custom_shape_types_convert.h index b61cb447108..97b7e0e4364 100644 --- a/OdfFile/DataTypes/custom_shape_types_convert.h +++ b/OdfFile/DataTypes/custom_shape_types_convert.h @@ -30,6 +30,7 @@ * */ #pragma once +#include struct _shape_converter { diff --git a/OdfFile/DataTypes/referenceformat.cpp b/OdfFile/DataTypes/referenceformat.cpp new file mode 100644 index 00000000000..c5795d8b19c --- /dev/null +++ b/OdfFile/DataTypes/referenceformat.cpp @@ -0,0 +1,104 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "referenceformat.h" +#include +#include + +namespace cpdoccore { +namespace odf_types { +std::wostream & operator << (std::wostream & _Wostream, const reference_format & _Val) +{ + switch(_Val.get_type()) + { + case reference_format::chapter: + _Wostream << L"chapter"; + break; + case reference_format::direction: + _Wostream << L"direction"; + break; + case reference_format::caption: + _Wostream << L"caption"; + break; + case reference_format::category_and_value: + _Wostream << L"category-and-value"; + break; + case reference_format::value: + _Wostream << L"value"; + break; + case reference_format::number: + _Wostream << L"number"; + break; + case reference_format::number_all_superior: + _Wostream << L"number-all-superior"; + break; + case reference_format::number_no_superior: + _Wostream << L"number-no-superior"; + break; + default: + case reference_format::text: + _Wostream << L"text"; + break; + } + return _Wostream; +} + +reference_format reference_format::parse(const std::wstring & Str) +{ + std::wstring tmp = Str; + boost::algorithm::to_lower(tmp); + + if (tmp == L"chapter") + return reference_format(chapter); + else if (tmp == L"direction") + return reference_format(direction); + else if (tmp == L"text") + return reference_format(text); + else if (tmp == L"caption") + return reference_format(caption); + else if (tmp == L"category-and-value") + return reference_format(category_and_value); + else if (tmp == L"value") + return reference_format(value); + else if (tmp == L"number") + return reference_format(number); + else if (tmp == L"number-all-superior") + return reference_format(number_all_superior); + else if (tmp == L"number-no-superior") + return reference_format(number_no_superior); + else + { + return reference_format(text); + } +} +} +} diff --git a/OdfFile/DataTypes/referenceformat.h b/OdfFile/DataTypes/referenceformat.h new file mode 100644 index 00000000000..54e679f516b --- /dev/null +++ b/OdfFile/DataTypes/referenceformat.h @@ -0,0 +1,76 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include +#include "odfattributes.h" + + +namespace cpdoccore { +namespace odf_types { + +class reference_format +{ +public: + enum type + { + chapter, + direction, + text, + caption, + category_and_value, + value, + number, + number_all_superior, + number_no_superior + }; + + reference_format() {} + reference_format(type _Type) : type_(_Type) + {} + + type get_type() const + { + return type_; + }; + static reference_format parse(const std::wstring & Str); + +private: + type type_; + +}; +std::wostream & operator << (std::wostream & _Wostream, const reference_format& _Val); +} +APPLY_PARSE_XML_ATTRIBUTES(odf_types::reference_format); + +} diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 45e696350e0..a2138f65f3b 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -40,7 +40,8 @@ SOURCES += \ core_debug { SOURCES += \ - ../../DataTypes/mathvariant.cpp \ + ../../DataTypes/referenceformat.cpp \ + ../../DataTypes/mathvariant.cpp \ ../../DataTypes/anchortype.cpp \ ../../DataTypes/animation_attlists.cpp \ ../../DataTypes/backgroundcolor.cpp \ @@ -445,7 +446,8 @@ HEADERS += \ ../../Common/xml/xmlchar.h \ ../../Common/xml/xmlelement.h \ \ - ../../DataTypes/mathvariant.h \ + ../../DataTypes/referenceformat.h \ + ../../DataTypes/mathvariant.h \ ../../DataTypes/anchortype.h \ ../../DataTypes/animation_attlists.h \ ../../DataTypes/backgroundcolor.h \ diff --git a/OdfFile/Projects/Linux/odf_datatypes.cpp b/OdfFile/Projects/Linux/odf_datatypes.cpp index b13da53e57f..ca12641c14d 100644 --- a/OdfFile/Projects/Linux/odf_datatypes.cpp +++ b/OdfFile/Projects/Linux/odf_datatypes.cpp @@ -153,3 +153,4 @@ #include "../../DataTypes/sparklines.cpp" #include "../../DataTypes/tabledatatype.cpp" #include "../../DataTypes/tableoperator.cpp" +#include "../../DataTypes/referenceformat.cpp" diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj b/OdfFile/Projects/Windows/cpcommon.vcxproj index 55607999e58..e4890c3f57a 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj @@ -253,6 +253,7 @@ + @@ -383,6 +384,7 @@ + diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters index 41ae74406d6..909e9e65ba4 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters @@ -126,6 +126,10 @@ + + + + @@ -143,15 +147,133 @@ - - datatypes odf - - - datatypes odf - - - datatypes odf - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -489,11 +611,5 @@ datatypes odf - - datatypes odf - - - datatypes odf - \ No newline at end of file diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index dd5bc730bf0..57e4549b0da 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -91,6 +91,31 @@ void paragraph_content_element::docx_serialize_field(const std::wstring & field_ strm << L""; } } + +void paragraph_content_element::docx_serialize_field(const std::wstring& field_name, office_element_ptr_array& content, + oox::docx_conversion_context& Context, bool bLock) +{ + std::wostream& strm = Context.output_stream(); + Context.finish_run(); + + if (false == field_name.empty()) + { + strm << L""; + strm << L"" << field_name << L""; + } + + docx_serialize_run(content, Context); + + if (false == field_name.empty()) + { + strm << L""; + } +} void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstring & name, office_element_ptr & text, oox::docx_conversion_context & Context) { std::wostream & strm = Context.output_stream(); @@ -105,7 +130,20 @@ void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstrin strm << L""; } +void paragraph_content_element::docx_serialize_sdt_placeholder(const std::wstring& name, office_element_ptr_array& content, oox::docx_conversion_context& Context) +{ + std::wostream& strm = Context.output_stream(); + Context.finish_run(); + strm << L""; + strm << L""; + + docx_serialize_run(content, Context); + + strm << L""; +} void paragraph_content_element::docx_serialize_run(office_element_ptr & text, oox::docx_conversion_context & Context) { Context.add_new_run(); @@ -115,6 +153,13 @@ void paragraph_content_element::docx_serialize_run(office_element_ptr & text, oo } Context.finish_run(); } +void paragraph_content_element::docx_serialize_run(office_element_ptr_array& content, oox::docx_conversion_context& Context) +{ + for (size_t i = 0; i < content.size(); ++i) + { + docx_serialize_run(content[i], Context); + } +} //------------------------------------------------------------------------------------------------------------ const wchar_t * text::ns = L""; @@ -396,7 +441,26 @@ void bookmark_ref::add_attributes( const xml::attributes_wc_ptr & Attributes ) } void bookmark_ref::add_text(const std::wstring & Text) { - content_ = Text; + office_element_ptr elm = text::create(Text); + content_.push_back( elm ); +} +void bookmark_ref::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content_); +} +void bookmark_ref::docx_convert(oox::docx_conversion_context& Context) +{ + std::wstring field_name = (ref_name_ ? L"REF " + *ref_name_ : L"REF") + L" \\h"; + + if (reference_format_) + { + switch (reference_format_->get_type()) + { + case reference_format::direction: field_name += L" \\p"; break; + case reference_format::number: field_name += L" \\n"; break; + } + } + docx_serialize_field(field_name, content_, Context); } // text:reference-ref ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1088,30 +1152,32 @@ void chapter::pptx_convert(oox::pptx_conversion_context & Context) const wchar_t * text_placeholder::ns = L"text"; const wchar_t * text_placeholder::name = L"placeholder"; +void text_placeholder::add_attributes( const xml::attributes_wc_ptr & Attributes ) +{ +} std::wostream & text_placeholder::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { - CP_SERIALIZE_TEXT(text_, bXmlEncode); - return _Wostream; + CP_SERIALIZE_TEXT(content_, bXmlEncode); + return _Wostream; } - -void text_placeholder::add_attributes( const xml::attributes_wc_ptr & Attributes ) +void text_placeholder::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) { + CP_CREATE_ELEMENT(content_); } void text_placeholder::add_text(const std::wstring & Text) { - text_ = text::create(Text) ; + office_element_ptr text = text::create(Text) ; + content_.push_back(text); } - void text_placeholder::docx_convert(oox::docx_conversion_context & Context) { - docx_serialize_sdt_placeholder(L"Click placeholder and overwrite", text_, Context); + docx_serialize_sdt_placeholder(L"Click placeholder and overwrite", content_, Context); } - void text_placeholder::pptx_convert(oox::pptx_conversion_context & Context) { - if (text_) + for (size_t i = 0; i < content_.size(); ++i) { - text_->pptx_convert(Context); + content_[i]->pptx_convert(Context); } } @@ -1424,18 +1490,18 @@ void sequence::add_attributes( const xml::attributes_wc_ptr & Attributes ) } std::wostream & sequence::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { - CP_SERIALIZE_TEXT(text_, bXmlEncode); + CP_SERIALIZE_TEXT(content_, bXmlEncode); return _Wostream; } void sequence::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { - CP_CREATE_ELEMENT(text_); + CP_CREATE_ELEMENT(content_); } void sequence::add_text(const std::wstring & Text) { office_element_ptr elm = text::create(Text) ; - text_.push_back( elm ); + content_.push_back( elm ); } void sequence::docx_convert(oox::docx_conversion_context & Context) @@ -1485,9 +1551,9 @@ void sequence::docx_convert(oox::docx_conversion_context & Context) Context.start_bookmark(name); Context.output_stream() << L""; Context.add_new_run(); - for (size_t i = 0; i < text_.size(); i++) + for (size_t i = 0; i < content_.size(); i++) { - text_[i]->docx_convert(Context); + content_[i]->docx_convert(Context); } Context.finish_run(); @@ -1502,9 +1568,9 @@ void sequence::docx_convert(oox::docx_conversion_context & Context) } void sequence::pptx_convert(oox::pptx_conversion_context & Context) { - for (size_t i = 0; i < text_.size(); i++) + for (size_t i = 0; i < content_.size(); i++) { - text_[i]->pptx_convert(Context); + content_[i]->pptx_convert(Context); } } //------------------------------------------------------------------------------------------------------------ diff --git a/OdfFile/Reader/Format/paragraph_elements.h b/OdfFile/Reader/Format/paragraph_elements.h index d690b77546e..19be7cc8daa 100644 --- a/OdfFile/Reader/Format/paragraph_elements.h +++ b/OdfFile/Reader/Format/paragraph_elements.h @@ -42,6 +42,7 @@ #include "../../DataTypes/noteclass.h" #include "../../DataTypes/bool.h" #include "../../DataTypes/bibliography.h" +#include "../../DataTypes/referenceformat.h" #include "../../Reader/Converter/docx_conversion_context.h" @@ -67,9 +68,14 @@ class paragraph_content_element : public office_element_impl(elm.get()); + if (ref) + { + if (false == value.empty()) ref->ref_name_ = value; + + ref->reference_format_ = odf_types::reference_format::parse(format.empty() ? L"text" : format); + + } + }break; } if (elm) diff --git a/OdfFile/Writer/Format/odf_text_context.h b/OdfFile/Writer/Format/odf_text_context.h index 9bfb87c7931..960a18d382e 100644 --- a/OdfFile/Writer/Format/odf_text_context.h +++ b/OdfFile/Writer/Format/odf_text_context.h @@ -58,6 +58,7 @@ namespace odf_writer fieldDropDown, fieldDate, fieldTime, + fieldRef, fieldBibliography = 0xff + 1, fieldIndex, diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index da0f3a5fc7c..89c8a3a133b 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -767,6 +767,33 @@ void odt_conversion_context::set_field_instr() if (instr.length() > 9) current_fields.back().value = instr.substr(9, instr.length() - 5); } + res1 = instr.find(L"REF"); + if (std::wstring::npos != res1 && current_fields.back().type == 0) + { + current_fields.back().type = fieldRef; + std::map options = parse_instr_options(instr.substr(4)); + + for (std::map::iterator it = options.begin(); it != options.end(); ++it) + { + if (it->first == L" ")//field-argument + { + current_fields.back().value = it->second; + boost::algorithm::trim(current_fields.back().value); + } + else if (it->first == L"h") + { + current_fields.back().bHyperlinks = true; + } + else if (it->first == L"p") + { + current_fields.back().format = L"direction"; + } + else if (it->first == L"r" || it->first == L"n") + { + current_fields.back().format = L"number"; + } + } + } res1 = instr.find(L"PAGE"); if (std::wstring::npos != res1 && current_fields.back().type == 0) { diff --git a/OdfFile/Writer/Format/paragraph_elements.cpp b/OdfFile/Writer/Format/paragraph_elements.cpp index 6df4f4a83d6..7be39843430 100644 --- a/OdfFile/Writer/Format/paragraph_elements.cpp +++ b/OdfFile/Writer/Format/paragraph_elements.cpp @@ -188,6 +188,42 @@ void text_bookmark_end::serialize(std::wostream & _Wostream) } } } +//---------------------------------------------------------------------------------- +// text:bookmark-ref +//---------------------------------------------------------------------------------- +const wchar_t* text_bookmark_ref::ns = L"text"; +const wchar_t* text_bookmark_ref::name = L"bookmark-ref"; + +void text_bookmark_ref::create_child_element(const std::wstring& Ns, const std::wstring& Name) +{ + CP_CREATE_ELEMENT(content_); +} +void text_bookmark_ref::add_child_element(const office_element_ptr& child_element) +{ + content_.push_back(child_element); +} +void text_bookmark_ref::add_text(const std::wstring& Text) +{ + office_element_ptr elm = text_text::create(Text); + content_.push_back(elm); +} +void text_bookmark_ref::serialize(std::wostream& _Wostream) +{ + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE() + { + CP_XML_ATTR_OPT_ENCODE_STRING(L"text:ref-name", ref_name_); + CP_XML_ATTR_OPT(L"text:reference-format", reference_format_); + + for (size_t i = 0; i < content_.size(); i++) + { + content_[i]->serialize(CP_XML_STREAM()); + } + } + } +} + //---------------------------------------------------------------------------------- // text:reference-mark //---------------------------------------------------------------------------------- diff --git a/OdfFile/Writer/Format/paragraph_elements.h b/OdfFile/Writer/Format/paragraph_elements.h index 78e345513d9..9b1fb663fdf 100644 --- a/OdfFile/Writer/Format/paragraph_elements.h +++ b/OdfFile/Writer/Format/paragraph_elements.h @@ -42,6 +42,7 @@ #include "../../DataTypes/targetframename.h" #include "../../DataTypes/noteclass.h" #include "../../DataTypes/bibliography.h" +#include "../../DataTypes/referenceformat.h" #include "../../DataTypes/common_attlists.h" @@ -211,7 +212,33 @@ class text_bookmark_end : public office_element_impl std::wstring text_name_; }; CP_REGISTER_OFFICE_ELEMENT2(text_bookmark_end); +//------------------------------------------------------------------------------------------------------------------- +// text:bookmark-ref +//------------------------------------------------------------------------------------------------------------------- +class text_bookmark_ref : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + + static const ElementType type = typeTextBookmarkRef; + + text_bookmark_ref() {}; + text_bookmark_ref(const std::wstring& Name) : ref_name_(Name) {}; + virtual void create_child_element(const std::wstring& Ns, const std::wstring& Name); + virtual void add_child_element(const office_element_ptr& child_element); + virtual void add_text(const std::wstring& Text); + + virtual void serialize(std::wostream& _Wostream); + + _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + + _CP_OPT(std::wstring) text_; + office_element_ptr_array content_; +}; +CP_REGISTER_OFFICE_ELEMENT2(text_bookmark_ref); // text:reference-mark //--------------------------------------------------------------------------------------------------- class text_reference_mark : public office_element_impl @@ -920,18 +947,17 @@ class text_sequence_ref : public office_element_impl static const wchar_t * ns; static const wchar_t * name; - static const ElementType type = typeTextSequenceRef; - + static const ElementType type = typeTextSequenceRef; virtual void create_child_element (const std::wstring & Ns, const std::wstring & Name){} virtual void add_child_element ( const office_element_ptr & child_element){} virtual void serialize(std::wostream & _Wostream); - _CP_OPT(std::wstring) reference_format_;//caption, category-and-value, value, chapter, direction, page, text, number, number-all-superior, number-no-superior - _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + _CP_OPT(std::wstring) ref_name_; - std::wstring content_; + std::wstring content_; }; CP_REGISTER_OFFICE_ELEMENT2(text_sequence_ref); //------------------------------------------------------------------------------------------------------------------- From f93a628c24a429f124be117a3a77cc884bb7ae4f Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Sun, 10 Mar 2024 21:58:34 +0300 Subject: [PATCH 398/794] Refactoring build --- Common/3dParty/boost/boost.pri | 4 + Common/3dParty/boost/boost_android.sh | 326 ------------------ Common/3dParty/curl/build-android-common.sh | 220 ------------ Common/3dParty/curl/build-android-curl.sh | 128 ------- Common/3dParty/curl/curl.pri | 18 +- Common/3dParty/icu/icu.pri | 5 +- Common/3dParty/openssl/openssl.pri | 11 +- Common/3dParty/v8/android/build.py | 2 +- Common/3dParty/v8/v8.pri | 2 + Common/base.pri | 6 + DesktopEditor/cximage/raw/libdcr.h | 2 +- .../doctrenderer/js_internal/v8/v8_base.h | 36 +- DesktopEditor/graphics/Timer.cpp | 78 ++--- DesktopEditor/graphics/Timer.h | 58 ++-- DesktopEditor/graphics/pro/raster.pri | 4 + 15 files changed, 121 insertions(+), 779 deletions(-) delete mode 100755 Common/3dParty/boost/boost_android.sh delete mode 100755 Common/3dParty/curl/build-android-common.sh delete mode 100755 Common/3dParty/curl/build-android-curl.sh diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index e590f9c27d2..dcc0e87b709 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -4,6 +4,10 @@ CORE_BOOST_LIBS = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib core_android { INCLUDEPATH += $$PWD/build/android/include CORE_BOOST_LIBS = $$PWD/build/android/lib/$$CORE_BUILDS_PLATFORM_PREFIX + + DEFINES += "_HAS_AUTO_PTR_ETC=0" + QMAKE_CFLAGS += -Wno-enum-constexpr-conversion + QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } bundle_xcframeworks { diff --git a/Common/3dParty/boost/boost_android.sh b/Common/3dParty/boost/boost_android.sh deleted file mode 100755 index e5510d28113..00000000000 --- a/Common/3dParty/boost/boost_android.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/bin/bash - -cd boost_1_72_0 -OUTPUT_DIR="../build/android" - -BOOST_LIBS="filesystem system date_time regex" - -CPPSTD="-std=c++11 -frtti -fexceptions" - -# Must set these after parseArgs to fill in overriden values -# Todo: -g -DNDEBUG are for debug builds only... -# Boost.test defines are needed to build correct instrumentable boost_unit_test_framework static lib -# it does not affect the functionality of single-header usage. -# See http://www.boost.org/doc/libs/1_66_0/libs/test/doc/html/boost_test/adv_scenarios/static_lib_customizations/entry_point.html -EXTRA_FLAGS="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS \ - -DBOOST_TEST_NO_MAIN -DBOOST_TEST_ALTERNATIVE_INIT_API -DANDROID_STL=c++_static \ - -Wno-unused-local-typedef" -EXTRA_ANDROID_FLAGS="$EXTRA_FLAGS" - -if [[ -n "$USE_CXX11_ABI" ]]; then - EXTRA_LINUX_FLAGS="$EXTRA_FLAGS -D_GLIBCXX_USE_CXX11_ABI=$USE_CXX11_ABI" -else - EXTRA_LINUX_FLAGS="$EXTRA_FLAGS" -fi - -doneSection() -{ - echo - echo "Done" - echo "=================================================================" - echo -} - -bootstrapBoost() -{ - BOOTSTRAP_LIBS=$BOOST_LIBS - BOOST_LIBS_COMMA=$(echo $BOOTSTRAP_LIBS | sed -e "s/ /,/g") - echo "Bootstrapping for $1 (with libs $BOOST_LIBS_COMMA)" - ./bootstrap.sh --with-libraries=$BOOST_LIBS_COMMA - - doneSection -} - -generateAndroidUserConfig() -{ - HOSTOS="$(uname | awk '{ print $1}' | tr [:upper:] [:lower:])-" # darwin or linux - OSARCH="$(uname -m)" - - # Boost doesn't build with -Werror - # Reported to boost-users@lists.boost.org - - cat > "./tools/build/src/user-config.jam" <x86 android ---target=i686-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/x86-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/i686-linux-android --DANDROID --D__ANDROID_API__=19 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --mstackrealign --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -using clang : 5.0~x86_64 -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -x86 android ---target=x86_64-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/x86_64-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/x86_64-linux-android --DANDROID --D__ANDROID_API__=21 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --mstackrealign --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -using clang : 5.0~arm -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -arm android ---target=armv7-none-linux-androideabi ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/arm-linux-androideabi --DANDROID --D__ANDROID_API__=19 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --fno-integrated-as --no-canonical-prefixes --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow --march=armv7-a --mfloat-abi=softfp --mfpu=vfpv3-d16 --mthumb -; -using clang : 5.0~arm64 -: $ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOSTOS$OSARCH/bin/clang++ $EXTRA_ANDROID_FLAGS -: -arm android ---target=aarch64-none-linux-android ---gcc-toolchain=$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/$HOSTOS$OSARCH ---sysroot=$ANDROID_NDK_ROOT/sysroot --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/include --isystem $ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include --isystem $ANDROID_NDK_ROOT/sources/android/support/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include --isystem $ANDROID_NDK_ROOT/sysroot/usr/include/aarch64-linux-android --DANDROID --D__ANDROID_API__=21 --ffunction-sections --funwind-tables --fstack-protector-strong --fno-limit-debug-info --fPIC --no-canonical-prefixes --Wa,--noexecstack --Wformat --Werror=format-security --Wall --Wshadow -; -EOF -} - -buildBoost_Android() -{ - mkdir -p $OUTPUT_DIR - echo > ${OUTPUT_DIR}/android-build.log - - if [[ -z "$ANDROID_NDK_ROOT" ]]; then - echo "Must specify ANDROID_NDK_ROOT" - exit 1 - fi - - export NO_BZIP2=1 - - # build libicu if locale requested but not provided - # if echo $LIBRARIES | grep locale; then - # if [ -e libiconv-libicu-android ]; then - # echo "ICONV and ICU already compiled" - # else - # echo "boost_locale selected - compiling ICONV and ICU" - # git clone https://github.com/pelya/libiconv-libicu-android.git - # cd libiconv-libicu-android - # ./build.sh || exit 1 - # cd .. - # fi - # fi - - echo clean - ./b2 --clean - - echo Building release x86 Boost for Android Emulator - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/x86" toolset=clang-5.0~x86 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=32 variant=release cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release x86_64 Boost for Android Emulator - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/x86_64" toolset=clang-5.0~x86_64 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=64 variant=release cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release armv7 Boost for Android - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/armeabi-v7a" toolset=clang-5.0~arm \ - abi=aapcs architecture=arm address-model=32 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=release cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building release arm64 Boost for Android - - ./b2 --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/arm64-v8a" toolset=clang-5.0~arm64 \ - abi=aapcs architecture=arm address-model=64 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=release cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection -} - -buildBoost_Android_debug() -{ - mkdir -p $OUTPUT_DIR - echo > ${OUTPUT_DIR}/android-build.log - - export NO_BZIP2=1 - - # build libicu if locale requested but not provided - # if echo $LIBRARIES | grep locale; then - # if [ -e libiconv-libicu-android ]; then - # echo "ICONV and ICU already compiled" - # else - # echo "boost_locale selected - compiling ICONV and ICU" - # git clone https://github.com/pelya/libiconv-libicu-android.git - # cd libiconv-libicu-android - # ./build.sh || exit 1 - # cd .. - # fi - # fi - - echo Building debug x86 Boost for Android Emulator - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/x86" toolset=clang-5.0~x86 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=32 variant=debug cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug x86_64 Boost for Android Emulator - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/x86_64" toolset=clang-5.0~x86_64 \ - architecture=x86 target-os=android define=_LITTLE_ENDIAN \ - optimization=speed \ - address-model=64 variant=debug cxxflags="${CPPSTD}" \ - link=static threading=multi install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error staging Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug armv7 Boost for Android - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/armeabi-v7a" toolset=clang-5.0~arm \ - abi=aapcs architecture=arm address-model=32 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=debug cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection - - echo Building debug arm64 Boost for Android - - ./b2 $THREADS --build-dir=android-build --stagedir=android-build/stage \ - --prefix="$OUTPUT_DIR" \ - --libdir="$OUTPUT_DIR/lib/debug/arm64-v8a" toolset=clang-5.0~arm64 \ - abi=aapcs architecture=arm address-model=64 binary-format=elf threading=multi \ - optimization=space \ - target-os=android variant=debug cxxflags="${CPPSTD}" \ - link=static install >> "${OUTPUT_DIR}/android-build.log" 2>&1 - if [ $? != 0 ]; then echo "Error installing Android. Check ${OUTPUT_DIR}/android-build.log"; exit 1; fi - - doneSection -} - -bootstrapBoost -generateAndroidUserConfig -buildBoost_Android -#buildBoost_Android_debug - -echo "Completed successfully" diff --git a/Common/3dParty/curl/build-android-common.sh b/Common/3dParty/curl/build-android-common.sh deleted file mode 100755 index d1b069c0473..00000000000 --- a/Common/3dParty/curl/build-android-common.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source ./build-common.sh - -export PLATFORM_TYPE="Android" -export ARCHS=("arm" "arm64" "x86" "x86_64") -export ABIS=("armeabi-v7a" "arm64-v8a" "x86" "x86_64") -export ABI_TRIPLES=("arm-linux-androideabi" "aarch64-linux-android" "i686-linux-android" "x86_64-linux-android") -export ANDROID_API=21 - -# for test -# export ARCHS=("x86_64") -# export ABIS=("x86_64") -# export ABI_TRIPLES=("x86_64-linux-android") - -if [[ -z ${ANDROID_NDK_ROOT} ]]; then - echo "ANDROID_NDK_ROOT not defined" - exit 1 -fi - -function get_toolchain() { - HOST_OS=$(uname -s) - case ${HOST_OS} in - Darwin) HOST_OS=darwin ;; - Linux) HOST_OS=linux ;; - FreeBsd) HOST_OS=freebsd ;; - CYGWIN* | *_NT-*) HOST_OS=cygwin ;; - esac - - HOST_ARCH=$(uname -m) - case ${HOST_ARCH} in - i?86) HOST_ARCH=x86 ;; - x86_64 | amd64) HOST_ARCH=x86_64 ;; - esac - - echo "${HOST_OS}-${HOST_ARCH}" -} - -function get_android_arch() { - local common_arch=$1 - case ${common_arch} in - arm) - echo "arm-v7a" - ;; - arm64) - echo "arm64-v8a" - ;; - x86) - echo "x86" - ;; - x86_64) - echo "x86-64" - ;; - esac -} - -function get_target_build() { - local arch=$1 - case ${arch} in - arm-v7a) - echo "arm" - ;; - arm64-v8a) - echo "arm64" - ;; - x86) - echo "x86" - ;; - x86-64) - echo "x86_64" - ;; - esac -} - -function get_build_host_internal() { - local arch=$1 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "arm-linux-androideabi" - ;; - arm64-v8a) - echo "aarch64-linux-android" - ;; - x86) - echo "i686-linux-android" - ;; - x86-64) - echo "x86_64-linux-android" - ;; - esac -} - -function android_get_build_host() { - local arch=$(get_android_arch $1) - get_build_host_internal $arch -} - -function get_clang_target_host() { - local arch=$1 - local api=$2 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "armv7a-linux-androideabi${api}" - ;; - arm64-v8a) - echo "aarch64-linux-android${api}" - ;; - x86) - echo "i686-linux-android${api}" - ;; - x86-64) - echo "x86_64-linux-android${api}" - ;; - esac -} - -function set_android_toolchain_bin() { - export PATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/$(get_toolchain)/bin:$PATH - echo PATH=$PATH -} - -function set_android_toolchain() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - local build_host=$(get_build_host_internal "$arch") - local clang_target_host=$(get_clang_target_host "$arch" "$api") - - export AR=${build_host}-ar - export CC=${clang_target_host}-clang - export CXX=${clang_target_host}-clang++ - export AS=${build_host}-as - export LD=${build_host}-ld - export RANLIB=${build_host}-ranlib - export STRIP=${build_host}-strip -} - -function get_common_includes() { - local toolchain=$(get_toolchain) - echo "-I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/include -I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/local/include" -} -function get_common_linked_libraries() { - local api=$1 - local arch=$2 - local toolchain=$(get_toolchain) - local build_host=$(get_build_host_internal "$arch") - echo "-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/${build_host}/lib -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/lib/${build_host}/${api} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/lib" -} - -function set_android_cpu_feature() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - case ${arch} in - arm-v7a | arm-v7a-neon) - export CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - arm64-v8a) - export CFLAGS="-march=armv8-a -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv8-a -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86) - export CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=i686 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86-64) - export CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=x86-64 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - esac -} - -function android_printf_global_params() { - local arch=$1 - local abi=$2 - local abi_triple=$3 - local in_dir=$4 - local out_dir=$5 - echo -e "arch = $arch" - echo -e "abi = $abi" - echo -e "abi_triple = $abi_triple" - echo -e "PLATFORM_TYPE = $PLATFORM_TYPE" - echo -e "ANDROID_API = $ANDROID_API" - echo -e "in_dir = $in_dir" - echo -e "out_dir = $out_dir" - echo -e "AR = $AR" - echo -e "CC = $CC" - echo -e "CXX = $CXX" - echo -e "AS = $AS" - echo -e "LD = $LD" - echo -e "RANLIB = $RANLIB" - echo -e "STRIP = $STRIP" - echo -e "CFLAGS = $CFLAGS" - echo -e "CXXFLAGS = $CXXFLAGS" - echo -e "LDFLAGS = $LDFLAGS" - echo -e "CPPFLAGS = $CPPFLAGS" -} diff --git a/Common/3dParty/curl/build-android-curl.sh b/Common/3dParty/curl/build-android-curl.sh deleted file mode 100755 index 697e8845b9c..00000000000 --- a/Common/3dParty/curl/build-android-curl.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# # read -n1 -p "Press any key to continue..." - -set -u - -source ./build-android-common.sh - -init_log_color - -TOOLS_ROOT=$(pwd) - -SOURCE="$0" -while [ -h "$SOURCE" ]; do - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" -done -pwd_path="$(cd -P "$(dirname "$SOURCE")" && pwd)" - -echo pwd_path=${pwd_path} -echo TOOLS_ROOT=${TOOLS_ROOT} - -LIB_VERSION="curl-7_68_0" -LIB_NAME="curl-7.68.0" -LIB_DEST_DIR="${pwd_path}/build/android/curl-universal" - -echo "https://github.com/curl/curl/releases/download/${LIB_VERSION}/${LIB_NAME}.tar.gz" - -# https://curl.haxx.se/download/${LIB_NAME}.tar.gz -# https://github.com/curl/curl/releases/download/curl-7_69_0/curl-7.69.0.tar.gz -# https://github.com/curl/curl/releases/download/curl-7_68_0/curl-7.68.0.tar.gz -rm -rf "${LIB_DEST_DIR}" "${LIB_NAME}" -[ -f "${LIB_NAME}.tar.gz" ] || curl -L -o ${LIB_NAME}.tar.gz https://github.com/curl/curl/releases/download/${LIB_VERSION}/${LIB_NAME}.tar.gz -s -[ -f "${LIB_NAME}.tar.gz" ] || log_error "curl download error!" - -set_android_toolchain_bin - -function configure_make() { - - ARCH=$1 - ABI=$2 - ABI_TRIPLE=$3 - - log_info "configure $ABI start..." - - if [ -d "${LIB_NAME}" ]; then - rm -fr "${LIB_NAME}" - fi - tar xfz "${LIB_NAME}.tar.gz" - pushd . - cd "${LIB_NAME}" - - PREFIX_DIR="${pwd_path}/build/android/${ABI}" - if [ -d "${PREFIX_DIR}" ]; then - rm -fr "${PREFIX_DIR}" - fi - mkdir -p "${PREFIX_DIR}" - - OUTPUT_ROOT=${TOOLS_ROOT}/build/android/${ABI} - mkdir -p ${OUTPUT_ROOT}/log - - set_android_toolchain "curl" "${ARCH}" "${ANDROID_API}" - set_android_cpu_feature "curl" "${ARCH}" "${ANDROID_API}" - - export ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} - echo ANDROID_NDK_HOME=${ANDROID_NDK_HOME} - - OPENSSL_OUT_DIR="${pwd_path}/../openssl/build/android/${ABI}" - - export LDFLAGS="${LDFLAGS} -L${OPENSSL_OUT_DIR}/lib" - # export LDFLAGS="-Wl,-rpath-link,-L${OPENSSL_OUT_DIR}/lib $LDFLAGS " - - android_printf_global_params "$ARCH" "$ABI" "$ABI_TRIPLE" "$PREFIX_DIR" "$OUTPUT_ROOT" - - if [[ "${ARCH}" == "x86_64" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "x86" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "arm" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - elif [[ "${ARCH}" == "arm64" ]]; then - - ./configure --host=$(android_get_build_host "${ARCH}") --prefix="${PREFIX_DIR}" --enable-ipv6 --with-ssl=${OPENSSL_OUT_DIR} --enable-static --disable-shared >"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - - else - log_error "not support" && exit 1 - fi - - log_info "make $ABI start..." - - make clean >>"${OUTPUT_ROOT}/log/${ABI}.log" - if make -j$(get_cpu_count) >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1; then - make install >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - fi - - popd -} - -log_info "${PLATFORM_TYPE} ${LIB_NAME} start..." - -for ((i = 0; i < ${#ARCHS[@]}; i++)); do - if [[ $# -eq 0 || "$1" == "${ARCHS[i]}" ]]; then - configure_make "${ARCHS[i]}" "${ABIS[i]}" "${ABI_TRIPLES[i]}" - fi -done - -log_info "${PLATFORM_TYPE} ${LIB_NAME} end..." diff --git a/Common/3dParty/curl/curl.pri b/Common/3dParty/curl/curl.pri index d1178d404ef..6d24ea212d6 100644 --- a/Common/3dParty/curl/curl.pri +++ b/Common/3dParty/curl/curl.pri @@ -1,18 +1,10 @@ core_android { - - ABI_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - contains(ABI_PATH, "armv7" ) { - ABI_PATH = $$replace(ABI_PATH, "armv7", "armeabi-v7a") - } - contains(ABI_PATH, "arm64_v8a" ) { - ABI_PATH = $$replace(ABI_PATH, "arm64_v8a", "arm64-v8a") - } INCLUDEPATH += \ - $$PWD/build/android/$$ABI_PATH/include \ - $$PWD/../openssl/build/android/$$ABI_PATH/include \ + $$PWD/build/android/include \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/include LIBS += \ - $$PWD/build/android/$$ABI_PATH/lib/libcurl.a \ - $$PWD/../openssl/build/android/$$ABI_PATH/lib/libssl.a \ - $$PWD/../openssl/build/android/$$ABI_PATH/lib/libcrypto.a \ + $$PWD/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libcurl.a \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib/libssl.a \ + $$PWD/../openssl/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib/libcrypto.a \ } diff --git a/Common/3dParty/icu/icu.pri b/Common/3dParty/icu/icu.pri index d63020fa5c3..c5ae929f8ac 100644 --- a/Common/3dParty/icu/icu.pri +++ b/Common/3dParty/icu/icu.pri @@ -43,8 +43,7 @@ core_ios { core_android { INCLUDEPATH += $$PWD/android/build/include - ICU_LIBS_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - LIBS += $$PWD/android/build/$$ICU_LIBS_PATH/libicuuc.a - LIBS += $$PWD/android/build/$$ICU_LIBS_PATH/libicudata.a + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicuuc.a + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicudata.a } diff --git a/Common/3dParty/openssl/openssl.pri b/Common/3dParty/openssl/openssl.pri index 861eb4d3433..cb565d46210 100644 --- a/Common/3dParty/openssl/openssl.pri +++ b/Common/3dParty/openssl/openssl.pri @@ -11,16 +11,7 @@ open_ssl_common { OPENSSL_LIBS_DIRECTORY = $$PWD/build/$$OPEN_SSL_PLATFORM/lib core_android { - - OPENSSL_ABI_PATH = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") - contains(OPENSSL_ABI_PATH, "armv7" ) { - OPENSSL_ABI_PATH = $$replace(OPENSSL_ABI_PATH, "armv7", "armeabi-v7a") - } - contains(OPENSSL_ABI_PATH, "arm64_v8a" ) { - OPENSSL_ABI_PATH = $$replace(OPENSSL_ABI_PATH, "arm64_v8a", "arm64-v8a") - } - - OPENSSL_LIBS_DIRECTORY = $$PWD/build/android/$$OPENSSL_ABI_PATH/lib + OPENSSL_LIBS_DIRECTORY = $$PWD/build/android/$$CORE_BUILDS_PLATFORM_PREFIX_DST/lib } core_ios { diff --git a/Common/3dParty/v8/android/build.py b/Common/3dParty/v8/android/build.py index 14129064c6d..0c31835c777 100644 --- a/Common/3dParty/v8/android/build.py +++ b/Common/3dParty/v8/android/build.py @@ -123,7 +123,7 @@ def get_android_args(platform, sdk_ver=21): "v8_static_library=true", "v8_monolithic=true", "use_custom_libcxx=false", - "android_ndk_version=\\\"21.1.6352462\\\"", + "android_ndk_version=\\\"26.2.11394342\\\"", "android_sdk_version=\\\"" + str(sdk_ver) + "\\\"", "clang_use_chrome_plugins=false", "v8_use_external_startup_data=false", diff --git a/Common/3dParty/v8/v8.pri b/Common/3dParty/v8/v8.pri index 24f6fe1afb2..1148ffb566d 100644 --- a/Common/3dParty/v8/v8.pri +++ b/Common/3dParty/v8/v8.pri @@ -30,6 +30,8 @@ core_android { isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_armv7): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/armeabi-v7a isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_x86): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/x86 isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_x86_64): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/x86_64 + + LIBS += -ldl } INCLUDEPATH += \ diff --git a/Common/base.pri b/Common/base.pri index 59a3bb0e2ae..eb6a1ec793d 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -19,6 +19,11 @@ isEmpty(PUBLISHER_NAME){ PUBLISHER_NAME = $$cat(copyright.txt) } +DEST_MAKEFILE_NAME = $$(DEST_MAKEFILE_NAME) +!isEmpty(DEST_MAKEFILE_NAME){ + MAKEFILE = $${DEST_MAKEFILE_NAME} +} + APPLICATION_NAME_DEFAULT = $$(APPLICATION_NAME_DEFAULT) !isEmpty(APPLICATION_NAME_DEFAULT){ DEFINES += "APPLICATION_NAME_DEFAULT=$${APPLICATION_NAME_DEFAULT}" @@ -366,6 +371,7 @@ core_android { CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "-", "_") CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "armeabi_v7", "armv7") CORE_BUILDS_PLATFORM_PREFIX = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "armv7a", "armv7") + CORE_BUILDS_PLATFORM_PREFIX_DST = $$replace(CORE_BUILDS_PLATFORM_PREFIX, "android_", "") !isEmpty(OO_DESTDIR_BUILD_OVERRIDE) { isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_arm64_v8a):OO_DESTDIR_BUILD_OVERRIDE=$$OO_DESTDIR_BUILD_OVERRIDE/arm64-v8a diff --git a/DesktopEditor/cximage/raw/libdcr.h b/DesktopEditor/cximage/raw/libdcr.h index 0b828454aac..6d74732a87e 100644 --- a/DesktopEditor/cximage/raw/libdcr.h +++ b/DesktopEditor/cximage/raw/libdcr.h @@ -58,7 +58,7 @@ #ifdef __ANDROID__ #include -#if __ANDROID_API__ < 28 +#if __ANDROID_API__ < 22 static void swab(const char* __src, char* __dst, ssize_t __byte_count) { ssize_t len = __byte_count; diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index 01c6d1bc37d..7842fed0e8c 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -52,26 +52,33 @@ v8::Local CreateV8String(v8::Isolate* i, const char* str, const int& len = -1); v8::Local CreateV8String(v8::Isolate* i, const std::string& str); +#define ANDROID_LOGS #ifdef ANDROID_LOGS -#include +//#define ANDROID_LOGS_ALL_FUNCTIONS +#include +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "js", __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "js", __VA_ARGS__) #endif -#ifdef V8_OS_XP +#if 1 class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { + LOGW("allocate: %d\n", (int)length); void* ret = malloc(length); memset(ret, 0, length); return ret; } virtual void* AllocateUninitialized(size_t length) { + LOGW("allocate_uninitialized: %d\n", (int)length); return malloc(length); } virtual void Free(void* data, size_t length) { + LOGW("free: %d\n", (int)length); free(data); } }; @@ -114,7 +121,9 @@ class CV8Initializer v8::V8::InitializeICUDefaultLocation(sPrA.c_str()); v8::V8::InitializeExternalStartupData(sPrA.c_str()); #ifdef V8_VERSION_89_PLUS - m_platform = v8::platform::NewDefaultPlatform(); + //m_platform = v8::platform::NewDefaultPlatform(); + v8::V8::SetFlagsFromString("--single-threaded"); + m_platform = v8::platform::NewSingleThreadedDefaultPlatform(); v8::V8::InitializePlatform(m_platform.get()); #else m_platform = v8::platform::CreateDefaultPlatform(); @@ -481,9 +490,15 @@ namespace NSJSBase CInspectorPool::get().getInspector(V8IsolateOneArg).startAgent(false); #endif +#ifdef ANDROID_LOGS_ALL_FUNCTIONS + std::string sFuncName(name); + std::string sFunc = "[JS call_func: " + sFuncName + "]"; + LOGW(sFunc.c_str()); +#endif + LOGGER_START - v8::Local _name = CreateV8String(CV8Worker::GetCurrent(), name); + v8::Local _name = CreateV8String(CV8Worker::GetCurrent(), name); v8::Handle _func = value->Get(V8ContextFirstArg _name).ToLocalChecked(); CJSValueV8* _return = new CJSValueV8(); @@ -514,7 +529,12 @@ namespace NSJSBase LOGGER_LAP_NAME(name) - JSSmart _ret = _return; +#ifdef ANDROID_LOGS_ALL_FUNCTIONS + sFunc = "[JS call_func_end: " + sFuncName + "]"; + LOGW(sFunc.c_str()); +#endif + + JSSmart _ret = _return; return _ret; } @@ -804,10 +824,8 @@ namespace NSJSBase #endif #ifdef ANDROID_LOGS - LOGE("NSJSBase::CV8TryCatch::Check() - error:"); - LOGE(std::to_string(nLineNumber).c_str()); - LOGE(strCode.c_str()); - LOGE(strException.c_str()); + std::string sLog = "[JS (" + std::to_string(nLineNumber) + ")]: " + strCode + ", " + strException; + LOGE(sLog.c_str()); #endif return true; } diff --git a/DesktopEditor/graphics/Timer.cpp b/DesktopEditor/graphics/Timer.cpp index 832c5910098..a81bbdad8c8 100644 --- a/DesktopEditor/graphics/Timer.cpp +++ b/DesktopEditor/graphics/Timer.cpp @@ -39,8 +39,8 @@ namespace NSTimers { - // CLOCK_MONOTONIC defined ONLY since macOS 10.12!!! (crash on earlier version) - DWORD GetTickCount() + // CLOCK_MONOTONIC defined ONLY since macOS 10.12!!! (crash on earlier version) + DWORD GetTickCount() { #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) return ::GetTickCount(); @@ -49,55 +49,55 @@ namespace NSTimers struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); + return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); #else - //uint64_t nano = mach_absolute_time(); - //return nano / 1000000; - return getUptimeInMilliseconds(); + //uint64_t nano = mach_absolute_time(); + //return nano / 1000000; + return getUptimeInMilliseconds(); #endif #endif } - CTimer::CTimer() : NSThreads::CBaseThread() - { - m_dwInterval = 40; - m_bIsCOMNeed = FALSE; - } - CTimer::~CTimer() - { - } + CTimer::CTimer() : NSThreads::CBaseThread() + { + m_dwInterval = 40; + m_bIsCOMNeed = FALSE; + } + CTimer::~CTimer() + { + } - void CTimer::SetInterval(const DWORD& dwInterval) { m_dwInterval = dwInterval; } - void CTimer::SetCOMNeed(const INT& bIsCOM) { m_bIsCOMNeed = bIsCOM; } + void CTimer::SetInterval(const DWORD& dwInterval) { m_dwInterval = dwInterval; } + void CTimer::SetCOMNeed(const INT& bIsCOM) { m_bIsCOMNeed = bIsCOM; } - DWORD CTimer::ThreadProc() - { + DWORD CTimer::ThreadProc() + { #ifdef _CAN_USE_COM_THREADS - if (m_bIsCOMNeed) - CoInitialize(NULL); + if (m_bIsCOMNeed) + CoInitialize(NULL); #endif - DWORD m_startTime, m_curTime; - m_startTime = NSTimers::GetTickCount(); + DWORD m_startTime, m_curTime; + m_startTime = NSTimers::GetTickCount(); - while (m_bRunThread) - { - m_curTime = NSTimers::GetTickCount(); - while (m_curTime - m_startTime < m_dwInterval) - { - NSThreads::Sleep(10); - if (!m_bRunThread) - break; - m_curTime = NSTimers::GetTickCount(); - } + while (m_bRunThread) + { + m_curTime = NSTimers::GetTickCount(); + while (m_curTime - m_startTime < m_dwInterval) + { + NSThreads::Sleep(10); + if (!m_bRunThread) + break; + m_curTime = NSTimers::GetTickCount(); + } - m_startTime = NSTimers::GetTickCount(); - OnTimer(); - } + m_startTime = NSTimers::GetTickCount(); + OnTimer(); + } #ifdef _CAN_USE_COM_THREADS - if (m_bIsCOMNeed) - CoUninitialize(); + if (m_bIsCOMNeed) + CoUninitialize(); #endif - return 0; - } + return 0; + } } diff --git a/DesktopEditor/graphics/Timer.h b/DesktopEditor/graphics/Timer.h index 5e21823599f..62ef2ba626c 100644 --- a/DesktopEditor/graphics/Timer.h +++ b/DesktopEditor/graphics/Timer.h @@ -41,51 +41,51 @@ namespace NSTimers { - KERNEL_DECL DWORD GetTickCount(); + KERNEL_DECL DWORD GetTickCount(); - class KERNEL_DECL CTimer : public NSThreads::CBaseThread + class KERNEL_DECL CTimer : public NSThreads::CBaseThread { private: DWORD m_dwInterval; - INT m_bIsCOMNeed; + INT m_bIsCOMNeed; public: - CTimer(); - virtual ~CTimer(); + CTimer(); + virtual ~CTimer(); - void SetInterval(const DWORD& dwInterval); - void SetCOMNeed(const INT& bIsCOM); + void SetInterval(const DWORD& dwInterval); + void SetCOMNeed(const INT& bIsCOM); protected: - virtual DWORD ThreadProc(); + virtual DWORD ThreadProc(); virtual void OnTimer() = 0; }; - - inline static unsigned long getUptimeInMilliseconds() - { + + inline static unsigned long getUptimeInMilliseconds() + { #if defined(_IOS) || defined(_MAC) - const int64_t kOneMillion = 1000 * 1000; - static mach_timebase_info_data_t s_timebase_info; - - if (s_timebase_info.denom == 0) { - (void) mach_timebase_info(&s_timebase_info); - } - - // mach_absolute_time() returns billionth of seconds, - // so divide by one million to get milliseconds - return (unsigned long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom)); + const int64_t kOneMillion = 1000 * 1000; + static mach_timebase_info_data_t s_timebase_info; + + if (s_timebase_info.denom == 0) { + (void) mach_timebase_info(&s_timebase_info); + } + + // mach_absolute_time() returns billionth of seconds, + // so divide by one million to get milliseconds + return (unsigned long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom)); #endif - + #ifdef __ANDROID__ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - - return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + return (ts.tv_sec * 1000 + (DWORD)(ts.tv_nsec / 1000000)); #endif - - return 0; - } + + return 0; + } } #endif diff --git a/DesktopEditor/graphics/pro/raster.pri b/DesktopEditor/graphics/pro/raster.pri index feaaad1e2d8..f5e54810fc6 100644 --- a/DesktopEditor/graphics/pro/raster.pri +++ b/DesktopEditor/graphics/pro/raster.pri @@ -28,6 +28,10 @@ core_windows { LIBS += -lUser32 } +core_android { + QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types +} + INCLUDEPATH += \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \ $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg \ From 76e05db9da3f5dbb97726230aea8a6b06be225b1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 11 Mar 2024 13:54:41 +0600 Subject: [PATCH 399/794] Fix bug #66657 --- .../Format/Logic/Biff_structures/SyntaxPtg.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index fdd9920eecc..2511efa6bc9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -427,7 +427,7 @@ const bool SyntaxPtg::extract_PtgStr(std::wstring::const_iterator& first, std::w // static const bool SyntaxPtg::extract_PtgName(std::wstring::const_iterator& first, std::wstring::const_iterator last, unsigned int& out_num) { - static boost::wregex reg_name(L"^(\\w[\\w\\d.]*)([-+*/^&%<=>: ;),]|$)"); + static boost::wregex reg_name(L"^([\\w[:Unicode:]][\\w[:Unicode:]\\d.]*)([-+*/^&%<=>: ;),]|$)"); boost::match_results results; if(boost::regex_search(first, last, results, reg_name)) @@ -447,7 +447,7 @@ const bool SyntaxPtg::extract_PtgName(std::wstring::const_iterator& first, std:: // static const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std::wstring::const_iterator last, PtgList& ptgList, unsigned short ixti) { - static boost::wregex reg_table_name(L"^(\\w[\\w\\d.]*)\\["); //tableName '=SUM(tblName[Total])' + static boost::wregex reg_table_name(L"^([\\w[:Unicode:]][[:Unicode:]\\w\\d.]*)\\["); //tableName '=SUM(tblName[Total])' boost::match_results results; if (boost::regex_search(first, last, results, reg_table_name)) @@ -464,9 +464,9 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: ptgList.invalid = false; ptgList.nonresident = false; ptgList.ixti = ixti; - static boost::wregex reg_inside_table1(L"\\[#?[\\s\\w\\d.]+\\]"); - static boost::wregex reg_inside_table2(L"\\[#\\w[\\s\\w\\d.]*\\],\\[#\\w[\\s\\w\\d.]*\\]"); - static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[\\s\\w\\d.]+\\]"); + static boost::wregex reg_inside_table1(L"\\[#?[\\s\\w[:Unicode:]\\d.]+\\]"); + static boost::wregex reg_inside_table2(L"\\[#[\\w[:Unicode:]][\\s\\w[:Unicode:]\\d.]*\\],\\[#[\\w[:Unicode:]][[:Unicode:]\\s\\w\\d.]*\\]"); + static boost::wregex reg_inside_table3(L"^[,;:]?\\[#?[[:Unicode:]\\s\\w\\d.]+\\]"); static boost::wregex reg_inside_table4(L"\\[#?(\\[.+?\\]\\,)?(\\[.+?\\])?.+?\\]"); static boost::wregex reg_inside_table5(L"^[,;:]?\\[.+?\\]"); static boost::wregex reg_inside_table6(L"\\[\\]"); @@ -713,7 +713,7 @@ const bool SyntaxPtg::extract_PtgRef(std::wstring::const_iterator& first, std::w // static const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std::wstring::const_iterator last, unsigned short& ixti) { - static boost::wregex reg_sheets(L"^(\\w[\\w\\d.]*(:\\w[\\w\\d.]*)?)!"); + static boost::wregex reg_sheets(L"^([\\w[:Unicode:]][[:Unicode:]\\w\\d.]*(:[\\w[:Unicode:]][[:Unicode:]\\w\\d.]*)?)!"); static boost::wregex reg_quoted(L"^'((''|[^]['\\/*?])*)'!"); boost::match_results results; if (boost::regex_search(first, last, results, reg_sheets) || @@ -736,7 +736,7 @@ const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std:: // static const bool SyntaxPtg::extract_UndefinedName(std::wstring::const_iterator& first, std::wstring::const_iterator last) { - static boost::wregex reg_undef(L"^([\\w\\d.]+)([-+*/^&%<=>: ;),]|$)"); + static boost::wregex reg_undef(L"^([[:Unicode:]\\w\\d.]+)([-+*/^&%<=>: ;),]|$)"); boost::match_results results; if(boost::regex_search(first, last, results, reg_undef)) { From 320dcf8a0faf06f545546c49022b51e5b049b5d7 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 11 Mar 2024 18:25:03 +0500 Subject: [PATCH 400/794] Add odg file format conversion --- Common/OfficeFileFormatChecker2.cpp | 5 + Common/OfficeFileFormats.h | 1 + OdfFile/Common/odf_elements_type.h | 1 + OdfFile/Projects/Linux/OdfFormatLib.pro | 2 + OdfFile/Projects/Linux/odf_reader.cpp | 1 + OdfFile/Reader/Converter/ConvertOO2OOX.cpp | 1 + OdfFile/Reader/Format/odf_document_impl.cpp | 5 + OdfFile/Reader/Format/office_drawing.cpp | 160 ++++++++++++++++++++ OdfFile/Reader/Format/office_drawing.h | 79 ++++++++++ X2tConverter/src/cextracttools.cpp | 1 + 10 files changed, 256 insertions(+) create mode 100644 OdfFile/Reader/Format/office_drawing.cpp create mode 100644 OdfFile/Reader/Format/office_drawing.h diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 1fdb6b6f349..faea7b07e78 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -1084,6 +1084,7 @@ bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileNa const char *odtFormatLine = "application/vnd.oasis.opendocument.text"; const char *odsFormatLine = "application/vnd.oasis.opendocument.spreadsheet"; const char *odpFormatLine = "application/vnd.oasis.opendocument.presentation"; + const char* odgFormatLine = "application/vnd.oasis.opendocument.graphics"; const char *ottFormatLine = "application/vnd.oasis.opendocument.text-template"; const char *otsFormatLine = "application/vnd.oasis.opendocument.spreadsheet-template"; const char *otpFormatLine = "application/vnd.oasis.opendocument.presentation-template"; @@ -1134,6 +1135,10 @@ bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileNa { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; } + else if (NULL != strstr((char*)pBuffer, odgFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG; + } else if (NULL != strstr((char *)pBuffer, epubFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB; diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index 243abd1d896..fc98dc017a0 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -71,6 +71,7 @@ #define AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0009 #define AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000a #define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX_PACKAGE AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000b +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x000c #define AVS_OFFICESTUDIO_FILE_SPREADSHEET 0x0100 #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0001 diff --git a/OdfFile/Common/odf_elements_type.h b/OdfFile/Common/odf_elements_type.h index 79d4ea8c3af..f1032012248 100644 --- a/OdfFile/Common/odf_elements_type.h +++ b/OdfFile/Common/odf_elements_type.h @@ -574,6 +574,7 @@ enum ElementType typeOfficeScripts, typeOfficeScript, typeOfficePresentation, + typeOfficeDrawing, typeOfficeChart, typeOfficeEventListeners, diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index a2138f65f3b..34c9054d707 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -387,6 +387,7 @@ SOURCES += \ ../../Writer/Format/odp_page_state.cpp \ ../../Writer/Format/odp_slide_context.cpp \ ../../Writer/Format/office_presentation.cpp \ + ../../Writer/Format/office_drawing.cpp \ ../../Writer/Format/style_presentation.cpp \ ../../Writer/Format/odf_math_context.cpp \ ../../Writer/Format/math_elementaries.cpp \ @@ -594,6 +595,7 @@ HEADERS += \ ../../Reader/Format/office_elements_type.h \ ../../Reader/Format/office_event_listeners.h \ ../../Reader/Format/office_presentation.h \ + ../../Reader/Format/office_drawing.h \ ../../Reader/Format/office_scripts.h \ ../../Reader/Format/office_forms.h \ ../../Reader/Format/office_settings.h \ diff --git a/OdfFile/Projects/Linux/odf_reader.cpp b/OdfFile/Projects/Linux/odf_reader.cpp index ffb0063d209..3a465f4b4d6 100644 --- a/OdfFile/Projects/Linux/odf_reader.cpp +++ b/OdfFile/Projects/Linux/odf_reader.cpp @@ -62,6 +62,7 @@ #include "../../Reader/Format/office_elements_create.cpp" #include "../../Reader/Format/office_event_listeners.cpp" #include "../../Reader/Format/office_presentation.cpp" +#include "../../Reader/Format/office_drawing.cpp" #include "../../Reader/Format/office_scripts.cpp" #include "../../Reader/Format/office_forms.cpp" #include "../../Reader/Format/office_settings.cpp" diff --git a/OdfFile/Reader/Converter/ConvertOO2OOX.cpp b/OdfFile/Reader/Converter/ConvertOO2OOX.cpp index 4403d1d907f..d51c204dccd 100644 --- a/OdfFile/Reader/Converter/ConvertOO2OOX.cpp +++ b/OdfFile/Reader/Converter/ConvertOO2OOX.cpp @@ -120,6 +120,7 @@ _UINT32 ConvertODF2OOXml(const std::wstring & srcPath, const std::wstring & dstP break; case 3: case 6: + case 7: nResult = ConvertOdp2Pptx(inputOdf, dstPath, fontsPath); break; } diff --git a/OdfFile/Reader/Format/odf_document_impl.cpp b/OdfFile/Reader/Format/odf_document_impl.cpp index 953fc32f61a..3ed2f4a9b14 100644 --- a/OdfFile/Reader/Format/odf_document_impl.cpp +++ b/OdfFile/Reader/Format/odf_document_impl.cpp @@ -50,6 +50,7 @@ #include "office_text.h" #include "office_spreadsheet.h" #include "office_presentation.h" +#include "office_drawing.h" #include "office_chart.h" #include "office_annotation.h" #include "office_settings.h" @@ -540,6 +541,10 @@ int odf_document::Impl::GetMimetype(std::wstring value) { return 6; } + else if (std::wstring::npos != value.find(L"application/vnd.oasis.opendocument.graphics")) + { + return 7; + } return 0; } void odf_document::Impl::parse_manifests(office_element *element) diff --git a/OdfFile/Reader/Format/office_drawing.cpp b/OdfFile/Reader/Format/office_drawing.cpp new file mode 100644 index 00000000000..572e074a731 --- /dev/null +++ b/OdfFile/Reader/Format/office_drawing.cpp @@ -0,0 +1,160 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + + +#include "office_drawing.h" +#include "draw_page.h" + +#include +#include "odf_document.h" +#include "odfcontext.h" + +#include "serialize_elements.h" + +namespace cpdoccore { +namespace odf_reader { + +const wchar_t* office_drawing::ns = L"office"; +const wchar_t* office_drawing::name = L"drawing"; + +void office_drawing::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + if CP_CHECK_NAME(L"draw", L"page") + { + CP_CREATE_ELEMENT(pages_); + } + else if CP_CHECK_NAME(L"table", L"tracked-changes") + { + CP_CREATE_ELEMENT(tracked_changes_); + } + else if CP_CHECK_NAME(L"table", L"content-validations") + { + CP_CREATE_ELEMENT(content_validations_); + } + else if CP_CHECK_NAME(L"presentation", L"footer-decl") + { + CP_CREATE_ELEMENT(footer_decls_); + } + else if CP_CHECK_NAME(L"presentation", L"date-time-decl") + { + CP_CREATE_ELEMENT(date_time_decls_); + } + else if CP_CHECK_NAME(L"text", L"user-field-decls") + { + CP_CREATE_ELEMENT(user_fields_); + } + else if CP_CHECK_NAME(L"text", L"sequence-decls") + { + CP_CREATE_ELEMENT(sequences_); + } + else if CP_CHECK_NAME(L"text", L"variable-decls") + { + CP_CREATE_ELEMENT(variables_); + } +} + +void office_drawing::add_text(const std::wstring& Text) +{ +} + +void office_drawing::add_attributes(const xml::attributes_wc_ptr& Attributes) +{ +} + +void office_drawing::docx_convert(oox::docx_conversion_context& Context) +{ + Context.start_office_text(); + _CP_LOG << L"[info][docx] process pages (" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->docx_convert(Context); + } + Context.end_office_text(); +} + +void office_drawing::xlsx_convert(oox::xlsx_conversion_context& Context) +{ + Context.start_office_spreadsheet(this); + _CP_LOG << L"[info][xlsx] process pages (" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->xlsx_convert(Context); + } + Context.end_office_spreadsheet(); +} + +void office_drawing::pptx_convert(oox::pptx_conversion_context& Context) +{ + Context.start_office_presentation(); + + _CP_LOG << L"[info][pptx] process pages(" << pages_.size() << L" elmements)" << std::endl; + + for (size_t i = 0; i < footer_decls_.size(); i++) + { + presentation_footer_decl* style = dynamic_cast(footer_decls_[i].get()); + + if (!style) + continue; + + std::wstring style_name_ = L"footer:" + style->presentation_name_.get_value_or(L""); + Context.root()->odf_context().drawStyles().add(style_name_, footer_decls_[i]); + } + for (size_t i = 0; i < date_time_decls_.size(); i++) + { + presentation_date_time_decl* style = dynamic_cast(date_time_decls_[i].get()); + + if (!style) + continue; + + std::wstring style_name_ = L"datetime:" + style->presentation_name_.get_value_or(L""); + Context.root()->odf_context().drawStyles().add(style_name_, date_time_decls_[i]); + } + if (user_fields_) + user_fields_->pptx_convert(Context); + + if (variables_) + variables_->pptx_convert(Context); + + if (sequences_) + sequences_->pptx_convert(Context); + + for (size_t i = 0; i < pages_.size(); i++) + { + pages_[i]->pptx_convert(Context); + } + Context.end_office_presentation(); +} + +} +} diff --git a/OdfFile/Reader/Format/office_drawing.h b/OdfFile/Reader/Format/office_drawing.h new file mode 100644 index 00000000000..cb76f595b01 --- /dev/null +++ b/OdfFile/Reader/Format/office_drawing.h @@ -0,0 +1,79 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include + +#include "office_elements.h" +#include "office_elements_create.h" + +namespace cpdoccore { +namespace odf_reader { + +class office_drawing : public office_element_impl +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeOfficeDrawing; + CPDOCCORE_DEFINE_VISITABLE(); + + virtual void docx_convert(oox::docx_conversion_context& Context); + virtual void xlsx_convert(oox::xlsx_conversion_context& Context); + virtual void pptx_convert(oox::pptx_conversion_context& Context); + +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes); + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); + virtual void add_text(const std::wstring& Text); + +public: + + office_element_ptr tracked_changes_; + office_element_ptr content_validations_; + + office_element_ptr_array date_time_decls_; + office_element_ptr_array footer_decls_; + + office_element_ptr_array pages_; + + office_element_ptr user_fields_; + office_element_ptr variables_; + office_element_ptr sequences_; + +}; + +CP_REGISTER_OFFICE_ELEMENT2(office_drawing); + +} // namespace odf_reader +} // namespace cpdoccore diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index bf4144f9123..6f1c8108f8b 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -472,6 +472,7 @@ namespace NExtractTools case AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT: case AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS: case AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP: + case AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG: { if (0 == sExt2.compare(L".bin")) res = TCD_ODF2OOT_BIN; From e8a4dab0ea770f10a7815c103b7dfb5fb690bea1 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 11 Mar 2024 18:40:48 +0500 Subject: [PATCH 401/794] Add office_drawing file to visual studio project --- OdfFile/Projects/Windows/cpodf.vcxproj | 2 ++ OdfFile/Projects/Windows/cpodf.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index 9261997573f..5005311b91b 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -510,6 +510,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) @@ -747,6 +748,7 @@ + diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index 7ab9701d637..c254de81ba5 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -481,6 +481,9 @@ oox\pptx + + elements + @@ -934,5 +937,8 @@ oox\pptx + + elements + \ No newline at end of file From 5c52489394cf68ec3998c3498ccbd8d3e212ef38 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 11 Mar 2024 18:04:37 +0300 Subject: [PATCH 402/794] Fix function calling order --- DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js | 2 +- PdfFile/PdfReader.cpp | 3 +-- PdfFile/SrcReader/PdfAnnot.cpp | 8 ++++---- PdfFile/SrcReader/PdfAnnot.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 5f253963719..797fe711ce2 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1141,7 +1141,7 @@ if (nFontFlag & (1 << 5)) oFont["vertical"] = reader.readDouble(); if (nFontFlag & (1 << 6)) - oFont["actual"] = reader.readDouble(); + oFont["actual"] = reader.readString(); oFont["size"] = reader.readDouble(); oFont["color"] = []; oFont["color"].push(reader.readDouble2()); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 46dafed8bfa..26152eb05e4 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1535,8 +1535,7 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade else if (sType == "FreeText") { PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); - std::map mFreeText = pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); - m_mFonts.insert(mFreeText.begin(), mFreeText.end()); + pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); pAnnot = pFreeText; } else if (sType == "Line") diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 53e794b1f5c..6d4a0ced436 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2221,9 +2221,9 @@ std::vector CAnnotMarkup::ReadRC(const std::string& sR return arrRC; } -std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { - return SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); + SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); } std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, const std::vector& arrRC, int nTypeFonts) { @@ -2261,8 +2261,8 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec { if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && - (*arrFontList)[nIndex]->m_bBold == bBold && - (*arrFontList)[nIndex]->m_bItalic == bItalic) + (*arrFontList)[nIndex]->m_bBold == bBold && + (*arrFontList)[nIndex]->m_bItalic == bItalic) { bNew = false; break; diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index f28809dd6c9..3262785b7b5 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -343,8 +343,8 @@ class CAnnotMarkup : public CAnnot CFontData(const CFontData& oFont); }; + void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); static std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, const std::vector& arrRC, int nTypeFonts = 3); - std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); static std::vector ReadRC(const std::string& sRC); protected: CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); From db3d665f8cc04bc78bca5903ac93975bccf8adaf Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 11 Mar 2024 19:27:53 +0300 Subject: [PATCH 403/794] fix bug #66821 --- .../Converter/pptx_conversion_context.cpp | 1015 +++++++++-------- 1 file changed, 509 insertions(+), 506 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_conversion_context.cpp b/OdfFile/Reader/Converter/pptx_conversion_context.cpp index f857f0e1d08..49f975a0eb6 100644 --- a/OdfFile/Reader/Converter/pptx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/pptx_conversion_context.cpp @@ -53,675 +53,678 @@ namespace cpdoccore { } namespace oox { + namespace package + { + class pptx_document; + } - namespace package - { - class pptx_document; - } + pptx_conversion_context::pptx_conversion_context(odf_reader::odf_document* odfDocument) + :output_document_(NULL) + , odf_document_(odfDocument) + , pptx_text_context_(odf_document_->odf_context(), *this) + , pptx_table_context_(*this) + , pptx_comments_context_(comments_context_handle_) + , pptx_slide_context_(*this/*, pptx_text_context_*/) + , math_context_(odf_document_->odf_context().fontContainer(), true) + , last_idx_placeHolder(1) + , last_uniq_big_id(1) + { + } - pptx_conversion_context::pptx_conversion_context(odf_reader::odf_document* odfDocument) - :output_document_(NULL) - , odf_document_(odfDocument) - , pptx_text_context_(odf_document_->odf_context(), *this) - , pptx_table_context_(*this) - , pptx_comments_context_(comments_context_handle_) - , pptx_slide_context_(*this/*, pptx_text_context_*/) - , math_context_(odf_document_->odf_context().fontContainer(), true) - , last_idx_placeHolder(1) - , last_uniq_big_id(1) - { - } + pptx_conversion_context::~pptx_conversion_context() + { + } - pptx_conversion_context::~pptx_conversion_context() - { - } + void pptx_conversion_context::set_output_document(package::pptx_document* document) + { + output_document_ = document; + } - void pptx_conversion_context::set_output_document(package::pptx_document* document) - { - output_document_ = document; - } + void pptx_conversion_context::set_font_directory(std::wstring pathFonts) + { + pptx_slide_context_.get_mediaitems()->set_font_directory(pathFonts); + } + void pptx_conversion_context::add_page_name(const std::wstring& page_name) + { + page_names_.push_back(page_name); + } - void pptx_conversion_context::set_font_directory(std::wstring pathFonts) - { - pptx_slide_context_.get_mediaitems()->set_font_directory(pathFonts); - } -void pptx_conversion_context::add_page_name(const std::wstring& page_name) -{ - page_names_.push_back(page_name); -} + const std::vector& pptx_conversion_context::get_page_names() const + { + return page_names_; + } -const std::vector& pptx_conversion_context::get_page_names() const -{ - return page_names_; -} + void pptx_conversion_context::process_layouts() + { + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - void pptx_conversion_context::process_layouts() + get_text_context().set_process_layouts(true); + + //актуальные + for (size_t layout_index = 0; layout_index < layouts.content.size(); layout_index++) { - odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); + start_layout(layout_index); - get_text_context().set_process_layouts(true); + odf_reader::style_presentation_page_layout* layout = + root()->odf_context().pageLayoutContainer().presentation_page_layout_by_name(layouts.content[layout_index].layout_name); - //актуальные - for (size_t layout_index = 0; layout_index < layouts.content.size(); layout_index++) + if (layout) { - start_layout(layout_index); - - odf_reader::style_presentation_page_layout* layout = - root()->odf_context().pageLayoutContainer().presentation_page_layout_by_name(layouts.content[layout_index].layout_name); - - if (layout) - { - layout->pptx_convert(*this); - } - //нужно вытащить footers - odf_reader::style_master_page* master = - root()->odf_context().pageLayoutContainer().master_page_by_name(layouts.content[layout_index].master_name); + layout->pptx_convert(*this); + } + //нужно вытащить footers + odf_reader::style_master_page* master = + root()->odf_context().pageLayoutContainer().master_page_by_name(layouts.content[layout_index].master_name); - if (master) + if (master) + { + for (size_t i = 0; i < master->content_.size(); i++) { - for (size_t i = 0; i < master->content_.size(); i++) + odf_reader::draw_frame* frame = dynamic_cast(master->content_[i].get()); + if (frame) { - odf_reader::draw_frame* frame = dynamic_cast(master->content_[i].get()); - if (frame) + odf_types::common_presentation_attlist& common_presentation_attlist_ = frame->common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; + + if (common_presentation_attlist_.presentation_class_) { - odf_types::common_presentation_attlist& common_presentation_attlist_ = frame->common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; + odf_types::presentation_class::type type = common_presentation_attlist_.presentation_class_->get_type(); - if (common_presentation_attlist_.presentation_class_) + if (type == odf_types::presentation_class::footer || + type == odf_types::presentation_class::date_time || + type == odf_types::presentation_class::header || + type == odf_types::presentation_class::page_number) { - odf_types::presentation_class::type type = common_presentation_attlist_.presentation_class_->get_type(); - - if (type == odf_types::presentation_class::footer || - type == odf_types::presentation_class::date_time || - type == odf_types::presentation_class::header || - type == odf_types::presentation_class::page_number) - { - if (frame->idx_in_owner < 0) - frame->idx_in_owner = last_idx_placeHolder++; - - frame->pptx_convert_placeHolder(*this); - } + if (frame->idx_in_owner < 0) + frame->idx_in_owner = last_idx_placeHolder++; + + frame->pptx_convert_placeHolder(*this); } } } } - end_layout(); } - get_text_context().set_process_layouts(false); + end_layout(); } - void pptx_conversion_context::process_master_pages() - { - odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - - process_masters_ = true; - get_text_context().set_process_layouts(true); + get_text_context().set_process_layouts(false); + } + void pptx_conversion_context::process_master_pages() + { + odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - //берем только актуальные - odf_reader::office_element_ptr master_notes_; + process_masters_ = true; + get_text_context().set_process_layouts(true); - for (size_t master_index = 0; master_index < masters.content.size(); master_index++) - { - start_master(master_index); + //берем только актуальные + odf_reader::office_element_ptr master_notes_; - odf_reader::style_master_page* master = - root()->odf_context().pageLayoutContainer().master_page_by_name(masters.content[master_index].master_name); - - if (master) - { - master->pptx_convert(*this); + for (size_t master_index = 0; master_index < masters.content.size(); master_index++) + { + start_master(master_index); - if (!master_notes_ && master->presentation_notes_) - master_notes_ = master->presentation_notes_; - } + odf_reader::style_master_page* master = + root()->odf_context().pageLayoutContainer().master_page_by_name(masters.content[master_index].master_name); + if (master) + { + master->pptx_convert(*this); - end_master(); + if (!master_notes_ && master->presentation_notes_) + master_notes_ = master->presentation_notes_; } - if (master_notes_) - { - start_master_notes(); - master_notes_->pptx_convert(*this); - end_master_notes(); - } - process_masters_ = false; - get_text_context().set_process_layouts(false); + end_master(); } - void pptx_conversion_context::process_styles() + if (master_notes_) { - + start_master_notes(); + master_notes_->pptx_convert(*this); + end_master_notes(); } - void pptx_conversion_context::process_theme(std::wstring name) - { - int current = themes_.size() + 1; + process_masters_ = false; + get_text_context().set_process_layouts(false); - if (name.empty()) - { - name = L"User Theme: " + std::to_wstring(current); - } - start_theme(name); - // - pptx_serialize_clrScheme(current_theme().clrSchemeData()); - pptx_serialize_fmtScheme(current_theme().fmtSchemeData()); - pptx_serialize_fontScheme(current_theme().fontSchemeData()); - // - end_theme(); + } - } - void pptx_conversion_context::start_document() + void pptx_conversion_context::process_styles() + { + + } + void pptx_conversion_context::process_theme(std::wstring name) + { + int current = themes_.size() + 1; + + if (name.empty()) { - odf_reader::odf_read_context& odfContext = root()->odf_context(); - std::vector instances; + name = L"User Theme: " + std::to_wstring(current); + } + start_theme(name); + // + pptx_serialize_clrScheme(current_theme().clrSchemeData()); + pptx_serialize_fmtScheme(current_theme().fmtSchemeData()); + pptx_serialize_fontScheme(current_theme().fontSchemeData()); + // + end_theme(); - instances.push_back(odfContext.styleContainer().style_default_by_type(odf_types::style_family::Presentation)); - instances.push_back(odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::Presentation, false)); + } + void pptx_conversion_context::start_document() + { + odf_reader::odf_read_context& odfContext = root()->odf_context(); + std::vector instances; - odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); - odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances); + instances.push_back(odfContext.styleContainer().style_default_by_type(odf_types::style_family::Presentation)); + instances.push_back(odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::Presentation, false)); - process_masters_ = false; - } + odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); + odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances); - void pptx_conversion_context::end_document() + process_masters_ = false; + } + + void pptx_conversion_context::end_document() + { + for (size_t i = 0; i < slideMasters_.size(); i++) { - for (size_t i = 0; i < slideMasters_.size(); i++) - { - pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; + pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slideM->write_to(content->content()); - content->add_rels(slideM->Rels());//media & links rels + slideM->write_to(content->content()); + content->add_rels(slideM->Rels());//media & links rels - output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml + output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml - CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml + CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml + { + CP_XML_NODE(L"p:sldMasterId") { - CP_XML_NODE(L"p:sldMasterId") - { - CP_XML_ATTR(L"id", 0x80000000 + last_uniq_big_id++); - CP_XML_ATTR(L"r:id", slideM->rId()); - } + CP_XML_ATTR(L"id", 0x80000000 + last_uniq_big_id++); + CP_XML_ATTR(L"r:id", slideM->rId()); } } - if (!slideMasters_.empty()) - presentation_.slidesProperties() << slideMasters_[0]->Sizes().str(); + } + if (!slideMasters_.empty()) + presentation_.slidesProperties() << slideMasters_[0]->Sizes().str(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < slides_.size(); i++) - { - pptx_xml_slide_ptr& slide = slides_[i]; + //////////////////////////////////////////////////////////////////////////////////////////////////// + for (size_t i = 0; i < slides_.size(); i++) + { + pptx_xml_slide_ptr& slide = slides_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slide->write_to(content->content()); - content->add_rels(slide->Rels());//media & links rels + slide->write_to(content->content()); + content->add_rels(slide->Rels());//media & links rels - output_document_->get_ppt_files().add_slide(content);//slide.xml + output_document_->get_ppt_files().add_slide(content);//slide.xml - CP_XML_WRITER(presentation_.slidesData())//presentation.xml + CP_XML_WRITER(presentation_.slidesData())//presentation.xml + { + CP_XML_NODE(L"p:sldId") { - CP_XML_NODE(L"p:sldId") - { - CP_XML_ATTR(L"id", 0x100 + i); - CP_XML_ATTR(L"r:id", slide->rId()); - } + CP_XML_ATTR(L"id", 0x100 + i); + CP_XML_ATTR(L"r:id", slide->rId()); } } - //---------------------------------------------------------------------------------- - for (size_t i = 0; i < slideLayouts_.size(); i++) - { - pptx_xml_slideLayout_ptr& slideL = slideLayouts_[i]; + } + //---------------------------------------------------------------------------------- + for (size_t i = 0; i < slideLayouts_.size(); i++) + { + pptx_xml_slideLayout_ptr& slideL = slideLayouts_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slideL->write_to(content->content()); - content->add_rels(slideL->Rels());//media & links rels + slideL->write_to(content->content()); + content->add_rels(slideL->Rels());//media & links rels - output_document_->get_ppt_files().add_slideLayout(content);//slideMaster.xml - } - //---------------------------------------------------------------------------------- - for (size_t i = 0; i < notes_.size(); i++) - { - pptx_xml_slideNotes_ptr& slideN = notes_[i]; + output_document_->get_ppt_files().add_slideLayout(content);//slideMaster.xml + } + //---------------------------------------------------------------------------------- + for (size_t i = 0; i < notes_.size(); i++) + { + pptx_xml_slideNotes_ptr& slideN = notes_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slideN->write_to(content->content()); - content->add_rels(slideN->Rels());//media & links rels + slideN->write_to(content->content()); + content->add_rels(slideN->Rels());//media & links rels - output_document_->get_ppt_files().add_notes(content); - } - if (slideNotesMaster_) - { - package::slide_content_ptr content = package::slide_content::create(); + output_document_->get_ppt_files().add_notes(content); + } + if (slideNotesMaster_) + { + package::slide_content_ptr content = package::slide_content::create(); - slideNotesMaster_->write_to(content->content()); - content->add_rels(slideNotesMaster_->Rels());//media & links rels + slideNotesMaster_->write_to(content->content()); + content->add_rels(slideNotesMaster_->Rels());//media & links rels - output_document_->get_ppt_files().add_notesMaster(content); + output_document_->get_ppt_files().add_notesMaster(content); - CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml + CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml + { + CP_XML_NODE(L"p:notesMasterId") { - CP_XML_NODE(L"p:notesMasterId") - { - CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); - } + CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); } } - //else - pptx_serialize_size(current_presentation().slidesNotesProperties(), 6858000, 9144000, L"p:notesSz"); + } + //else + pptx_serialize_size(current_presentation().slidesNotesProperties(), 6858000, 9144000, L"p:notesSz"); - //////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < charts_.size(); i++) - { - package::chart_content_ptr content = package::chart_content::create(); + for (size_t i = 0; i < charts_.size(); i++) + { + package::chart_content_ptr content = package::chart_content::create(); - charts_[i]->serialize(content->content()); - charts_[i]->dump_rels(content->get_rel_file()->get_rels()); + charts_[i]->serialize(content->content()); + charts_[i]->dump_rels(content->get_rel_file()->get_rels()); - output_document_->get_ppt_files().add_charts(content); + output_document_->get_ppt_files().add_charts(content); - } - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < themes_.size(); i++) - { - output_document_->get_ppt_files().add_theme(themes_[i]); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + for (size_t i = 0; i < themes_.size(); i++) + { + output_document_->get_ppt_files().add_theme(themes_[i]); - } - package::ppt_comments_files_ptr comments = package::ppt_comments_files::create(comments_context_handle_.content()); + } + package::ppt_comments_files_ptr comments = package::ppt_comments_files::create(comments_context_handle_.content()); - output_document_->get_ppt_files().set_presentation(presentation_); - output_document_->get_ppt_files().set_comments(comments); - output_document_->get_ppt_files().set_authors_comments(authors_comments_); - output_document_->get_ppt_files().set_media(get_mediaitems()); + output_document_->get_ppt_files().set_presentation(presentation_); + output_document_->get_ppt_files().set_comments(comments); + output_document_->get_ppt_files().set_authors_comments(authors_comments_); + output_document_->get_ppt_files().set_media(get_mediaitems()); - output_document_->get_content_types_file().set_media(get_mediaitems()); - } + output_document_->get_content_types_file().set_media(get_mediaitems()); + } - void pptx_conversion_context::start_body() - { + void pptx_conversion_context::start_body() + { - } + } - void pptx_conversion_context::end_body() + void pptx_conversion_context::end_body() + { + } + pptx_xml_slideNotesMaster& pptx_conversion_context::current_notesMaster() + { + if (slideNotesMaster_) { + return *slideNotesMaster_; } - pptx_xml_slideNotesMaster& pptx_conversion_context::current_notesMaster() + else { - if (slideNotesMaster_) - { - return *slideNotesMaster_; - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideNotes& pptx_conversion_context::current_notes() + } + pptx_xml_slideNotes& pptx_conversion_context::current_notes() + { + if (!notes_.empty()) { - if (!notes_.empty()) - { - return *notes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *notes_.back().get(); } - pptx_xml_slide& pptx_conversion_context::current_slide() + else { - if (!slides_.empty()) - { - return *slides_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideLayout& pptx_conversion_context::current_layout() + } + pptx_xml_slide& pptx_conversion_context::current_slide() + { + if (!slides_.empty()) { - if (!slideLayouts_.empty()) - { - return *slideLayouts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *slides_.back().get(); } - pptx_xml_theme& pptx_conversion_context::current_theme() + else { - if (!themes_.empty()) - { - return *themes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_presentation& pptx_conversion_context::current_presentation() + } + pptx_xml_slideLayout& pptx_conversion_context::current_layout() + { + if (!slideLayouts_.empty()) { - return presentation_; + return *slideLayouts_.back().get(); } - - oox_chart_context& pptx_conversion_context::current_chart() + else { - if (!charts_.empty()) - { - return *charts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideMaster& pptx_conversion_context::current_master() + } + pptx_xml_theme& pptx_conversion_context::current_theme() + { + if (!themes_.empty()) { - if (!slideMasters_.empty()) - { - return *slideMasters_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *themes_.back().get(); } - void pptx_conversion_context::create_new_slide(std::wstring const& name) + else { - pptx_xml_slide_ptr s = pptx_xml_slide::create(name, slides_.size() + 1); - slides_.push_back(s); + throw std::runtime_error("internal error"); } - void pptx_conversion_context::create_new_slideNotes() + } + pptx_xml_presentation& pptx_conversion_context::current_presentation() + { + return presentation_; + } + + oox_chart_context& pptx_conversion_context::current_chart() + { + if (!charts_.empty()) { - pptx_xml_slideNotes_ptr s = pptx_xml_slideNotes::create(notes_.size() + 1); - notes_.push_back(s); + return *charts_.back().get(); } - void pptx_conversion_context::create_new_slideNotesMaster() + else { - slideNotesMaster_ = pptx_xml_slideNotesMaster::create(); + throw std::runtime_error("internal error"); } - void pptx_conversion_context::create_new_slideLayout(int id) + } + pptx_xml_slideMaster& pptx_conversion_context::current_master() + { + if (!slideMasters_.empty()) { - pptx_xml_slideLayout_ptr s = pptx_xml_slideLayout::create(id); - slideLayouts_.push_back(s); + return *slideMasters_.back().get(); } - void pptx_conversion_context::create_new_slideMaster(int id) + else { - pptx_xml_slideMaster_ptr s = pptx_xml_slideMaster::create(id); - slideMasters_.push_back(s); + throw std::runtime_error("internal error"); } - bool pptx_conversion_context::start_page(const std::wstring& pageName, const std::wstring& pageStyleName, - const std::wstring& pageLayoutName, - const std::wstring& pageMasterName) - { - create_new_slide(pageName); - get_slide_context().start_slide();//pageName, pageStyleName); - get_slide_context().get_animation_context().clear(); + } + void pptx_conversion_context::create_new_slide(std::wstring const& name) + { + pptx_xml_slide_ptr s = pptx_xml_slide::create(name, slides_.size() + 1); + slides_.push_back(s); + } + void pptx_conversion_context::create_new_slideNotes() + { + pptx_xml_slideNotes_ptr s = pptx_xml_slideNotes::create(notes_.size() + 1); + notes_.push_back(s); + } + void pptx_conversion_context::create_new_slideNotesMaster() + { + slideNotesMaster_ = pptx_xml_slideNotesMaster::create(); + } + void pptx_conversion_context::create_new_slideLayout(int id) + { + pptx_xml_slideLayout_ptr s = pptx_xml_slideLayout::create(id); + slideLayouts_.push_back(s); + } + void pptx_conversion_context::create_new_slideMaster(int id) + { + pptx_xml_slideMaster_ptr s = pptx_xml_slideMaster::create(id); + slideMasters_.push_back(s); + } + bool pptx_conversion_context::start_page(const std::wstring& pageName, const std::wstring& pageStyleName, + const std::wstring& pageLayoutName, + const std::wstring& pageMasterName) + { + create_new_slide(pageName); + get_slide_context().start_slide();//pageName, pageStyleName); + get_slide_context().get_animation_context().clear(); - current_master_page_name_ = pageMasterName; - current_layout_page_name_ = pageLayoutName; + current_master_page_name_ = pageMasterName; + current_layout_page_name_ = pageLayoutName; - //const std::wstring masterPageNameLayout = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(current_master_page_name_); + //const std::wstring masterPageNameLayout = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(current_master_page_name_); - std::pair layout_id = - root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName, pageMasterName); + std::pair layout_id = + root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName, pageMasterName); - current_slide().Rels().add(relationship(layout_id.second, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout", - std::wstring(L"../slideLayouts/slideLayout") + std::to_wstring(layout_id.first) + L".xml")); + current_slide().Rels().add(relationship(layout_id.second, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout", + std::wstring(L"../slideLayouts/slideLayout") + std::to_wstring(layout_id.first) + L".xml")); - return true; - } + return true; + } - bool pptx_conversion_context::start_layout(int layout_index) + bool pptx_conversion_context::start_layout(int layout_index) + { + if (layout_index >= 0) { - if (layout_index >= 0) - { - odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - - create_new_slideLayout(layouts.content[layout_index].Id); - - get_slide_context().start_slide();//layouts.content[layout_index].layout_name, L"");//????? + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - current_master_page_name_ = layouts.content[layout_index].master_name; - current_layout_page_name_ = L""; + create_new_slideLayout(layouts.content[layout_index].Id); - std::pair master_id = //std::pair(1, L"smId1"); - root()->odf_context().styleContainer().presentation_masters().add_or_find(layouts.content[layout_index].master_name); + get_slide_context().start_slide();//layouts.content[layout_index].layout_name, L"");//????? - root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name, layouts.content[layout_index]); + current_master_page_name_ = layouts.content[layout_index].master_name; + current_layout_page_name_ = L""; - current_layout().Rels().add(relationship(L"smId1"/*master_id.second*/, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", - std::wstring(L"../slideMasters/slideMaster") + std::to_wstring(master_id.first) + L".xml")); + std::pair master_id = //std::pair(1, L"smId1"); + root()->odf_context().styleContainer().presentation_masters().add_or_find(layouts.content[layout_index].master_name); - // - } - else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) - { - } + root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name, layouts.content[layout_index]); - //layout type - - // - //1375 - //1376 - //1377 - //1378 - //1379 - //1380 - //1381 - //1382 - //1383 - //1384 - //1385 - //1386 - //1387 - //1388 - //1389 - //1390 - //1391 - //1392 - //1393 - //1394 - //1395 - //1396 - //1397 - //1398 - //1399 - //1400 - //1401 - //1402 - //1403 - //1404 - //1405 ---------------------------------- !!!!!!!!!!!!! - //1406 - //1407 - //1408 - //1409 - - return true; - } - bool pptx_conversion_context::start_master(int master_index) - { - odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - - create_new_slideMaster(masters.content[master_index].Id); - - get_slide_context().start_slide(); - - current_master_page_name_ = L""; - current_layout_page_name_ = L""; + current_layout().Rels().add(relationship(L"smId1"/*master_id.second*/, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster", + std::wstring(L"../slideMasters/slideMaster") + std::to_wstring(master_id.first) + L".xml")); - process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами - current_master().add_theme(current_theme().id(), L"tId1"); + // + } + else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) + { + } + + //layout type + + // + //1375 + //1376 + //1377 + //1378 + //1379 + //1380 + //1381 + //1382 + //1383 + //1384 + //1385 + //1386 + //1387 + //1388 + //1389 + //1390 + //1391 + //1392 + //1393 + //1394 + //1395 + //1396 + //1397 + //1398 + //1399 + //1400 + //1401 + //1402 + //1403 + //1404 + //1405 ---------------------------------- !!!!!!!!!!!!! + //1406 + //1407 + //1408 + //1409 + + return true; + } + bool pptx_conversion_context::start_master(int master_index) + { + odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - for (size_t i = 0; i < masters.content[master_index].layouts.size(); i++) - { - current_master().add_layout(masters.content[master_index].layouts[i].Id, masters.content[master_index].layouts[i].rId, 0x80000000 + last_uniq_big_id++); - } + create_new_slideMaster(masters.content[master_index].Id); - //---------------------------------------------------------------------------------- - //размеры страниц в презентации - const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); + get_slide_context().start_slide(); - odf_reader::page_layout_instance* pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); + current_master_page_name_ = L""; + current_layout_page_name_ = L""; - if (pages_layouts) - pages_layouts->pptx_serialize(current_master().Sizes(), *this); + process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами + current_master().add_theme(current_theme().id(), L"tId1"); - return true; - } - void pptx_conversion_context::end_page() + for (size_t i = 0; i < masters.content[master_index].layouts.size(); i++) { - if (!get_comments_context().empty()) - { - std::wstringstream strm; - get_comments_context().serialize(strm); + current_master().add_layout(masters.content[master_index].layouts[i].Id, masters.content[master_index].layouts[i].rId, 0x80000000 + last_uniq_big_id++); + } - const std::pair commentsName = - comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments()); + //---------------------------------------------------------------------------------- + //размеры страниц в презентации + const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); - get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); - } + odf_reader::page_layout_instance* pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); - get_slide_context().serialize_background(current_slide().Background()); - get_slide_context().serialize_objects(current_slide().Data()); - get_slide_context().serialize_animations(current_slide().Timing()); + if (pages_layouts) + pages_layouts->pptx_serialize(current_master().Sizes(), *this); - { - // NOTE: При использовании operator<< потока буст пушит туда лишний пробел перед значением. - // С этим пробелом наш редактор onlyoffice на распознает значение. - // Example: - // ppt_y - // ppt_y - // TODO: Figure out how to push value without redundant space character - current_slide().remove_timing_redundant_space(); - } + return true; + } + void pptx_conversion_context::end_page() + { + if (!get_comments_context().empty()) + { + std::wstringstream strm; + get_comments_context().serialize(strm); - get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... + const std::pair commentsName = + comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments()); - get_slide_context().end_slide(); + get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); } - bool pptx_conversion_context::start_page_notes() - { - create_new_slideNotes(); - current_slide().Rels().add(relationship(notes_.back()->rId(), L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", - L"../notesSlides/notesSlide" + std::to_wstring(notes_.size()) + L".xml")); + get_slide_context().serialize_background(current_slide().Background()); + get_slide_context().serialize_objects(current_slide().Data()); + get_slide_context().serialize_animations(current_slide().Timing()); - get_slide_context().start_slide(); + { + // NOTE: При использовании operator<< потока буст пушит туда лишний пробел перед значением. + // С этим пробелом наш редактор onlyoffice на распознает значение. + // Example: + // ppt_y + // ppt_y + // TODO: Figure out how to push value without redundant space character + current_slide().remove_timing_redundant_space(); + } - current_notes().Rels().add(relationship(L"nId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", - L"../slides/slide" + std::to_wstring(slides_.size()) + L".xml")); + get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... - return true; - } + get_slide_context().end_slide(); + } + bool pptx_conversion_context::start_page_notes() + { + create_new_slideNotes(); - void pptx_conversion_context::end_page_notes() - { - get_slide_context().serialize_background(current_notes().Background()); - get_slide_context().serialize_objects(current_notes().Data()); + current_slide().Rels().add(relationship(notes_.back()->rId(), L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", + L"../notesSlides/notesSlide" + std::to_wstring(notes_.size()) + L".xml")); - get_slide_context().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... + get_slide_context().start_slide(); - get_slide_context().end_slide(); - } - bool pptx_conversion_context::start_master_notes() - { - create_new_slideNotesMaster(); + current_notes().Rels().add(relationship(L"nId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", + L"../slides/slide" + std::to_wstring(slides_.size()) + L".xml")); - get_slide_context().start_slide(); + return true; + } - process_theme(L"");//add default theme - одинаковые но под разными именами - current_notesMaster().add_theme(current_theme().id(), L"tId1"); + void pptx_conversion_context::end_page_notes() + { + get_slide_context().serialize_background(current_notes().Background()); + get_slide_context().serialize_objects(current_notes().Data()); - get_slide_context().start_slide(); - return true; - } + get_slide_context().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... - void pptx_conversion_context::end_master_notes() - { - get_slide_context().serialize_background(current_notesMaster().Background()); - get_slide_context().serialize_objects(current_notesMaster().Data()); + get_slide_context().end_slide(); + } + bool pptx_conversion_context::start_master_notes() + { + create_new_slideNotesMaster(); - get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... + get_slide_context().start_slide(); - get_slide_context().end_slide(); + process_theme(L"");//add default theme - одинаковые но под разными именами + current_notesMaster().add_theme(current_theme().id(), L"tId1"); - for (size_t i = 0; i < notes_.size(); i++) - { - notes_[i]->Rels().add(relationship(L"nmId1", - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", - L"../notesMasters/notesMaster1.xml")); - } - } - void pptx_conversion_context::end_layout() - { - get_slide_context().serialize_objects(current_layout().Data()); + get_slide_context().start_slide(); + return true; + } - get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... + void pptx_conversion_context::end_master_notes() + { + get_slide_context().serialize_background(current_notesMaster().Background()); + get_slide_context().serialize_objects(current_notesMaster().Data()); - get_slide_context().end_slide(); - } + get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... - std::pair pptx_conversion_context::add_author_comments(std::wstring author) - { - if (!authors_comments_) - { - authors_comments_ = pptx_xml_authors_comments::create(); - if (!authors_comments_)return std::pair(-1, -1); - } + get_slide_context().end_slide(); - return authors_comments_->add_or_find(author); + for (size_t i = 0; i < notes_.size(); i++) + { + notes_[i]->Rels().add(relationship(L"nmId1", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster", + L"../notesMasters/notesMaster1.xml")); } + } + void pptx_conversion_context::end_layout() + { + get_slide_context().process_drawings(); - void pptx_conversion_context::end_master() - { - get_slide_context().serialize_background(current_master().Background(), true); - get_slide_context().serialize_objects(current_master().Data()); - get_slide_context().serialize_HeaderFooter(current_master().DataExtra()); + get_slide_context().serialize_objects(current_layout().Data()); - get_slide_context().dump_rels(current_master().Rels());//hyperlinks, mediaitems, ... + get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... - get_slide_context().end_slide(); - } - void pptx_conversion_context::start_theme(std::wstring& name) - { - themes_.push_back(pptx_xml_theme::create(name, themes_.size() + 1)); - } - void pptx_conversion_context::end_theme() - { - } - void pptx_conversion_context::start_office_presentation() - { - } + get_slide_context().end_slide(); + } - void pptx_conversion_context::end_office_presentation() + std::pair pptx_conversion_context::add_author_comments(std::wstring author) + { + if (!authors_comments_) { + authors_comments_ = pptx_xml_authors_comments::create(); + if (!authors_comments_)return std::pair(-1, -1); } - void pptx_conversion_context::start_chart(std::wstring name) - { - charts_.push_back(oox_chart_context_ptr(new oox_chart_context(get_mediaitems(), name))); - //добавляем новую форму для диаграммы - //в ней будет информационная часть - и она пишется каждый раз в свою xml (их - по числу диаграмм) - //этот контекст нужно передавать в файл - } - void pptx_conversion_context::end_chart() - { - //current_chart().set_drawing_link(current_sheet().get_drawing_link()); - //излишняя инфа - } - void pptx_conversion_context::add_jsaProject(const std::string& content) - { - if (content.empty()) return; + return authors_comments_->add_or_find(author); + } - output_document_->get_ppt_files().add_jsaProject(content); - output_document_->get_content_types_file().add_or_find_default(L"bin"); - } + void pptx_conversion_context::end_master() + { + get_slide_context().process_drawings(); + + get_slide_context().serialize_background(current_master().Background(), true); + get_slide_context().serialize_objects(current_master().Data()); + get_slide_context().serialize_HeaderFooter(current_master().DataExtra()); + + get_slide_context().dump_rels(current_master().Rels());//hyperlinks, mediaitems, ... + + get_slide_context().end_slide(); + } + void pptx_conversion_context::start_theme(std::wstring& name) + { + themes_.push_back(pptx_xml_theme::create(name, themes_.size() + 1)); + } + void pptx_conversion_context::end_theme() + { + } + void pptx_conversion_context::start_office_presentation() + { + } + + void pptx_conversion_context::end_office_presentation() + { + } + void pptx_conversion_context::start_chart(std::wstring name) + { + charts_.push_back(oox_chart_context_ptr(new oox_chart_context(get_mediaitems(), name))); + //добавляем новую форму для диаграммы + //в ней будет информационная часть - и она пишется каждый раз в свою xml (их - по числу диаграмм) + //этот контекст нужно передавать в файл + + } + void pptx_conversion_context::end_chart() + { + //current_chart().set_drawing_link(current_sheet().get_drawing_link()); + //излишняя инфа + } + void pptx_conversion_context::add_jsaProject(const std::string& content) + { + if (content.empty()) return; + + output_document_->get_ppt_files().add_jsaProject(content); + output_document_->get_content_types_file().add_or_find_default(L"bin"); + } } } From 69a71d78ed98d29e76005da9b5c11782dd34fb2f Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 12 Mar 2024 01:33:24 +0300 Subject: [PATCH 404/794] [x2t] For bug 66819 --- X2tConverter/src/ASCConverters.cpp | 8 +++----- X2tConverter/src/lib/csv.h | 3 +++ X2tConverter/src/lib/html.h | 20 +++++++++++++++++--- X2tConverter/src/lib/xlsx.h | 14 +++++++++++++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 3e1e861c082..613b2605ef9 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -536,7 +536,6 @@ namespace NExtractTools } else { - std::wstring sDocxFile; std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); NSDirectory::CreateDirectory(sDocxDir); @@ -544,14 +543,13 @@ namespace NExtractTools AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatFrom) { - sDocxFile = sFrom; - convertParams.m_sTempParamOOXMLFile = sDocxFile; + convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) { params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sDocxFile, params, convertParams); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sDocxFile, sDocxDir); + nRes = zip2dir(convertParams.m_sTempParamOOXMLFile, sDocxDir); if (false == SUCCEEDED_X2T(nRes)) { diff --git a/X2tConverter/src/lib/csv.h b/X2tConverter/src/lib/csv.h index cd01472e477..0ce635462e7 100644 --- a/X2tConverter/src/lib/csv.h +++ b/X2tConverter/src/lib/csv.h @@ -136,6 +136,9 @@ namespace NExtractTools nRes = oCXlsxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sMediaPath, sEmbedPath); } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); return nRes; } diff --git a/X2tConverter/src/lib/html.h b/X2tConverter/src/lib/html.h index 1b0129f594e..2a9b8d7aa78 100644 --- a/X2tConverter/src/lib/html.h +++ b/X2tConverter/src/lib/html.h @@ -152,7 +152,17 @@ namespace NExtractTools // doct_bin => html _UINT32 doct_bin2html_internal(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); + _UINT32 nRes = 0; + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + std::wstring sFileFromDir = NSDirectory::GetFolderPath(sTargetBin); std::wstring sImagesDirectory = combinePath(sFileFromDir, L"media"); std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); if (!NSDirectory::Exists(sImagesDirectory)) @@ -161,17 +171,21 @@ namespace NExtractTools NSDoctRenderer::CDoctrenderer oDoctRenderer(NULL != params.m_sAllFontsPath ? *params.m_sAllFontsPath : L""); std::wstring sXml = getDoctXml(NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, NSDoctRenderer::DoctRendererFormat::FormatFile::HTML, - sFrom, sHtmlFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); + sTargetBin, sHtmlFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); std::wstring sResult; oDoctRenderer.Execute(sXml, sResult); + + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); if (sResult.find(L"error") != std::wstring::npos) { std::wcerr << L"DoctRenderer:" << sResult << std::endl; return AVS_FILEUTILS_ERROR_CONVERT; } - return 0; + return nRes; } // doct_bin -> epub diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index fdd8a159e7d..42d38762447 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -177,16 +177,28 @@ namespace NExtractTools _UINT32 nRes = 0; + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::XLST, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + std::wstring sTempUnpackedXLSB = convertParams.m_sTempResultOOXMLDirectory; convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSX; - nRes = xlst_bin2xlsx_dir(sFrom, sTempUnpackedXLSX, params, convertParams); + nRes = xlst_bin2xlsx_dir(sTargetBin, sTempUnpackedXLSX, params, convertParams); if (SUCCEEDED_X2T(nRes)) { convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSB; nRes = xlsx_dir2xlsb_dir(sTempUnpackedXLSX, sTempUnpackedXLSB, params, convertParams); } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); return nRes; } _UINT32 xlst_bin2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) From 8a9e5ad2671fdc167ab047e6eed0b1d74148d2fc Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 12 Mar 2024 10:46:05 +0300 Subject: [PATCH 405/794] Fix bugs in html to ooxml conversion --- .../3dParty/html/css/src/CCompiledStyle.cpp | 14 ++++--- .../3dParty/html/css/src/StyleProperties.cpp | 19 +++++++-- Common/3dParty/html/css/src/StyleProperties.h | 2 + .../html/css/src/xhtml/CDocumentStyle.cpp | 2 + .../html/css/src/xhtml/CXmlElement.cpp | 1 + Common/3dParty/html/htmltoxhtml.h | 7 ++++ HtmlFile2/htmlfile2.cpp | 39 +++++++++++-------- 7 files changed, 59 insertions(+), 25 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index b07f5cac784..a3f6e8d68ee 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -21,11 +21,11 @@ namespace NSCSS CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point) {} - CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : - m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), - m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), - m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), - m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){} + CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) : + m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), + m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), + m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), + m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){} CCompiledStyle::~CCompiledStyle() { @@ -176,6 +176,7 @@ namespace NSCSS break; } CASE(L"margin-top"): + CASE(L"topmargin"): { if (bIsThereBorder) break; @@ -186,6 +187,7 @@ namespace NSCSS } CASE(L"margin-right"): CASE(L"margin-block-end"): + CASE(L"rightmargin"): { if (bIsThereBorder) break; @@ -195,6 +197,7 @@ namespace NSCSS break; } CASE(L"margin-bottom"): + CASE(L"bottommargin"): { if (bIsThereBorder) break; @@ -205,6 +208,7 @@ namespace NSCSS } CASE(L"margin-left"): CASE(L"margin-block-start"): + CASE(L"leftmargin"): { if (bIsThereBorder) break; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 16cb254e618..69128e1e2ac 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1423,7 +1423,12 @@ namespace NSCSS bool CBorderSide::Empty() const { - return m_oWidth.Empty() || m_oWidth.Zero(); + return m_oWidth.Empty(); + } + + bool CBorderSide::Zero() const + { + return m_oWidth.Zero(); } CBorderSide &CBorderSide::operator+=(const CBorderSide &oBorderSide) @@ -1622,6 +1627,12 @@ namespace NSCSS m_oRight.Empty() && m_oBottom.Empty(); } + bool CBorder::Zero() const + { + return m_oLeft.Zero() && m_oTop.Zero() && + m_oRight.Zero() && m_oBottom.Zero(); + } + bool CBorder::EqualSides() const { return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; @@ -1654,6 +1665,9 @@ namespace NSCSS CBorder &CBorder::operator+=(const CBorder &oBorder) { + if (oBorder.Empty()) + return *this; + m_oLeft = oBorder.m_oLeft; m_oTop = oBorder.m_oTop; m_oRight = oBorder.m_oRight; @@ -2200,8 +2214,7 @@ namespace NSCSS void CFont::Clear() { - m_oSize = CDigit(24., 0); - + m_oSize .Clear(); m_oLineHeight.Clear(); m_oFamily .Clear(); m_oStretch .Clear(); diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 909a184be73..5ddef84aa3c 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -439,6 +439,7 @@ namespace NSCSS const CColor& GetColor() const; bool Empty() const; + bool Zero() const; CBorderSide& operator+=(const CBorderSide& oBorderSide); bool operator==(const CBorderSide& oBorderSide) const; @@ -499,6 +500,7 @@ namespace NSCSS void Unblock(); bool Empty() const; + bool Zero() const; bool EqualSides() const; const CEnum& GetCollapse() const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index c2e9cd797f1..957f1983916 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -74,6 +74,8 @@ namespace NSCSS void CDocumentStyle::CombineStandardStyles(const std::vector& arStandartedStyles, CXmlElement& oElement) { + oElement.AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); + if (arStandartedStyles.empty()) return; diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 68689d3be29..469d4dc6da1 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -233,6 +233,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"99"); AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"24"); AddPropertiesInR(CSSProperties::RunnerProperties::R_Color, L"0000FF"); AddPropertiesInR(CSSProperties::RunnerProperties::R_U, L"single"); } diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 41f3ab630da..f3cfabda279 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -37,6 +37,13 @@ static void replace_all(std::string& s, const std::string& s1, const std::string static std::wstring htmlToXhtml(std::string& sFileContent) { + // Избавляемся от лишних символов до <... + boost::regex oRegex("<[a-zA-Z]"); + boost::match_results oResult; + + if (boost::regex_search(sFileContent, oResult, oRegex)) + sFileContent.erase(0, oResult.position()); + // Избавление от size_t posA = sFileContent.find("& arSelectors) { - m_bWasSpace = false; + m_bWasSpace = true; if (!m_bInP) return; @@ -1403,7 +1403,7 @@ class CHtmlFile2_Private oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); + oXml->WriteString(L"\"/>"); j += stoi(sCol); it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); @@ -1445,7 +1445,7 @@ class CHtmlFile2_Private if (!oStyle.m_oBorder.Empty()) wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; - else if (bTableHasBorderAttribute) + else if (bTableHasBorderAttribute && !oStyle.m_oBorder.Zero()) wsTcPr += L""; if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) @@ -1497,7 +1497,7 @@ class CHtmlFile2_Private oXml->WriteString(wsTcPr); - oXml->WriteString(L""); + oXml->WriteString(L""); m_bWasPStyle = false; // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным @@ -1534,7 +1534,7 @@ class CHtmlFile2_Private oXml->WriteString(L"sGridSpan : it2->sGridSpan); oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); + oXml->WriteString(L"\"/>"); j += stoi(sCol); it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); @@ -1546,7 +1546,7 @@ class CHtmlFile2_Private else { for (; j < unMaxColumns; ++j) - oXml->WriteString(L""); + oXml->WriteString(L""); } oXml->WriteString(L""); @@ -1563,13 +1563,18 @@ class CHtmlFile2_Private NSStringUtils::CStringBuilder oBody; NSStringUtils::CStringBuilder oFoot; - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); - TTableStyles oTableStyles; - oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) + { + int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); + sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; oTableStyles.m_bHaveBorderAttribute = true; + } + + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + + oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") WriteEmptyParagraph(oXml, true); @@ -1582,10 +1587,7 @@ class CHtmlFile2_Private if (!oStyle.m_oDisplay.GetWidth().Empty()) { if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) - { - wsTable += L""; - } else wsTable += L""; } @@ -1593,11 +1595,14 @@ class CHtmlFile2_Private wsTable += L""; if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) - { oTableStyles.m_nCellSpacing = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"]); + else + oTableStyles.m_nCellSpacing = 15; - wsTable += L""; - } + wsTable += L""; + + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) + oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); From 9ffc34b7e2f4b2724a45132e75ccbd2a468f7e57 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 12 Mar 2024 11:51:47 +0300 Subject: [PATCH 406/794] Developing DocxRenderer - pptx shapes (in progress) - no br logic --- DocxRenderer/DocxRenderer.cpp | 23 ++++ DocxRenderer/DocxRenderer.h | 1 + DocxRenderer/src/logic/Page.cpp | 60 ++++++-- DocxRenderer/src/logic/elements/BaseItem.h | 1 + DocxRenderer/src/logic/elements/ContText.cpp | 129 +++++++++++++++++- DocxRenderer/src/logic/elements/ContText.h | 1 + DocxRenderer/src/logic/elements/DropCap.cpp | 44 +++--- DocxRenderer/src/logic/elements/DropCap.h | 6 +- DocxRenderer/src/logic/elements/Image.h | 2 + DocxRenderer/src/logic/elements/Paragraph.cpp | 57 +++++--- DocxRenderer/src/logic/elements/Paragraph.h | 4 + DocxRenderer/src/logic/elements/Shape.cpp | 89 ++++++++---- DocxRenderer/src/logic/elements/Shape.h | 2 + DocxRenderer/src/logic/elements/TextLine.cpp | 19 +++ DocxRenderer/src/logic/elements/TextLine.h | 3 + 15 files changed, 356 insertions(+), 85 deletions(-) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index e2a95a631b4..a375bf48207 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -128,6 +128,29 @@ std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz return xml_shapes; } +std::vector CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage) +{ + m_pInternal->m_oDocument.Clear(); + m_pInternal->m_oDocument.Init(false); + + m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true; + m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true; + + DrawPage(pFile, nPage); + + std::vector xml_shapes; + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXmlPptx(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + m_pInternal->m_oDocument.Clear(); + return xml_shapes; +} + void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage) { //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index 5a49a66ecd0..239b998aa0f 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -194,6 +194,7 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); std::vector ScanPage(IOfficeDrawingFile* pFile, size_t nPage); + std::vector ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage); private: CDocxRenderer_Private* m_pInternal; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 494dced878f..8dba2dda2d2 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1407,16 +1407,13 @@ namespace NSDocxRenderer // alignment check bool is_first_line = false; + std::shared_ptr gap_check_line = m_arTextLines[0]; for (size_t index = 0; index < ar_positions.size() - 1; ++index) { - Position position_top; - Position position_bot; + Position position_bot = ar_positions[index]; - position_bot = ar_positions[index]; - if (index == 0) - position_top = position_bot; - else - position_top = ar_positions[index - 1]; + auto& line_top = m_arTextLines[index]; + auto& line_bot = m_arTextLines[index + 1]; if (index == 0 || ar_delims[index - 1]) is_first_line = true; @@ -1424,7 +1421,7 @@ namespace NSDocxRenderer is_first_line = false; // первая строка может быть с отступом - if (is_first_line && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) + if (is_first_line && line_bot->m_dLeft < line_top->m_dLeft) { // если больше трех линий - проверим третью if (index < ar_positions.size() - 2) @@ -1441,15 +1438,48 @@ namespace NSDocxRenderer bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); if (is_unknown) ar_delims[index] = true; - } - // отдельно просмотрим возможные параграфы по две строки - for (size_t index = 0; index < ar_delims.size() - 1; ++index) - { - if (!ar_delims[index] && ar_delims[index + 1]) + if (ar_delims[index]) + gap_check_line = line_bot; + + // bla-bla-bla + // text bla-bla-bla-bla + // + // bla-bla-bla text + // bla-bla-bla-bla + else if (!ar_delims[index]) { - // ширина верхней строчки сильно меньше нижней - if (m_arTextLines[index]->m_dWidth * 3 < m_arTextLines[index + 1]->m_dWidth) + double gap = 0; + std::shared_ptr cont = nullptr; + + if (position_bot.left) + { + gap = line_bot->m_dRight - gap_check_line->m_dRight; + cont = line_bot->m_arConts[0]; + + } + else if (position_bot.right) + { + gap = line_bot->m_dLeft - gap_check_line->m_dLeft; + cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1]; + } + else + continue; + + if (gap < 0) + { + gap_check_line = line_bot; + continue; + } + + size_t cont_len = cont->m_oText.length(); + size_t space_pos = cont->m_oText.ToStdWString().find_first_of(L' '); + if (space_pos == std::wstring::npos) + space_pos = cont_len; + + // to save time doing it roughly + double rough_width = cont->m_dWidth / cont_len * space_pos; + if (gap > rough_width * 1.2) ar_delims[index] = true; } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index ba303ac6c2e..cd70f383e64 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -54,6 +54,7 @@ namespace NSDocxRenderer virtual void Clear() = 0; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const = 0; virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index ad9ab166cb1..17e4c1b7e8b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -176,7 +176,7 @@ namespace NSDocxRenderer oWriter.WriteString(L"\"/>"); } - if(m_bIsEmbossPresent) + if (m_bIsEmbossPresent) oWriter.WriteString(L""); else if(m_bIsEngravePresent) oWriter.WriteString(L""); @@ -196,7 +196,132 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } - if(m_bIsUnderlinePresent) + if (m_bIsUnderlinePresent) + { + oWriter.WriteString(L""); + } + + if (m_bIsHighlightPresent) + { + //note В (); + if (colorTable.IsStandardColor(m_lHighlightColor)) + { + oWriter.WriteString(L""); + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + { + int lSize = static_cast(3.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); + } + else if (m_bWriteStyleRaw) + { + int lSize = static_cast(2.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L""); + } + + if (m_bWriteStyleRaw) + { + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\" w:hAnsi=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:cs=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\" w:hint=\"default\"/>"); + + if (m_pFontStyle->bBold) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (m_pFontStyle->bItalic) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L"oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + } + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L""); + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L""); + if (m_bIsAddBrEnd) oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + + void CContText::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L"(dSpacing); + } + + // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + lCalculatedSpacing -= 1; + + oWriter.WriteString(L" spc=\""); + oWriter.AddInt(lCalculatedSpacing * 100); + oWriter.WriteString(L"\""); +////////////////////////////////////////////////////////////////////// + if (m_bIsOutlinePresent) + oWriter.WriteString(L""); + if (m_bIsShadowPresent) + oWriter.WriteString(L""); + + if (m_bIsStrikeoutPresent) + { + if (m_bIsDoubleStrikeout) + oWriter.WriteString(L""); + else + oWriter.WriteString(L""); + } + + if (m_bIsUnderlinePresent) { oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":pPr>"); + oWriter.WriteString(L"<" + wsTag + L":spacing " + wsTag + L":after=\"0\""); + oWriter.WriteString(L" " + wsTag + L":line=\""); oWriter.AddInt(static_cast((m_dBaselinePos - m_dTop) * c_dMMToDx)); oWriter.WriteString(L"\" "); - oWriter.WriteString(L"w:lineRule=\"exact\" />"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(wsTag + L":lineRule=\"exact\" />"); + oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":r>"); + oWriter.WriteString(L"<" + wsTag + L":rPr>"); + oWriter.WriteString(L"<" + wsTag + L":rFonts " + wsTag + L":ascii=\"" + wsFont + + L"\" " + wsTag + L":hAnsi=\"" + wsFont + + L"\" " + wsTag + L":eastAsia=\"" + wsFont + + L"\" " + wsTag + L":cs=\"" + wsFont + L"\" />"); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L"" + wsText + L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":t xml:space=\"preserve\">" + wsText + L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"w"); + } + void CDropCap::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"a"); } } diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h index 5d4ec09db2a..8ad094990f3 100644 --- a/DocxRenderer/src/logic/elements/DropCap.h +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -18,8 +18,12 @@ namespace NSDocxRenderer CDropCap() = default; ~CDropCap() = default; - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void Clear() override {} + + private: + void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const; }; } diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index 02f76e25293..b5dbe9fb8f8 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -22,5 +22,7 @@ namespace NSDocxRenderer CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); void Clear() override final {}; void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final + {} }; } diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 92741016ae7..b28ce3eae90 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -14,54 +14,54 @@ namespace NSDocxRenderer m_arLines.clear(); } - void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const + void CParagraph::BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const { - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":p>"); + oWriter.WriteString(L"<" + wsTag + L":pPr>"); // styles - if(!m_wsStyleId.empty()) oWriter.WriteString(L""); + if(!m_wsStyleId.empty()) oWriter.WriteString(L"<" + wsTag + L":pStyle " + wsTag + L":val=\"" + m_wsStyleId + L"\"/>"); - oWriter.WriteString(L" 0) { - oWriter.WriteString(L" w:before=\""); + oWriter.WriteString(L" " + wsTag + L":before=\""); oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dSpaceAfter > 0) { - oWriter.WriteString(L" w:after=\""); + oWriter.WriteString(L" " + wsTag + L":after=\""); oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dLineHeight > 0) { - oWriter.WriteString(L" w:line=\""); + oWriter.WriteString(L" " + wsTag + L":line=\""); oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + oWriter.WriteString(L"\" " + wsTag + L":lineRule=\"exact\""); // exact - точный размер строки } oWriter.WriteString(L"/>"); //конец w:spacing - oWriter.WriteString(L" 0) { - oWriter.WriteString(L" w:left=\""); + oWriter.WriteString(L" " + wsTag + L":left=\""); oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dRightBorder > 0) { - oWriter.WriteString(L" w:right=\""); + oWriter.WriteString(L" " + wsTag + L":right=\""); oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края oWriter.WriteString(L"\""); } if (m_bIsNeedFirstLineIndent) { - oWriter.WriteString(L" w:firstLine=\""); + oWriter.WriteString(L" " + wsTag + L":firstLine=\""); oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); oWriter.WriteString(L"\""); } @@ -70,16 +70,16 @@ namespace NSDocxRenderer switch (m_eTextAlignmentType) { case tatByCenter: - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"center\"/>"); break; case tatByRight: - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"end\"/>"); break; case tatByWidth: - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"both\"/>"); break; case tatByLeft: - oWriter.WriteString(L""); + oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"begin\"/>"); break; case tatUnknown: default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять @@ -88,20 +88,34 @@ namespace NSDocxRenderer if (m_bIsShadingPresent) { - oWriter.WriteString(L""); } + } - oWriter.WriteString(L""); + void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"w"); + oWriter.WriteString(L""); for(const auto& line : m_arLines) if(line) line->ToXml(oWriter); - oWriter.WriteString(L""); } + void CParagraph::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"a"); + + oWriter.WriteString(L""); + for(const auto& line : m_arLines) + if(line) + line->ToXmlPptx(oWriter); + oWriter.WriteString(L""); + } + void CParagraph::RemoveHighlightColor() { if (!m_bIsShadingPresent) @@ -134,8 +148,7 @@ namespace NSDocxRenderer while(!pLastCont) pLastCont = pLine->m_arConts[--iNumConts]; - // добавляем br в конец каждой строки - pLastCont->m_bIsAddBrEnd = true; + pLastCont->m_oText += L" "; } } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index 219e59a1ee7..cb5ad9a8aa6 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -40,8 +40,12 @@ namespace NSDocxRenderer virtual ~CParagraph(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; void RemoveHighlightColor(); void MergeLines(); + + private: + void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const; }; } diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 4f0526c3273..a42d978b8c3 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -781,13 +781,20 @@ namespace NSDocxRenderer oWriter.WriteString(L"\""); } oWriter.WriteString(L">"); - oWriter.WriteString(L""); + + oWriter.WriteString(L"(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); oWriter.WriteString(L"\" cy=\""); oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); //Если просто текст без графики @@ -869,6 +876,36 @@ namespace NSDocxRenderer } } + void CShape::BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки. + oWriter.WriteString(L" spcFirstLastPara=\"0\""); //должен ли соблюдаться интервал между абзацами до и после, заданный пользователем. + oWriter.WriteString(L" vertOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по вертикали + oWriter.WriteString(L" horzOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по горизонтали. + oWriter.WriteString(L" vert=\"horz\""); + //oWriter.WriteString(L" wrap=\"none\""); //граница шейпа по ширине текста + oWriter.WriteString(L" wrap=\"square\""); //Определяет параметры обертки, которые будут использоваться для данного текстового тела. + //на сколько граница текста отступает от границы шейпа + oWriter.WriteString(L" lIns=\"0\""); //left по умолчанию 0.25см = 91440 + oWriter.WriteString(L" tIns=\"0\""); //top по умолчанию 0.13см = 45720 + oWriter.WriteString(L" rIns=\"0\""); //right по умолчанию 0.25см + oWriter.WriteString(L" bIns=\"0\""); //bottom по умолчанию 0.13см + oWriter.WriteString(L" numCol=\"1\""); //Определяет количество колонок текста в ограничивающем прямоугольнике. + oWriter.WriteString(L" spcCol=\"0\""); //Определяет пространство между колонками текста в текстовой области (только если numCol >1) + oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). + oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. + oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top + oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. + oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. + oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + } + void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const { if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) @@ -884,32 +921,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L"1) - oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false). - oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt. - oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top - oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля. - oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта. - oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта. - oWriter.WriteString(L">"); - - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + BuildTextBoxParams(oWriter); oWriter.WriteString(L""); } else @@ -917,4 +929,27 @@ namespace NSDocxRenderer oWriter.WriteString(L""); } } + void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L""); + + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + for (const auto& obj : m_arOutputObjects) + obj->ToXmlPptx(oWriter); + + oWriter.WriteString(L""); + } + oWriter.WriteString(L""); + } + + }; // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index edaaf0c16e4..7de2a05b0c0 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -62,6 +62,7 @@ namespace NSDocxRenderer virtual ~CShape(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter)const override final; void SetVector(CVectorGraphics&& oVector); @@ -85,6 +86,7 @@ namespace NSDocxRenderer void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; + void BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const; static void ResetRelativeHeight(); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index a538dfecb2a..160c85bb043 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -75,6 +75,8 @@ namespace NSDocxRenderer wide_space->m_pFontStyle = pFirst->m_pFontStyle; wide_space->m_pShape = nullptr; wide_space->m_iNumDuplicates = 0; + + // cache that value? (calls rarely) wide_space->CalcSelected(); }; @@ -245,4 +247,21 @@ namespace NSDocxRenderer if(cont) cont->ToXml(oWriter); } + + void CTextLine::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + for (const auto& cont : m_arConts) + if(cont) + cont->ToXmlPptx(oWriter); + } + + size_t CTextLine::GetLength() const + { + size_t len = 0; + for (const auto& cont : m_arConts) + if (cont) + len += cont->m_oText.length(); + + return len; + } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 63fc1ebff5d..fdb9bd25875 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -35,6 +35,7 @@ namespace NSDocxRenderer virtual ~CTextLine(); virtual void Clear() override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void RecalcWithNewItem(const CContText* pCont); virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept; @@ -45,5 +46,7 @@ namespace NSDocxRenderer bool IsShadingPresent(const CTextLine* pLine) const noexcept; bool IsCanBeDeleted() const; + + size_t GetLength() const; }; } From 29a41195461c3aad0e7ede8b25394f4755a23e9e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 12 Mar 2024 15:04:00 +0600 Subject: [PATCH 407/794] Fix inline string conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 5a2e0d941b3..76225939f1f 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2141,6 +2141,26 @@ namespace OOX pSource = str; } } + else if(m_oRichText.IsInit()) + { + if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + if(m_oValue.IsInit()) + str->value = m_oRichText->ToString(); + oCell = &str->cell; + + pSource = str; + + } + else + { + auto str(new XLSB::CellSt); + str->value = m_oRichText->ToString(); + oCell = &str->cell; + pSource = str; + } + } else { auto pCellblank = new(XLSB::CellBlank); From e18883f126bc8b7154ebb69e4f476ab3b29d13e1 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 12 Mar 2024 14:54:08 +0300 Subject: [PATCH 408/794] Fix bugs in html to ooxml conversion --- .../3dParty/html/css/src/StyleProperties.cpp | 21 ++- Common/3dParty/html/css/src/StyleProperties.h | 1 + .../html/css/src/xhtml/CDocumentStyle.cpp | 16 ++- HtmlFile2/htmlfile2.cpp | 125 ++++++++++-------- 4 files changed, 95 insertions(+), 68 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 69128e1e2ac..01c9a708a39 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -151,10 +151,10 @@ namespace NSCSS case Millimeter: return CUnitMeasureConverter::ConvertMm(m_oValue, enUnitMeasure, 96); case Inch: return CUnitMeasureConverter::ConvertIn(m_oValue, enUnitMeasure, 96); case Peak: return CUnitMeasureConverter::ConvertPc(m_oValue, enUnitMeasure, 96); + case Twips: return CUnitMeasureConverter::ConvertTw(m_oValue, enUnitMeasure, 96); case Em: case Rem: return m_oValue * dPrevValue; - case None: - case Twips: return m_oValue; + case None: return m_oValue; } } @@ -254,7 +254,8 @@ namespace NSCSS bool CDigit::operator==(const CDigit &oDigit) const { - return (std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON); + return (std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON) && + m_enUnitMeasure == oDigit.m_enUnitMeasure; } bool CDigit::operator!=(const double &oValue) const @@ -1333,8 +1334,13 @@ namespace NSCSS return false; if (L"none" == wsValue) + { + SetColor(L"#ffffff", unLevel, bHardMode); + SetStyle(L"solid", unLevel, bHardMode); + SetWidth(L"0",unLevel,bHardMode); return true; - + } + const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); for (const std::wstring& sValue : arValues) { @@ -1431,6 +1437,11 @@ namespace NSCSS return m_oWidth.Zero(); } + bool CBorderSide::Valid() const + { + return !m_oWidth.Empty() && !m_oWidth.Zero(); + } + CBorderSide &CBorderSide::operator+=(const CBorderSide &oBorderSide) { m_oWidth = oBorderSide.m_oWidth; @@ -2287,7 +2298,7 @@ namespace NSCSS m_oStretch == oFont.m_oStretch && m_oStyle == oFont.m_oStyle && m_oVariant == oFont.m_oVariant && - m_oWeight == oFont.m_oWeight; + m_oWeight == oFont.m_oWeight; } CColorValue::CColorValue() diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 5ddef84aa3c..980ac640da8 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -440,6 +440,7 @@ namespace NSCSS bool Empty() const; bool Zero() const; + bool Valid() const; CBorderSide& operator+=(const CBorderSide& oBorderSide); bool operator==(const CBorderSide& oBorderSide) const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 957f1983916..996ac8bcacc 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -304,7 +304,12 @@ namespace NSCSS // sSpacingValue += L"w:after=\"0\" w:before=\"0\""; if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) - sSpacingValue += L" w:line=\"" + std::to_wstring(oStyle.m_oFont.GetLineHeight().ToInt(NSCSS::Twips, DEFAULT_LINEHEIGHT)) + L"\" w:lineRule=\"auto\""; + { + const std::wstring wsLine{std::to_wstring(oStyle.m_oFont.GetLineHeight().ToInt(NSCSS::Twips, DEFAULT_LINEHEIGHT))}; + const std::wstring wsLineRule{(NSCSS::Percent == oStyle.m_oFont.GetLineHeight().GetUnitMeasure() ? L"auto" : L"atLeast")}; + + sSpacingValue += L" w:line=\"" + wsLine + L"\" w:lineRule=\"" + wsLineRule + L"\""; + } if (!sSpacingValue.empty()) { @@ -392,7 +397,7 @@ namespace NSCSS { if (oBorder.Empty()) return L""; - + std::wstring wsColor = oBorder.GetColor().ToWString(); std::wstring wsStyle = oBorder.GetStyle().ToWString(); double dWidth = oBorder.GetWidth().ToDouble(Point) * 8; // Так как значение указано в восьмых долях точки @@ -403,9 +408,6 @@ namespace NSCSS if (wsStyle.empty()) wsStyle = L"single"; - if (1 > dWidth) - dWidth = 1; - return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(static_cast(dWidth)) + + L"\" w:space=\"0\" w:color=\"" + wsColor + L"\""; } @@ -416,11 +418,11 @@ namespace NSCSS return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(oStyle.m_oFont.GetSize().ToInt(NSCSS::Point) * 2)); // Значения шрифта увеличивает на 2 + oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. + 0.5))); // Значения шрифта увеличивает на 2 if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); - + oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 29267408a42..9564c6557f9 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -927,13 +927,8 @@ class CHtmlFile2_Private else ReplaceSpaces(sText); - if (std::iswspace(sText.front())) - { - if (1 == sText.length()) - sText = L"\u00A0"; - else if (m_bWasSpace) - sText.erase(0, 1); - } + if (std::iswspace(sText.front()) && m_bWasSpace) + sText.erase(0, 1); oXml->WriteEncodeXmlString(sText); oXml->WriteString(L""); @@ -1313,16 +1308,16 @@ class CHtmlFile2_Private { std::wstring wsTable; - if (!oBorder.GetTopBorder().Empty()) + if (oBorder.GetTopBorder().Valid()) wsTable += L""; - if (!oBorder.GetLeftBorder().Empty()) + if (oBorder.GetLeftBorder().Valid()) wsTable += L""; - if (!oBorder.GetBottomBorder().Empty()) + if (oBorder.GetBottomBorder().Valid()) wsTable += L""; - if (!oBorder.GetRightBorder().Empty()) + if (oBorder.GetRightBorder().Valid()) wsTable += L""; return wsTable; @@ -1355,6 +1350,7 @@ class CHtmlFile2_Private } } + while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) { // tr - строки в таблице @@ -1367,18 +1363,9 @@ class CHtmlFile2_Private int j = 1; // Столбец oXml->WriteString(L""); - std::wstring wsTrPr; - - if (L"thead" == wsName) - wsTrPr += L""; - - if (0 <= oTableStyles.m_nCellSpacing) - wsTrPr += L""; - else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) - wsTrPr += L""; + int nHeight = -1; - if (!wsTrPr.empty()) - oXml->WriteString(L"" + wsTrPr + L""); + NSStringUtils::CStringBuilder oTrBody; do { @@ -1398,19 +1385,19 @@ class CHtmlFile2_Private std::vector::iterator it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); while(it1 != mTable.end() || it2 != mTable.end()) { - oXml->WriteString(L""); - oXml->WriteString(it1->sPr); - oXml->WriteString(L""); + oTrBody.WriteString(it1->sPr); + oTrBody.WriteString(L"sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); + oTrBody.WriteString(sCol); + oTrBody.WriteString(L"\"/>"); j += stoi(sCol); it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); } - GetSubClass(oXml, sSelectors); - oXml->WriteString(L""); + GetSubClass(&oTrBody, sSelectors); + oTrBody.WriteString(L""); std::vector arNewSelectors; @@ -1428,6 +1415,9 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); + if (!oStyle.m_oDisplay.GetHeight().Empty()) + nHeight = std::max(nHeight, oStyle.m_oDisplay.GetHeight().ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT)); + std::wstring wsTcPr; if (!oStyle.m_oDisplay.GetWidth().Empty()) @@ -1435,7 +1425,7 @@ class CHtmlFile2_Private if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) wsTcPr += L""; else - wsTcPr += L""; + wsTcPr += L""; } else wsTcPr += L""; @@ -1443,19 +1433,20 @@ class CHtmlFile2_Private if(nColspan != 1) wsTcPr += L""; - if (!oStyle.m_oBorder.Empty()) - wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; - else if (bTableHasBorderAttribute && !oStyle.m_oBorder.Zero()) - wsTcPr += L""; + if (!oStyle.m_oBorder.Zero()) + { + if (!oStyle.m_oBorder.Empty()) + wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; + else if (bTableHasBorderAttribute) + wsTcPr += L""; + } if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) wsTcPr += L""; std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); - if (wsVerticalAlign.empty()) - wsTcPr += L""; - else + if (!wsVerticalAlign.empty()) wsTcPr += L""; if (!oStyle.m_oPadding.Empty() && (NULL == oTableStyles.m_pPadding || oStyle.m_oPadding != *oTableStyles.m_pPadding)) @@ -1483,7 +1474,7 @@ class CHtmlFile2_Private if(nRowspan != 1) { - oXml->WriteString(L""); + oTrBody.WriteString(L""); std::wstring sColspan = std::to_wstring(nColspan); if(nRowspan == 0) mTable.push_back({0, j, sColspan, wsTcPr}); @@ -1495,9 +1486,9 @@ class CHtmlFile2_Private if(nColspan != 1) j += nColspan - 1; - oXml->WriteString(wsTcPr); + oTrBody.WriteString(wsTcPr); - oXml->WriteString(L""); + oTrBody.WriteString(L""); m_bWasPStyle = false; // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным @@ -1505,23 +1496,23 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.sRStyle += L""; - readStream(oXml, sSelectors, oTSR); + readStream(&oTrBody, sSelectors, oTSR); } // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") { - readStream(oXml, sSelectors, oTS); + readStream(&oTrBody, sSelectors, oTS); } sSelectors.pop_back(); if (m_bInP) - wrP(oXml, sSelectors, oTS); - else if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"") - oXml->WriteString(L""); + wrP(&oTrBody, sSelectors, oTS); + else if (oTrBody.GetSubData(oTrBody.GetCurSize() - 6) != L"") + oTrBody.WriteString(L""); - CloseP(oXml, sSelectors); + CloseP(&oTrBody, sSelectors); - oXml->WriteString(L""); + oTrBody.WriteString(L""); j++; // Вставляем ячейки после @@ -1529,12 +1520,12 @@ class CHtmlFile2_Private it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); while(it1 != mTable.end() || it2 != mTable.end()) { - oXml->WriteString(L""); - oXml->WriteString(it1->sPr); - oXml->WriteString(L""); + oTrBody.WriteString(it1->sPr); + oTrBody.WriteString(L"sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/>"); + oTrBody.WriteString(sCol); + oTrBody.WriteString(L"\"/>"); j += stoi(sCol); it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); @@ -1546,9 +1537,26 @@ class CHtmlFile2_Private else { for (; j < unMaxColumns; ++j) - oXml->WriteString(L""); + oTrBody.WriteString(L""); } + std::wstring wsTrPr; + + if (L"thead" == wsName) + wsTrPr += L""; + + if (nHeight > 0) + wsTrPr += L""; + + if (0 <= oTableStyles.m_nCellSpacing) + wsTrPr += L""; + else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) + wsTrPr += L""; + + if (!wsTrPr.empty()) + oXml->WriteString(L"" + wsTrPr + L""); + + oXml->WriteString(oTrBody.GetData()); oXml->WriteString(L""); i++; } @@ -1567,8 +1575,13 @@ class CHtmlFile2_Private if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) { - int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); - sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; + const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); + + if (0 >= nWidth) + sSelectors.back().m_mAttributes[L"border"] = L"none"; + else + sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; + oTableStyles.m_bHaveBorderAttribute = true; } @@ -1626,7 +1639,7 @@ class CHtmlFile2_Private } // borders - if (!oStyle.m_oBorder.Empty()) + if (!oStyle.m_oBorder.Empty() && !oStyle.m_oBorder.Zero()) wsTable += L"" + CreateBorders(oStyle.m_oBorder) + L""; if (!oStyle.m_oPadding.Empty()) From 4a22b26ac1eefde697a6fea2ba247a5c5d9cd315 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 12 Mar 2024 20:24:02 +0600 Subject: [PATCH 409/794] Fix connection conversion --- .../Biff12_records/BeginExtConnection.cpp | 1 + OOXML/XlsxFormat/Table/Connections.cpp | 47 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp b/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp index d3382ca305a..02040d7c562 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp @@ -107,6 +107,7 @@ namespace XLSB SETBIT(flags, 16, fLoadSourceDataFile) SETBIT(flags, 17, fLoadSourceConnectionFile) SETBIT(flags, 18, fLoadConnectionDesc) + SETBIT(flags, 19, 1) SETBIT(flags, 20, fLoadSSOApplicationID) record << wInterval << flags; diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index f1211d70666..9230e719796 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -604,28 +604,52 @@ namespace OOX if(m_oUrl.IsInit()) ptr->stURL = m_oUrl.get(); + else + ptr->fLoadURL = false; if(m_oPost.IsInit()) ptr->stWebPost = m_oPost.get(); + else + ptr->fLoadWebPost = false; if(m_oEditPage.IsInit()) ptr->stEditWebPage = m_oEditPage.get(); + else + ptr->fLoadEditWebPage = false; if(m_oXml.IsInit()) ptr->fSrcIsXML = m_oXml.get(); + else + ptr->fSrcIsXML = false; if(m_oSourceData.IsInit()) ptr->fImportSourceData = m_oSourceData.get(); + else + ptr->fImportSourceData = false; if(m_oConsecutive.IsInit()) ptr->fConsecDelim = m_oConsecutive.get(); + else + ptr->fConsecDelim = false; if(m_oFirstRow.IsInit()) ptr->fSameSettings = m_oFirstRow.get(); + else + ptr->fSameSettings = false; if(m_oXl97.IsInit()) ptr->fXL97Format = m_oXl97.get(); + else + ptr->fXL97Format = false; if(m_oTextDates.IsInit()) ptr->fNoDateRecog = m_oTextDates.get(); + else + ptr->fNoDateRecog = false; if(m_oXl2000.IsInit()) ptr->fRefreshedInXL9 = m_oXl2000.get(); + else + ptr->fRefreshedInXL9 = false; if(m_oHtmlTables.IsInit()) ptr->fTablesOnlyHTML = m_oHtmlTables.get(); + else + ptr->fRefreshedInXL9 = false; if(m_oHtmlFormat.IsInit()) ptr->wHTMLFmt = m_oHtmlFormat->GetValue(); + else + ptr->wHTMLFmt = false; return XLS::BaseObjectPtr{ptr1}; } EElementType CWebPr::getType() const @@ -1005,24 +1029,38 @@ namespace OOX ptr1->dwConnID = m_oId->GetValue(); if(m_oCredentials.IsInit()) ptr1->iCredMethod = m_oCredentials->GetValue(); + else + ptr1->iCredMethod = 0; if(m_oBackground.IsInit()) ptr1->fBackgroundQuery = m_oBackground.get(); else ptr1->fBackgroundQuery = false; if(m_oDeleted.IsInit()) ptr1->fDeleted = m_oDeleted.get(); + else + ptr1->fDeleted = false; if(m_oDescription.IsInit()) ptr1->stConnDesc = m_oDescription.get(); else ptr1->fLoadConnectionDesc = false; if(m_oInterval.IsInit()) ptr1->wInterval = m_oInterval.get(); + else + ptr1->wInterval = 0; if(m_oKeepAlive.IsInit()) ptr1->fMaintain = m_oKeepAlive.get(); + else + ptr1->fMaintain = false; if(m_oMinRefreshableVersion.IsInit()) ptr1->bVerRefreshableMin = m_oMinRefreshableVersion.get(); + else if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oRefreshedVersion.get(); + else + ptr1->bVerRefreshableMin = 0; if(m_oNew.IsInit()) ptr1->fNewQuery = m_oNew.get(); + else + ptr1->fNewQuery = false; if(m_oOdcFile.IsInit()) ptr1->stConnectionFile = m_oOdcFile.get(); else @@ -1033,16 +1071,20 @@ namespace OOX ptr1->fAlwaysUseConnectionFile = false; if(m_oReconnectionMethod.IsInit()) ptr1->irecontype = m_oReconnectionMethod.get(); + else + ptr1->irecontype = 1; if(m_oRefreshedVersion.IsInit()) ptr1->bVerRefreshed = m_oRefreshedVersion.get(); if(m_oRefreshOnLoad.IsInit()) ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); + else + ptr1->fRefreshOnLoad = false; if(m_oSaveData.IsInit()) ptr1->fSaveData = m_oSaveData.get(); if(m_oSavePassword.IsInit()) - { ptr1->pc = m_oSavePassword.get(); - } + else + ptr1->pc = 0; if(m_oSingleSignOnId.IsInit()) ptr1->stSso = m_oSingleSignOnId.get(); else @@ -1293,6 +1335,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); } + else { NSStringUtils::CStringBuilder sXml; From 65112e860e19d6c7051d5695cdb3ed07ab9ffe06 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 12 Mar 2024 21:46:19 +0600 Subject: [PATCH 410/794] Fix query table conversion --- OOXML/XlsxFormat/Table/Tables.cpp | 53 +++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 4d28e8cbfa8..d1ed94f2dec 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -1142,18 +1142,28 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oId.IsInit()) ptr->idField = m_oId->GetValue(); + else + ptr->idField = 0; if(m_oTableColumnId.IsInit()) ptr->idList = m_oTableColumnId->GetValue(); + else + ptr->idList = 0; if(m_oName.IsInit()) ptr->name = m_oName.get(); if(m_oRowNumbers.IsInit()) ptr->fRowNums = m_oRowNumbers.get(); if(m_oFillFormulas.IsInit()) ptr->fFillDown = m_oFillFormulas.get(); + else + ptr->fFillDown = false; if(m_oDataBound.IsInit()) ptr->fUserIns = m_oDataBound.get(); + else + ptr->fUserIns = false; if(m_oClipped.IsInit()) ptr->fClipped = m_oClipped.get(); + else + ptr->fClipped = false; return XLS::BaseObjectPtr{ptr1}; } @@ -1437,6 +1447,8 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") ptr->wVerBeforeRefreshAlert = m_oMinimumVersion->GetValue(); if(m_FieldIdWrapped.IsInit()) ptr->fidWrapped = m_FieldIdWrapped.get(); + else + ptr->fidWrapped = false; if(m_HeadersInLastRefresh.IsInit()) ptr->fTitlesOld = m_HeadersInLastRefresh.get(); if(m_PreserveSortFilterLayout.IsInit()) @@ -1573,33 +1585,61 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oAdjustColumnWidth.IsInit()) ptr->fAutoFit = m_oAdjustColumnWidth.get(); + else + ptr->fAutoFit = true; if(m_oApplyAlignmentFormats.IsInit()) ptr->fibitAtrAlc = m_oApplyAlignmentFormats.get(); + else + ptr->fibitAtrAlc = false; if(m_oApplyBorderFormats.IsInit()) ptr->fibitAtrBdr = m_oApplyBorderFormats.get(); + else + ptr->fibitAtrBdr = false; if(m_oApplyFontFormats.IsInit()) ptr->fibitAtrFnt = m_oApplyFontFormats.get(); + else + ptr->fibitAtrFnt = false; if(m_oApplyNumberFormats.IsInit()) ptr->fibitAtrNum = m_oApplyNumberFormats.get(); + else + ptr->fibitAtrNum = false; if(m_oApplyPatternFormats.IsInit()) ptr->fibitAtrPat = m_oApplyPatternFormats.get(); + else + ptr->fibitAtrPat = false; if(m_oApplyWidthHeightFormats.IsInit()) ptr->fibitAtrProt = m_oApplyWidthHeightFormats.get(); + else + ptr->fibitAtrProt = false; if(m_oBackgroundRefresh.IsInit()) ptr->fAsync = m_oBackgroundRefresh.get(); + else + ptr->fAsync = true; if(m_oAutoFormatId.IsInit()) ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + else + ptr->itblAutoFmt = 0; if(m_oConnectionId.IsInit()) ptr->dwConnID = m_oConnectionId->GetValue(); + else + ptr->dwConnID = 0; if(m_oDisableEdit.IsInit()) ptr->fDisableEdit = m_oDisableEdit.get(); + else + ptr->fDisableEdit = false; if(m_oDisableRefresh.IsInit()) ptr->fDisableRefresh = m_oDisableRefresh.get(); + else + ptr->fDisableRefresh = false; if(m_oFillFormulas.IsInit()) ptr->fFill = m_oFillFormulas.get(); + else + ptr->fFill = false; if(m_oFirstBackgroundRefresh.IsInit()) ptr->fNewAsync = m_oFirstBackgroundRefresh.get(); + else + ptr->fNewAsync = true; ptr->fOverwrite = false; ptr->fShrink = false; @@ -1611,17 +1651,25 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->fTitles = m_oHeaders.get(); if(m_oIntermediate.IsInit()) ptr->fDummyList = m_oIntermediate.get(); + else + ptr->fDummyList = 0; - if(!ptr->name.empty()) - m_oName = ptr->name; + if(m_oName.IsInit()) + ptr->name = m_oName.get(); if(m_oPreserveFormatting.IsInit()) ptr->fPreserveFmt = m_oPreserveFormatting.get(); if(m_oRefreshOnLoad.IsInit()) ptr->fAutoRefresh = m_oRefreshOnLoad.get(); + else + ptr->fAutoRefresh = false; if(m_oRemoveDataOnSave.IsInit()) ptr->fSaveData = !m_oRemoveDataOnSave.get(); + else + ptr->fSaveData = true; if(m_oRowNumbers.IsInit()) ptr->fRowNums = m_oRowNumbers.get(); + else + ptr->fRowNums = false; if(m_oQueryTableRefresh.IsInit()) ptr1->m_QSIR = m_oQueryTableRefresh->toBin(); @@ -1771,6 +1819,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); } + else { NSStringUtils::CStringBuilder sXml; From 48c1478374a2fd5ee23473777b9a3cf7a457f297 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 12 Mar 2024 19:58:47 +0300 Subject: [PATCH 411/794] fix bug #66840 --- .../Converter/xlsx_conditionalFormatting.cpp | 478 +++++++++++++----- .../Converter/xlsx_conditionalFormatting.h | 5 +- OdfFile/Reader/Converter/xlsx_output_xml.cpp | 21 +- OdfFile/Reader/Converter/xlsx_output_xml.h | 1 + OdfFile/Reader/Converter/xlsx_table_state.cpp | 6 +- OdfFile/Reader/Converter/xlsx_table_state.h | 3 +- .../Reader/Converter/xlsx_tablecontext.cpp | 8 +- OdfFile/Reader/Converter/xlsx_tablecontext.h | 3 +- .../Converter/xlsxconversioncontext.cpp | 3 +- OdfFile/Reader/Format/calcext_elements.cpp | 4 + OdfFile/Reader/Format/calcext_elements.h | 13 +- OdfFile/Writer/Converter/XlsxConverter.cpp | 87 +++- OdfFile/Writer/Converter/XlsxConverter.h | 6 +- OdfFile/Writer/Format/calcext_elements.cpp | 11 +- OdfFile/Writer/Format/calcext_elements.h | 11 +- OdfFile/Writer/Format/ods_table_state.cpp | 34 +- OdfFile/Writer/Format/ods_table_state.h | 3 + 17 files changed, 526 insertions(+), 171 deletions(-) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 7ab8a319b85..197b67eef30 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -74,6 +74,34 @@ namespace oox { } } } + void serializeEx(std::wostream& _Wostream) + { + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE(L"x14:cfvo") + { + switch (type) + { + case 0: CP_XML_ATTR(L"type", L"percent"); break; + case 1: CP_XML_ATTR(L"type", L"num"); break; + case 2: CP_XML_ATTR(L"type", L"max"); break; + case 3: CP_XML_ATTR(L"type", L"min"); break; + case 4: CP_XML_ATTR(L"type", L"autoMax"); break; + case 5: CP_XML_ATTR(L"type", L"autoMin"); break; + case 6: CP_XML_ATTR(L"type", L"formula"); break; + case 7: CP_XML_ATTR(L"type", L"percentile"); break;//BOA PARA ESTUDAR - JOGAR LOTOFACIL minha predileta 1.ods + + } + if (val) + { + CP_XML_NODE(L"xm:f") + { + CP_XML_CONTENT(*val); + } + } + } + } + } }; struct rule @@ -100,11 +128,12 @@ namespace oox { //data bar icon_set _CP_OPT(bool) showValue; //data bar - _CP_OPT(int) minLength; - _CP_OPT(int) maxLength; + _CP_OPT(unsigned int) minLength; + _CP_OPT(unsigned int) maxLength; _CP_OPT(std::wstring) axis_position; _CP_OPT(std::wstring) axis_color; _CP_OPT(std::wstring) negative_color; + _CP_OPT(bool) gradient; //icon set _CP_OPT(int) icon_set_type; _CP_OPT(bool) reverse; @@ -112,9 +141,19 @@ namespace oox { _CP_OPT(int) iconset_type; //date is _CP_OPT(int) time_period; + + bool isExtended() + { + if (gradient || axis_color || axis_position || negative_color) + { + return true; + } + return false; + } }; struct conditionalFormatting { + bool bUsed = false; std::wstring ref; std::vector rules; }; @@ -125,161 +164,349 @@ class xlsx_conditionalFormatting_context::Impl void serialize(std::wostream & _Wostream) { - if (!conditionalFormattings_.empty()) - { - int priority = 1; - CP_XML_WRITER(_Wostream) - { - for (size_t i = 0 ; i < conditionalFormattings_.size(); i++) - { - conditionalFormatting & c = conditionalFormattings_[i]; - - if (c.rules.size() < 1) continue; - - CP_XML_NODE(L"conditionalFormatting") - { - CP_XML_ATTR(L"sqref", c.ref); + if (conditionalFormattings_.empty()) return; + + int priority = 1; + CP_XML_WRITER(_Wostream) + { + for (size_t i = 0; i < conditionalFormattings_.size(); i++) + { + conditionalFormatting& c = conditionalFormattings_[i]; + + if (c.bUsed) continue; + if (c.rules.size() < 1) continue; - for (size_t j = 0 ; j < c.rules.size(); j++) + CP_XML_NODE(L"conditionalFormatting") + { + CP_XML_ATTR(L"sqref", c.ref); + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + + CP_XML_NODE(L"cfRule") { - if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + CP_XML_ATTR(L"priority", priority++); - CP_XML_NODE(L"cfRule") - { - CP_XML_ATTR(L"priority", priority++); - - if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); - if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); - if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); - if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); - if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); - if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); - if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); - if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage",*c.rules[j].above); - if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage",*c.rules[j].equal); - if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); - - if (c.rules[j].type == 1) + if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); + if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); + if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); + if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); + if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); + if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); + if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); + if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage", *c.rules[j].above); + if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage", *c.rules[j].equal); + if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); + + if (c.rules[j].type == 1) + { + if (c.rules[j].formula_type) + CP_XML_ATTR(L"type", *c.rules[j].formula_type); + else + CP_XML_ATTR(L"type", L"cellIs"); + if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) { - if (c.rules[j].formula_type) - CP_XML_ATTR(L"type", *c.rules[j].formula_type); - else - CP_XML_ATTR(L"type", L"cellIs"); - if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) + CP_XML_NODE(L"formula") { - CP_XML_NODE(L"formula") + CP_XML_CONTENT(*c.rules[j].formula); + } + } + if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) + { + CP_XML_NODE(L"formula") + { + CP_XML_CONTENT(*c.rules[j].formula2); + } + } + } + else if (c.rules[j].type == 2) + { + CP_XML_ATTR(L"type", L"dataBar"); + CP_XML_NODE(L"dataBar") + { + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); + if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + if (c.rules[j].gradient) CP_XML_ATTR(L"gradient", *c.rules[j].gradient); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + + CP_XML_NODE(L"color") + { + CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + } + } + } + else if (c.rules[j].type == 3) + { + CP_XML_ATTR(L"type", L"colorScale"); + CP_XML_NODE(L"colorScale") + { + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + for (size_t k = 0; k < c.rules[j].color.size(); k++) + { + CP_XML_NODE(L"color") { - CP_XML_CONTENT(*c.rules[j].formula); + CP_XML_ATTR(L"rgb", c.rules[j].color[k]); } } - if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) + } + } + else if (c.rules[j].type == 4) + { + CP_XML_ATTR(L"type", L"iconSet"); + CP_XML_NODE(L"iconSet") + { + if (c.rules[j].icon_set_type) { - CP_XML_NODE(L"formula") + switch (*c.rules[j].icon_set_type) { - CP_XML_CONTENT(*c.rules[j].formula2); + case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; + case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; + case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; + case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; + case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; + case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; + case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; + case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; + case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; + case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; + case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; + case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; + case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; + case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; + case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; + case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; + case 0: + default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; + break; } } + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } } - else if (c.rules[j].type == 2) + } + else if (c.rules[j].type == 5) + { + CP_XML_ATTR(L"type", L"timePeriod"); + switch (*c.rules[j].time_period) { - CP_XML_ATTR(L"type", L"dataBar"); - CP_XML_NODE(L"dataBar") + case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; + case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; + case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; + case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; + case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; + case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; + case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; + case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; + case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; + case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + } + } + } + } + } + } + } + } + void serializeEx(std::wostream& _Wostream) + { + if (conditionalFormattings_.empty()) return; + + int priority = 1; + CP_XML_WRITER(_Wostream) + { + for (size_t i = 0; i < conditionalFormattings_.size(); i++) + { + conditionalFormatting& c = conditionalFormattings_[i]; + + if (c.bUsed) continue; + if (c.rules.size() < 1) continue; + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].isExtended()) + { + c.bUsed = true; + break; + } + } + if (!c.bUsed) continue; + + CP_XML_NODE(L"x14:conditionalFormatting") + { + CP_XML_ATTR(L"xmlns:xm", L"http://schemas.microsoft.com/office/excel/2006/main"); + + for (size_t j = 0; j < c.rules.size(); j++) + { + if (c.rules[j].type < 1 || c.rules[j].type > 5) continue; + + CP_XML_NODE(L"x14:cfRule") + { + CP_XML_ATTR(L"priority", priority++); + + if (c.rules[j].dxfId) CP_XML_ATTR(L"dxfId", *c.rules[j].dxfId); + if (c.rules[j].percent) CP_XML_ATTR(L"percent", *c.rules[j].percent); + if (c.rules[j].operator_) CP_XML_ATTR(L"operator", *c.rules[j].operator_); + if (c.rules[j].stopIfTrue) CP_XML_ATTR(L"stopIfTrue", *c.rules[j].stopIfTrue); + if (c.rules[j].text) CP_XML_ATTR(L"text", *c.rules[j].text); + if (c.rules[j].rank) CP_XML_ATTR(L"rank", *c.rules[j].rank); + if (c.rules[j].bottom) CP_XML_ATTR(L"bottom", *c.rules[j].bottom); + if (c.rules[j].above) CP_XML_ATTR(L"aboveAverage", *c.rules[j].above); + if (c.rules[j].equal) CP_XML_ATTR(L"equalAverage", *c.rules[j].equal); + if (c.rules[j].stdDev) CP_XML_ATTR(L"stdDev", *c.rules[j].stdDev); + + if (c.rules[j].type == 1) + { + if (c.rules[j].formula_type) + CP_XML_ATTR(L"type", *c.rules[j].formula_type); + else + CP_XML_ATTR(L"type", L"cellIs"); + if ((c.rules[j].formula) && (!c.rules[j].formula->empty())) + { + CP_XML_NODE(L"formula") + { + CP_XML_CONTENT(*c.rules[j].formula); + } + } + if ((c.rules[j].formula2) && (!c.rules[j].formula2->empty())) + { + CP_XML_NODE(L"formula") { - if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); - if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); - if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + CP_XML_CONTENT(*c.rules[j].formula2); + } + } + } + else if (c.rules[j].type == 2) + { + CP_XML_ATTR(L"type", L"dataBar"); + CP_XML_NODE(L"x14:dataBar") + { + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + if (c.rules[j].minLength) CP_XML_ATTR(L"minLength", *c.rules[j].minLength); + if (c.rules[j].maxLength) CP_XML_ATTR(L"maxLength", *c.rules[j].maxLength); + if (c.rules[j].gradient) CP_XML_ATTR(L"gradient", *c.rules[j].gradient); + if (c.rules[j].axis_position) CP_XML_ATTR(L"axisPosition", *c.rules[j].axis_position); - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) + { + c.rules[j].cfvo[k].serializeEx(CP_XML_STREAM()); + } + CP_XML_NODE(L"x14:fillColor") + { + CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + } + if (c.rules[j].negative_color) + { + CP_XML_NODE(L"x14:negativeFillColor") { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + CP_XML_ATTR(L"rgb", *c.rules[j].negative_color); } - - CP_XML_NODE(L"color") + } + if (c.rules[j].axis_color) + { + CP_XML_NODE(L"x14:axisColor") { - CP_XML_ATTR(L"rgb", !c.rules[j].color.empty() ? c.rules[j].color[0] : L"FF000000"); + CP_XML_ATTR(L"rgb", *c.rules[j].axis_color); } } } - else if (c.rules[j].type == 3) + } + else if (c.rules[j].type == 3) + { + CP_XML_ATTR(L"type", L"colorScale"); + CP_XML_NODE(L"x14:colorScale") { - CP_XML_ATTR(L"type", L"colorScale"); - CP_XML_NODE(L"colorScale") + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) { - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) - { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); - } - for (size_t k = 0; k < c.rules[j].color.size(); k++) + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); + } + for (size_t k = 0; k < c.rules[j].color.size(); k++) + { + CP_XML_NODE(L"x14:color") { - CP_XML_NODE(L"color") - { - CP_XML_ATTR(L"rgb", c.rules[j].color[k]); - } - } + CP_XML_ATTR(L"rgb", c.rules[j].color[k]); + } } } - else if (c.rules[j].type == 4) + } + else if (c.rules[j].type == 4) + { + CP_XML_ATTR(L"type", L"iconSet"); + CP_XML_NODE(L"x14:iconSet") { - CP_XML_ATTR(L"type", L"iconSet"); - CP_XML_NODE(L"iconSet") + if (c.rules[j].icon_set_type) { - if (c.rules[j].icon_set_type) + switch (*c.rules[j].icon_set_type) { - switch (*c.rules[j].icon_set_type) - { - case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; - case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; - case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; - case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; - case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; - case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; - case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; - case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; - case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; - case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; - case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; - case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; - case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; - case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; - case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; - case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; - case 0: - default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; - break; - } + case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; + case 2: CP_XML_ATTR(L"iconSet", L"3Flags"); break; + case 3: CP_XML_ATTR(L"iconSet", L"3Signs"); break; + case 4: CP_XML_ATTR(L"iconSet", L"3Symbols"); break; + case 5: CP_XML_ATTR(L"iconSet", L"3Symbols2"); break; + case 6: CP_XML_ATTR(L"iconSet", L"3TrafficLights1"); break; + case 7: CP_XML_ATTR(L"iconSet", L"3TrafficLights2"); break; + case 8: CP_XML_ATTR(L"iconSet", L"4Arrows"); break; + case 9: CP_XML_ATTR(L"iconSet", L"4ArrowsGray"); break; + case 10: CP_XML_ATTR(L"iconSet", L"4Rating"); break; + case 11: CP_XML_ATTR(L"iconSet", L"4RedToBlack"); break; + case 12: CP_XML_ATTR(L"iconSet", L"4TrafficLights"); break; + case 13: CP_XML_ATTR(L"iconSet", L"5Arrows"); break; + case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; + case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; + case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; + case 0: + default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; + break; } - if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); - - for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) - { - c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); - } } - } - else if (c.rules[j].type == 5) - { - CP_XML_ATTR(L"type", L"timePeriod"); - switch (*c.rules[j].time_period) + if (c.rules[j].showValue) CP_XML_ATTR(L"showValue", *c.rules[j].showValue); + + for (size_t k = 0; k < c.rules[j].cfvo.size(); k++) { - case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; - case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; - case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; - case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; - case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; - case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; - case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; - case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; - case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; - case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + c.rules[j].cfvo[k].serialize(CP_XML_STREAM()); } } } + else if (c.rules[j].type == 5) + { + CP_XML_ATTR(L"type", L"timePeriod"); + switch (*c.rules[j].time_period) + { + case 0: CP_XML_ATTR(L"timePeriod", L"today"); break; + case 1: CP_XML_ATTR(L"timePeriod", L"yesterday"); break; + case 2: CP_XML_ATTR(L"timePeriod", L"tomorrow"); break; + case 3: CP_XML_ATTR(L"timePeriod", L"last7Days"); break; + case 4: CP_XML_ATTR(L"timePeriod", L"thisMonth"); break; + case 5: CP_XML_ATTR(L"timePeriod", L"lastMonth"); break; + case 6: CP_XML_ATTR(L"timePeriod", L"nextMonth"); break; + case 7: CP_XML_ATTR(L"timePeriod", L"thisWeek"); break; + case 8: CP_XML_ATTR(L"timePeriod", L"lastWeek"); break; + case 9: CP_XML_ATTR(L"timePeriod", L"nextWeek"); break; + } + } } - } - } - } - } - } + } + + CP_XML_NODE(L"xm:sqref") + { + CP_XML_CONTENT(c.ref); + } + } + } + } + } std::vector conditionalFormattings_; }; @@ -295,7 +522,10 @@ void xlsx_conditionalFormatting_context::serialize(std::wostream & _Wostream) { return impl_->serialize(_Wostream); } - +void xlsx_conditionalFormatting_context::serializeEx(std::wostream& _Wostream) +{ + return impl_->serializeEx(_Wostream); +} void xlsx_conditionalFormatting_context::start(std::wstring ref) { formulasconvert::odf2oox_converter converter; @@ -554,7 +784,11 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f) impl_->conditionalFormattings_.back().rules.back().formula = val; } } -void xlsx_conditionalFormatting_context::set_dataBar(_CP_OPT(int) min, _CP_OPT(int) max) +void xlsx_conditionalFormatting_context::set_gradient(bool val) +{ + impl_->conditionalFormattings_.back().rules.back().gradient = val; +} +void xlsx_conditionalFormatting_context::set_dataBar(_CP_OPT(unsigned int) min, _CP_OPT(unsigned int) max) { impl_->conditionalFormattings_.back().rules.back().minLength = min; impl_->conditionalFormattings_.back().rules.back().maxLength = max; diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h index cfbbde04a1c..ae3183febe2 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.h @@ -50,7 +50,9 @@ class xlsx_conditionalFormatting_context void add_rule(int type); void set_formula(std::wstring f); - void set_dataBar(_CP_OPT(int) min, _CP_OPT(int) max); + + void set_dataBar(_CP_OPT(unsigned int) min, _CP_OPT(unsigned int) max); + void set_gradient(bool val); void set_dxf (int dxf_id); void set_showVal(bool val); @@ -67,6 +69,7 @@ class xlsx_conditionalFormatting_context void set_icon_set_type(int type); void serialize(std::wostream & _Wostream); + void serializeEx(std::wostream& _Wostream); private: class Impl; _CP_SCOPED_PTR(Impl) impl_; diff --git a/OdfFile/Reader/Converter/xlsx_output_xml.cpp b/OdfFile/Reader/Converter/xlsx_output_xml.cpp index b5c4379d326..3b983b9276a 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.cpp +++ b/OdfFile/Reader/Converter/xlsx_output_xml.cpp @@ -78,6 +78,7 @@ class xlsx_xml_worksheet::Impl std::wstringstream tableParts_; std::wstringstream autofilter_; std::wstringstream conditionalFormatting_; + std::wstringstream conditionalFormattingEx_; std::wstringstream picture_background_; std::wstringstream dataValidations_; std::wstringstream dataValidationsX14_; @@ -148,6 +149,10 @@ std::wostream & xlsx_xml_worksheet::conditionalFormatting() { return impl_->conditionalFormatting_; } +std::wostream& xlsx_xml_worksheet::conditionalFormattingEx() +{ + return impl_->conditionalFormattingEx_; +} std::wostream & xlsx_xml_worksheet::sort() { return impl_->sort_; @@ -312,8 +317,9 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) std::wstring dataValidations14 = impl_->dataValidationsX14_.str(); std::wstring sparklines = impl_->sparklines_.str(); + std::wstring condFormattings = impl_->conditionalFormattingEx_.str(); - if (false == dataValidations14.empty() || false == sparklines.empty()) + if (false == dataValidations14.empty() || false == sparklines.empty() || false == condFormattings.empty()) { CP_XML_NODE(L"extLst") { @@ -337,6 +343,19 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) CP_XML_STREAM() << sparklines; } } + if (false == condFormattings.empty()) + { + CP_XML_NODE(L"ext") + { + CP_XML_ATTR(L"uri", L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}"); + CP_XML_ATTR(L"xmlns:x14", L"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"); + + CP_XML_NODE(L"x14:conditionalFormattings") + { + CP_XML_STREAM() << condFormattings; + } + } + } } } } diff --git a/OdfFile/Reader/Converter/xlsx_output_xml.h b/OdfFile/Reader/Converter/xlsx_output_xml.h index ba49392a979..62c487b6006 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.h +++ b/OdfFile/Reader/Converter/xlsx_output_xml.h @@ -61,6 +61,7 @@ class xlsx_xml_worksheet: noncopyable std::wostream & autofilter(); std::wostream & tableParts(); std::wostream & conditionalFormatting(); + std::wostream & conditionalFormattingEx(); std::wostream & picture_background(); std::wostream & dataValidations(); std::wostream & dataValidationsX14(); diff --git a/OdfFile/Reader/Converter/xlsx_table_state.cpp b/OdfFile/Reader/Converter/xlsx_table_state.cpp index 1c3249a2d96..445c20d3538 100644 --- a/OdfFile/Reader/Converter/xlsx_table_state.cpp +++ b/OdfFile/Reader/Converter/xlsx_table_state.cpp @@ -794,10 +794,14 @@ void xlsx_table_state::serialize_hyperlinks(std::wostream & strm) { return xlsx_hyperlinks_.xlsx_serialize(strm); } -void xlsx_table_state::serialize_conditionalFormatting(std::wostream & strm) +void xlsx_table_state::serialize_condFormatting(std::wostream & strm) { return xlsx_conditionalFormatting_context_.serialize(strm); } +void xlsx_table_state::serialize_condFormattingEx(std::wostream& strm) +{ + return xlsx_conditionalFormatting_context_.serializeEx(strm); +} void xlsx_table_state::dump_rels_hyperlinks(rels & Rels) { return xlsx_hyperlinks_.dump_rels(Rels); diff --git a/OdfFile/Reader/Converter/xlsx_table_state.h b/OdfFile/Reader/Converter/xlsx_table_state.h index 69f48a37b4a..b0ca244f7b6 100644 --- a/OdfFile/Reader/Converter/xlsx_table_state.h +++ b/OdfFile/Reader/Converter/xlsx_table_state.h @@ -203,7 +203,8 @@ class xlsx_table_state void set_background (std::wstring rId) { tableBackground_ = rId; } - void serialize_conditionalFormatting (std::wostream & _Wostream); + void serialize_condFormatting (std::wostream & _Wostream); + void serialize_condFormattingEx (std::wostream& _Wostream); void serialize_table_format (std::wostream & _Wostream); void serialize_merge_cells (std::wostream & _Wostream); void serialize_hyperlinks (std::wostream & _Wostream); diff --git a/OdfFile/Reader/Converter/xlsx_tablecontext.cpp b/OdfFile/Reader/Converter/xlsx_tablecontext.cpp index ed345d18d95..57897738b02 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.cpp +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.cpp @@ -621,9 +621,13 @@ namespace oox { { return state()->serialize_protection(_Wostream); } - void xlsx_table_context::serialize_conditionalFormatting(std::wostream& _Wostream) + void xlsx_table_context::serialize_condFormatting(std::wostream& _Wostream) { - return state()->serialize_conditionalFormatting(_Wostream); + return state()->serialize_condFormatting(_Wostream); + } + void xlsx_table_context::serialize_condFormattingEx(std::wostream& _Wostream) + { + return state()->serialize_condFormattingEx(_Wostream); } void xlsx_table_context::serialize_merge_cells(std::wostream& _Wostream) { diff --git a/OdfFile/Reader/Converter/xlsx_tablecontext.h b/OdfFile/Reader/Converter/xlsx_tablecontext.h index 86b14088413..7cde938de77 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.h +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.h @@ -88,7 +88,8 @@ class xlsx_table_context void serialize_autofilter (std::wostream & _Wostream); void serialize_merge_cells (std::wostream & _Wostream); void serialize_table_format (std::wostream & _Wostream); - void serialize_conditionalFormatting(std::wostream & _Wostream); + void serialize_condFormatting (std::wostream & _Wostream); + void serialize_condFormattingEx (std::wostream& _Wostream); void serialize_hyperlinks (std::wostream & _Wostream); void serialize_ole_objects (std::wostream & _Wostream); void serialize_controls (std::wostream & _Wostream); diff --git a/OdfFile/Reader/Converter/xlsxconversioncontext.cpp b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp index acdbf417687..7c7b79323c6 100644 --- a/OdfFile/Reader/Converter/xlsxconversioncontext.cpp +++ b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp @@ -520,7 +520,8 @@ void xlsx_conversion_context::end_table() get_table_context().serialize_table_format (current_sheet().sheetFormat()); get_table_context().serialize_page_properties (current_sheet().page_properties()); get_table_context().serialize_header_footer (current_sheet().header_footer()); - get_table_context().serialize_conditionalFormatting (current_sheet().conditionalFormatting()); + get_table_context().serialize_condFormattingEx (current_sheet().conditionalFormattingEx()); + get_table_context().serialize_condFormatting (current_sheet().conditionalFormatting()); get_table_context().serialize_tableParts (current_sheet().tableParts(), current_sheet().sheet_rels()); get_table_context().serialize_autofilter (current_sheet().autofilter()); get_table_context().serialize_sort (current_sheet().sort()); diff --git a/OdfFile/Reader/Format/calcext_elements.cpp b/OdfFile/Reader/Format/calcext_elements.cpp index 0cf91a8721c..7460fde492f 100644 --- a/OdfFile/Reader/Format/calcext_elements.cpp +++ b/OdfFile/Reader/Format/calcext_elements.cpp @@ -60,6 +60,7 @@ void calcext_data_bar_attr::add_attributes( const xml::attributes_wc_ptr & Attri CP_APPLY_ATTR(L"calcext:min-length", min_length_); CP_APPLY_ATTR(L"calcext:max-length", max_length_); CP_APPLY_ATTR(L"calcext:axis-position", axis_position_); + CP_APPLY_ATTR(L"calcext:gradient", gradient_); } void calcext_icon_set_attr::add_attributes( const xml::attributes_wc_ptr & Attributes ) @@ -181,6 +182,9 @@ void calcext_data_bar::xlsx_convert(oox::xlsx_conversion_context & Context) if (attr_.axis_position_) Context.get_conditionalFormatting_context().set_axis_position(*attr_.axis_position_); + if (attr_.gradient_) + Context.get_conditionalFormatting_context().set_gradient(*attr_.gradient_); + Context.get_conditionalFormatting_context().set_dataBar(attr_.min_length_, attr_.max_length_); for (size_t i = 0 ; i < content_.size(); i++) diff --git a/OdfFile/Reader/Format/calcext_elements.h b/OdfFile/Reader/Format/calcext_elements.h index 146f8dd442c..d0013593291 100644 --- a/OdfFile/Reader/Format/calcext_elements.h +++ b/OdfFile/Reader/Format/calcext_elements.h @@ -53,12 +53,13 @@ class calcext_data_bar_attr public: void add_attributes( const xml::attributes_wc_ptr & Attributes ); - _CP_OPT(odf_types::color) axis_color_; - _CP_OPT(odf_types::color) positive_color_; - _CP_OPT(odf_types::color) negative_color_; - _CP_OPT(std::wstring) axis_position_; - _CP_OPT(int) max_length_; - _CP_OPT(int) min_length_; + _CP_OPT(odf_types::color) axis_color_; + _CP_OPT(odf_types::color) positive_color_; + _CP_OPT(odf_types::color) negative_color_; + _CP_OPT(std::wstring) axis_position_; + _CP_OPT(bool) gradient_; + _CP_OPT(unsigned int) min_length_; + _CP_OPT(unsigned int) max_length_; }; class calcext_condition_attr diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 330958e14e7..fee7de8d107 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -445,9 +445,10 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) if (!oox_sheet->m_arrConditionalFormatting.empty() || oox_sheet->m_oExtLst.IsInit()) { - std::multimap mapSorted; + std::multimap> mapSorted; - std::vector arUnsorted; + std::vector> arUnsorted; + std::vector> arUnsortedEx; // sort by prioritet for (size_t fmt = 0; fmt < oox_sheet->m_arrConditionalFormatting.size(); fmt++) @@ -465,9 +466,9 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) } } if (priority >= 0) - mapSorted.insert(std::make_pair(priority, cond_fmt)); + mapSorted.insert(std::make_pair(priority, std::make_pair(cond_fmt, false))); else - arUnsorted.push_back(cond_fmt); + arUnsorted.push_back(std::make_pair(cond_fmt, false)); } } @@ -492,27 +493,32 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) } } if (priority >= 0) - mapSorted.insert(std::make_pair(priority, cond_fmt)); + mapSorted.insert(std::make_pair(priority, std::make_pair(cond_fmt, true))); else - arUnsorted.push_back(cond_fmt); + arUnsortedEx.push_back(std::make_pair(cond_fmt, true)); } } } } //-------------------------------------------------------------------------- - if (arUnsorted.size() + mapSorted.size() > 0) + if (arUnsorted.size() + mapSorted.size() + arUnsortedEx.size() > 0) { ods_context->start_conditional_formats(); for (size_t fmt = 0; fmt < arUnsorted.size(); fmt++) { - convert(arUnsorted[fmt]); + convert(arUnsorted[fmt].first, oox_sheet->m_mapConditionalFormattingEx, arUnsorted[fmt].second); } - for (std::multimap::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) + for (std::multimap>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { - convert(it->second); + convert(it->second.first, oox_sheet->m_mapConditionalFormattingEx, it->second.second); + } + + for (size_t fmt = 0; fmt < arUnsortedEx.size(); fmt++) + { + convert(arUnsortedEx[fmt].first, oox_sheet->m_mapConditionalFormattingEx, arUnsortedEx[fmt].second); } ods_context->end_conditional_formats(); } @@ -3409,24 +3415,51 @@ void XlsxConverter::convert(OOX::Spreadsheet::CAltTextTable *alt_text) if (!alt_text) return; } -void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt) +void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt, + std::map& mapCFRuleEx, bool isExt) { if (!oox_cond_fmt)return; - if (oox_cond_fmt->m_oSqRef.IsInit()) + bool bRule = false; + for (size_t i = 0; i < oox_cond_fmt->m_arrItems.size(); i++) + { + if (oox_cond_fmt->m_arrItems[i]->bUsage) continue; + bRule = true; + break; + } + if (!bRule) return; + + if (oox_cond_fmt->m_oSqRef.IsInit()) { ods_context->current_table()->start_conditional_format(oox_cond_fmt->m_oSqRef.get()); for (size_t i = 0; i < oox_cond_fmt->m_arrItems.size(); i++) { - convert(oox_cond_fmt->m_arrItems[i]);//rule + convert(oox_cond_fmt->m_arrItems[i], mapCFRuleEx, isExt);//rule } ods_context->current_table()->end_conditional_format(); } } -void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule) +void XlsxConverter::convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule, + std::map& mapCFRuleEx, bool isExt) { - if (!oox_cond_rule)return; + if (!oox_cond_rule) return; + + std::map::iterator pFind; + if (oox_cond_rule->m_oExtId.IsInit()) + { + pFind = mapCFRuleEx.find(*oox_cond_rule->m_oExtId); + + if (pFind != mapCFRuleEx.end()) + { + OOX::Spreadsheet::CConditionalFormattingRule newRule = + OOX::Spreadsheet::CConditionalFormattingRule::Merge(*oox_cond_rule, *pFind->second); + + pFind->second->bUsage = true; + convert(&newRule, mapCFRuleEx, true); + return; + } + } if (false == oox_cond_rule->m_oType.IsInit()) return; @@ -3480,26 +3513,38 @@ void XlsxConverter::convert(OOX::Spreadsheet::CDataBar *oox_cond_databar) _CP_OPT(odf_types::color) color; - if (oox_cond_databar->m_oBorderColor.IsInit()) - convert(oox_cond_databar->m_oBorderColor.GetPointer(), color); - else + if (oox_cond_databar->m_oColor.IsInit()) convert(oox_cond_databar->m_oColor.GetPointer(), color); + else if (oox_cond_databar->m_oBorderColor.IsInit()) // ???? + convert(oox_cond_databar->m_oBorderColor.GetPointer(), color); ods_context->current_table()->set_conditional_databar_color(color); convert(oox_cond_databar->m_oAxisColor.GetPointer(), color); ods_context->current_table()->set_conditional_databar_axis_color(color); - convert(oox_cond_databar->m_oNegativeBorderColor.GetPointer(), color); + if (oox_cond_databar->m_oNegativeFillColor.IsInit()) + convert(oox_cond_databar->m_oNegativeFillColor.GetPointer(), color); + else if (oox_cond_databar->m_oNegativeBorderColor.IsInit()) // ???? + convert(oox_cond_databar->m_oNegativeBorderColor.GetPointer(), color); + ods_context->current_table()->set_conditional_databar_negative_color(color); + if (oox_cond_databar->m_oGradient.IsInit()) + ods_context->current_table()->set_conditional_databar_gradient(oox_cond_databar->m_oGradient->ToBool()); + if (oox_cond_databar->m_oAxisPosition.IsInit()) ods_context->current_table()->set_conditional_databar_axis_position(oox_cond_databar->m_oAxisPosition->ToString()); if (oox_cond_databar->m_oShowValue.IsInit()) ods_context->current_table()->set_conditional_show_value(oox_cond_databar->m_oShowValue->ToBool()); - //nullable> m_oMaxLength; - //nullable> m_oMinLength; + + if (oox_cond_databar->m_oMaxLength.IsInit()) + ods_context->current_table()->set_conditional_databar_max(oox_cond_databar->m_oMaxLength->GetValue()); + + if (oox_cond_databar->m_oMinLength.IsInit()) + ods_context->current_table()->set_conditional_databar_min(oox_cond_databar->m_oMinLength->GetValue()); + for (size_t i=0; i< oox_cond_databar->m_arrValues.size(); i++) convert(oox_cond_databar->m_arrValues[i].GetPointer()); } diff --git a/OdfFile/Writer/Converter/XlsxConverter.h b/OdfFile/Writer/Converter/XlsxConverter.h index 39a268bfff5..1266979c112 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.h +++ b/OdfFile/Writer/Converter/XlsxConverter.h @@ -233,8 +233,10 @@ namespace Oox2Odf void convert(OOX::Spreadsheet::CSheetProtection *oox_prot); void convert(OOX::Spreadsheet::CDataValidations *oox_validations); void convert(OOX::Spreadsheet::CDataValidation *oox_validation); - void convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmt); - void convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule); + void convert(OOX::Spreadsheet::CConditionalFormatting *oox_cond_fmtc, + std::map& mapCFRuleEx, bool isExt); + void convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule, + std::map& mapCFRuleEx, bool isExt); void convert(OOX::Spreadsheet::CAutofilter *oox_filter); void convert(OOX::Spreadsheet::CFilterColumn *oox_filter_column); void convert(OOX::Spreadsheet::CDataBar *oox_cond_databar); diff --git a/OdfFile/Writer/Format/calcext_elements.cpp b/OdfFile/Writer/Format/calcext_elements.cpp index 57ffb5166ed..49efa3a4b4d 100644 --- a/OdfFile/Writer/Format/calcext_elements.cpp +++ b/OdfFile/Writer/Format/calcext_elements.cpp @@ -44,10 +44,13 @@ namespace odf_writer { void calcext_data_bar_attr::serialize(CP_ATTR_NODE) { - CP_XML_ATTR_OPT(L"calcext:axis-color", calcext_axis_color_); - CP_XML_ATTR_OPT(L"calcext:positive-color", calcext_positive_color_); - CP_XML_ATTR_OPT(L"calcext:negative-color", calcext_negative_color_); - CP_XML_ATTR_OPT(L"calcext:axis-position", calcext_axis_position_); + CP_XML_ATTR_OPT(L"calcext:axis-color", axis_color_); + CP_XML_ATTR_OPT(L"calcext:positive-color", positive_color_); + CP_XML_ATTR_OPT(L"calcext:negative-color", negative_color_); + CP_XML_ATTR_OPT(L"calcext:axis-position", axis_position_); + CP_XML_ATTR_OPT(L"calcext:gradient", gradient_); + CP_XML_ATTR_OPT(L"calcext:min-length", min_length_); + CP_XML_ATTR_OPT(L"calcext:max-length", max_length_); } void calcext_icon_set_attr::serialize(CP_ATTR_NODE) diff --git a/OdfFile/Writer/Format/calcext_elements.h b/OdfFile/Writer/Format/calcext_elements.h index 45f30c80cbd..9885064689b 100644 --- a/OdfFile/Writer/Format/calcext_elements.h +++ b/OdfFile/Writer/Format/calcext_elements.h @@ -56,10 +56,13 @@ class calcext_data_bar_attr public: void serialize(CP_ATTR_NODE); - _CP_OPT(odf_types::color) calcext_axis_color_; - _CP_OPT(odf_types::color) calcext_positive_color_; - _CP_OPT(odf_types::color) calcext_negative_color_; - _CP_OPT(std::wstring) calcext_axis_position_; + _CP_OPT(odf_types::color) axis_color_; + _CP_OPT(odf_types::color) positive_color_; + _CP_OPT(odf_types::color) negative_color_; + _CP_OPT(std::wstring) axis_position_; + _CP_OPT(odf_types::Bool) gradient_; + _CP_OPT(unsigned int) min_length_; + _CP_OPT(unsigned int) max_length_; }; class calcext_condition_attr diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index 2d45a6c37ef..adb678bf35b 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -2257,7 +2257,7 @@ void ods_table_state::set_conditional_databar_color(_CP_OPT(color)& color) if (cond_format) { - cond_format->attr_.calcext_positive_color_ = color; + cond_format->attr_.positive_color_ = color; } } void ods_table_state::set_conditional_databar_axis_color(_CP_OPT(color)& color) @@ -2266,7 +2266,7 @@ void ods_table_state::set_conditional_databar_axis_color(_CP_OPT(color)& color) if (cond_format) { - cond_format->attr_.calcext_axis_color_ = color; + cond_format->attr_.axis_color_ = color; } } void ods_table_state::set_conditional_databar_negative_color(_CP_OPT(color)& color) @@ -2275,7 +2275,7 @@ void ods_table_state::set_conditional_databar_negative_color(_CP_OPT(color)& col if (cond_format) { - cond_format->attr_.calcext_negative_color_ = color; + cond_format->attr_.negative_color_ = color; } } void ods_table_state::set_conditional_databar_axis_position(const std::wstring& type) @@ -2284,9 +2284,35 @@ void ods_table_state::set_conditional_databar_axis_position(const std::wstring& if (cond_format) { - cond_format->attr_.calcext_axis_position_ = type; + cond_format->attr_.axis_position_ = type; } +} +void ods_table_state::set_conditional_databar_gradient(bool val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + + if (cond_format) + { + cond_format->attr_.gradient_ = val; + } +} +void ods_table_state::set_conditional_databar_max(unsigned int val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + if (cond_format) + { + cond_format->attr_.max_length_ = val; + } +} +void ods_table_state::set_conditional_databar_min(unsigned int val) +{ + calcext_data_bar* cond_format = dynamic_cast(current_level_.back().get()); + + if (cond_format) + { + cond_format->attr_.min_length_ = val; + } } } diff --git a/OdfFile/Writer/Format/ods_table_state.h b/OdfFile/Writer/Format/ods_table_state.h index 85a5f6a86b0..af32f5c59ee 100644 --- a/OdfFile/Writer/Format/ods_table_state.h +++ b/OdfFile/Writer/Format/ods_table_state.h @@ -398,6 +398,9 @@ class ods_table_state void set_conditional_databar_negative_color(_CP_OPT(odf_types::color) & color); void set_conditional_databar_axis_color(_CP_OPT(odf_types::color) & color); void set_conditional_databar_axis_position(const std::wstring& value); + void set_conditional_databar_gradient(bool val); + void set_conditional_databar_max(unsigned int val); + void set_conditional_databar_min(unsigned int val); void set_conditional_style_name(const std::wstring &style_name); void set_conditional_operator(int _operator); From 245ba212c43e130988cebe6437071debf3718802 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 12 Mar 2024 23:55:01 +0300 Subject: [PATCH 412/794] fix bug #66849 --- OOXML/XlsxFormat/Table/Tables.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 4d28e8cbfa8..1f53cb3ba65 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -625,7 +625,14 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(i->m_oName.IsInit()) { i->m_oName = boost::algorithm::erase_all_copy(i->m_oName.get(), L"_x000a_"); - XLS::GlobalWorkbookInfo::mapTableColumnNames_static.at(m_oId->GetValue()).at(colInd) = i->m_oName.get(); + std::unordered_map>::iterator pFind = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(m_oId->GetValue()); + if (pFind != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + if (colInd < pFind->second.size()) + { + pFind->second[colInd] = i->m_oName.get(); + } + } } colInd++; } From a6370ec0a657a4f66101cae1b530021be58abfc4 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 13 Mar 2024 10:37:33 +0300 Subject: [PATCH 413/794] fix bug #66842 --- OdfFile/DataTypes/iconset_type.cpp | 18 +++++++++++++++++- OdfFile/DataTypes/iconset_type.h | 5 ++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/OdfFile/DataTypes/iconset_type.cpp b/OdfFile/DataTypes/iconset_type.cpp index e33365eb071..8239ab3a778 100644 --- a/OdfFile/DataTypes/iconset_type.cpp +++ b/OdfFile/DataTypes/iconset_type.cpp @@ -92,8 +92,18 @@ std::wostream & operator << (std::wostream & _Wostream, const iconset_type & _Va case iconset_type::Rating5: _Wostream << L"5Rating"; break; - default: + case iconset_type::Boxes5: + _Wostream << L"5Boxes"; break; + case iconset_type::Triangles3: + _Wostream << L"3Triangles"; + break; + case iconset_type::Stars3: + _Wostream << L"3Stars"; + break; + default: + _Wostream << L"3Arrows"; + break; } return _Wostream; } @@ -137,6 +147,12 @@ iconset_type iconset_type::parse(const std::wstring & Str) return iconset_type( Quarters5 ); else if (tmp == L"5rating") return iconset_type( Rating5 ); + else if (tmp == L"5Boxes") + return iconset_type( Boxes5 ); + else if (tmp == L"3Stars") + return iconset_type(Stars3); + else if (tmp == L"3Triangles") + return iconset_type(Triangles3); else { return iconset_type( Arrows3 ); diff --git a/OdfFile/DataTypes/iconset_type.h b/OdfFile/DataTypes/iconset_type.h index 71f4dfd20cc..e06745520ca 100644 --- a/OdfFile/DataTypes/iconset_type.h +++ b/OdfFile/DataTypes/iconset_type.h @@ -59,7 +59,10 @@ class iconset_type Arrows5, Arrows5Gray, Quarters5, - Rating5 + Rating5, + Stars3, + Triangles3, + Boxes5 }; iconset_type() {} From b065aff618ded70da1a4d2929b3b250693e9b00a Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 13 Mar 2024 10:57:11 +0300 Subject: [PATCH 414/794] Fixes for android --- Common/3dParty/v8/android/howto.txt | 46 ++++++++++++++++++ .../doctrenderer/js_internal/v8/v8_base.h | 10 ++-- .../src/main/cpp/jni/objects/JniBaseObjects.h | 48 +++++++------------ X2tConverter/src/main.cpp | 2 +- 4 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 Common/3dParty/v8/android/howto.txt diff --git a/Common/3dParty/v8/android/howto.txt b/Common/3dParty/v8/android/howto.txt new file mode 100644 index 00000000000..099db5a4a70 --- /dev/null +++ b/Common/3dParty/v8/android/howto.txt @@ -0,0 +1,46 @@ +Fixes for build 12.1 version for android with use_custom_libcxx: + +1) src/build/config/BUILD.gn + +group("common_deps") { ... } + +if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++" ] +} + +=> + +if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++" ] +} else { + # ONLYOFFICE-HACK + public_deps += [ "//buildtools/third_party/libunwind" ] +} + +2) src/buildtools/third_party/libunbind/BUILD.gn + +visibility = [ "//buildtools/third_party/libc++abi" ] + +=> +visibility = [ "//buildtools/third_party/libc++abi" ] +# ONLYOFFICE-HACK +visibility += ["//build/config:common_deps"] + +3) src/zone/zone.h + +all records: +static_assert(alignof(T) <= kAlignmentInBytes); + +=> + +// ONLYOFFICE-HACK +//static_assert(alignof(T) <= kAlignmentInBytes); + +Fixes for link static library WITH custom libc++: + +v8.pri: +v8_custom_libcxx { + LIBS += $$CORE_V8_PATH_LIBS/third_party/libc++/libc++/*.o + LIBS += $$CORE_V8_PATH_LIBS/third_party/libc++abi/libc++abi/*.o + LIBS += $$CORE_V8_PATH_LIBS/third_party/libunwind/libunwind/*.o +} diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index 7842fed0e8c..fe200c07dfb 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -60,7 +60,7 @@ v8::Local CreateV8String(v8::Isolate* i, const std::string& str); #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "js", __VA_ARGS__) #endif -#if 1 +#if V8_OS_XP class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: @@ -121,9 +121,7 @@ class CV8Initializer v8::V8::InitializeICUDefaultLocation(sPrA.c_str()); v8::V8::InitializeExternalStartupData(sPrA.c_str()); #ifdef V8_VERSION_89_PLUS - //m_platform = v8::platform::NewDefaultPlatform(); - v8::V8::SetFlagsFromString("--single-threaded"); - m_platform = v8::platform::NewSingleThreadedDefaultPlatform(); + m_platform = v8::platform::NewDefaultPlatform(); v8::V8::InitializePlatform(m_platform.get()); #else m_platform = v8::platform::CreateDefaultPlatform(); @@ -153,7 +151,11 @@ class CV8Initializer #endif v8::V8::Dispose(); + #ifdef V8_VERSION_121_PLUS + v8::V8::DisposePlatform(); + #else v8::V8::ShutdownPlatform(); + #endif if (m_pAllocator) delete m_pAllocator; diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h index 4522a3f1fc3..ba56a040866 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/objects/JniBaseObjects.h @@ -3,10 +3,9 @@ #include #include -#include -#include #include #include +#include "../../../../../../../../../DesktopEditor/common/File.h" #define DELETE_LOCAL_REF(ENV, REFERENCE) \ if (REFERENCE != NULL && !ENV->IsSameObject(REFERENCE, NULL)) { \ @@ -140,8 +139,8 @@ class JniBaseObjects { static std::string jstringToString(JNIEnv* env, jstring jstr) { jboolean isCopy; const char * charPath = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - const std::string str(charPath, charPath + size); + const int size = env->GetStringUTFLength(jstr); + const std::string str(charPath, (size_t)size); env->ReleaseStringUTFChars(jstr, charPath); return str; } @@ -149,23 +148,28 @@ class JniBaseObjects { static std::string* jstringToPString(JNIEnv* env, jstring jstr) { jboolean isCopy; const char * charPath = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - std::string* pStr = new std::string(charPath, charPath + size); + const int size = env->GetStringUTFLength(jstr); + std::string* pStr = new std::string(charPath, (size_t)size); env->ReleaseStringUTFChars(jstr, charPath); return pStr; } static std::wstring jstringToWString(JNIEnv* env, jstring jstr) { jboolean isCopy; - const char * cstr = env->GetStringUTFChars(jstr, &isCopy); - const int size = env->GetStringLength(jstr); - const std::wstring wstr = charsToWString(cstr); - env->ReleaseStringUTFChars(jstr, cstr); - return wstr; + const char * charPath = env->GetStringUTFChars(jstr, &isCopy); + const int size = env->GetStringUTFLength(jstr); + std::wstring pStr = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)charPath, (LONG)size); + env->ReleaseStringUTFChars(jstr, charPath); + return pStr; } - static jstring wStringToJString(JNIEnv* env, const std::wstring wstr) { - return env->NewStringUTF(wStringToString(wstr).c_str()); + static jstring wStringToJString(JNIEnv* env, const std::wstring& wstr) { + std::string sTmp = U_TO_UTF8(wstr); + return stringToJString(env, sTmp); + } + + static jstring stringToJString(JNIEnv* env, const std::string& str) { + return env->NewStringUTF(str.c_str()); } static jstring charToJString(JNIEnv* env, const char * str) { @@ -184,24 +188,6 @@ class JniBaseObjects { return jArray; } - static std::wstring charsToWString(const char * str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.from_bytes(str); - } - - static std::wstring stringToWString(const std::string & str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.from_bytes(str); - } - - static std::string wStringToString(const std::wstring & str) { - using convert_typeX = std::codecvt_utf8; - std::wstring_convert converterX; - return converterX.to_bytes(str); - } - static jobjectArray wStringToObjectArray(JNIEnv *jEnv, std::wstring *data, int length) { jobjectArray jObjectArray = NULL; jsize len = length; diff --git a/X2tConverter/src/main.cpp b/X2tConverter/src/main.cpp index 6b19ec11c70..c615cb5cdbb 100644 --- a/X2tConverter/src/main.cpp +++ b/X2tConverter/src/main.cpp @@ -98,7 +98,7 @@ int wmain_lib(int argc, wchar_t *argv[]) if (sMemoryLimit.empty()) sMemoryLimit = NSSystemUtils::gc_EnvMemoryLimitDefault; -#if !defined(_DEBUG) +#if !defined(_DEBUG) && !defined(__ANDROID__) && !defined(_IOS) long long nMemoryLimit; if (NSStringExt::FromHumanReadableByteCount(sMemoryLimit, nMemoryLimit) && nMemoryLimit > 0) limit_memory((size_t)nMemoryLimit); From 53677bf8ccff17a044411c33a6ac436754f432e4 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 13 Mar 2024 11:04:55 +0300 Subject: [PATCH 415/794] Revert test changes --- Common/3dParty/v8/android/build.py | 2 +- Common/3dParty/v8/v8.pri | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Common/3dParty/v8/android/build.py b/Common/3dParty/v8/android/build.py index 0c31835c777..14129064c6d 100644 --- a/Common/3dParty/v8/android/build.py +++ b/Common/3dParty/v8/android/build.py @@ -123,7 +123,7 @@ def get_android_args(platform, sdk_ver=21): "v8_static_library=true", "v8_monolithic=true", "use_custom_libcxx=false", - "android_ndk_version=\\\"26.2.11394342\\\"", + "android_ndk_version=\\\"21.1.6352462\\\"", "android_sdk_version=\\\"" + str(sdk_ver) + "\\\"", "clang_use_chrome_plugins=false", "v8_use_external_startup_data=false", diff --git a/Common/3dParty/v8/v8.pri b/Common/3dParty/v8/v8.pri index 1148ffb566d..24f6fe1afb2 100644 --- a/Common/3dParty/v8/v8.pri +++ b/Common/3dParty/v8/v8.pri @@ -30,8 +30,6 @@ core_android { isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_armv7): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/armeabi-v7a isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_x86): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/x86 isEqual(CORE_BUILDS_PLATFORM_PREFIX, android_x86_64): CORE_V8_PATH_LIBS=$$CORE_V8_PATH_LIBS/x86_64 - - LIBS += -ldl } INCLUDEPATH += \ From e518efc5e1cbb6a545d44fdab97eeb7a677ac615 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 13 Mar 2024 11:10:31 +0300 Subject: [PATCH 416/794] . --- .../doctrenderer/js_internal/v8/v8_base.h | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index fe200c07dfb..671407ac7e9 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -52,33 +52,36 @@ v8::Local CreateV8String(v8::Isolate* i, const char* str, const int& len = -1); v8::Local CreateV8String(v8::Isolate* i, const std::string& str); +#ifdef __ANDROID__ + +#ifdef _DEBUG #define ANDROID_LOGS +#endif + #ifdef ANDROID_LOGS -//#define ANDROID_LOGS_ALL_FUNCTIONS #include #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "js", __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "js", __VA_ARGS__) #endif +#endif + #if V8_OS_XP class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { - LOGW("allocate: %d\n", (int)length); void* ret = malloc(length); memset(ret, 0, length); return ret; } virtual void* AllocateUninitialized(size_t length) { - LOGW("allocate_uninitialized: %d\n", (int)length); return malloc(length); } virtual void Free(void* data, size_t length) { - LOGW("free: %d\n", (int)length); free(data); } }; @@ -492,12 +495,6 @@ namespace NSJSBase CInspectorPool::get().getInspector(V8IsolateOneArg).startAgent(false); #endif -#ifdef ANDROID_LOGS_ALL_FUNCTIONS - std::string sFuncName(name); - std::string sFunc = "[JS call_func: " + sFuncName + "]"; - LOGW(sFunc.c_str()); -#endif - LOGGER_START v8::Local _name = CreateV8String(CV8Worker::GetCurrent(), name); @@ -531,11 +528,6 @@ namespace NSJSBase LOGGER_LAP_NAME(name) -#ifdef ANDROID_LOGS_ALL_FUNCTIONS - sFunc = "[JS call_func_end: " + sFuncName + "]"; - LOGW(sFunc.c_str()); -#endif - JSSmart _ret = _return; return _ret; } From 38ce36fa7563154cb3e011142cf1d328b9e2e0a6 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 13 Mar 2024 11:11:58 +0300 Subject: [PATCH 417/794] . --- DesktopEditor/doctrenderer/js_internal/v8/v8_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index 671407ac7e9..a6b5e332c37 100644 --- a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h +++ b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h @@ -66,7 +66,7 @@ v8::Local CreateV8String(v8::Isolate* i, const std::string& str); #endif -#if V8_OS_XP +#ifdef V8_OS_XP class MallocArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: From 6995a5ef34f70772b8018b5f3d72615013e0e387 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 13 Mar 2024 14:42:40 +0600 Subject: [PATCH 418/794] Fix endless formula conversion --- .../XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index d0405285065..14d55c2e1ed 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -401,6 +401,10 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R else { + //add error name to prevent endless formula conversion + rgce.sequence.clear(); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgErr(L"#NAME?"))); + break; // EXCEPT::RT::WrongFormulaString("Unknown operand format in formula.", assembled_formula); } last_ptg = found_operand; From 112dbd9e8883d8558dc9c2b5a975c58f14c0d443 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 13 Mar 2024 12:18:59 +0300 Subject: [PATCH 419/794] Fixes for build module --- DesktopEditor/cximage/png/pnglibconf.h | 2 +- DesktopEditor/graphics/pro/Image.h | 4 ++-- DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp | 1 + DesktopEditor/raster/Metafile/MetaFile.cpp | 8 ++++---- DesktopEditor/raster/Metafile/MetaFile.h | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/DesktopEditor/cximage/png/pnglibconf.h b/DesktopEditor/cximage/png/pnglibconf.h index a0c12ae94d7..db81a16d46a 100644 --- a/DesktopEditor/cximage/png/pnglibconf.h +++ b/DesktopEditor/cximage/png/pnglibconf.h @@ -128,7 +128,7 @@ #define PNG_READ_TEXT_SUPPORTED #define PNG_WRITE_BGR_SUPPORTED #define PNG_USER_CHUNKS_SUPPORTED -#define PNG_CONSOLE_IO_SUPPORTED +//#define PNG_CONSOLE_IO_SUPPORTED #define PNG_WRITE_PACK_SUPPORTED #define PNG_READ_FILLER_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED diff --git a/DesktopEditor/graphics/pro/Image.h b/DesktopEditor/graphics/pro/Image.h index 38606d11d67..afce354eb11 100644 --- a/DesktopEditor/graphics/pro/Image.h +++ b/DesktopEditor/graphics/pro/Image.h @@ -121,8 +121,8 @@ namespace MetaFile IMetaFile(NSFonts::IApplicationFonts *pAppFonts) {} virtual ~IMetaFile() {} - virtual void SetImageSize(int nWidth, int nHeight) = 0; - virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; + virtual void SetImageSize(int nWidth, int nHeight) = 0; + virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0; virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0; virtual void Close() = 0; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e75..cf6435762ce 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,6 +39,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : IMetaFile(pAppFonts) {} virtual ~CMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } diff --git a/DesktopEditor/raster/Metafile/MetaFile.cpp b/DesktopEditor/raster/Metafile/MetaFile.cpp index 2ed522173d2..5fa5c01c38c 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.cpp +++ b/DesktopEditor/raster/Metafile/MetaFile.cpp @@ -81,10 +81,10 @@ namespace MetaFile Close(); RELEASEINTERFACE(m_pFontManager); } - void CMetaFile::SetImageSize(int nWidth, int nHeight) - { - // for meta with empty size - } + void CMetaFile::SetImageSize(int nWidth, int nHeight) + { + // for meta with empty size + } std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight) { diff --git a/DesktopEditor/raster/Metafile/MetaFile.h b/DesktopEditor/raster/Metafile/MetaFile.h index 94bcf378238..1d1d563877a 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.h +++ b/DesktopEditor/raster/Metafile/MetaFile.h @@ -62,7 +62,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts); virtual ~CMetaFile(); - void SetImageSize(int nWidth, int nHeight); + void SetImageSize(int nWidth, int nHeight); bool LoadFromFile(const wchar_t* wsFilePath); bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize); bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight); From 9832010dd7150d93d345724f9d927399ebb603c8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 13 Mar 2024 19:22:40 +0600 Subject: [PATCH 420/794] Add xti reading while xml read --- OOXML/XlsxFormat/Workbook/Sheets.cpp | 16 +++++++ OOXML/XlsxFormat/Workbook/Sheets.h | 1 + OOXML/XlsxFormat/Workbook/Workbook.cpp | 59 ++++++++++++-------------- OOXML/XlsxFormat/Workbook/Workbook.h | 1 + 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index 6fc2a4616d3..e4309a7c55a 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -178,6 +178,12 @@ namespace OOX } } + auto sheetIndex = 0; + for(auto i:m_arrItems) + { if(i->m_oName.IsInit()) + AddSheetRef(i->m_oName.get(), sheetIndex); + sheetIndex++; + } } void CSheets::fromBin(std::vector& obj) { @@ -205,6 +211,16 @@ namespace OOX void CSheets::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { } + void CSheets::AddSheetRef(const std::wstring& link, const _INT32& sheetIndex) + { + XLS::GlobalWorkbookInfo::_xti val_1; + val_1.iSup = sheetIndex; + val_1.itabFirst = sheetIndex; + val_1.itabLast = sheetIndex; + val_1.link = link; + + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(val_1); + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Sheets.h b/OOXML/XlsxFormat/Workbook/Sheets.h index fc1956be6ad..fcb5b5af0a8 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.h +++ b/OOXML/XlsxFormat/Workbook/Sheets.h @@ -100,6 +100,7 @@ namespace OOX virtual EElementType getType () const; private: + void AddSheetRef(const std::wstring& link, const _INT32& sheetIndex); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 9342b0ac087..3c23b8f636d 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -297,36 +297,6 @@ namespace OOX auto ptr(new XLSB::BUNDLESHS); ptr->m_arBrtBundleSh = m_oSheets->toBin(); workBookStream->m_BUNDLESHS = XLS::BaseObjectPtr{ptr}; - - auto ptr1(new XLSB::EXTERNALS); - workBookStream->m_EXTERNALS = XLS::BaseObjectPtr{ptr1}; - auto externSheet(new XLSB::ExternSheet); - ptr1->m_BrtExternSheet = XLS::BaseObjectPtr{externSheet}; - externSheet->cXTI = ptr->m_arBrtBundleSh.size(); - for(auto i = 0; i < ptr->m_arBrtBundleSh.size(); i++) - { - auto sup(new XLSB::SUP); - auto supSelf(new XLSB::SupSelf); - sup->m_source = XLS::BaseObjectPtr{supSelf}; - ptr1->m_arSUP.push_back(XLS::BaseObjectPtr{sup}); - auto xti(new XLS::XTI); - xti->iSupBook = i; - xti->itabFirst = i; - xti->itabLast = i; - - auto biffStructPtr = XLS::BiffStructurePtr(xti); - externSheet->rgXTI.push_back(biffStructPtr); - - XLS::GlobalWorkbookInfo::_xti val_1; - val_1.iSup = xti->iSupBook; - val_1.itabFirst = i; - val_1.itabLast = i; - auto sheet = static_cast(ptr->m_arBrtBundleSh[i].get()); - val_1.link = sheet->strName; - - XLS::GlobalWorkbookInfo::arXti_External_static.push_back(val_1); - - } } if (m_oWorkbookPr.IsInit()) workBookStream->m_BrtWbProp = m_oWorkbookPr->toBin(); @@ -339,13 +309,13 @@ namespace OOX if (m_oWorkbookProtection.IsInit()) workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); + workBookStream->m_EXTERNALS = WriteXtiRefs(); if (m_oExternalReferences.IsInit()) { auto ptr = static_cast(workBookStream->m_EXTERNALS.get()); auto sups = m_oExternalReferences->toBin(); if(!sups.empty()) ptr->m_arSUP.insert(ptr->m_arSUP.end(), sups.begin(), sups.end()); - } @@ -632,6 +602,33 @@ xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\"\ return lActiveSheet; } + XLS::BaseObjectPtr CWorkbook::WriteXtiRefs() const + { + auto ptr(new XLSB::EXTERNALS); + + + auto externSheet(new XLSB::ExternSheet); + ptr->m_BrtExternSheet = XLS::BaseObjectPtr{externSheet}; + + for(auto i:XLS::GlobalWorkbookInfo::arXti_External_static) + { + auto sup(new XLSB::SUP); + auto supSelf(new XLSB::SupSelf); + sup->m_source = XLS::BaseObjectPtr{supSelf}; + ptr->m_arSUP.push_back(XLS::BaseObjectPtr{sup}); + + auto xti(new XLS::XTI); + xti->iSupBook = i.iSup; + xti->itabFirst = i.itabFirst; + xti->itabLast = i.itabLast; + + auto biffStructPtr = XLS::BiffStructurePtr(xti); + externSheet->rgXTI.push_back(biffStructPtr); + } + externSheet->cXTI = externSheet->rgXTI.size(); + return XLS::BaseObjectPtr{ptr}; + } + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Workbook.h b/OOXML/XlsxFormat/Workbook/Workbook.h index a3b31d97db8..a5046deadab 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -141,6 +141,7 @@ namespace OOX void PrepareToWrite(); LONG GetActiveSheetIndex(); + XLS::BaseObjectPtr WriteXtiRefs() const; CPath m_oReadPath; From 0053b72656e419e4f161559709defb9d7d996146 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 13 Mar 2024 17:13:25 +0300 Subject: [PATCH 421/794] Remove unused files --- .../3dParty/openssl/build-android-common.sh | 220 ------------------ .../3dParty/openssl/build-android-openssl.sh | 126 ---------- 2 files changed, 346 deletions(-) delete mode 100755 Common/3dParty/openssl/build-android-common.sh delete mode 100755 Common/3dParty/openssl/build-android-openssl.sh diff --git a/Common/3dParty/openssl/build-android-common.sh b/Common/3dParty/openssl/build-android-common.sh deleted file mode 100755 index d1b069c0473..00000000000 --- a/Common/3dParty/openssl/build-android-common.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source ./build-common.sh - -export PLATFORM_TYPE="Android" -export ARCHS=("arm" "arm64" "x86" "x86_64") -export ABIS=("armeabi-v7a" "arm64-v8a" "x86" "x86_64") -export ABI_TRIPLES=("arm-linux-androideabi" "aarch64-linux-android" "i686-linux-android" "x86_64-linux-android") -export ANDROID_API=21 - -# for test -# export ARCHS=("x86_64") -# export ABIS=("x86_64") -# export ABI_TRIPLES=("x86_64-linux-android") - -if [[ -z ${ANDROID_NDK_ROOT} ]]; then - echo "ANDROID_NDK_ROOT not defined" - exit 1 -fi - -function get_toolchain() { - HOST_OS=$(uname -s) - case ${HOST_OS} in - Darwin) HOST_OS=darwin ;; - Linux) HOST_OS=linux ;; - FreeBsd) HOST_OS=freebsd ;; - CYGWIN* | *_NT-*) HOST_OS=cygwin ;; - esac - - HOST_ARCH=$(uname -m) - case ${HOST_ARCH} in - i?86) HOST_ARCH=x86 ;; - x86_64 | amd64) HOST_ARCH=x86_64 ;; - esac - - echo "${HOST_OS}-${HOST_ARCH}" -} - -function get_android_arch() { - local common_arch=$1 - case ${common_arch} in - arm) - echo "arm-v7a" - ;; - arm64) - echo "arm64-v8a" - ;; - x86) - echo "x86" - ;; - x86_64) - echo "x86-64" - ;; - esac -} - -function get_target_build() { - local arch=$1 - case ${arch} in - arm-v7a) - echo "arm" - ;; - arm64-v8a) - echo "arm64" - ;; - x86) - echo "x86" - ;; - x86-64) - echo "x86_64" - ;; - esac -} - -function get_build_host_internal() { - local arch=$1 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "arm-linux-androideabi" - ;; - arm64-v8a) - echo "aarch64-linux-android" - ;; - x86) - echo "i686-linux-android" - ;; - x86-64) - echo "x86_64-linux-android" - ;; - esac -} - -function android_get_build_host() { - local arch=$(get_android_arch $1) - get_build_host_internal $arch -} - -function get_clang_target_host() { - local arch=$1 - local api=$2 - case ${arch} in - arm-v7a | arm-v7a-neon) - echo "armv7a-linux-androideabi${api}" - ;; - arm64-v8a) - echo "aarch64-linux-android${api}" - ;; - x86) - echo "i686-linux-android${api}" - ;; - x86-64) - echo "x86_64-linux-android${api}" - ;; - esac -} - -function set_android_toolchain_bin() { - export PATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/$(get_toolchain)/bin:$PATH - echo PATH=$PATH -} - -function set_android_toolchain() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - local build_host=$(get_build_host_internal "$arch") - local clang_target_host=$(get_clang_target_host "$arch" "$api") - - export AR=${build_host}-ar - export CC=${clang_target_host}-clang - export CXX=${clang_target_host}-clang++ - export AS=${build_host}-as - export LD=${build_host}-ld - export RANLIB=${build_host}-ranlib - export STRIP=${build_host}-strip -} - -function get_common_includes() { - local toolchain=$(get_toolchain) - echo "-I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/include -I${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/local/include" -} -function get_common_linked_libraries() { - local api=$1 - local arch=$2 - local toolchain=$(get_toolchain) - local build_host=$(get_build_host_internal "$arch") - echo "-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/${build_host}/lib -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/sysroot/usr/lib/${build_host}/${api} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${toolchain}/lib" -} - -function set_android_cpu_feature() { - local name=$1 - local arch=$(get_android_arch $2) - local api=$3 - case ${arch} in - arm-v7a | arm-v7a-neon) - export CFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - arm64-v8a) - export CFLAGS="-march=armv8-a -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=armv8-a -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86) - export CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=i686 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - x86-64) - export CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -Wno-unused-function -fno-integrated-as -fstrict-aliasing -fPIC -DANDROID -D__ANDROID_API__=${api} -Os -ffunction-sections -fdata-sections $(get_common_includes)" - export CXXFLAGS="-std=c++11 -Os -ffunction-sections -fdata-sections" - export LDFLAGS="-march=x86-64 -Wl,--gc-sections -Os -ffunction-sections -fdata-sections $(get_common_linked_libraries ${api} ${arch})" - export CPPFLAGS=${CFLAGS} - ;; - esac -} - -function android_printf_global_params() { - local arch=$1 - local abi=$2 - local abi_triple=$3 - local in_dir=$4 - local out_dir=$5 - echo -e "arch = $arch" - echo -e "abi = $abi" - echo -e "abi_triple = $abi_triple" - echo -e "PLATFORM_TYPE = $PLATFORM_TYPE" - echo -e "ANDROID_API = $ANDROID_API" - echo -e "in_dir = $in_dir" - echo -e "out_dir = $out_dir" - echo -e "AR = $AR" - echo -e "CC = $CC" - echo -e "CXX = $CXX" - echo -e "AS = $AS" - echo -e "LD = $LD" - echo -e "RANLIB = $RANLIB" - echo -e "STRIP = $STRIP" - echo -e "CFLAGS = $CFLAGS" - echo -e "CXXFLAGS = $CXXFLAGS" - echo -e "LDFLAGS = $LDFLAGS" - echo -e "CPPFLAGS = $CPPFLAGS" -} diff --git a/Common/3dParty/openssl/build-android-openssl.sh b/Common/3dParty/openssl/build-android-openssl.sh deleted file mode 100755 index e710b6fb6e3..00000000000 --- a/Common/3dParty/openssl/build-android-openssl.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash -# -# Copyright 2016 leenjewel -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# # read -n1 -p "Press any key to continue..." - -set -u - -source ./build-android-common.sh - -init_log_color - -TOOLS_ROOT=$(pwd) - -SOURCE="$0" -while [ -h "$SOURCE" ]; do - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" -done -pwd_path="$(cd -P "$(dirname "$SOURCE")" && pwd)" - -echo pwd_path=${pwd_path} -echo TOOLS_ROOT=${TOOLS_ROOT} - -# openssl-1.1.0f has a configure bug -# openssl-1.1.1d has fix configure bug -LIB_VERSION="OpenSSL_1_1_1i" -LIB_NAME="openssl-1.1.1i" - -echo "https://www.openssl.org/source/${LIB_NAME}.tar.gz" - -# https://github.com/openssl/openssl/archive/OpenSSL_1_1_1d.tar.gz -# https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.tar.gz -[ -f "${LIB_NAME}.tar.gz" ] || curl -L -o ${LIB_NAME}.tar.gz https://www.openssl.org/source/${LIB_NAME}.tar.gz -s -[ -f "${LIB_NAME}.tar.gz" ] || log_error "openssl download error!" - -set_android_toolchain_bin - -function configure_make() { - - ARCH=$1 - ABI=$2 - ABI_TRIPLE=$3 - - log_info "configure $ABI start..." - - if [ -d "${LIB_NAME}" ]; then - rm -fr "${LIB_NAME}" - fi - tar xfz "${LIB_NAME}.tar.gz" - pushd . - cd "${LIB_NAME}" - - PREFIX_DIR="${pwd_path}/build/android/${ABI}" - if [ -d "${PREFIX_DIR}" ]; then - rm -fr "${PREFIX_DIR}" - fi - mkdir -p "${PREFIX_DIR}" - - OUTPUT_ROOT=${TOOLS_ROOT}/build/android/${ABI} - mkdir -p ${OUTPUT_ROOT}/log - - set_android_toolchain "openssl" "${ARCH}" "${ANDROID_API}" - set_android_cpu_feature "openssl" "${ARCH}" "${ANDROID_API}" - - export ANDROID_NDK_HOME=${ANDROID_NDK_ROOT} - echo ANDROID_NDK_HOME=${ANDROID_NDK_HOME} - - android_printf_global_params "$ARCH" "$ABI" "$ABI_TRIPLE" "$PREFIX_DIR" "$OUTPUT_ROOT" - - if [[ "${ARCH}" == "x86_64" ]]; then - - ./Configure android-x86_64 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "x86" ]]; then - - ./Configure android-x86 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "arm" ]]; then - - ./Configure android-arm --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - elif [[ "${ARCH}" == "arm64" ]]; then - - ./Configure android-arm64 --prefix="${PREFIX_DIR}" no-shared no-tests enable-ssl3 enable-ssl3-method enable-md2 no-asm - - else - log_error "not support" && exit 1 - fi - - log_info "make $ABI start..." - - sed -ie 's/LIB_CFLAGS=/LIB_CFLAGS=-fvisibility=hidden /g' ./Makefile - sed -ie 's/LIB_CXXFLAGS=/LIB_CXXFLAGS=-fvisibility=hidden /g' ./Makefile - - make clean >"${OUTPUT_ROOT}/log/${ABI}.log" - if make -j$(get_cpu_count) >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1; then - make install_sw >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - make install_ssldirs >>"${OUTPUT_ROOT}/log/${ABI}.log" 2>&1 - fi - - popd -} - -log_info "${PLATFORM_TYPE} ${LIB_NAME} start..." - -for ((i = 0; i < ${#ARCHS[@]}; i++)); do - if [[ $# -eq 0 || "$1" == "${ARCHS[i]}" ]]; then - configure_make "${ARCHS[i]}" "${ABIS[i]}" "${ABI_TRIPLES[i]}" - fi -done - -log_info "${PLATFORM_TYPE} ${LIB_NAME} end..." From 27ebebdd0e4729b376c57dd3d3f3d644c43bed51 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 13 Mar 2024 17:27:31 +0300 Subject: [PATCH 422/794] fix flags --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 18 +++++++++--------- OOXML/XlsxFormat/Worksheets/SheetData.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index c3440c0393e..71f41e0f222 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -475,7 +475,7 @@ namespace OOX } return nLen; } - _UINT16 CFormulaXLSB::toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula) + _UINT32 CFormulaXLSB::toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula) { _UINT16 nFlags = 0; if(m_oCa.ToBool()) @@ -486,7 +486,7 @@ namespace OOX oStream.WriteULONG(0);//cce oStream.WriteULONG(0);//cb - _UINT16 nFlagsExt = 0; + _UINT32 nFlagsExt = 0; nFlagsExt |= m_oT.GetValue(); nFlagsExt |= 0x4; if(m_oAca.ToBool()) @@ -721,7 +721,7 @@ namespace OOX break; } - _UINT16 nFlags = 0; + _UINT32 nFlags = 0; if(m_oFormula.m_bIsInit) { nFlags = m_oFormula.toXLSB(oStream, bIsBlankFormula); @@ -733,13 +733,13 @@ namespace OOX } if (m_oCellMetadata.IsInit()) { - nFlags |= 0x4000; + nFlags |= 0x8000; } if (m_oValueMetadata.IsInit()) { - nFlags |= 0x8000; + nFlags |= 0x10000; } - oStream.WriteUSHORT(nFlags); + oStream.WriteULONG(nFlags); if(m_oFormula.m_bIsInit) { m_oFormula.toXLSBExt(oStream); @@ -1784,7 +1784,7 @@ namespace OOX m_oFormula->fromXLSB(oStream); } //todo it breaks xslb format - _UINT16 nFlags = oStream.GetUShort(); + _UINT32 nFlags = oStream.GetULong(); if(0 != (nFlags & 0x4)) { if(!m_oFormula.IsInit()) @@ -1806,11 +1806,11 @@ namespace OOX m_oRichText.Init(); m_oRichText->fromXLSBExt(oStream); } - if (0 != (nStyleRef & 0x4000)) + if (0 != (nFlags & 0x8000)) { m_oCellMetadata = oStream.GetULong(); } - if (0 != (nStyleRef & 0x8000)) + if (0 != (nFlags & 0x10000)) { m_oValueMetadata = oStream.GetULong(); } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index fb7b09dc4be..d3effe3fb7b 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -61,7 +61,7 @@ namespace OOX void Clean(); void fromXML(XmlUtils::CXmlLiteReader& oReader); _UINT32 getXLSBSize(); - _UINT16 toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula); + _UINT32 toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula); void toXLSBExt(NSBinPptxRW::CXlsbBinaryWriter& oStream); bool m_bIsInit; From 1a676ace8bdc6ef3894efe39b4ebd977524dad73 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 13 Mar 2024 18:43:13 +0300 Subject: [PATCH 423/794] fix bug #66857 --- Common/OfficeFileFormatChecker2.cpp | 2 +- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 2 +- OdfFile/DataTypes/iconset_type.h | 2 +- OdfFile/Reader/Format/calcext_elements.cpp | 2 +- OdfFile/Writer/Format/calcext_elements.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 1fdb6b6f349..2ee7f1bede9 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -299,7 +299,7 @@ bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) std::string UserType, ClipboardFormat, Program; POLE::Stream streamCompObject(storage, L"CompObj"); - if (false == streamCompObject.fail()) + if (false == streamCompObject.fail() && streamCompObject.size() >= 28) { streamCompObject.seek(28); // skip Header diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 073c3f05a01..cbec1638f2d 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -5867,7 +5867,7 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh } } } - if (pImageFileCache.IsInit() && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) + if (false == pImageFileCache.IsInit() && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) { sIdImageFileCache = pOleObject->m_oObjectPr->m_oRid->GetValue(); diff --git a/OdfFile/DataTypes/iconset_type.h b/OdfFile/DataTypes/iconset_type.h index e06745520ca..cfee13fb156 100644 --- a/OdfFile/DataTypes/iconset_type.h +++ b/OdfFile/DataTypes/iconset_type.h @@ -60,8 +60,8 @@ class iconset_type Arrows5Gray, Quarters5, Rating5, - Stars3, Triangles3, + Stars3, Boxes5 }; diff --git a/OdfFile/Reader/Format/calcext_elements.cpp b/OdfFile/Reader/Format/calcext_elements.cpp index 7460fde492f..2eee236ec80 100644 --- a/OdfFile/Reader/Format/calcext_elements.cpp +++ b/OdfFile/Reader/Format/calcext_elements.cpp @@ -238,7 +238,7 @@ void calcext_icon_set::xlsx_convert(oox::xlsx_conversion_context & Context) } } -// calcext_formatting_entry +/// calcext:formatting-entry //--------------------------------------------------------------------------------------------------------- const wchar_t * calcext_formatting_entry::ns = L"calcext"; const wchar_t * calcext_formatting_entry::name = L"formatting-entry"; diff --git a/OdfFile/Writer/Format/calcext_elements.cpp b/OdfFile/Writer/Format/calcext_elements.cpp index 49efa3a4b4d..2e2fda1e7a6 100644 --- a/OdfFile/Writer/Format/calcext_elements.cpp +++ b/OdfFile/Writer/Format/calcext_elements.cpp @@ -239,7 +239,7 @@ void calcext_icon_set::serialize(std::wostream & _Wostream) } } -// calcext_formatting_entry +// calcext:formatting-entry ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * calcext_formatting_entry::ns = L"calcext"; const wchar_t * calcext_formatting_entry::name = L"formatting-entry"; From 00769d01c12c338a8757a709b58250dd60ae7422 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 14 Mar 2024 11:42:25 +0300 Subject: [PATCH 424/794] Fix bug 66537 --- PdfFile/SrcReader/RendererOutputDev.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index e9943ad7bd8..552d99bc6f0 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -1608,7 +1608,7 @@ namespace PdfReader nLen = 0; } } - else if (L"" != wsFileName && (pFont8bit = dynamic_cast(pFont)) && pFont8bit->getHasEncoding()) + else if (L"" != wsFileName && (pFont8bit = dynamic_cast(pFont))) { char **ppEncoding = pFont8bit->getEncoding(); if (!ppEncoding) From 7d15bbc7c28e915b0b857a0a50f44a7a2eb5c9ea Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 14 Mar 2024 12:17:51 +0300 Subject: [PATCH 425/794] Fix build --- DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e75..cf6435762ce 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,6 +39,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : IMetaFile(pAppFonts) {} virtual ~CMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } From 08ae2f5d2e41b40676fa02526012487611418b42 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 14 Mar 2024 15:37:38 +0300 Subject: [PATCH 426/794] Fix bug 66721 --- PdfFile/SrcReader/RendererOutputDev.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 552d99bc6f0..867f9e20d8a 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3945,8 +3945,8 @@ namespace PdfReader pNewTm[1] = pTm[1] * dITextScale * pGState->getHorizScaling(); pNewTm[2] = -pTm[2] * dITextScale; pNewTm[3] = -pTm[3] * dITextScale; - pNewTm[4] = dX; - pNewTm[5] = dY; + pNewTm[4] = dX - dOriginX; + pNewTm[5] = dY - dOriginY; } else { From 94ceab0a03e137561430f3a354513d1b6a80a5a4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 14 Mar 2024 19:33:07 +0600 Subject: [PATCH 427/794] Add multysheet xti using --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 22 +++++++++ .../XlsFile/Format/Auxiliary/HelpFunc.h | 1 + .../Logic/Biff_structures/SyntaxPtg.cpp | 49 +++++++++++++------ OOXML/XlsxFormat/Workbook/Workbook.cpp | 2 +- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 4050d9f5417..8659502a69d 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -692,6 +692,28 @@ unsigned short sheetsnames2ixti(std::wstring name) return 0xFFFF; } + unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti) + { + auto pos1 = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == firstIxti; + }); + + auto pos2 = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == secondIxti; + }); + if (pos1 == XLS::GlobalWorkbookInfo::arXti_External_static.cend() || pos2 == XLS::GlobalWorkbookInfo::arXti_External_static.cend()) + return 0; + XLS::GlobalWorkbookInfo::_xti newXti; + newXti.iSup = XLS::GlobalWorkbookInfo::arXti_External_static.size(); + newXti.itabFirst = pos1->itabFirst; + newXti.itabFirst = pos1->itabLast; + newXti.link = name; + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); + return newXti.iSup; + } + unsigned int definenames2index(std::wstring name) { unsigned int index; diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index a7a06f1e93e..f839fa0f1f1 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -96,5 +96,6 @@ unsigned int definenames2index(std::wstring name); bool isTableFmla(const std::wstring& tableName, _UINT32& listIndex); bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexColumn); unsigned int getColumnsCount(_UINT32 listIndex); +unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index 2511efa6bc9..f24f5e7ad22 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -714,22 +714,39 @@ const bool SyntaxPtg::extract_PtgRef(std::wstring::const_iterator& first, std::w const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std::wstring::const_iterator last, unsigned short& ixti) { static boost::wregex reg_sheets(L"^([\\w[:Unicode:]][[:Unicode:]\\w\\d.]*(:[\\w[:Unicode:]][[:Unicode:]\\w\\d.]*)?)!"); - static boost::wregex reg_quoted(L"^'((''|[^]['\\/*?])*)'!"); - boost::match_results results; - if (boost::regex_search(first, last, results, reg_sheets) || - boost::regex_search(first, last, results, reg_quoted)) - { - - std::wstring sheets_names = results.str(1); - - ixti = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); - if(0xFFFF != ixti) - { - first = results[0].second; - return true; - } - } - return false; + static boost::wregex reg_sheet(L"^([^:]+):(.*)$"); + static boost::wregex reg_quoted(L"^'((''|[^]['\\/*?])*)'!"); + boost::match_results results; + if (boost::regex_search(first, last, results, reg_sheets) || + boost::regex_search(first, last, results, reg_quoted)) + { + + std::wstring sheets_names = results.str(1); + + ixti = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); + if(0xFFFF != ixti) + { + first = results[0].second; + return true; + } + boost::match_results results2; + if (boost::regex_search(sheets_names, results2, reg_sheet)) + { + auto firstSheetName = results2.str(1); + auto secondSheetName = results2.str(2); + auto xti1 = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(firstSheetName, L"''", L"'")); + auto xti2 = XMLSTUFF::sheetsnames2ixti(boost::algorithm::replace_all_copy(secondSheetName, L"''", L"'")); + if(0xFFFF != xti1 && 0xFFFF != xti2) + { + ixti = XMLSTUFF::AddMultysheetXti(sheets_names, xti1, xti2); + if(!ixti) + return false; + first = results[0].second; + return true; + } + } + } + return false; } diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 3c23b8f636d..38f7695e6cf 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -309,7 +309,7 @@ namespace OOX if (m_oWorkbookProtection.IsInit()) workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); - workBookStream->m_EXTERNALS = WriteXtiRefs(); + workBookStream->m_EXTERNALS = WriteXtiRefs(); if (m_oExternalReferences.IsInit()) { auto ptr = static_cast(workBookStream->m_EXTERNALS.get()); From c3ef38b1e169e82bceaae17cf0ab4092bd30512e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 14 Mar 2024 18:53:22 +0300 Subject: [PATCH 428/794] For bug 66933 --- PdfFile/PdfWriter.cpp | 14 +++++++++++--- PdfFile/PdfWriter.h | 2 +- PdfFile/SrcWriter/Document.cpp | 24 ++++++++++++++++++++++++ PdfFile/SrcWriter/Document.h | 18 ++++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5ff8a24dc33..1e40ee0a518 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2666,7 +2666,7 @@ void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, cons //---------------------------------------------------------------------------------------- // Внутренние функции //---------------------------------------------------------------------------------------- -PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) +PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlpha) { TColor oColor; int nImageW = abs((int)pImage->GetWidth()); @@ -3041,12 +3041,17 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w if (c_BrushTypeTexture == lBrushType) { std::wstring wsTexturePath = m_oBrush.GetTexturePath(); + BYTE nAlpha = m_oBrush.GetTextureAlpha(); CImageFileFormatChecker oImageFormat(wsTexturePath); PdfWriter::CImageDict* pImage = NULL; int nImageW = 0; int nImageH = 0; - if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) + if (m_pDocument->HasImage(wsTexturePath, nAlpha)) + { + pImage = m_pDocument->GetImage(wsTexturePath, nAlpha); + } + else if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) { pImage = m_pDocument->CreateImage(); CBgraFrame oFrame; @@ -3060,6 +3065,8 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w pImage->LoadJpeg(wsTexturePath.c_str(), nImageW, nImageH, oFrame.IsGrayScale()); else pImage->LoadJpx(wsTexturePath.c_str(), nImageW, nImageH); + + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } } else if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || @@ -3103,6 +3110,7 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w nImageW = abs((int)oImage.GetWidth()); nImageH = abs((int)oImage.GetHeight()); pImage = LoadImage(&oImage, 255); + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } else { @@ -3110,11 +3118,11 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w nImageW = abs((int)oImage.GetWidth()); nImageH = abs((int)oImage.GetHeight()); pImage = LoadImage(&oImage, 255); + m_pDocument->AddImage(wsTexturePath, nAlpha, pImage); } if (pImage) { - BYTE nAlpha = m_oBrush.GetTextureAlpha(); if (0xFF != nAlpha) pImage->AddTransparency(nAlpha); diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index ab64292c354..8d6c48a0617 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -221,7 +221,7 @@ class CPdfWriter PdfWriter::CPage* m_pPage; private: - PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha); + PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); bool DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 94097d7d418..cfdc7d5bbb7 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -172,6 +172,7 @@ namespace PdfWriter m_vFillAlpha.clear(); m_vStrokeAlpha.clear(); m_vRadioGroups.clear(); + m_vImages.clear(); m_pTransparencyGroup = NULL; @@ -212,6 +213,7 @@ namespace PdfWriter m_vTTFonts.clear(); m_vFreeTypeFonts.clear(); m_vSignatures.clear(); + m_vImages.clear(); if (m_pFreeTypeLibrary) { FT_Done_FreeType(m_pFreeTypeLibrary); @@ -1236,6 +1238,28 @@ namespace PdfWriter return pField; } + bool CDocument::HasImage(const std::wstring& wsImagePath, BYTE nAlpha) + { + for (size_t i = 0, nSize = m_vImages.size(); i < nSize; ++i) + { + if (m_vImages[i].wsImagePath == wsImagePath && m_vImages[i].nAlpha == nAlpha) + return true; + } + return false; + } + CImageDict* CDocument::GetImage(const std::wstring& wsImagePath, BYTE nAlpha) + { + for (size_t i = 0, nSize = m_vImages.size(); i < nSize; ++i) + { + if (m_vImages[i].wsImagePath == wsImagePath && m_vImages[i].nAlpha == nAlpha) + return m_vImages[i].pImage; + } + return NULL; + } + void CDocument::AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage) + { + m_vImages.push_back({wsImagePath, nAlpha, pImage}); + } bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) { CFieldBase* pBase = m_mFields[sName]; diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index f8a1dbead25..464b90b357a 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -178,6 +178,10 @@ namespace PdfWriter CSignatureField* CreateSignatureField(); CDateTimeField* CreateDateTimeField(); bool CheckFieldName(CFieldBase* pField, const std::string& sName); + + bool HasImage(const std::wstring& wsImagePath, BYTE nAlpha); + CImageDict* GetImage(const std::wstring& wsImagePath, BYTE nAlpha); + void AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage); bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); @@ -245,6 +249,19 @@ namespace PdfWriter CImageDict* pImage; ICertificate* pCertificate; }; + struct TImageInfo + { + TImageInfo(const std::wstring& _wsImagePath, BYTE _nAlpha, CImageDict* _pImage) + { + wsImagePath = _wsImagePath; + nAlpha = _nAlpha; + pImage = _pImage; + } + + std::wstring wsImagePath; + BYTE nAlpha; + CImageDict* pImage; + }; CCatalog* m_pCatalog; COutline* m_pOutlines; @@ -260,6 +277,7 @@ namespace PdfWriter bool m_bEncrypt; CEncryptDict* m_pEncryptDict; std::vector m_vSignatures; + std::vector m_vImages; unsigned int m_unFormFields; unsigned int m_unCompressMode; std::vector m_vExtGrStates; From a684336b7205753fb30aac240a16865708704e6c Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 14 Mar 2024 20:06:20 +0300 Subject: [PATCH 429/794] Fix build --- Common/3dParty/boost/boost.pri | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index dcc0e87b709..919b60a42b3 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -10,6 +10,11 @@ core_android { QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } +core_ios { + QMAKE_CFLAGS += -Wno-enum-constexpr-conversion + QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion +} + bundle_xcframeworks { xcframework_platform_ios_simulator { CORE_BOOST_LIBS = $$PWD/build/ios_xcframework/ios_simulator/lib/$$CORE_BUILDS_PLATFORM_PREFIX From 933741ca88d65ee11e9d6138d733bb29b55dde95 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 15 Mar 2024 12:12:53 +0300 Subject: [PATCH 430/794] Fix ios build --- Common/3dParty/boost/boost.pri | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index dcc0e87b709..919b60a42b3 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -10,6 +10,11 @@ core_android { QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } +core_ios { + QMAKE_CFLAGS += -Wno-enum-constexpr-conversion + QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion +} + bundle_xcframeworks { xcframework_platform_ios_simulator { CORE_BOOST_LIBS = $$PWD/build/ios_xcframework/ios_simulator/lib/$$CORE_BUILDS_PLATFORM_PREFIX From f682f5148105762523431972f6e4eaf3c2246f32 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 15 Mar 2024 12:17:11 +0300 Subject: [PATCH 431/794] Fix bug 66933 --- PdfFile/PdfWriter.cpp | 20 ++++++++++++++++---- PdfFile/PdfWriter.h | 2 +- PdfFile/PdfWriter_empty.cpp | 4 ++-- PdfFile/SrcWriter/Document.cpp | 2 ++ PdfFile/lib/xpdf/Stream.cc | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 1e40ee0a518..d069ee202e2 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1027,6 +1027,16 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con if (!IsPageValid()) return S_OK; + if (m_pDocument->HasImage(wsImagePathSrc, nAlpha)) + { + PdfWriter::CImageDict* pPdfImage = m_pDocument->GetImage(wsImagePathSrc, nAlpha); + m_pPage->GrSave(); + UpdateTransform(); + m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); + m_pPage->GrRestore(); + return S_OK; + } + std::wstring sTempImagePath = GetDownloadFile(wsImagePathSrc, wsTempDirectory); std::wstring wsImagePath = sTempImagePath.empty() ? wsImagePathSrc : sTempImagePath; @@ -1057,8 +1067,10 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con } HRESULT hRes = S_OK; - if (!pAggImage || !DrawImage(pAggImage, dX, dY, dW, dH, nAlpha)) + PdfWriter::CImageDict* pPdfImage = NULL; + if (!pAggImage || !(pPdfImage = DrawImage(pAggImage, dX, dY, dW, dH, nAlpha))) hRes = S_FALSE; + m_pDocument->AddImage(wsImagePathSrc, nAlpha, pPdfImage); if (NSFile::CFileBinary::Exists(sTempImagePath)) NSFile::CFileBinary::Remove(sTempImagePath); @@ -2761,18 +2773,18 @@ PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlph return pPdfImage; } -bool CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) +PdfWriter::CImageDict* CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { PdfWriter::CImageDict* pPdfImage = LoadImage(pImage, nAlpha); if (!pPdfImage) - return false; + return NULL; m_pPage->GrSave(); UpdateTransform(); m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); m_pPage->GrRestore(); - return true; + return pPdfImage; } bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 8d6c48a0617..22da5bb1453 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -222,7 +222,7 @@ class CPdfWriter private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); - bool DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); + PdfWriter::CImageDict* DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); diff --git a/PdfFile/PdfWriter_empty.cpp b/PdfFile/PdfWriter_empty.cpp index 0552f1f71dc..3060af7bb4f 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/PdfFile/PdfWriter_empty.cpp @@ -143,8 +143,8 @@ bool CPdfWriter::AddPage(int nPageIndex) { return false; } bool CPdfWriter::EditClose() { return false; } void CPdfWriter::PageRotate(int nRotate) {} void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) {} -PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) { return NULL; } -bool CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return false; } +PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlpha) { return NULL; } +PdfWriter::CImageDict* CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return NULL; } bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { return false; } bool CPdfWriter::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) { return false; } bool CPdfWriter::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids) { return false; } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index cfdc7d5bbb7..8277f5c4eb2 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1258,6 +1258,8 @@ namespace PdfWriter } void CDocument::AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage) { + if (!pImage) + return; m_vImages.push_back({wsImagePath, nAlpha, pImage}); } bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) diff --git a/PdfFile/lib/xpdf/Stream.cc b/PdfFile/lib/xpdf/Stream.cc index 0d2d284bb5b..5a7b0eefd0e 100644 --- a/PdfFile/lib/xpdf/Stream.cc +++ b/PdfFile/lib/xpdf/Stream.cc @@ -5252,7 +5252,7 @@ void FlateStream::readSome() { totalOut += remain; // check for a 'decompression bomb' - if (totalOut > 50000000 && totalIn < totalOut / 250) { + if (totalOut > 100000000 && totalIn < totalOut / 250) { error(errSyntaxError, getPos(), "Decompression bomb in flate stream"); endOfBlock = eof = gTrue; remain = 0; From 53ca119a99e79a2040c682223250411885c5971c Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 14 Mar 2024 14:09:17 +0300 Subject: [PATCH 432/794] Improved conversion of tables from html to ooxml --- HtmlFile2/htmlfile2.cpp | 105 ++++++++++++++++++----------------- HtmlFile2/src/StringFinder.h | 2 +- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 9564c6557f9..b90498ab2a4 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -71,15 +71,16 @@ struct CTextSettings { bool bBdo; // Реверс текста bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) + bool bAddSpaces; // Не добавлять пробелы перед текстом int nLi; // Уровень списка std::wstring sRStyle; // w:rStyle std::wstring sPStyle; // w:pStyle - CTextSettings(bool _bBdo, bool _bPre, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : - bBdo(_bBdo), bPre(_bPre), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) {} + CTextSettings(bool _bBdo, bool _bPre, bool _bAddSpaces, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : + bBdo(_bBdo), bPre(_bPre), bAddSpaces(_bAddSpaces), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) {} CTextSettings(const CTextSettings& oTS) : - bBdo(oTS.bBdo), bPre(oTS.bPre), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} + bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} }; //Необходимые стили таблицы @@ -498,19 +499,19 @@ class CHtmlFile2_Private return false; std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); - bool bNeedConvert = true; - if (nLength > 4) - { - if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) - bNeedConvert = false; - if (pData[0] == 0xFE && pData[1] == 0xFF) - bNeedConvert = false; - - if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) - bNeedConvert = false; - if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) - bNeedConvert = false; - } +// bool bNeedConvert = true; +// if (nLength > 4) +// { +// if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) +// bNeedConvert = false; +// if (pData[0] == 0xFE && pData[1] == 0xFF) +// bNeedConvert = false; + +// if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) +// bNeedConvert = false; +// if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) +// bNeedConvert = false; +// } RELEASEARRAYOBJECTS(pData); size_t nFind = sFileContent.find("version=\""); @@ -876,7 +877,7 @@ class CHtmlFile2_Private m_oDocXml.WriteString(L"\"/>"); */ - readStream(&m_oDocXml, sSelectors, { false, false, -1, L"", L"" }); + readStream(&m_oDocXml, sSelectors, { false, false, true, -1, L"", L"" }); } void readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sName) @@ -889,7 +890,7 @@ class CHtmlFile2_Private if (find == std::wstring::npos) return; - if (m_bInP && !iswspace(sText.front()) && !m_bWasSpace) + if (oTS.bAddSpaces && m_bInP && !iswspace(sText.front()) && !m_bWasSpace) oXml->WriteString(L" "); std::wstring sPStyle = wrP(oXml, sSelectors, oTS); @@ -1350,12 +1351,14 @@ class CHtmlFile2_Private } } - while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) { // tr - строки в таблице if(m_oLightReader.GetName() != L"tr") continue; + + GetSubClass(oXml, sSelectors); + int nTrDeath = m_oLightReader.GetDepth(); if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode(nTrDeath)) continue; @@ -1374,9 +1377,9 @@ class CHtmlFile2_Private while(m_oLightReader.MoveToNextAttribute()) { if(m_oLightReader.GetName() == L"colspan") - nColspan = std::min((MAXCOLUMNSINTABLE - j), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + nColspan = std::min((MAXCOLUMNSINTABLE - j + 1), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); else if(m_oLightReader.GetName() == L"rowspan") - nRowspan = std::min((MAXROWSINTABLE - i), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + nRowspan = std::min((MAXROWSINTABLE - i + 1), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); } m_oLightReader.MoveToElement(); @@ -1484,7 +1487,9 @@ class CHtmlFile2_Private } if(nColspan != 1) - j += nColspan - 1; + j += nColspan; + else + ++j; oTrBody.WriteString(wsTcPr); @@ -1504,16 +1509,31 @@ class CHtmlFile2_Private readStream(&oTrBody, sSelectors, oTS); } sSelectors.pop_back(); - + if (m_bInP) wrP(&oTrBody, sSelectors, oTS); else if (oTrBody.GetSubData(oTrBody.GetCurSize() - 6) != L"") oTrBody.WriteString(L""); - CloseP(&oTrBody, sSelectors); + if (j - 1 == MAXCOLUMNSINTABLE) + { + while (m_oLightReader.ReadNextSiblingNode2(nTrDeath) && L"td" == m_oLightReader.GetName()) + { + GetSubClass(&oTrBody, sSelectors); + + CTextSettings oTSTd{oTS}; + oTSTd.bAddSpaces = false; + + readStream(&oTrBody, sSelectors, oTSTd); + sSelectors.pop_back(); + } + } + CloseP(&oTrBody, sSelectors); oTrBody.WriteString(L""); - j++; + + if (j - 1 == MAXCOLUMNSINTABLE) + break; // Вставляем ячейки после it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); @@ -1530,7 +1550,7 @@ class CHtmlFile2_Private it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); } - } while(m_oLightReader.ReadNextSiblingNode(nTrDeath) && j < MAXCOLUMNSINTABLE); + } while(m_oLightReader.ReadNextSiblingNode(nTrDeath) && j <= MAXCOLUMNSINTABLE); if (j > unMaxColumns) unMaxColumns = j; @@ -1558,6 +1578,7 @@ class CHtmlFile2_Private oXml->WriteString(oTrBody.GetData()); oXml->WriteString(L""); + sSelectors.pop_back(); i++; } } @@ -1609,34 +1630,16 @@ class CHtmlFile2_Private if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) oTableStyles.m_nCellSpacing = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"]); - else + else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) oTableStyles.m_nCellSpacing = 15; - wsTable += L""; + if (0 < oTableStyles.m_nCellSpacing) + wsTable += L""; if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); - std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); - - if (wsAlign.empty()) - { - NSCSS::CNode oLastNode = sSelectors.back(); - sSelectors.pop_back(); - - NSCSS::CCompiledStyle oTempSettingsStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); - - wsAlign = oTempSettingsStyle.m_oText.GetAlign().ToWString(); - - if (wsAlign.empty()) - { - NSCSS::CCompiledStyle oTempStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); - - wsAlign = oTempStyle.m_oText.GetAlign().ToWString(); - } - - sSelectors.push_back(oLastNode); - } + const std::wstring wsAlign = (oStyle.m_oDisplay.GetHAlign().Empty()) ? L"center" : oStyle.m_oDisplay.GetHAlign().ToWString(); // borders if (!oStyle.m_oBorder.Empty() && !oStyle.m_oBorder.Zero()) @@ -1661,9 +1664,7 @@ class CHtmlFile2_Private else wsTable += L""; - if (!wsAlign.empty()) - wsTable += L""; - + wsTable += L""; wsTable += L""; wsTable += L""; @@ -1720,7 +1721,7 @@ class CHtmlFile2_Private m_bWasPStyle = false; } // Заголовок таблицы выравнивание посередине - CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"" }; + CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.bAddSpaces, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"" }; readStream(oXml, sSelectors, oTSP); if (m_bInP) m_bWasPStyle = false; diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index f90027b8773..f41830abc8c 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -166,7 +166,7 @@ namespace NSStringFinder const int nValue = std::stoi(*oResult.begin()); - return (nValue >= nMinValue) ? nValue : nMinValue; + return std::max(nMinValue, nValue); } int ToDouble(const std::wstring& oValue, double dMinValue = 0.) From d0adabc5f7ee99de8cf6a817e5560aece3a80aa5 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 15 Mar 2024 17:04:33 +0500 Subject: [PATCH 433/794] Fix bug #66795 --- OdfFile/Reader/Format/draw_frame_pptx.cpp | 15 +++++++++++++++ OdfFile/Writer/Format/odf_drawing_context.cpp | 9 ++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 55df515d82c..47831d9ec99 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -197,6 +197,21 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.root()->odf_context().styleContainer().style_by_name(textStyleName, odf_types::style_family::Paragraph, Context.process_masters_); paragraph_format_properties paragraph_properties = calc_paragraph_properties_content(textStyleInst); + + if (paragraph_properties.style_writing_mode_) + { + const odf_types::writing_mode& mode = *paragraph_properties.style_writing_mode_; + if (mode.get_type() == odf_types::writing_mode::TbRl) + { + _property vert = _property(L"text_vert", 1); + Context.get_slide_context().set_property(vert); + } + else if (mode.get_type() == odf_types::writing_mode::TbLr) + { + _property vert270 = _property(L"text_vert", 2); + Context.get_slide_context().set_property(vert270); + } + } } if (office_event_listeners_) office_event_listeners_->pptx_convert(Context); diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index ead1b31063e..adc1d3b981f 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -2761,12 +2761,13 @@ void odf_drawing_context::set_textarea_writing_mode(int mode) { switch(mode) { + case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст + paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbLr); + break; case 5://textverticaltypeWordArtVert: case 6://textverticaltypeWordArtVertRtl: - case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст case 3://SimpleTypes::textverticaltypeVert: case 2://SimpleTypes::textverticaltypeMongolianVert: - paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbRl); break; case 0://SimpleTypes::textverticaltypeEaVert: @@ -2782,9 +2783,11 @@ void odf_drawing_context::set_textarea_writing_mode(int mode) { switch(mode) { + case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст + impl_->current_paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbLr); + break; case 5://textverticaltypeWordArtVert: case 6://textverticaltypeWordArtVertRtl: - case 4://SimpleTypes::textverticaltypeVert270: //нужно отзеркалить по горизонтали текст case 3://SimpleTypes::textverticaltypeVert: case 2://SimpleTypes::textverticaltypeMongolianVert: impl_->current_paragraph_properties->style_writing_mode_ = odf_types::writing_mode(odf_types::writing_mode::TbRl); From 1a92ec57e1b46703ca9a4f5084eb108ea7557061 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 15 Mar 2024 18:09:36 +0600 Subject: [PATCH 434/794] Fix multisheet reference conversion --- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp | 2 +- .../Format/Logic/Biff_structures/StringPtgParser.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 8659502a69d..49cd1496ec7 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -708,7 +708,7 @@ unsigned short sheetsnames2ixti(std::wstring name) XLS::GlobalWorkbookInfo::_xti newXti; newXti.iSup = XLS::GlobalWorkbookInfo::arXti_External_static.size(); newXti.itabFirst = pos1->itabFirst; - newXti.itabFirst = pos1->itabLast; + newXti.itabLast = pos2->itabFirst; newXti.link = name; XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); return newXti.iSup; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 14d55c2e1ed..1f3544d4d89 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -307,7 +307,14 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if(SyntaxPtg::extract_PtgRef(it, itEnd, operand_str)) { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + auto pos = std::find_if(XLS::GlobalWorkbookInfo::arXti_External_static.cbegin(), XLS::GlobalWorkbookInfo::arXti_External_static.cend(), + [&](XLS::GlobalWorkbookInfo::_xti i) { + return i.iSup == ixti; + }); + if(pos->itabFirst == pos->itabLast) + rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); + else + rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRefErr(it, itEnd)) { From e53416e934ebb8eed38bd308c96db7ed94049b8a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 15 Mar 2024 18:10:58 +0600 Subject: [PATCH 435/794] Add worksheet write before another parts --- OOXML/XlsbFormat/Xlsb.cpp | 16 ++++++++++++++++ OOXML/XlsbFormat/Xlsb.h | 1 + X2tConverter/src/lib/xlsx.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 74a9c26ce71..2a511c3f05a 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -122,6 +122,22 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* return true; } +void OOX::Spreadsheet::CXlsb::WriteSheetData() +{ + for(auto &worksheet : m_arWorksheets) + { + + //для оптимизации по памяти сразу записываем в файл все листы + if(m_bWriteToXlsb) + { + WriteSheet(worksheet); + }// + + //cell_table_temlate.reset(); + //reader.reset(); + } +} + XLS::GlobalWorkbookInfo* OOX::Spreadsheet::CXlsb::GetGlobalinfo() { return xls_global_info.get(); diff --git a/OOXML/XlsbFormat/Xlsb.h b/OOXML/XlsbFormat/Xlsb.h index 065dc60d28b..40a8689541a 100644 --- a/OOXML/XlsbFormat/Xlsb.h +++ b/OOXML/XlsbFormat/Xlsb.h @@ -70,6 +70,7 @@ namespace OOX void PrepareSi(); void PrepareTableFormula(); void ReadSheetData(); + void WriteSheetData(); void SetPropForWriteSheet(const std::wstring &sPath, OOX::CContentTypes& oContentTypes); void WriteSheet(CWorksheet* worksheet); diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index fdd8a159e7d..f2c96a298fa 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -166,6 +166,8 @@ namespace NExtractTools oXlsb.Read(oox_path); OOX::CContentTypes oContentTypes; + oXlsb.SetPropForWriteSheet(sTo, oContentTypes); + oXlsb.WriteSheetData(); _UINT32 nRes = oXlsb.WriteBin(sTo, oContentTypes) ? S_OK : AVS_FILEUTILS_ERROR_CONVERT; return nRes; From fb4c8ebf328aabf65cf01ba0318b0df51131992f Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 15 Mar 2024 15:57:57 +0300 Subject: [PATCH 436/794] Refactoring and fix bugs --- .../3dParty/html/css/src/CCompiledStyle.cpp | 8 -- .../3dParty/html/css/src/StyleProperties.cpp | 25 ++--- Common/3dParty/html/css/src/StyleProperties.h | 6 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 78 ++++++++------- .../html/css/src/xhtml/CDocumentStyle.h | 8 +- .../html/css/src/xhtml/CXmlElement.cpp | 2 +- HtmlFile2/htmlfile2.cpp | 94 +++++++++++++------ 7 files changed, 119 insertions(+), 102 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index a3f6e8d68ee..e28fa3ecc0d 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -390,20 +390,12 @@ namespace NSCSS CASE(L"background-color"): { m_oBackground.SetColor(pPropertie.second, unLevel, bHardMode); - - if (bIsThereBorder) - m_oBackground.InBorder(); - break; } CASE(L"background"): CASE(L"bgcolor"): { m_oBackground.SetBackground(pPropertie.second, unLevel, bHardMode); - - if (bIsThereBorder) - m_oBackground.InBorder(); - break; } //DISPLAY diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 01c9a708a39..adf65ad7c0d 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -471,9 +471,6 @@ namespace NSCSS if ((CHECK_CONDITIONS && !bHardMode) || (wsValue.empty() && unLevel == m_unLevel)) return false; - if (8 == unLevel) - unLevel = 8; - if (wsValue.empty()) { SetEmpty(unLevel); @@ -1192,7 +1189,7 @@ namespace NSCSS } // BACKGROUND - CBackground::CBackground() : m_bInBorder(false) + CBackground::CBackground() {} void CBackground::Equation(CBackground &oFirstBackground, CBackground &oSecondBackground) @@ -1218,30 +1215,24 @@ namespace NSCSS return false; } - void CBackground::InBorder() - { - m_bInBorder = true; - } - const CColor& CBackground::GetColor() const { return m_oColor; } - bool CBackground::IsInBorder() const + bool CBackground::Empty() const { - return m_bInBorder; + return m_oColor.Empty(); } - bool CBackground::Empty() const + bool CBackground::IsNone() const { - return m_oColor.Empty(); + return ColorType::ColorNone == m_oColor.GetType(); } CBackground &CBackground::operator=(const CBackground &oBackground) { m_oColor = oBackground.m_oColor; - m_bInBorder = oBackground.m_bInBorder; return *this; } @@ -1250,16 +1241,12 @@ namespace NSCSS { m_oColor += oBackground.m_oColor; - if (oBackground.m_bInBorder) - m_bInBorder = true; - return *this; } bool CBackground::operator==(const CBackground &oBackground) const { - return m_oColor == oBackground.m_oColor && - m_bInBorder == oBackground.m_bInBorder; + return m_oColor == oBackground.m_oColor; } // TRANSFORM diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 980ac640da8..eac50a24631 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -378,19 +378,17 @@ namespace NSCSS bool SetColor (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetBackground(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); - void InBorder(); const CColor& GetColor() const; - bool IsInBorder() const; - bool Empty() const; + bool Empty() const; + bool IsNone() const; CBackground& operator =(const CBackground& oBackground); CBackground& operator+=(const CBackground& oBackground); bool operator==(const CBackground& oBackground) const; private: CColor m_oColor; - bool m_bInBorder; }; class CTransform diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 996ac8bcacc..5f2b8fd0309 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -74,8 +74,6 @@ namespace NSCSS void CDocumentStyle::CombineStandardStyles(const std::vector& arStandartedStyles, CXmlElement& oElement) { - oElement.AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); - if (arStandartedStyles.empty()) return; @@ -153,6 +151,7 @@ namespace NSCSS if (!oParentStyle.Empty()) { + oParentStyle.AddBasicProperties(BProperties::B_BasedOn, L"normal"); oParentStyle.AddBasicProperties(BProperties::B_StyleId, L"(" + oParentStyle.GetStyleId() + L")"); if (!bIsPStyle) { @@ -270,7 +269,8 @@ namespace NSCSS void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) { ConvertStyle(oStyle, oXmlElement, true); - if (oStyle.Empty() && oXmlElement.Empty()) + + if (oStyle.Empty()) return; oXmlElement.AddPropertiesInP(PProperties::P_Jc, oStyle.m_oText.GetAlign().ToWString()); @@ -317,12 +317,8 @@ namespace NSCSS oXmlElement.AddPropertiesInP(PProperties::P_ContextualSpacing, L"true"); } - if (!oStyle.m_oBackground.Empty()) - { - const std::wstring wsColor = oStyle.m_oBackground.GetColor().ToWString(); - if (wsColor != L"ffffff") - oXmlElement.AddPropertiesInP(PProperties::P_Shd, wsColor); - } + if (!oStyle.m_oBackground.Empty() && oStyle.HaveThisParent(L"table")) + oXmlElement.AddPropertiesInP(PProperties::P_Shd, oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()); if (!oStyle.m_oBorder.Empty() && !oStyle.HaveThisParent(L"table")) { @@ -431,12 +427,12 @@ namespace NSCSS oXmlElement.AddPropertiesInR(RProperties::R_SmallCaps, oStyle.m_oFont.GetVariant().ToWString()); } - void CDocumentStyle::WriteRStyle (const NSCSS::CCompiledStyle& oStyle) + bool CDocumentStyle::WriteRStyle(const NSCSS::CCompiledStyle& oStyle) { if(oStyle.GetId().empty()) { m_sId = L"normal"; - return; + return false; } CStyleUsed structStyle(oStyle, false); @@ -446,49 +442,59 @@ namespace NSCSS if (oItem != m_arStyleUsed.end()) { m_sId = (*oItem).getId(); - return; + return false; } CXmlElement oXmlElement; SetRStyle(oStyle, oXmlElement); - if (!oStyle.Empty() || !oXmlElement.Empty()) - { - structStyle.setId(oXmlElement.GetStyleId()); - m_arStyleUsed.push_back(structStyle); - m_sStyle += oXmlElement.GetRStyle(); - } + if (oXmlElement.Empty()) + return false; + + structStyle.setId(oXmlElement.GetStyleId()); + m_arStyleUsed.push_back(structStyle); + m_sStyle += oXmlElement.GetRStyle(); + + return true; } - void CDocumentStyle::WriteLitePStyle(const CCompiledStyle &oStyle) + bool CDocumentStyle::WriteLitePStyle(const CCompiledStyle &oStyle) { if (oStyle.Empty()) - return; + return false; CXmlElement oXmlElement; SetPStyle(oStyle, oXmlElement); - if (!oXmlElement.Empty()) - m_sStyle += oXmlElement.GetPStyle(true); + if (oXmlElement.Empty()) + return false; + + m_sStyle += oXmlElement.GetPStyle(true); + return true; } - void CDocumentStyle::WriteLiteRStyle(const CCompiledStyle &oStyle) + bool CDocumentStyle::WriteLiteRStyle(const CCompiledStyle &oStyle) { if (oStyle.Empty()) - return; + return false; CXmlElement oXmlElement; SetRStyle(oStyle, oXmlElement); - if (!oXmlElement.Empty()) - m_sStyle += oXmlElement.GetRStyle(true); + if (oXmlElement.Empty()) + return false; + + m_sStyle += oXmlElement.GetRStyle(true); + return true; } - void CDocumentStyle::WritePStyle (const NSCSS::CCompiledStyle& oStyle) + bool CDocumentStyle::WritePStyle(const NSCSS::CCompiledStyle& oStyle) { + Clear(); + if(oStyle.GetId().empty()) { m_sId = L"normal"; - return; + return true; } CStyleUsed structStyle(oStyle, true); @@ -497,17 +503,19 @@ namespace NSCSS if (oItem != m_arStyleUsed.end()) { m_sId = (*oItem).getId(); - return; + return true; } CXmlElement oXmlElement; SetPStyle(oStyle, oXmlElement); - if (!oStyle.Empty() || !oXmlElement.Empty()) - { - structStyle.setId(oXmlElement.GetStyleId()); - m_arStyleUsed.push_back(structStyle); - m_sStyle += oXmlElement.GetPStyle(); - } + if (!oXmlElement.Empty()) + return false; + + structStyle.setId(oXmlElement.GetStyleId()); + m_arStyleUsed.push_back(structStyle); + m_sStyle += oXmlElement.GetPStyle(); + + return true; } } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 487c30418cc..91bb61cd407 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -49,10 +49,10 @@ namespace NSCSS CDocumentStyle(); ~CDocumentStyle(); - void WritePStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteRStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteLitePStyle(const NSCSS::CCompiledStyle& oStyle); - void WriteLiteRStyle(const NSCSS::CCompiledStyle& oStyle); + bool WritePStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteRStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteLitePStyle(const NSCSS::CCompiledStyle& oStyle); + bool WriteLiteRStyle(const NSCSS::CCompiledStyle& oStyle); void SetStyle(const std::wstring& sStyle); void SetId (const std::wstring& sId); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 469d4dc6da1..3b07b4c8082 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -27,7 +27,7 @@ CXmlElement::CXmlElement(const std::wstring& sNameDefaultElement) bool CXmlElement::Empty() const { - return m_mBasicValues.empty() && m_mPStyleValues.empty() && m_mRStyleValues.empty(); + return m_mPStyleValues.empty() && m_mRStyleValues.empty(); } void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index b90498ab2a4..f9fce7ac582 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -829,7 +829,9 @@ class CHtmlFile2_Private std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bP) { // NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - bP ? m_oXmlStyle.WritePStyle(oStyle) : m_oXmlStyle.WriteRStyle(oStyle); + if ((bP && !m_oXmlStyle.WritePStyle(oStyle)) || (!bP && !m_oXmlStyle.WriteRStyle(oStyle))) + return L""; + m_oStylesXml.WriteString(m_oXmlStyle.GetStyle()); return m_oXmlStyle.GetIdAndClear(); } @@ -916,11 +918,16 @@ class CHtmlFile2_Private oXml->WriteString(oTS.sPStyle); oXml->WriteString(L""); } - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L""); + oXml->WriteString(L""); + if (!sRStyle.empty()) + { + oXml->WriteString(L"WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + oXml->WriteString(oTS.sRStyle); + oXml->WriteString(L""); + } + oXml->WriteString(L""); sText.erase(0, nAfter + 1); nAfter = sText.find_first_of(L"\n\r"); } @@ -931,12 +938,12 @@ class CHtmlFile2_Private if (std::iswspace(sText.front()) && m_bWasSpace) sText.erase(0, 1); - oXml->WriteEncodeXmlString(sText); - oXml->WriteString(L""); - if (!sText.empty()) m_bWasSpace = std::iswspace(sText.back()); + oXml->WriteEncodeXmlString(sText); + oXml->WriteString(L""); + return; } @@ -1101,10 +1108,15 @@ class CHtmlFile2_Private readStream(oXml, sSelectors, oTSR); wrP(oXml, sSelectors, oTS); - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); + oXml->WriteString(L""); + if (!sRStyle.empty()) + { + oXml->WriteString(L"WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + oXml->WriteString(oTS.sRStyle); + oXml->WriteString(L""); + } oXml->WriteString(L"""); } // Текст верхнего регистра @@ -1253,6 +1265,12 @@ class CHtmlFile2_Private oTSPre.bPre = true; readStream(oXml, sSelectors, oTSPre); } + else if (sName == L"nobr") + { + CTextSettings oTSPre(oTS); + oTSPre.bPre = true; + readStream(oXml, sSelectors, oTSPre); + } // Таблицы else if(sName == L"table") readTable(oXml, sSelectors, oTS); @@ -1377,10 +1395,11 @@ class CHtmlFile2_Private while(m_oLightReader.MoveToNextAttribute()) { if(m_oLightReader.GetName() == L"colspan") - nColspan = std::min((MAXCOLUMNSINTABLE - j + 1), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + nColspan = std::min((MAXCOLUMNSINTABLE - j), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); else if(m_oLightReader.GetName() == L"rowspan") - nRowspan = std::min((MAXROWSINTABLE - i + 1), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + nRowspan = std::min((MAXROWSINTABLE - i), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); } + m_oLightReader.MoveToElement(); // Вставляем ячейки до @@ -1418,7 +1437,7 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - if (!oStyle.m_oDisplay.GetHeight().Empty()) + if (!oStyle.m_oDisplay.GetHeight().Empty() && 1 == nColspan && 1 == nRowspan) nHeight = std::max(nHeight, oStyle.m_oDisplay.GetHeight().ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT)); std::wstring wsTcPr; @@ -1433,7 +1452,7 @@ class CHtmlFile2_Private else wsTcPr += L""; - if(nColspan != 1) + if(nColspan > 1) wsTcPr += L""; if (!oStyle.m_oBorder.Zero()) @@ -1445,8 +1464,11 @@ class CHtmlFile2_Private } if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) - wsTcPr += L""; - + { + const std::wstring wsShdFill{oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()}; + wsTcPr += L""; + } + std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); if (!wsVerticalAlign.empty()) @@ -1475,7 +1497,7 @@ class CHtmlFile2_Private ""; } - if(nRowspan != 1) + if(nRowspan > 1 && nColspan >= 1 && j < MAXCOLUMNSINTABLE) { oTrBody.WriteString(L""); std::wstring sColspan = std::to_wstring(nColspan); @@ -1486,7 +1508,7 @@ class CHtmlFile2_Private mTable.push_back({k, j, sColspan, wsTcPr}); } - if(nColspan != 1) + if(nColspan > 1) j += nColspan; else ++j; @@ -1506,7 +1528,11 @@ class CHtmlFile2_Private // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") { - readStream(&oTrBody, sSelectors, oTS); + if (!readStream(&oTrBody, sSelectors, oTS)) + { + oTrBody.WriteString(L""); + m_bInP = false; + } } sSelectors.pop_back(); @@ -1517,7 +1543,7 @@ class CHtmlFile2_Private if (j - 1 == MAXCOLUMNSINTABLE) { - while (m_oLightReader.ReadNextSiblingNode2(nTrDeath) && L"td" == m_oLightReader.GetName()) + while (m_oLightReader.ReadNextSiblingNode(nTrDeath) && L"td" == m_oLightReader.GetName()) { GetSubClass(&oTrBody, sSelectors); @@ -1527,6 +1553,7 @@ class CHtmlFile2_Private readStream(&oTrBody, sSelectors, oTSTd); sSelectors.pop_back(); } + } CloseP(&oTrBody, sSelectors); @@ -2183,8 +2210,6 @@ class CHtmlFile2_Private if (m_bWasPStyle) return L""; - oXml->WriteString(L"> temporary; size_t i = 0; while(i != sSelectors.size()) @@ -2204,6 +2229,9 @@ class CHtmlFile2_Private std::wstring sPStyle = GetStyle(oStyle, true); + if (sPStyle.empty()) + return L""; + m_oXmlStyle.WriteLitePStyle(oStyleSetting); std::wstring sPSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); @@ -2227,6 +2255,7 @@ class CHtmlFile2_Private } } + oXml->WriteString(L"WriteString(sPStyle); oXml->WriteString(L"\"/>"); oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); @@ -2251,12 +2280,15 @@ class CHtmlFile2_Private const std::wstring sRSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - - oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); - oXml->WriteString(L""); + if (!sRStyle.empty()) + { + oXml->WriteString(L"WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + + oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); + oXml->WriteString(L""); + } return sRStyle; } From 4364f95fb6f8394cde58a7213674b9b89f4e959c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 15 Mar 2024 16:30:12 +0300 Subject: [PATCH 437/794] Fix bug 66947 --- PdfFile/lib/xpdf/XRef.cc | 10 +++++++--- PdfFile/lib/xpdf/XRef.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/PdfFile/lib/xpdf/XRef.cc b/PdfFile/lib/xpdf/XRef.cc index 3b0f2fe998a..1b2721be139 100644 --- a/PdfFile/lib/xpdf/XRef.cc +++ b/PdfFile/lib/xpdf/XRef.cc @@ -946,6 +946,7 @@ GBool XRef::constructXRef() { } // read each stream object, check for xref or object stream + GBool bRoot = gFalse; for (int i = 0; i < streamObjNumsLen; ++i) { Object obj; fetch(streamObjNums[i], entries[streamObjNums[i]].gen, &obj); @@ -953,8 +954,8 @@ GBool XRef::constructXRef() { Dict *dict = obj.streamGetDict(); Object type; dict->lookup("Type", &type); - if (type.isName("XRef")) { - saveTrailerDict(dict, gTrue); + if (type.isName("XRef") && !bRoot) { + bRoot = saveTrailerDict(dict, gTrue); } else if (type.isName("ObjStm")) { constructObjectStreamEntries(&obj, streamObjNums[i]); } @@ -991,7 +992,8 @@ void XRef::constructTrailerDict(GFileOffset pos) { // If [dict] "looks like" a trailer dict (i.e., has a Root entry), // save it as the trailer dict. -void XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { +GBool XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { + GBool bRes = gFalse; Object obj; dict->lookupNF("Root", &obj); if (obj.isRef()) { @@ -1005,9 +1007,11 @@ void XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) { trailerDict.free(); } trailerDict.initDict(dict); + bRes = gTrue; } } obj.free(); + return bRes; } // Look for an object header ("nnn ggg obj") at [p]. The first diff --git a/PdfFile/lib/xpdf/XRef.h b/PdfFile/lib/xpdf/XRef.h index 9eb93eb3962..3ea5ba7a393 100644 --- a/PdfFile/lib/xpdf/XRef.h +++ b/PdfFile/lib/xpdf/XRef.h @@ -174,7 +174,7 @@ class XRef { GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n); GBool constructXRef(); void constructTrailerDict(GFileOffset pos); - void saveTrailerDict(Dict *dict, GBool isXRefStream); + GBool saveTrailerDict(Dict *dict, GBool isXRefStream); char *constructObjectEntry(char *p, GFileOffset pos, int *objNum); void constructObjectStreamEntries(Object *objStr, int objStrObjNum); GBool constructXRefEntry(int num, int gen, GFileOffset pos, From be0c6b13e75718743db5301bb6f455624745f30f Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 15 Mar 2024 17:56:17 +0400 Subject: [PATCH 438/794] Strings unify --- DesktopEditor/doctrenderer/json/json.cpp | 13 ++++------ DesktopEditor/doctrenderer/json/json.h | 6 +---- .../doctrenderer/json/json_values.cpp | 17 ++++++++++++ .../doctrenderer/json/serialization.h | 8 ++---- DesktopEditor/doctrenderer/test/json/main.cpp | 26 +++++-------------- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/DesktopEditor/doctrenderer/json/json.cpp b/DesktopEditor/doctrenderer/json/json.cpp index 4639bab11a8..88b4825f608 100644 --- a/DesktopEditor/doctrenderer/json/json.cpp +++ b/DesktopEditor/doctrenderer/json/json.cpp @@ -66,16 +66,13 @@ namespace NSJSON static_cast(m_internal->m_value.get())->isDouble()); } - bool IValue::IsStringA() const + bool IValue::IsString() const { - return (m_internal->m_type == CTypedValue::vtPrimitive && - static_cast(m_internal->m_value.get())->isStringA()); - } + if (m_internal->m_type != CTypedValue::vtPrimitive) + return false; - bool IValue::IsStringW() const - { - return (m_internal->m_type == CTypedValue::vtPrimitive && - static_cast(m_internal->m_value.get())->isStringW()); + CPrimitive* pPrimitive = static_cast(m_internal->m_value.get()); + return (pPrimitive->isStringA() || pPrimitive->isStringW()); } bool IValue::IsArray() const diff --git a/DesktopEditor/doctrenderer/json/json.h b/DesktopEditor/doctrenderer/json/json.h index e2de0b4e433..179fb2b3a54 100644 --- a/DesktopEditor/doctrenderer/json/json.h +++ b/DesktopEditor/doctrenderer/json/json.h @@ -73,11 +73,7 @@ namespace NSJSON /** * Returns true if the value is a string. */ - bool IsStringA() const; - /** - * Returns true if the value is a wstring. - */ - bool IsStringW() const; + bool IsString() const; /** * Returns true if the value is an array. */ diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp index 8b157056220..d0d7b27d4a2 100644 --- a/DesktopEditor/doctrenderer/json/json_values.cpp +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -1,5 +1,8 @@ #include "json_values.h" +#include +#include + namespace NSJSON { IBaseValue::IBaseValue() @@ -113,6 +116,13 @@ namespace NSJSON { if (m_type == ptStringA) return m_string; + + if (m_type == ptStringW) + { + std::wstring_convert> converter; + return std::string(converter.to_bytes(m_wstring)); + } + #ifdef JSON_DEBUG throw std::bad_cast(); #endif @@ -123,6 +133,13 @@ namespace NSJSON { if (m_type == ptStringW) return m_wstring; + + if (m_type == ptStringA) + { + std::wstring_convert> converter; + return std::wstring(converter.from_bytes(m_string)); + } + #ifdef JSON_DEBUG throw std::bad_cast(); #endif diff --git a/DesktopEditor/doctrenderer/json/serialization.h b/DesktopEditor/doctrenderer/json/serialization.h index 844d6256339..d7a8a11f38a 100644 --- a/DesktopEditor/doctrenderer/json/serialization.h +++ b/DesktopEditor/doctrenderer/json/serialization.h @@ -29,13 +29,9 @@ namespace NSJSON { ret = NSJSBase::CJSContext::createDouble((double)value); } - else if (value.IsStringA()) + else if (value.IsString()) { - ret = NSJSBase::CJSContext::createString((std::string)value); - } - else if (value.IsStringW()) - { - ret = NSJSBase::CJSContext::createString((std::wstring)value); + ret = NSJSBase::CJSContext::createString(value.ToStringA()); } // arrays else if (value.IsArray()) diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp index e527566b624..2a1661fbd67 100644 --- a/DesktopEditor/doctrenderer/test/json/main.cpp +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -180,32 +180,18 @@ class CJSONTest : public testing::Test return false; } } - else if (value.IsStringA()) - { - if (makeExpects) - EXPECT_TRUE(jsValue->isString()); - if (!jsValue->isString()) - return false; - - std::string val = value.ToStringA(); - std::string jsVal = jsValue->toStringA(); - if (makeExpects) - EXPECT_EQ(val, jsVal); - if (val != jsVal) - return false; - } else { if (makeExpects) { - EXPECT_TRUE(value.IsStringW()); + EXPECT_TRUE(value.IsString()); EXPECT_TRUE(jsValue->isString()); } if (!jsValue->isString()) return false; - std::wstring val = value.ToStringW(); - std::wstring jsVal = jsValue->toStringW(); + std::string val = value.ToStringA(); + std::string jsVal = jsValue->toStringA(); if (makeExpects) EXPECT_EQ(val, jsVal); if (val != jsVal) @@ -569,10 +555,10 @@ TEST_F(CJSONTest, wrong_usage) EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::wstring)val, L""); + EXPECT_EQ((std::wstring)val, L"test"); #endif - val = L"тест"; + val = L"test"; #ifdef JSON_DEBUG EXPECT_THROW((bool)val, std::bad_cast); EXPECT_THROW((int)val, std::bad_cast); @@ -582,7 +568,7 @@ TEST_F(CJSONTest, wrong_usage) EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::string)val, ""); + EXPECT_EQ((std::string)val, "test"); #endif val = CValue::CreateObject(); From b2c8696d1da85c7520c8ac284c46bd6d66e8d2e0 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 15 Mar 2024 18:16:58 +0400 Subject: [PATCH 439/794] Change strings conversion function --- DesktopEditor/doctrenderer/json/json_values.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp index d0d7b27d4a2..049ef75531e 100644 --- a/DesktopEditor/doctrenderer/json/json_values.cpp +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -1,7 +1,7 @@ #include "json_values.h" -#include -#include +// for string <=> wstring conversion +#include "../../common/File.h" namespace NSJSON { @@ -119,8 +119,7 @@ namespace NSJSON if (m_type == ptStringW) { - std::wstring_convert> converter; - return std::string(converter.to_bytes(m_wstring)); + return U_TO_UTF8(m_wstring); } #ifdef JSON_DEBUG @@ -136,8 +135,7 @@ namespace NSJSON if (m_type == ptStringA) { - std::wstring_convert> converter; - return std::wstring(converter.from_bytes(m_string)); + return UTF8_TO_U(m_string); } #ifdef JSON_DEBUG From ce9d61a3aaf1e0c32b8a5ff684036bf4e42cb655 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 15 Mar 2024 18:31:42 +0400 Subject: [PATCH 440/794] Fixed json test --- DesktopEditor/doctrenderer/test/json/main.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp index 2a1661fbd67..021e7341d91 100644 --- a/DesktopEditor/doctrenderer/test/json/main.cpp +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -550,26 +550,24 @@ TEST_F(CJSONTest, wrong_usage) EXPECT_THROW((bool)val, std::bad_cast); EXPECT_THROW((int)val, std::bad_cast); EXPECT_THROW((double)val, std::bad_cast); - EXPECT_THROW((std::wstring)val, std::bad_cast); #else EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::wstring)val, L"test"); #endif + EXPECT_EQ((std::wstring)val, L"test"); val = L"test"; #ifdef JSON_DEBUG EXPECT_THROW((bool)val, std::bad_cast); EXPECT_THROW((int)val, std::bad_cast); EXPECT_THROW((double)val, std::bad_cast); - EXPECT_THROW((std::string)val, std::bad_cast); #else EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::string)val, "test"); #endif + EXPECT_EQ((std::string)val, "test"); val = CValue::CreateObject(); #ifdef JSON_DEBUG From b311bb319b8d6d9833803f8e08e464a29530f482 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 15 Mar 2024 18:37:48 +0300 Subject: [PATCH 441/794] ScanPagePptx done --- DocxRenderer/src/logic/Page.cpp | 4 +- DocxRenderer/src/logic/elements/ContText.cpp | 152 +++++++++---------- DocxRenderer/src/logic/elements/TextLine.cpp | 2 +- DocxRenderer/src/resources/LinesTable.h | 30 +++- 4 files changed, 102 insertions(+), 86 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 8dba2dda2d2..394ce469a33 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1527,7 +1527,7 @@ namespace NSDocxRenderer pParagraph->m_dLeft = pLine->m_dLeft; pParagraph->m_dTop = pLine->m_dTop; pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - pParagraph->m_dWidth = pLine->m_dWidth * 1.03; // чтобы текст точно уместился + pParagraph->m_dWidth = pLine->m_dWidth; pParagraph->m_dHeight = pLine->m_dHeight; pParagraph->m_dRight = pLine->m_dRight; @@ -1564,7 +1564,7 @@ namespace NSDocxRenderer pShape->m_dRight = pParagraph->m_dRight; pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; pShape->m_dHeight = pParagraph->m_dHeight; - pShape->m_dWidth = pParagraph->m_dWidth * 1.03; // чтобы текст точно уместился + pShape->m_dWidth = pParagraph->m_dWidth; pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 17e4c1b7e8b..116c23349ea 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -289,126 +289,116 @@ namespace NSDocxRenderer void CContText::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const { oWriter.WriteString(L""); - oWriter.WriteString(L"(dSpacing); } // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; + lCalculatedSpacing -= 15; oWriter.WriteString(L" spc=\""); - oWriter.AddInt(lCalculatedSpacing * 100); + oWriter.AddInt(lCalculatedSpacing); oWriter.WriteString(L"\""); -////////////////////////////////////////////////////////////////////// + if (m_bIsOutlinePresent) - oWriter.WriteString(L""); - if (m_bIsShadowPresent) - oWriter.WriteString(L""); + oWriter.WriteString(L" ln=\"1\""); + // if (m_bIsShadowPresent) if (m_bIsStrikeoutPresent) { if (m_bIsDoubleStrikeout) - oWriter.WriteString(L""); + oWriter.WriteString(L" strike=\"dblStrike\""); else - oWriter.WriteString(L""); + oWriter.WriteString(L" strike=\"sngStrike\""); } if (m_bIsUnderlinePresent) { - oWriter.WriteString(L""); + oWriter.WriteString(L" u="); + oWriter.WriteString(SingletonInstance().ConvertLineToStringPptx(m_eUnderlineType)); } - if (m_bIsHighlightPresent) + UINT lSize = 0; + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + lSize = static_cast(1.5 * m_pFontStyle->dFontSize) * 100; + else if (m_bWriteStyleRaw) + lSize = static_cast(m_pFontStyle->dFontSize) * 100; + + oWriter.WriteString(L" sz=\""); + oWriter.AddUInt(lSize); + oWriter.WriteString(L"\""); + + if (m_pFontStyle->bBold) + oWriter.WriteString(L" b=\"1\""); + if (m_pFontStyle->bItalic) + oWriter.WriteString(L" i=\"1\""); + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L" baseline=\"-20000\">"); + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + oWriter.WriteString(L" baseline=\"30000\">"); + + oWriter.WriteString(L">"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"wsFontName); + oWriter.WriteString(L"\"/>"); + + if (m_bIsUnderlinePresent) { - //note В (); - if (colorTable.IsStandardColor(m_lHighlightColor)) + if (m_lUnderlineColor != m_pFontStyle->oBrush.Color1) { - oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); } else - { - oWriter.WriteString(L""); + oWriter.WriteString(L""); } - if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) - { - int lSize = static_cast(3.0 * m_pFontStyle->dFontSize); - oWriter.WriteString(L""); - } - else if (m_bWriteStyleRaw) + if (m_bIsHighlightPresent) { - int lSize = static_cast(2.0 * m_pFontStyle->dFontSize); - oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); } - if (m_bWriteStyleRaw) + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor) { - oWriter.WriteString(L"wsFontName); - oWriter.WriteString(L"\" w:hAnsi=\""); - oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); - oWriter.WriteString(L"\" w:cs=\""); - oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); - oWriter.WriteString(L"\" w:hint=\"default\"/>"); - - if (m_pFontStyle->bBold) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (m_pFontStyle->bItalic) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2) - { - oWriter.WriteString(L"oBrush.Color1)); - oWriter.WriteString(L"\"/>"); - } + oWriter.WriteString(L""); + oWriter.WriteString(L"oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); } - if (m_eVertAlignType == eVertAlignType::vatSubscript) - oWriter.WriteString(L""); - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L""); - if (m_bIsAddBrEnd) oWriter.WriteString(L""); - oWriter.WriteString(L""); + oWriter.WriteString(L""); + if (m_bIsAddBrEnd) oWriter.WriteString(L""); + oWriter.WriteString(L""); } bool CContText::IsEqual(const CContText *pCont) const noexcept diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 160c85bb043..87437aab8f3 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -62,7 +62,7 @@ namespace NSDocxRenderer bool bIsBigDelta = dDifference > dSpaceDefaultSize; bool bIsVeryBigDelta = dDifference > dSpaceWideSize; - if(bIsVeryBigDelta) + if (bIsVeryBigDelta) { auto wide_space = std::make_shared(pFirst->m_pManager); diff --git a/DocxRenderer/src/resources/LinesTable.h b/DocxRenderer/src/resources/LinesTable.h index 1b178af2a60..e52876bafae 100644 --- a/DocxRenderer/src/resources/LinesTable.h +++ b/DocxRenderer/src/resources/LinesTable.h @@ -42,9 +42,9 @@ enum class eLineType class LinesTable { public: - LinesTable () + LinesTable() { - InitLinesTable (); + InitLinesTable(); } inline std::wstring ConvertLineToString(const eLineType& sKey) @@ -53,8 +53,15 @@ class LinesTable return iter == m_Table.end() ? L"\"none\"" : iter->second; } + inline std::wstring ConvertLineToStringPptx(const eLineType& sKey) + { + auto iter = m_TablePptx.find(sKey); + return iter == m_TablePptx.end() ? L"\"none\"" : iter->second; + } + private: std::map m_Table; + std::map m_TablePptx; private: void InitLinesTable() @@ -81,6 +88,25 @@ class LinesTable m_Table.insert({eLineType::ltWavyDouble, L"\"wavyDouble\"" }); m_Table.insert({eLineType::ltWords, L"\"words\"" }); m_Table.insert({eLineType::ltNone, L"\"none\"" }); + + m_TablePptx.insert({eLineType::ltSingle, L"\"sng\""}); + m_TablePptx.insert({eLineType::ltDouble, L"\"dbl\"" }); + m_TablePptx.insert({eLineType::ltThick, L"\"heavy\"" }); + m_TablePptx.insert({eLineType::ltDotted, L"\"dotted\"" }); + m_TablePptx.insert({eLineType::ltDottedHeavy, L"\"dottedHeavy\"" }); + m_TablePptx.insert({eLineType::ltDash, L"\"dash\"" }); + m_TablePptx.insert({eLineType::ltDashedHeavy, L"\"dashHeavy\"" }); + m_TablePptx.insert({eLineType::ltDashLong, L"\"dashLong\"" }); + m_TablePptx.insert({eLineType::ltDashLongHeavy, L"\"dashLongHeavy\"" }); + m_TablePptx.insert({eLineType::ltDotDash, L"\"dotDash\"" }); + m_TablePptx.insert({eLineType::ltDashDotHeavy, L"\"dotDashHeavy\"" }); + m_TablePptx.insert({eLineType::ltDotDotDash, L"\"dotDotDash\"" }); + m_TablePptx.insert({eLineType::ltDashDotDotHeavy, L"\"dotDotDashHeavy\"" }); + m_TablePptx.insert({eLineType::ltWave, L"\"wavy\"" }); + m_TablePptx.insert({eLineType::ltWavyHeavy, L"\"wavyHeavy\"" }); + m_TablePptx.insert({eLineType::ltWavyDouble, L"\"wavyDbl\"" }); + m_TablePptx.insert({eLineType::ltWords, L"\"words\"" }); + m_TablePptx.insert({eLineType::ltNone, L"\"none\"" }); } }; From b20e29daaf711d5642a5bbfc9e113f00488edc8d Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sun, 17 Mar 2024 09:24:24 +0300 Subject: [PATCH 442/794] fix bug #66960 --- OdfFile/Writer/Converter/ConvertDrawing.cpp | 4 +-- OdfFile/Writer/Converter/ConvertVml.cpp | 4 +-- OdfFile/Writer/Converter/DocxConverter.cpp | 4 +-- OdfFile/Writer/Converter/XlsxConverter.cpp | 4 +-- .../Writer/Format/odf_conversion_context.cpp | 30 ++++++++++++++----- .../Writer/Format/odf_conversion_context.h | 4 +-- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 7f9ee702cba..3965a23bd79 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -397,7 +397,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) { pathOle = find_link_by_id(oox_picture->oleObject->m_oId->get(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -442,7 +442,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) } - odf_ref_image = bExternal ? pathImage : odf_context()->add_imageobject(pathImage); + odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); odf_context()->drawing_context()->end_object_ole(); diff --git a/OdfFile/Writer/Converter/ConvertVml.cpp b/OdfFile/Writer/Converter/ConvertVml.cpp index de66957c098..3fd42d093f7 100644 --- a/OdfFile/Writer/Converter/ConvertVml.cpp +++ b/OdfFile/Writer/Converter/ConvertVml.cpp @@ -332,7 +332,7 @@ namespace Oox2Odf { pathOle = find_link_by_id(vml_object->m_oId->GetValue(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -345,7 +345,7 @@ namespace Oox2Odf std::wstring sIdImageFileCache = GetImageIdFromVmlShape(vml_shape); std::wstring pathImage = find_link_by_id(sIdImageFileCache, 1, bExternal); - std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage); + std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); diff --git a/OdfFile/Writer/Converter/DocxConverter.cpp b/OdfFile/Writer/Converter/DocxConverter.cpp index 7bceddb829e..8f349f14d66 100644 --- a/OdfFile/Writer/Converter/DocxConverter.cpp +++ b/OdfFile/Writer/Converter/DocxConverter.cpp @@ -3143,7 +3143,7 @@ void DocxConverter::convert(OOX::Logic::CObject* oox_obj) { pathOle = find_link_by_id(oox_obj->m_oOleObject->m_oId->GetValue(), 4, bExternal); } - std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle); + std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { @@ -3156,7 +3156,7 @@ void DocxConverter::convert(OOX::Logic::CObject* oox_obj) std::wstring sIdImageFileCache = GetImageIdFromVmlShape(oox_obj->m_oShape.GetPointer()); std::wstring pathImage = find_link_by_id(sIdImageFileCache, 1, bExternal); - std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage); + std::wstring odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); OoxConverter::convert(oox_obj->m_oShape.GetPointer(), NULL); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index fee7de8d107..893a2abb375 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -2962,7 +2962,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr std::wstring pathOle = find_link_by_id(sID, 4, bExternal); - odf_ref_object = odf_context()->add_oleobject(pathOle); + odf_ref_object = odf_context()->add_oleobject(pathOle, bExternal); } if ((object->m_oObjectPr.IsInit()) && (object->m_oObjectPr->m_oRid.IsInit())) { @@ -2970,7 +2970,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr std::wstring pathImage = find_link_by_id(sID, 1, bExternal); - odf_ref_image = odf_context()->add_imageobject(pathImage); + odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); } //-------------------------------------------------------------------------------------------------- if ((!bAnchor || odf_ref_image.empty()) && object->m_oShapeId.IsInit()) diff --git a/OdfFile/Writer/Format/odf_conversion_context.cpp b/OdfFile/Writer/Format/odf_conversion_context.cpp index 3415af65cb1..849724ada1e 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.cpp +++ b/OdfFile/Writer/Format/odf_conversion_context.cpp @@ -565,23 +565,37 @@ std::wstring odf_conversion_context::add_media(const std::wstring & file_name, b return odf_ref_name; } } -std::wstring odf_conversion_context::add_imageobject(const std::wstring & file_name) +std::wstring odf_conversion_context::add_imageobject(const std::wstring & file_name, bool bExternal) { if (file_name.empty()) return L""; - std::wstring odf_ref_name ; - mediaitems()->add_or_find(file_name,_mediaitems::typeObjectReplacement, odf_ref_name); + if (bExternal) + { + return file_name; + } + else + { + std::wstring odf_ref_name; + mediaitems()->add_or_find(file_name, _mediaitems::typeObjectReplacement, odf_ref_name); - return odf_ref_name; + return odf_ref_name; + } } -std::wstring odf_conversion_context::add_oleobject(const std::wstring & file_name) +std::wstring odf_conversion_context::add_oleobject(const std::wstring & file_name, bool bExternal) { if (file_name.empty()) return L""; - std::wstring odf_ref_name ; - mediaitems()->add_or_find(file_name,_mediaitems::typeOleObject, odf_ref_name); + if (bExternal) + { + return file_name; + } + else + { + std::wstring odf_ref_name; + mediaitems()->add_or_find(file_name, _mediaitems::typeOleObject, odf_ref_name); - return odf_ref_name; + return odf_ref_name; + } } void odf_conversion_context::add_tab(_CP_OPT(int) type, _CP_OPT(length) _length, _CP_OPT(int) leader) { diff --git a/OdfFile/Writer/Format/odf_conversion_context.h b/OdfFile/Writer/Format/odf_conversion_context.h index 1a163f5e487..c16098f3c51 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.h +++ b/OdfFile/Writer/Format/odf_conversion_context.h @@ -123,8 +123,8 @@ class odf_conversion_context : boost::noncopyable std::wstring add_image (const std::wstring & image_file_name, bool bExternal = false); std::wstring add_media (const std::wstring & file_name, bool bExternal = false); - std::wstring add_oleobject (const std::wstring & ole_file_name); - std::wstring add_imageobject(const std::wstring & ole_file_name); + std::wstring add_oleobject (const std::wstring & ole_file_name, bool bExternal = false); + std::wstring add_imageobject(const std::wstring & ole_file_name, bool bExternal = false); void add_meta(const std::wstring & ns, const std::wstring & name, const std::wstring & content); From 88008a9e7efbb063dd2a60a93d093d22e604821b Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sun, 17 Mar 2024 11:34:53 +0300 Subject: [PATCH 443/794] fix bug #66959 --- OdfFile/Reader/Converter/mediaitems.cpp | 1 + OdfFile/Reader/Format/draw_frame_docx.cpp | 45 +++++++++++++++-------- OdfFile/Reader/Format/draw_frame_pptx.cpp | 27 +++++++++----- OdfFile/Reader/Format/draw_frame_xlsx.cpp | 29 ++++++++++----- 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/OdfFile/Reader/Converter/mediaitems.cpp b/OdfFile/Reader/Converter/mediaitems.cpp index 66207875b48..dc07512d822 100644 --- a/OdfFile/Reader/Converter/mediaitems.cpp +++ b/OdfFile/Reader/Converter/mediaitems.cpp @@ -270,6 +270,7 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, } else if ( type == typeMsObject || type == typeOleObject) { + isMediaInternal = is_internal(href, odf_packet_); sub_path = L"embeddings/"; } else if ( type == typeControlProps) diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 64e4e50bf50..567d4eca62b 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -1644,18 +1644,21 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) try { std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring tempPath = Context.root()->get_temp_folder(); std::wstring odfPath = Context.root()->get_folder(); - + std::wstring tempPath = Context.root()->get_temp_folder(); + if (!odf_document_ && false == href.empty()) { if (href[0] == L'#') href = href.substr(1); - std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + if (Context.get_mediaitems()->is_internal_path(href, odfPath)) + { + std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; + // normalize path ???? todooo - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } //--------------------------------------------------------------------------------------------------------------------- office_element* contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; @@ -1807,25 +1810,35 @@ void draw_object_ole::docx_convert(oox::docx_conversion_context & Context) //------------------------------------------------ std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; - if (href.empty()) return; draw_frame* frame = Context.get_drawing_context().get_current_frame(); //owner if (!frame) return; - oox::_docx_drawing * drawing = dynamic_cast(frame->oox_drawing_.get()); + if (href.empty()) return; + + oox::_docx_drawing* drawing = dynamic_cast(frame->oox_drawing_.get()); if (!drawing) return; - - std::wstring extension; - detectObject(objectPath, drawing->objectProgId, extension, drawing->type); - NSFile::CFileBinary::Copy(objectPath, objectPath + extension); + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) + { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + + std::wstring extension; + detectObject(objectPath, drawing->objectProgId, extension, drawing->type); - bool isMediaInternal = true; - drawing->objectId = Context.get_mediaitems()->add_or_find(href + extension, drawing->type, isMediaInternal, href, Context.get_type_place()); + NSFile::CFileBinary::Copy(objectPath, objectPath + extension); + bool isMediaInternal = true; + drawing->objectId = Context.get_mediaitems()->add_or_find(href + extension, drawing->type, isMediaInternal, href, Context.get_type_place()); + } + else + { + bool isMediaInternal = false; + drawing->objectId = Context.get_mediaitems()->add_or_find(href, oox::typeOleObject, isMediaInternal, href, Context.get_type_place()); + + } } void draw_control::docx_convert(oox::docx_conversion_context & Context) { diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 55df515d82c..2145dfd07fb 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -341,12 +341,13 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context) { if (href[0] == L'#') href = href.substr(1); - std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; - - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); - - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + if (Context.get_mediaitems()->is_internal_path(href, odfPath)) + { + std::wstring objectPath = odfPath + FILE_SEPARATOR_STR + href; + // normalize path ???? todooo + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } //--------------------------------------------------------------------------------------------------------------------- office_element *contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; @@ -465,12 +466,14 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) { Context.get_slide_context().set_use_image_replacement(); - std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + std::wstring href = xlink_attlist_.href_.get_value_or(L""); + if (href.empty()) return; - if (!href.empty()) + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + std::wstring prog, extension; oox::_rels_type relsType; detectObject(objectPath, prog, extension, relsType); @@ -482,6 +485,10 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) else Context.get_slide_context().set_ole_object(href + extension, prog); } + else + { + Context.get_slide_context().set_ole_object(href, L""); + } } void draw_param::pptx_convert(oox::pptx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/draw_frame_xlsx.cpp b/OdfFile/Reader/Format/draw_frame_xlsx.cpp index ab7ee9bacf2..5aabe7921e9 100644 --- a/OdfFile/Reader/Format/draw_frame_xlsx.cpp +++ b/OdfFile/Reader/Format/draw_frame_xlsx.cpp @@ -340,19 +340,22 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context) try { std::wstring href = xlink_attlist_.href_.get_value_or(L""); - + std::wstring tempPath = Context.root()->get_temp_folder(); + if (!odf_document_ && false == href.empty()) { if (href[0] == L'#') href = href.substr(1); - - std::wstring tempPath = Context.root()->get_temp_folder(); + std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) + { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; - // normalize path ???? todooo - XmlUtils::replace_all( objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); + // normalize path ???? todooo + XmlUtils::replace_all(objectPath, FILE_SEPARATOR_STR + std::wstring(L"./"), FILE_SEPARATOR_STR); - odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + odf_document_ = odf_document_ptr(new odf_document(objectPath, tempPath, L"")); + } } office_element *contentSubDoc = odf_document_ ? odf_document_->get_impl()->get_content() : NULL; if (!contentSubDoc) @@ -439,11 +442,13 @@ void draw_object_ole::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_drawing_context().set_use_image_replacement(); std::wstring href = xlink_attlist_.href_.get_value_or(L""); - std::wstring folderPath = Context.root()->get_folder(); - std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + if (href.empty()) return; - if (!href.empty()) + std::wstring folderPath = Context.root()->get_folder(); + if (Context.get_mediaitems()->is_internal_path(href, folderPath)) { + std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + std::wstring prog, extension; oox::_rels_type relsType; detectObject(objectPath, prog, extension, relsType); @@ -455,6 +460,10 @@ void draw_object_ole::xlsx_convert(oox::xlsx_conversion_context & Context) else Context.get_drawing_context().set_ole_object(href + extension, prog); } + else + { + Context.get_drawing_context().set_ole_object(href, L""); + } } } From f89becf68fa046e181915d02c44ac8e744e3b91e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 18 Mar 2024 18:05:46 +0600 Subject: [PATCH 444/794] Fix bug #66934 --- .../CellFormatController/DateReader.cpp | 47 ++++++++++++++++--- .../Reader/CellFormatController/DateReader.h | 5 ++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp index 41db554ed56..e7c1eba05ea 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp @@ -43,7 +43,7 @@ // Определение основных форматов даты std::vector DateFormats = { - L"%d.%m.%Y", L"%d.%m.%y", L"%Y-%m-%d", L"%m/%d/%Y", + L"%d.%m.%Y", L"%d.%m.%y", L"%Y-%m-%d",L"%d/%m/%Y",L"%d/%m/%y", L"%m/%d/%Y", L"%m/%d/%y", L"%d %B %Y", L"%d %B, %Y", L"%d %b %Y", L"%d %b, %Y", L"%B %d %Y", L"%B %d, %Y", L"%b %d %Y", L"%b %d, %Y", L"%Y/%m/%d", L"%Y/%d/%m", L"%m-%d-%Y", @@ -67,7 +67,10 @@ bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) if(time.tm_year > 0) { - result = getStandartDate(time); + if(time.tm_year >= 70) + result = getStandartDate(time); + else + result = getNonUnixDate(time); return true; } return false; @@ -80,8 +83,38 @@ bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) _INT32 DateReader::getStandartDate(tm &date) { // Преобразование даты в формат excel - auto tp = std::chrono::system_clock::from_time_t(mktime(&date)); - auto excelTime = (tp.time_since_epoch().count() / 10000000) + 2209161600; - _INT32 tempTime = round(excelTime / 86400.0); - return tempTime; -} \ No newline at end of file + auto timeT = mktime(&date); + auto tp = std::chrono::system_clock::from_time_t(timeT); + auto excelTime = (tp.time_since_epoch().count() / 10000000) + 2209161600; + _INT32 tempTime = round(excelTime / 86400.0); + return tempTime; +} + +// Функция для определения високосного года +bool isLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +_INT32 DateReader::getNonUnixDate(tm &date) +{ + const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + long days = 1; + + // Добавляем количество дней за предыдущие годы + for (int year = 1900; year < date.tm_year + 1900; ++year) { + days += isLeapYear(year) ? 366 : 365; + } + + // Добавляем количество дней до начала текущего года + for (int month = 0; month < date.tm_mon; ++month) { + days += daysInMonth[month]; + if (month == 1 && isLeapYear(date.tm_year + 1900)) + days++; // добавляем 1 день для февраля в високосном году + } + + // Добавляем количество дней текущего месяца + days += date.tm_mday; + + return days; +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h index 7a79f827e97..0194100e05a 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h @@ -51,5 +51,10 @@ class DateReader /// @param datetime структура с датой /// @return дата в формате excel _INT32 getStandartDate(tm &date); + + /// @brief получение даты в виде числа в формате excel из дат от 1900 года и до 1970 + /// @param datetime структура с датой + /// @return дата в формате excel + _INT32 getNonUnixDate(tm &date); }; From 6874e110bb59f5c881fad0f7f92a105e5cf5a37d Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 18 Mar 2024 15:21:21 +0300 Subject: [PATCH 445/794] fix build --- OdfFile/Projects/Linux/OdfFormatLib.pro | 4 ++-- OdfFile/Projects/Windows/cpodf.vcxproj | 2 ++ OdfFile/Projects/Windows/cpodf.vcxproj.filters | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 34c9054d707..29d72fbf711 100644 --- a/OdfFile/Projects/Linux/OdfFormatLib.pro +++ b/OdfFile/Projects/Linux/OdfFormatLib.pro @@ -203,7 +203,8 @@ SOURCES += \ ../../Reader/Format/office_settings.cpp \ ../../Reader/Format/office_spreadsheet.cpp \ ../../Reader/Format/office_text.cpp \ - ../../Reader/Format/office_meta.cpp \ + ../../Reader/Format/office_drawing.cpp \ + ../../Reader/Format/office_meta.cpp \ ../../Reader/Format/paragraph_elements.cpp \ ../../Reader/Format/ruby.cpp \ ../../Reader/Format/search_table_cell.cpp \ @@ -387,7 +388,6 @@ SOURCES += \ ../../Writer/Format/odp_page_state.cpp \ ../../Writer/Format/odp_slide_context.cpp \ ../../Writer/Format/office_presentation.cpp \ - ../../Writer/Format/office_drawing.cpp \ ../../Writer/Format/style_presentation.cpp \ ../../Writer/Format/odf_math_context.cpp \ ../../Writer/Format/math_elementaries.cpp \ diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index 9261997573f..5005311b91b 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -510,6 +510,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) @@ -747,6 +748,7 @@ + diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index 7ab9701d637..c254de81ba5 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -481,6 +481,9 @@ oox\pptx + + elements + @@ -934,5 +937,8 @@ oox\pptx + + elements + \ No newline at end of file From 1b865e9b13e9f1aca5f7d079fdc99cc14d96fc97 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 18 Mar 2024 17:53:32 +0300 Subject: [PATCH 446/794] Refactoring AnnotField and FormField --- .../graphics/commands/AnnotField.cpp | 490 +++++++++++------- DesktopEditor/graphics/commands/AnnotField.h | 326 ++++++------ DesktopEditor/graphics/commands/FormField.cpp | 100 ---- DesktopEditor/graphics/commands/FormField.h | 33 -- PdfFile/PdfWriter.cpp | 32 -- 5 files changed, 460 insertions(+), 521 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 77b70a5345c..d85547551f6 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -34,9 +34,21 @@ #include "../MetafileToRenderer.h" #include "../../common/File.h" +// void Set(const BYTE& n) { m_n = n; } +// BYTE Get() const { return m_n; } + +// void Set(const int& n) { m_n = n; } +// int Get() const { return m_n; } + +// void Set(const double& d) { m_d = d; } +// double Get() const { return m_d; } + +// void Set(const std::wstring& ws) { m_ws = ws; } +// const std::wstring& Get() { return m_ws; } + CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotaion) { - m_nType = 0; + m_nType = -1; m_nFlag = 0; m_nID = 0; @@ -82,12 +94,11 @@ CAnnotFieldInfo::~CAnnotFieldInfo() void CAnnotFieldInfo::SetType(int nType) { + m_nType = nType; switch (nType) { case 0: { - m_nType = 15; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -97,8 +108,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 2: { - m_nType = 13; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -108,8 +117,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 3: { - m_nType = 9; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -120,8 +127,6 @@ void CAnnotFieldInfo::SetType(int nType) case 4: case 5: { - m_nType = 11; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -132,8 +137,6 @@ void CAnnotFieldInfo::SetType(int nType) case 6: case 7: { - m_nType = 12; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -146,8 +149,6 @@ void CAnnotFieldInfo::SetType(int nType) case 10: case 11: { - m_nType = 10; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -157,8 +158,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 13: { - m_nType = 14; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -168,8 +167,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 14: { - m_nType = 8; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -179,8 +176,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 15: { - m_nType = 24; - RELEASEOBJECT(m_pPopupPr); m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr(); break; @@ -194,20 +189,14 @@ void CAnnotFieldInfo::SetType(int nType) case 32: case 33: { - m_nType = nType - 26; - RELEASEOBJECT(m_pWidgetPr); m_pWidgetPr = new CAnnotFieldInfo::CWidgetAnnotPr(nType); break; } } } -bool CAnnotFieldInfo::IsValid() const -{ - return (m_nType != 0); -} -void CAnnotFieldInfo::GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) const +void CAnnotFieldInfo::GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) { dX1 = m_dX1; dY1 = m_dY1; @@ -220,207 +209,88 @@ void CAnnotFieldInfo::GetBorder(BYTE& nType, double& dWidth, std::vector dWidth = m_oBorder.dWidth; arrDash = m_oBorder.arrDash; } +int CAnnotFieldInfo::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::GetID() const { return m_nID; } +int CAnnotFieldInfo::GetAnnotFlag() const { return m_nAnnotFlag; } +int CAnnotFieldInfo::GetPage() const { return m_nPage; } +void CAnnotFieldInfo::GetBE(BYTE& nS, double& dI) { nS = m_pBE.first; dI = m_pBE.second; } +const std::wstring& CAnnotFieldInfo::GetNM() { return m_wsNM; } +const std::wstring& CAnnotFieldInfo::GetLM() { return m_wsLM; } +const std::wstring& CAnnotFieldInfo::GetContents() { return m_wsContents; } +const std::vector& CAnnotFieldInfo::GetC() { return m_arrC; } -// Common bool CAnnotFieldInfo::IsWidget() const { - return (m_nType < 8); + return (m_nType >= 26); } bool CAnnotFieldInfo::IsButtonWidget() const { - return (m_nType == 1 || m_nType == 2 || m_nType == 3); + return (m_nType == 27 || m_nType == 28 || m_nType == 29); } bool CAnnotFieldInfo::IsTextWidget() const { - return (m_nType == 4); + return (m_nType == 30); } bool CAnnotFieldInfo::IsChoiceWidget() const { - return (m_nType == 5 || m_nType == 6); + return (m_nType == 31 || m_nType == 32); } bool CAnnotFieldInfo::IsSignatureWidget() const { - return (m_nType == 7); + return (m_nType == 33); } bool CAnnotFieldInfo::IsMarkup() const { - return (m_nType > 6 && m_nType < 24); + return ((m_nType >= 0 && m_nType <= 17 && m_nType != 1 && m_nType != 15) || m_nType == 25); } bool CAnnotFieldInfo::IsText() const { - return (m_nType == 15); + return (m_nType == 0); } bool CAnnotFieldInfo::IsInk() const { - return (m_nType == 8); + return (m_nType == 14); } bool CAnnotFieldInfo::IsLine() const { - return (m_nType == 9); + return (m_nType == 3); } bool CAnnotFieldInfo::IsTextMarkup() const { - return (m_nType == 10); + return (m_nType >= 8 && m_nType <= 11); } bool CAnnotFieldInfo::IsSquareCircle() const { - return (m_nType == 11); + return (m_nType == 4 || m_nType == 5); } bool CAnnotFieldInfo::IsPolygonLine() const { - return (m_nType == 12); + return (m_nType == 6 || m_nType == 7); } bool CAnnotFieldInfo::IsPopup() const { - return (m_nType == 24); + return (m_nType == 15); } bool CAnnotFieldInfo::IsFreeText() const { - return (m_nType == 13); + return (m_nType == 2); } bool CAnnotFieldInfo::IsCaret() const { - return (m_nType == 14); -} - -CAnnotFieldInfo::CWidgetAnnotPr::CWidgetAnnotPr(BYTE nType) -{ - m_pButtonPr = NULL; - m_pTextPr = NULL; - m_pChoicePr = NULL; - m_pSignaturePr = NULL; - - m_nType = nType; - switch (nType) - { - case 26: - { - // Unknown widget - break; - } - case 27: - case 28: - case 29: - { - RELEASEOBJECT(m_pButtonPr); - m_pButtonPr = new CWidgetAnnotPr::CButtonWidgetPr(); - break; - } - case 30: - { - RELEASEOBJECT(m_pTextPr); - m_pTextPr = new CWidgetAnnotPr::CTextWidgetPr(); - break; - } - case 31: - case 32: - { - RELEASEOBJECT(m_pChoicePr); - m_pChoicePr = new CWidgetAnnotPr::CChoiceWidgetPr(); - break; - } - case 33: - { - RELEASEOBJECT(m_pSignaturePr); - m_pSignaturePr = new CWidgetAnnotPr::CSignatureWidgetPr(); - break; - } - } -} -CAnnotFieldInfo::CWidgetAnnotPr::~CWidgetAnnotPr() -{ - RELEASEOBJECT(m_pButtonPr); - RELEASEOBJECT(m_pTextPr); - RELEASEOBJECT(m_pChoicePr); - RELEASEOBJECT(m_pSignaturePr); - - for (int i = 0; i < m_arrAction.size(); ++i) - RELEASEOBJECT(m_arrAction[i]); + return (m_nType == 13); } -CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPdf::CBufferReader* pReader) -{ - CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pRes = new CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget(); - - pRes->nActionType = pReader->ReadByte(); - switch (pRes->nActionType) - { - case 14: // JavaScript - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 1: // GoTo - { - pRes->nInt1 = pReader->ReadInt(); - pRes->nKind = pReader->ReadByte(); - switch (pRes->nKind) - { - case 0: - case 2: - case 3: - case 6: - case 7: - { - pRes->nFlags = pReader->ReadByte(); - if (pRes->nFlags & (1 << 0)) - pRes->dD[0] = pReader->ReadDouble(); - if (pRes->nFlags & (1 << 1)) - pRes->dD[1] = pReader->ReadDouble(); - if (pRes->nFlags & (1 << 2)) - pRes->dD[2] = pReader->ReadDouble(); - break; - } - case 4: - { - pRes->dD[0] = pReader->ReadDouble(); - pRes->dD[1] = pReader->ReadDouble(); - pRes->dD[2] = pReader->ReadDouble(); - pRes->dD[3] = pReader->ReadDouble(); - break; - } - case 1: - case 5: - default: - { - break; - } - } - break; - } - case 10: // Named - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 6: // URI - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 9: // Hide - { - pRes->nKind = pReader->ReadByte(); - int n = pReader->ReadInt(); - for (int i = 0; i < n; ++i) - pRes->arrStr.push_back(pReader->ReadString()); - break; - } - case 12: // ResetForm - { - pRes->nInt1 = pReader->ReadInt(); - int n = pReader->ReadInt(); - for (int i = 0; i < n; ++i) - pRes->arrStr.push_back(pReader->ReadString()); - break; - } - } - - if (pReader->ReadByte()) - pRes->pNext = ReadAction(pReader); - - return pRes; -} +CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; } +CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; } +CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; } +CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; } +CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; } +CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; } +CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; } +CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; } +CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; } +CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; } +CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; } bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { @@ -497,9 +367,18 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta else if (IsWidget()) m_pWidgetPr->Read(pReader, nType); - return IsValid(); + return m_nType != -1; } +BYTE CAnnotFieldInfo::CMarkupAnnotPr::GetRT() const { return m_nRT; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetPopupID() const { return m_nPopupID; } +int CAnnotFieldInfo::CMarkupAnnotPr::GetIRTID() const { return m_nIRTID; } +double CAnnotFieldInfo::CMarkupAnnotPr::GetCA() const { return m_dCA; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetT() { return m_wsT; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetRC() { return m_wsRC; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetCD() { return m_wsCD; } +const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetSubj() { return m_wsSubj; } void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nFlag = nFlags; @@ -520,6 +399,12 @@ void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader if (nFlags & (1 << 7)) m_wsSubj = pReader->ReadString(); } + +CAnnotFieldInfo::CTextAnnotPr::CTextAnnotPr() : m_bOpen(false), m_nName(2), m_nState(7), m_nStateModel(2) {} +bool CAnnotFieldInfo::CTextAnnotPr::IsOpen() const { return m_bOpen; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetName() const { return m_nName; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetState() const { return m_nState; } +BYTE CAnnotFieldInfo::CTextAnnotPr::GetStateModel() const { return m_nStateModel; } void CAnnotFieldInfo::CTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_bOpen = nFlags & (1 << 15); @@ -530,6 +415,8 @@ void CAnnotFieldInfo::CTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* if (nFlags & (1 << 18)) m_nState = pReader->ReadByte(); } + +const std::vector< std::vector >& CAnnotFieldInfo::CInkAnnotPr::GetInkList() { return m_arrInkList; } void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader) { int n = pReader->ReadInt(); @@ -543,6 +430,17 @@ void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* p m_arrInkList.push_back(arrLine); } } + +bool CAnnotFieldInfo::CLineAnnotPr::IsCap() const { return m_bCap; } +BYTE CAnnotFieldInfo::CLineAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CLineAnnotPr::GetCP() const { return m_nCP; } +double CAnnotFieldInfo::CLineAnnotPr::GetLL() const { return m_dLL; } +double CAnnotFieldInfo::CLineAnnotPr::GetLLE() const { return m_dLLE; } +double CAnnotFieldInfo::CLineAnnotPr::GetLLO() const { return m_dLLO; } +void CAnnotFieldInfo::CLineAnnotPr::GetLE(BYTE& nLE1, BYTE& nLE2) { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } +void CAnnotFieldInfo::CLineAnnotPr::GetL(double& dL1, double& dL2, double& dL3, double& dL4) { dL1 = m_dL[0]; dL2 = m_dL[1]; dL3 = m_dL[2]; dL4 = m_dL[3]; } +void CAnnotFieldInfo::CLineAnnotPr::GetCO(double& dCO1, double& dCO2) { dCO1 = m_dCO[0]; dCO2 = m_dCO[1]; } +const std::vector& CAnnotFieldInfo::CLineAnnotPr::GetIC() { return m_arrIC; } void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_dL[0] = pReader->ReadDouble(); @@ -578,6 +476,9 @@ void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* m_dCO[1] = pReader->ReadDouble(); } } + +BYTE CAnnotFieldInfo::CTextMarkupAnnotPr::GetSubtype() const { return m_nSubtype; } +const std::vector& CAnnotFieldInfo::CTextMarkupAnnotPr::GetQuadPoints() { return m_arrQuadPoints; } void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) { m_nSubtype = nType; @@ -585,6 +486,10 @@ void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRe for (int i = 0; i < n; ++i) m_arrQuadPoints.push_back(pReader->ReadDouble()); } + +BYTE CAnnotFieldInfo::CSquareCircleAnnotPr::GetSubtype() const { return m_nSubtype; } +void CAnnotFieldInfo::CSquareCircleAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } +const std::vector& CAnnotFieldInfo::CSquareCircleAnnotPr::GetIC() { return m_arrIC; } void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) { m_nSubtype = nType; @@ -602,6 +507,12 @@ void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBuffer m_arrIC.push_back(pReader->ReadDouble()); } } + +BYTE CAnnotFieldInfo::CPolygonLineAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CPolygonLineAnnotPr::GetSubtype() const { return m_nSubtype; } +void CAnnotFieldInfo::CPolygonLineAnnotPr::GetLE(BYTE& nLE1, BYTE& nLE2) { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } +const std::vector& CAnnotFieldInfo::CPolygonLineAnnotPr::GetIC() { return m_arrIC; } +const std::vector& CAnnotFieldInfo::CPolygonLineAnnotPr::GetVertices() { return m_arrVertices; } void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) { int n = pReader->ReadInt(); @@ -623,6 +534,13 @@ void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferR if (nFlags & (1 << 20)) m_nIT = pReader->ReadByte(); } + +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetQ() const { return m_nQ; } +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetIT() const { return m_nIT; } +BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetLE() const { return m_nLE; } +const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; } +void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } +const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nQ = pReader->ReadByte(); @@ -646,6 +564,9 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead if (nFlags & (1 << 20)) m_nIT = pReader->ReadByte(); } + +BYTE CAnnotFieldInfo::CCaretAnnotPr::GetSy() const { return m_nSy; } +void CAnnotFieldInfo::CCaretAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { if (nFlags & (1 << 15)) @@ -658,6 +579,10 @@ void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* if (nFlags & (1 << 16)) m_nSy = pReader->ReadByte(); } + +bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; } +int CAnnotFieldInfo::CPopupAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CPopupAnnotPr::GetParentID() const { return m_nParentID; } void CAnnotFieldInfo::CPopupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader) { m_nFlag = pReader->ReadInt(); @@ -665,6 +590,171 @@ void CAnnotFieldInfo::CPopupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* if (m_nFlag & (1 << 1)) m_nParentID = pReader->ReadInt(); } + +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetQ() const { return m_nQ; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetH() const { return m_nH; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::GetType() const { return m_nType; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetR() const { return m_nR; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFlag() const { return m_nFlag; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFlags() const { return m_nFlags; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetParentID() const { return m_nParentID; } +int CAnnotFieldInfo::CWidgetAnnotPr::GetFontStyle() const { return m_nFontStyle; } +double CAnnotFieldInfo::CWidgetAnnotPr::GetFontSize() const { return m_dFS; } +double CAnnotFieldInfo::CWidgetAnnotPr::GetFontSizeAP() const { return m_dFSAP; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetTU() { return m_wsTU; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetDS() { return m_wsDS; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetDV() { return m_wsDV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetT() { return m_wsT; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontName() { return m_wsFN; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontKey() { return m_wsFK; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetTC() { return m_arrTC; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetBC() { return m_arrBC; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetBG() { return m_arrBG; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::GetActions() { return m_arrAction; } +CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetButtonWidgetPr() { return m_pButtonPr; } +CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetTextWidgetPr() { return m_pTextPr; } +CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetChoiceWidgetPr() { return m_pChoicePr; } +CAnnotFieldInfo::CWidgetAnnotPr::CSignatureWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetSignatureWidgetPr() { return m_pSignaturePr; } +CAnnotFieldInfo::CWidgetAnnotPr::CWidgetAnnotPr(BYTE nType) +{ + m_pButtonPr = NULL; + m_pTextPr = NULL; + m_pChoicePr = NULL; + m_pSignaturePr = NULL; + + m_nType = nType; + switch (nType) + { + case 26: + { + // Unknown widget + break; + } + case 27: + case 28: + case 29: + { + RELEASEOBJECT(m_pButtonPr); + m_pButtonPr = new CWidgetAnnotPr::CButtonWidgetPr(); + break; + } + case 30: + { + RELEASEOBJECT(m_pTextPr); + m_pTextPr = new CWidgetAnnotPr::CTextWidgetPr(); + break; + } + case 31: + case 32: + { + RELEASEOBJECT(m_pChoicePr); + m_pChoicePr = new CWidgetAnnotPr::CChoiceWidgetPr(); + break; + } + case 33: + { + RELEASEOBJECT(m_pSignaturePr); + m_pSignaturePr = new CWidgetAnnotPr::CSignatureWidgetPr(); + break; + } + } +} +CAnnotFieldInfo::CWidgetAnnotPr::~CWidgetAnnotPr() +{ + RELEASEOBJECT(m_pButtonPr); + RELEASEOBJECT(m_pTextPr); + RELEASEOBJECT(m_pChoicePr); + RELEASEOBJECT(m_pSignaturePr); + + for (int i = 0; i < m_arrAction.size(); ++i) + RELEASEOBJECT(m_arrAction[i]); +} + +CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget::CActionWidget() : pNext(NULL) {} +CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget::~CActionWidget() { RELEASEOBJECT(pNext); } +CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPdf::CBufferReader* pReader) +{ + CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pRes = new CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget(); + + pRes->nActionType = pReader->ReadByte(); + switch (pRes->nActionType) + { + case 14: // JavaScript + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 1: // GoTo + { + pRes->nInt1 = pReader->ReadInt(); + pRes->nKind = pReader->ReadByte(); + switch (pRes->nKind) + { + case 0: + case 2: + case 3: + case 6: + case 7: + { + pRes->nFlags = pReader->ReadByte(); + if (pRes->nFlags & (1 << 0)) + pRes->dD[0] = pReader->ReadDouble(); + if (pRes->nFlags & (1 << 1)) + pRes->dD[1] = pReader->ReadDouble(); + if (pRes->nFlags & (1 << 2)) + pRes->dD[2] = pReader->ReadDouble(); + break; + } + case 4: + { + pRes->dD[0] = pReader->ReadDouble(); + pRes->dD[1] = pReader->ReadDouble(); + pRes->dD[2] = pReader->ReadDouble(); + pRes->dD[3] = pReader->ReadDouble(); + break; + } + case 1: + case 5: + default: + { + break; + } + } + break; + } + case 10: // Named + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 6: // URI + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 9: // Hide + { + pRes->nKind = pReader->ReadByte(); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + pRes->arrStr.push_back(pReader->ReadString()); + break; + } + case 12: // ResetForm + { + pRes->nInt1 = pReader->ReadInt(); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + pRes->arrStr.push_back(pReader->ReadString()); + break; + } + } + + if (pReader->ReadByte()) + pRes->pNext = ReadAction(pReader); + + return pRes; +} void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) { m_wsFN = pReader->ReadString(); @@ -733,6 +823,21 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader else if (nType == 31 || nType == 32) m_pChoicePr->Read(pReader, nFlags); } + +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetS() const { return m_nS; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetTP() const { return m_nTP; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetSW() const { return m_nSW; } +BYTE CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetStyle() const { return m_nStyle; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetIFFlag() const { return m_nIFFlag; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetI() const { return m_nI; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetRI() const { return m_nRI; } +int CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetIX() const { return m_nIX; } +void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetA(double& dA1, double& dA2) { dA1 = m_dA1; dA2 = m_dA2; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetCA() { return m_wsCA; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetRC() { return m_wsRC; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetAC() { return m_wsAC; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::GetAP_N_Yes() { return m_wsAP_N_Yes; } void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) { if (nType == 27) @@ -777,6 +882,11 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToP m_wsAP_N_Yes = pReader->ReadString(); } } + +int CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetMaxLen() const { return m_nMaxLen; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRV() { return m_wsRV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetAPV() { return m_wsAPV; } void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag) { if (nFlags & (1 << 9)) @@ -788,6 +898,13 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf if (nFlags & (1 << 12)) m_wsAPV = pReader->ReadString(); } + +int CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetTI() const { return m_nTI; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetV() { return m_wsV; } +const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetAPV() { return m_wsAPV; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetI() { return m_arrI; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetArrV() { return m_arrV; } +const std::vector< std::pair >& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetOpt() { return m_arrOpt; } void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { if (nFlags & (1 << 9)) @@ -821,6 +938,8 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToP } CAnnotFieldDelete::CAnnotFieldDelete() : IAdvancedCommand(AdvancedCommandType::DeleteAnnot) {} +CAnnotFieldDelete::~CAnnotFieldDelete() {} +int CAnnotFieldDelete::GetID() { return m_nID; } bool CAnnotFieldDelete::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { m_nID = pReader->ReadInt(); @@ -833,6 +952,9 @@ CWidgetsInfo::~CWidgetsInfo() for (int i = 0; i < m_arrParents.size(); ++i) RELEASEOBJECT(m_arrParents[i]); } +const std::vector& CWidgetsInfo::GetCO() { return m_arrCO; } +const std::vector& CWidgetsInfo::GetButtonImg() { return m_arrButtonImg; } +const std::vector& CWidgetsInfo::GetParents() { return m_arrParents; } bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { int n = pReader->ReadInt(); @@ -880,6 +1002,7 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil } CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} +const std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { m_sShapeXML = pReader->ReadStringA(); @@ -887,7 +1010,4 @@ bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafile } CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} -bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) -{ - return true; -} +bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { return true; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index a402937f8d1..2ddf3f24a83 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -36,41 +36,29 @@ #include "../MetafileToRendererReader.h" class IMetafileToRenderter; -// void Set(const BYTE& n) { m_n = n; } -// BYTE Get() const { return m_n; } - -// void Set(const int& n) { m_n = n; } -// int Get() const { return m_n; } - -// void Set(const double& d) { m_d = d; } -// double Get() const { return m_d; } - -// void Set(const std::wstring& ws) { m_ws = ws; } -// const std::wstring& Get() const { return m_ws; } - class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand { public: - class CWidgetAnnotPr + class GRAPHICS_DECL CWidgetAnnotPr { public: - class CButtonWidgetPr + class GRAPHICS_DECL CButtonWidgetPr { public: - BYTE GetS() const { return m_nS; } - BYTE GetTP() const { return m_nTP; } - BYTE GetSW() const { return m_nSW; } - BYTE GetStyle() const { return m_nStyle; } - int GetIFFlag() const { return m_nIFFlag; } - int GetI() const { return m_nI; } - int GetRI() const { return m_nRI; } - int GetIX() const { return m_nIX; } - void GetA(double& dA1, double& dA2) const { dA1 = m_dA1; dA2 = m_dA2; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetCA() const { return m_wsCA; } - const std::wstring& GetRC() const { return m_wsRC; } - const std::wstring& GetAC() const { return m_wsAC; } - const std::wstring& GetAP_N_Yes() const { return m_wsAP_N_Yes; } + BYTE GetS() const; + BYTE GetTP() const; + BYTE GetSW() const; + BYTE GetStyle() const; + int GetIFFlag() const; + int GetI() const; + int GetRI() const; + int GetIX() const; + void GetA(double& dA1, double& dA2); + const std::wstring& GetV(); + const std::wstring& GetCA(); + const std::wstring& GetRC(); + const std::wstring& GetAC(); + const std::wstring& GetAP_N_Yes(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); @@ -91,13 +79,13 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsAP_N_Yes; }; - class CTextWidgetPr + class GRAPHICS_DECL CTextWidgetPr { public: - int GetMaxLen() const { return m_nMaxLen; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetRV() const { return m_wsRV; } - const std::wstring& GetAPV() const { return m_wsAPV; } + int GetMaxLen() const; + const std::wstring& GetV(); + const std::wstring& GetRV(); + const std::wstring& GetAPV(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag); @@ -108,15 +96,15 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsAPV; }; - class CChoiceWidgetPr + class GRAPHICS_DECL CChoiceWidgetPr { public: - int GetTI() const { return m_nTI; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetAPV() const { return m_wsAPV; } - const std::vector& GetI() const { return m_arrI; } - const std::vector& GetArrV() const { return m_arrV; } - const std::vector< std::pair >& GetOpt() const { return m_arrOpt; } + int GetTI() const; + const std::wstring& GetV(); + const std::wstring& GetAPV(); + const std::vector& GetI(); + const std::vector& GetArrV(); + const std::vector< std::pair >& GetOpt(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -129,57 +117,56 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector< std::pair > m_arrOpt; }; - class CSignatureWidgetPr + class GRAPHICS_DECL CSignatureWidgetPr { }; - class CActionWidget + class GRAPHICS_DECL CActionWidget { public: - CActionWidget() : pNext(NULL) {} - ~CActionWidget() { RELEASEOBJECT(pNext); } + CActionWidget(); + ~CActionWidget(); BYTE nKind; BYTE nFlags; BYTE nActionType; int nInt1; - double dD[4]; + double dD[4]{}; std::wstring wsType; std::wstring wsStr1; std::vector arrStr; CActionWidget* pNext; }; - public: CWidgetAnnotPr(BYTE nType); ~CWidgetAnnotPr(); - BYTE GetQ() const { return m_nQ; } - BYTE GetH() const { return m_nH; } - BYTE GetType() const { return m_nType; } - int GetR() const { return m_nR; } - int GetFlag() const { return m_nFlag; } - int GetFlags() const { return m_nFlags; } - int GetParentID() const { return m_nParentID; } - int GetFontStyle() const { return m_nFontStyle; } - double GetFontSize() const { return m_dFS; } - double GetFontSizeAP() const { return m_dFSAP; } - const std::wstring& GetTU() const { return m_wsTU; } - const std::wstring& GetDS() const { return m_wsDS; } - const std::wstring& GetDV() const { return m_wsDV; } - const std::wstring& GetT() const { return m_wsT; } - const std::wstring& GetFontName() const { return m_wsFN; } - const std::wstring& GetFontKey() const { return m_wsFK; } - const std::vector& GetTC() const { return m_arrTC; } - const std::vector& GetBC() const { return m_arrBC; } - const std::vector& GetBG() const { return m_arrBG; } - const std::vector GetActions() const { return m_arrAction; } - - CButtonWidgetPr* GetButtonWidgetPr() { return m_pButtonPr; } - CTextWidgetPr* GetTextWidgetPr() { return m_pTextPr; } - CChoiceWidgetPr* GetChoiceWidgetPr() { return m_pChoicePr; } - CSignatureWidgetPr* GetSignatureWidgetPr() { return m_pSignaturePr; } + BYTE GetQ() const; + BYTE GetH() const; + BYTE GetType() const; + int GetR() const; + int GetFlag() const; + int GetFlags() const; + int GetParentID() const; + int GetFontStyle() const; + double GetFontSize() const; + double GetFontSizeAP() const; + const std::wstring& GetTU(); + const std::wstring& GetDS(); + const std::wstring& GetDV(); + const std::wstring& GetT(); + const std::wstring& GetFontName(); + const std::wstring& GetFontKey(); + const std::vector& GetTC(); + const std::vector& GetBC(); + const std::vector& GetBG(); + const std::vector& GetActions(); + + CButtonWidgetPr* GetButtonWidgetPr(); + CTextWidgetPr* GetTextWidgetPr(); + CChoiceWidgetPr* GetChoiceWidgetPr(); + CSignatureWidgetPr* GetSignatureWidgetPr(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); @@ -211,18 +198,18 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand CSignatureWidgetPr* m_pSignaturePr; }; - class CMarkupAnnotPr + class GRAPHICS_DECL CMarkupAnnotPr { public: - BYTE GetRT() const { return m_nRT; } - int GetFlag() const { return m_nFlag; } - int GetPopupID() const { return m_nPopupID; } - int GetIRTID() const { return m_nIRTID; } - double GetCA() const { return m_dCA; } - const std::wstring& GetT() const { return m_wsT; } - const std::wstring& GetRC() const { return m_wsRC; } - const std::wstring& GetCD() const { return m_wsCD; } - const std::wstring& GetSubj() const { return m_wsSubj; } + BYTE GetRT() const; + int GetFlag() const; + int GetPopupID() const; + int GetIRTID() const; + double GetCA() const; + const std::wstring& GetT(); + const std::wstring& GetRC(); + const std::wstring& GetCD(); + const std::wstring& GetSubj(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -238,15 +225,15 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsSubj; }; - class CTextAnnotPr + class GRAPHICS_DECL CTextAnnotPr { public: - CTextAnnotPr() : m_bOpen(false), m_nName(2), m_nState(7), m_nStateModel(2) {} + CTextAnnotPr(); - bool IsOpen() const { return m_bOpen; } - BYTE GetName() const { return m_nName; } - BYTE GetState() const { return m_nState; } - BYTE GetStateModel() const { return m_nStateModel; } + bool IsOpen() const; + BYTE GetName() const; + BYTE GetState() const; + BYTE GetStateModel() const; void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -257,10 +244,10 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nStateModel; }; - class CInkAnnotPr + class GRAPHICS_DECL CInkAnnotPr { public: - const std::vector< std::vector >& GetInkList() const { return m_arrInkList; } + const std::vector< std::vector >& GetInkList(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); @@ -268,19 +255,19 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector< std::vector > m_arrInkList; }; - class CLineAnnotPr + class GRAPHICS_DECL CLineAnnotPr { public: - bool IsCap() const { return m_bCap; } - BYTE GetIT() const { return m_nIT; } - BYTE GetCP() const { return m_nCP; } - double GetLL() const { return m_dLL; } - double GetLLE() const { return m_dLLE; } - double GetLLO() const { return m_dLLO; } - void GetLE(BYTE& nLE1, BYTE& nLE2) const { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } - void GetL(double& dL1, double& dL2, double& dL3, double& dL4) const { dL1 = m_dL[0]; dL2 = m_dL[1]; dL3 = m_dL[2]; dL4 = m_dL[3]; } - void GetCO(double& dCO1, double& dCO2) const { dCO1 = m_dCO[0]; dCO2 = m_dCO[1]; } - const std::vector& GetIC() const { return m_arrIC; } + bool IsCap() const; + BYTE GetIT() const; + BYTE GetCP() const; + double GetLL() const; + double GetLLE() const; + double GetLLO() const; + void GetLE(BYTE& nLE1, BYTE& nLE2); + void GetL(double& dL1, double& dL2, double& dL3, double& dL4); + void GetCO(double& dCO1, double& dCO2); + const std::vector& GetIC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -291,17 +278,17 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand double m_dLL; double m_dLLE; double m_dLLO; - BYTE m_nLE[2]; - double m_dL[4]; - double m_dCO[2]; + BYTE m_nLE[2]{}; + double m_dL[4]{}; + double m_dCO[2]{}; std::vector m_arrIC; }; - class CTextMarkupAnnotPr + class GRAPHICS_DECL CTextMarkupAnnotPr { public: - BYTE GetSubtype() const { return m_nSubtype; } - const std::vector& GetQuadPoints() const { return m_arrQuadPoints; } + BYTE GetSubtype() const; + const std::vector& GetQuadPoints(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); @@ -310,46 +297,46 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector m_arrQuadPoints; }; - class CSquareCircleAnnotPr + class GRAPHICS_DECL CSquareCircleAnnotPr { public: - BYTE GetSubtype() const { return m_nSubtype; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } - const std::vector& GetIC() const { return m_arrIC; } + BYTE GetSubtype() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + const std::vector& GetIC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nSubtype; - double m_dRD[4]; + double m_dRD[4]{}; std::vector m_arrIC; }; - class CPolygonLineAnnotPr + class GRAPHICS_DECL CPolygonLineAnnotPr { public: - BYTE GetIT() const { return m_nIT; } - BYTE GetSubtype() const { return m_nSubtype; } - void GetLE(BYTE& nLE1, BYTE& nLE2) const { nLE1 = m_nLE[0]; nLE2 = m_nLE[1]; } - const std::vector& GetIC() const { return m_arrIC; } - const std::vector& GetVertices() const { return m_arrVertices; } + BYTE GetIT() const; + BYTE GetSubtype() const; + void GetLE(BYTE& nLE1, BYTE& nLE2); + const std::vector& GetIC(); + const std::vector& GetVertices(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nIT; BYTE m_nSubtype; - BYTE m_nLE[2]; + BYTE m_nLE[2]{}; std::vector m_arrIC; std::vector m_arrVertices; }; - class CPopupAnnotPr + class GRAPHICS_DECL CPopupAnnotPr { public: - bool IsOpen() const { return m_bOpen; } - int GetFlag() const { return m_nFlag; } - int GetParentID() const { return m_nParentID; } + bool IsOpen() const; + int GetFlag() const; + int GetParentID() const; void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); @@ -359,15 +346,15 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand int m_nParentID; }; - class CFreeTextAnnotPr + class GRAPHICS_DECL CFreeTextAnnotPr { public: - BYTE GetQ() const { return m_nQ; } - BYTE GetIT() const { return m_nIT; } - BYTE GetLE() const { return m_nLE; } - const std::wstring& GetDS() const { return m_wsDS; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } - const std::vector& GetCL() const { return m_arrCL; } + BYTE GetQ() const; + BYTE GetIT() const; + BYTE GetLE() const; + const std::wstring& GetDS(); + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + const std::vector& GetCL(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -380,11 +367,11 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector m_arrCL; }; - class CCaretAnnotPr + class GRAPHICS_DECL CCaretAnnotPr { public: - BYTE GetSy() const { return m_nSy; } - void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) const { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } + BYTE GetSy() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -393,32 +380,22 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand double m_dRD[4]{}; }; -private: - struct CBorder - { - BYTE nType; - double dWidth; - std::vector arrDash; - }; - -public: CAnnotFieldInfo(); virtual ~CAnnotFieldInfo(); void SetType(int nType); - bool IsValid() const; - - void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) const; - void GetBorder(BYTE& nType, double& dWidth, std::vector& arrDash); - int GetFlag() const { return m_nFlag; } - int GetID() const { return m_nID; } - int GetAnnotFlag() const { return m_nAnnotFlag; } - int GetPage() const { return m_nPage; } - void GetBE(BYTE& nS, double& dI) { nS = m_pBE.first; dI = m_pBE.second; } - const std::wstring& GetNM() const { return m_wsNM; } - const std::wstring& GetLM() const { return m_wsLM; } - const std::wstring& GetContents() const { return m_wsContents; } - const std::vector& GetC() const { return m_arrC; } + + void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2); + void GetBorder(BYTE& nType, double& dWidth, std::vector& arrDash); + int GetFlag() const; + int GetID() const; + int GetAnnotFlag() const; + int GetPage() const; + void GetBE(BYTE& nS, double& dI); + const std::wstring& GetNM(); + const std::wstring& GetLM(); + const std::wstring& GetContents(); + const std::vector& GetC(); bool IsWidget() const; bool IsButtonWidget() const; @@ -436,21 +413,28 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand bool IsFreeText() const; bool IsCaret() const; - CMarkupAnnotPr* GetMarkupAnnotPr() { return m_pMarkupPr; } - CTextAnnotPr* GetTextAnnotPr() { return m_pTextPr; } - CInkAnnotPr* GetInkAnnotPr() { return m_pInkPr; } - CLineAnnotPr* GetLineAnnotPr() { return m_pLinePr; } - CTextMarkupAnnotPr* GetTextMarkupAnnotPr() { return m_pTextMarkupPr; } - CSquareCircleAnnotPr* GetSquareCircleAnnotPr() { return m_pSquareCirclePr; } - CPolygonLineAnnotPr* GetPolygonLineAnnotPr() { return m_pPolygonLinePr; } - CPopupAnnotPr* GetPopupAnnotPr() { return m_pPopupPr; } - CFreeTextAnnotPr* GetFreeTextAnnotPr() { return m_pFreeTextPr; } - CCaretAnnotPr* GetCaretAnnotPr() { return m_pCaretPr; } - CWidgetAnnotPr* GetWidgetAnnotPr() { return m_pWidgetPr; } + CMarkupAnnotPr* GetMarkupAnnotPr(); + CTextAnnotPr* GetTextAnnotPr(); + CInkAnnotPr* GetInkAnnotPr(); + CLineAnnotPr* GetLineAnnotPr(); + CTextMarkupAnnotPr* GetTextMarkupAnnotPr(); + CSquareCircleAnnotPr* GetSquareCircleAnnotPr(); + CPolygonLineAnnotPr* GetPolygonLineAnnotPr(); + CPopupAnnotPr* GetPopupAnnotPr(); + CFreeTextAnnotPr* GetFreeTextAnnotPr(); + CCaretAnnotPr* GetCaretAnnotPr(); + CWidgetAnnotPr* GetWidgetAnnotPr(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); private: + struct CBorder + { + BYTE nType; + double dWidth; + std::vector arrDash; + }; + int m_nType; double m_dX1; double m_dY1; @@ -484,9 +468,9 @@ class GRAPHICS_DECL CAnnotFieldDelete : public IAdvancedCommand { public: CAnnotFieldDelete(); - virtual ~CAnnotFieldDelete() {} + virtual ~CAnnotFieldDelete(); - int GetID() { return m_nID; } + int GetID(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); @@ -512,9 +496,9 @@ class GRAPHICS_DECL CWidgetsInfo : public IAdvancedCommand CWidgetsInfo(); virtual ~CWidgetsInfo(); - const std::vector& GetCO() const { return m_arrCO; } - const std::vector& GetButtonImg() const { return m_arrButtonImg; } - const std::vector& GetParents() const { return m_arrParents; } + const std::vector& GetCO(); + const std::vector& GetButtonImg(); + const std::vector& GetParents(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); @@ -529,7 +513,7 @@ class GRAPHICS_DECL CShapeStart : public IAdvancedCommand public: CShapeStart(); - const std::string& GetShapeXML() { return m_sShapeXML; } + const std::string& GetShapeXML(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); diff --git a/DesktopEditor/graphics/commands/FormField.cpp b/DesktopEditor/graphics/commands/FormField.cpp index 81faf97f12f..ea876d48901 100644 --- a/DesktopEditor/graphics/commands/FormField.cpp +++ b/DesktopEditor/graphics/commands/FormField.cpp @@ -329,60 +329,6 @@ const std::wstring& CFormFieldInfo::CPictureFormPr::GetPicturePath() const return m_wsPicturePath; } -// -CFormFieldInfo::CSignatureFormPr::CSignatureFormPr() -{ -} -void CFormFieldInfo::CSignatureFormPr::SetName(const std::wstring& wsValue) -{ - m_wsName = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetContact(const std::wstring& wsValue) -{ - m_wsContact = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetReason(const std::wstring& wsValue) -{ - m_wsReason = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetPicturePath(const std::wstring& wsPath) -{ - m_wsPicturePath = wsPath; -} -void CFormFieldInfo::CSignatureFormPr::SetCert(const std::wstring& wsValue) -{ - m_wsCert = wsValue; -} -void CFormFieldInfo::CSignatureFormPr::SetDate(const bool& bDate) -{ - m_bDate = bDate; -} - -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetName() const -{ - return m_wsName; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetContact() const -{ - return m_wsContact; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetReason() const -{ - return m_wsReason; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetPicturePath() const -{ - return m_wsPicturePath; -} -const std::wstring& CFormFieldInfo::CSignatureFormPr::GetCert() const -{ - return m_wsCert; -} -bool CFormFieldInfo::CSignatureFormPr::GetDate() const -{ - return m_bDate; -} - // CFormFieldInfo::CDateTimeFormPr::CDateTimeFormPr() { @@ -565,10 +511,6 @@ bool CFormFieldInfo::IsPicture() const { return (m_nType == 4); } -bool CFormFieldInfo::IsSignature() const -{ - return (m_nType == 5); -} bool CFormFieldInfo::IsDateTime() const { return (m_nType == 6); @@ -605,14 +547,6 @@ const CFormFieldInfo::CPictureFormPr* CFormFieldInfo::GetPicturePr() const { return &m_oPicturePr; } -CFormFieldInfo::CSignatureFormPr* CFormFieldInfo::GetSignatureFormPr() -{ - return &m_oSignaturePr; -} -const CFormFieldInfo::CSignatureFormPr* CFormFieldInfo::GetSignaturePr() const -{ - return &m_oSignaturePr; -} CFormFieldInfo::CDateTimeFormPr* CFormFieldInfo::GetDateTimeFormPr() { return &m_oDateTimePr; @@ -747,40 +681,6 @@ bool CFormFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetaf if (nFlags & (1 << 22)) pPr->SetPicturePath(pCorrector->GetImagePath(pReader->ReadString())); } - else if (IsSignature()) - { - CFormFieldInfo::CSignatureFormPr* pPr = GetSignatureFormPr(); - - // Поля Настройки подписи - // Сведения о подписывающем - - // Имя - if (nFlags & (1 << 20)) - pPr->SetName(pReader->ReadString()); - - // Должность Игнорируется - - // Адрес электронной почты - if (nFlags & (1 << 21)) - pPr->SetContact(pReader->ReadString()); - - // Инструкция для подписывающего Игнорируется - - // Показывать дату подписи в строке подписи - pPr->SetDate(nFlags & (1 << 22)); - - // Цель подписания документа (причина) - if (nFlags & (1 << 23)) - pPr->SetReason(pReader->ReadString()); - - // Картинка - if (nFlags & (1 << 24)) - pPr->SetPicturePath(pCorrector->GetImagePath(pReader->ReadString())); - - // Необходимо передать сертификат, пароль, ключ, пароль ключа - if (nFlags & (1 << 25)) - pPr->SetCert(pReader->ReadString()); - } else if (IsDateTime()) { CFormFieldInfo::CDateTimeFormPr* pPr = GetDateTimeFormPr(); diff --git a/DesktopEditor/graphics/commands/FormField.h b/DesktopEditor/graphics/commands/FormField.h index 664b4082f5b..565827ce1d4 100644 --- a/DesktopEditor/graphics/commands/FormField.h +++ b/DesktopEditor/graphics/commands/FormField.h @@ -213,34 +213,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand LONG m_lShiftY; std::wstring m_wsPicturePath; }; - - class GRAPHICS_DECL CSignatureFormPr - { - public: - CSignatureFormPr(); - - void SetName(const std::wstring& wsValue); - void SetContact(const std::wstring& wsValue); - void SetReason(const std::wstring& wsValue); - void SetPicturePath(const std::wstring& wsPath); - void SetCert(const std::wstring& wsValue); - void SetDate(const bool& bDate); - - const std::wstring& GetName() const; - const std::wstring& GetContact() const; - const std::wstring& GetReason() const; - const std::wstring& GetPicturePath() const; - const std::wstring& GetCert() const; - bool GetDate() const; - - private: - std::wstring m_wsName; - std::wstring m_wsContact; - std::wstring m_wsReason; - std::wstring m_wsPicturePath; - std::wstring m_wsCert; - bool m_bDate; - }; class GRAPHICS_DECL CDateTimeFormPr { @@ -304,7 +276,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand bool IsDropDownList() const; bool IsCheckBox() const; bool IsPicture() const; - bool IsSignature() const; bool IsDateTime() const; CTextFormPr* GetTextFormPr(); @@ -318,9 +289,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand CPictureFormPr* GetPictureFormPr(); const CPictureFormPr* GetPicturePr() const; - - CSignatureFormPr* GetSignatureFormPr(); - const CSignatureFormPr* GetSignaturePr() const; CDateTimeFormPr* GetDateTimeFormPr(); const CDateTimeFormPr* GetDateTimePr() const; @@ -349,7 +317,6 @@ class GRAPHICS_DECL CFormFieldInfo : public IAdvancedCommand CDropDownFormPr m_oDropDownPr; CCheckBoxFormPr m_oCheckBoxPr; CPictureFormPr m_oPicturePr; - CSignatureFormPr m_oSignaturePr; CDateTimeFormPr m_oDateTimePr; }; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5ff8a24dc33..b7ea757558c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1200,11 +1200,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie PdfWriter::CPictureField* pField = m_pDocument->CreatePictureField(); pFieldBase = static_cast(pField); } - else if (oInfo.IsSignature()) - { - PdfWriter::CSignatureField* pField = m_pDocument->CreateSignatureField(); - pFieldBase = static_cast(pField); - } else if (oInfo.IsDateTime()) { PdfWriter::CDateTimeField* pField = m_pDocument->CreateDateTimeField(); @@ -1575,33 +1570,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pField->SetAppearance(pImage); } - else if (oInfo.IsSignature()) - { - const CFormFieldInfo::CSignatureFormPr* pPr = oInfo.GetSignaturePr(); - - PdfWriter::CSignatureField* pField = dynamic_cast(pFieldBase); - if (!pField) - return S_FALSE; - - pFieldBase->AddPageRect(m_pPage, PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - pField->SetName(pPr->GetName()); - pField->SetReason(pPr->GetReason()); - pField->SetContact(pPr->GetContact()); - pField->SetDate(pPr->GetDate()); - - std::wstring wsPath = pPr->GetPicturePath(); - PdfWriter::CImageDict* pImage = NULL; - if (!wsPath.empty()) - { - Aggplus::CImage oImage(wsPath); - pImage = LoadImage(&oImage, 255); - } - - pField->SetAppearance(pImage); - - // TODO Реализовать, когда появится поддержка CSignatureField - pField->SetCert(); - } else if (oInfo.IsDateTime()) { const CFormFieldInfo::CDateTimeFormPr* pPr = oInfo.GetDateTimePr(); From 13542b13884c29c6dfea9a596223825a2716782e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 18 Mar 2024 22:38:46 +0600 Subject: [PATCH 447/794] fIx content types writing for worksheets and pivot tables --- OOXML/XlsbFormat/Xlsb.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 2a511c3f05a..3aa80e3b93d 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -101,6 +101,10 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oDirPath, OOX::CContentTypes return false; m_bWriteToXlsb = true; + if(!m_oContentTypes.m_mapDefaults.empty() && !m_oContentTypes.m_mapOverrides.empty()) + { + oContentTypes.Merge(&m_oContentTypes); + } IFileContainer::Write(oDirPath / L"", OOX::CPath(_T("")), oContentTypes); From ad2c6b67f18d034be47e86d3887fc4e862a7a561 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 19 Mar 2024 11:00:37 +0300 Subject: [PATCH 448/794] fix bug #66864 --- .../PptFile/Reader/PPTDocumentInfo.cpp | 30 ++++++++++++++- MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h | 3 +- .../PptFile/Reader/PPTDocumentInfoOneUser.cpp | 37 +------------------ .../PptFile/Reader/PPTDocumentInfoOneUser.h | 2 - 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp index 54e0eb5f52b..8814c00b2ed 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp @@ -109,6 +109,34 @@ bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE return true; } +std::wstring CPPTDocumentInfo::GetBinFromStg(const std::wstring& name, _UINT32 nRef) +{ + for (size_t i = 0; i < m_arUsers.size(); ++i) + { + std::map<_UINT32, _UINT32>::iterator nIndexPsrRef = m_arUsers[i]->m_mapOffsetInPIDs.find(nRef); + if (m_arUsers[i]->m_mapOffsetInPIDs.end() != nIndexPsrRef) + { + std::wstring result; + _UINT32 offset_stream = nIndexPsrRef->second; + StreamUtils::StreamSeek(offset_stream, m_pStream); + + SRecordHeader oHeader; + oHeader.ReadFromStream(m_pStream); + + CRecordExObjStg* pExObjStg = new CRecordExObjStg(name, m_pCommonInfo->tempPath); + + if (pExObjStg) + { + pExObjStg->ReadFromStream(oHeader, m_pStream); + result = pExObjStg->m_sFileName; + + RELEASEOBJECT(pExObjStg); + } + return result; + } + } + return L""; +} bool CPPTDocumentInfo::LoadDocument() { @@ -116,7 +144,7 @@ bool CPPTDocumentInfo::LoadDocument() try { - m_arUsers[0]->ReadExtenalObjects(); + m_arUsers[0]->ReadExtenalObjects(); // todooo ???? прочитать по всем (см 66864) m_arUsers[0]->FromDocument(); } catch(int) //error code diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h index 880447f4eeb..40dde44c550 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h @@ -59,7 +59,8 @@ class CPPTDocumentInfo bool ReadFromStream(CRecordCurrentUserAtom* pCurrentUser, POLE::Stream* pStream); bool LoadDocument(); - + + std::wstring GetBinFromStg(const std::wstring& name, _UINT32 nRef); private: POLE::Stream* m_pStream; }; diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp index 39c18081a22..bb3ed69f996 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -423,7 +423,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) { if (pVbaAtom->m_nHasMacros) { - m_sVbaProjectFile = GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); + m_sVbaProjectFile = m_pDocumentInfo->GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); m_bMacros = (false == m_sVbaProjectFile.empty()); } @@ -431,39 +431,6 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) } return true; } -std::wstring CPPTUserInfo::GetBinFromStg(const std::wstring& name, _UINT32 nRef) -{ - POLE::Stream* pStream = m_pDocumentInfo->m_pStream; - - std::map<_UINT32, _UINT32>::iterator nIndexPsrRef = m_mapOffsetInPIDs.find(nRef); - - std::wstring result; - if (m_mapOffsetInPIDs.end() != nIndexPsrRef) - { - _UINT32 offset_stream = nIndexPsrRef->second; - StreamUtils::StreamSeek(offset_stream, pStream); - - POLE::Stream* pStreamTmp = pStream; - if (m_pDecryptor) - { - DecryptStream(pStream, nRef); - pStreamTmp = m_arStreamDecrypt.back()->stream_; - } - SRecordHeader oHeader; - oHeader.ReadFromStream(pStreamTmp); - - CRecordExObjStg *pExObjStg = new CRecordExObjStg(name, m_pDocumentInfo->m_pCommonInfo->tempPath); - - if (pExObjStg) - { - pExObjStg->ReadFromStream(oHeader, pStreamTmp); - result = pExObjStg->m_sFileName; - - RELEASEOBJECT(pExObjStg); - } - } - return result; -} //-------------------------------------------------------------------------------------------- void CPPTUserInfo::ReadExtenalObjects() { @@ -2570,7 +2537,7 @@ void CPPTUserInfo::LoadExOleObject(CRecordsContainer* pExObject) if (oArrayCString.size() > 1) oInfo.m_progName = oArrayCString[1]->m_strText; - oInfo.m_strFilePath = GetBinFromStg(L"", oArrayExOleObj[0]->m_nPersistID); // ExOleObjStg || ExControlStg + oInfo.m_strFilePath = m_pDocumentInfo->GetBinFromStg(L"", oArrayExOleObj[0]->m_nPersistID); // ExOleObjStg || ExControlStg m_oExMedia.m_arOleObjects.push_back(oInfo); } diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h index d8c584403aa..3812682dffa 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h @@ -132,8 +132,6 @@ class CPPTUserInfo : public CDocument bool ReadDocumentPersists(POLE::Stream* pStream); void ReadExtenalObjects(); - std::wstring GetBinFromStg(const std::wstring& name, _UINT32 nRef); - void DecryptStream(POLE::Stream *pStream, int block); void FromDocument(); From 6eaf5cc9d37b2e8bb478af392ce81d19c6b55d12 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 19 Mar 2024 11:15:25 +0300 Subject: [PATCH 449/794] Fix ScanPagePptx --- DocxRenderer/src/logic/Page.cpp | 537 +++++++++--------- DocxRenderer/src/logic/elements/Paragraph.cpp | 90 ++- DocxRenderer/src/logic/elements/Paragraph.h | 3 - DocxRenderer/src/resources/Constants.h | 1 + 4 files changed, 346 insertions(+), 285 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 394ce469a33..32dbb8b24b5 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -456,8 +456,8 @@ namespace NSDocxRenderer void CPage::BuildDiacriticalSymbols() { - for(size_t i = 0; i < m_arConts.size(); i++) - if(m_arConts[i] && m_arConts[i]->m_oText.length() == 1 && IsDiacriticalMark(m_arConts[i]->m_oText[0])) + for (size_t i = 0; i < m_arConts.size(); i++) + if (m_arConts[i] && m_arConts[i]->m_oText.length() == 1 && IsDiacriticalMark(m_arConts[i]->m_oText[0])) m_arDiacriticalSymbols.push_back(std::move(m_arConts[i])); } @@ -468,24 +468,24 @@ namespace NSDocxRenderer if(!a) return false; if(!b) return true; - if(fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + if (fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) return a->m_dLeft < b->m_dLeft; return a->m_dBaselinePos < b->m_dBaselinePos; }); - for(auto& cont : m_arConts) - if(cont) + for (auto& cont : m_arConts) + if (cont) AddContToTextLine(cont); } void CPage::MergeShapes() { - if(m_arShapes.empty()) + if (m_arShapes.empty()) return; using shape_ref_ptr_t = std::reference_wrapper>; - for(size_t i = 0; i < m_arShapes.size() - 1; i++) + for (size_t i = 0; i < m_arShapes.size() - 1; i++) { shape_ref_ptr_t val = m_arShapes[i]; shape_ref_ptr_t next_val = m_arShapes[i + 1]; @@ -1147,106 +1147,6 @@ namespace NSDocxRenderer v_type == eVerticalCrossingType::vctNoCrossingCurrentBelowNext; }; - // после переместим все в output objects - std::vector> ar_paragraphs; - - double avg_spacing{0.0}; - size_t avg_spacing_n{0}; - - double min_left{m_dWidth}; - double max_right{0.0}; - - // совпадает ли left, right, center со строкой ниже - struct Position { - bool left{false}; - bool center{false}; - bool right {false}; - }; - - // параграф будет набиваться строчками - auto paragraph = std::make_shared(); - - // lamda to setup and add paragpraph - auto add_paragraph = [this, &max_right, &min_left, &ar_paragraphs] (std::shared_ptr& paragraph) { - - paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; - paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; - paragraph->m_dRight = max_right; - paragraph->m_dLeft = min_left; - - paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; - paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; - - paragraph->m_dRightBorder = m_dWidth - max_right; - paragraph->m_dLeftBorder = min_left; - - paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); - paragraph->m_bIsNeedFirstLineIndent = false; - paragraph->m_dFirstLine = 0; - paragraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); - - paragraph->MergeLines(); - - // setting TextAlignmentType - if (paragraph->m_arLines.size() > 1) - { - Position position_curr = {true, true, true}; - bool first_left = false; - - for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) - { - auto& curr_line = paragraph->m_arLines[index]; - auto& prev_line = paragraph->m_arLines[index - 1]; - - // indent check - if (index == 1) - first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - else - position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; - - auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; - auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; - - position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; - } - if (position_curr.left && position_curr.right) - paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; - else if (position_curr.left) - paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; - else if (position_curr.right) - paragraph->m_eTextAlignmentType = CParagraph::tatByRight; - else if (position_curr.center) - paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; - - // indent check - if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) - { - paragraph->m_bIsNeedFirstLineIndent = true; - paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; - } - } - - if (ar_paragraphs.empty()) - paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; - else - paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; - - ar_paragraphs.push_back(std::move(paragraph)); - paragraph = std::make_shared(); - - min_left = m_dWidth; - max_right = 0.0; - }; - - // lamda to add line and setup min_left/max_right - auto add_line = [&min_left, &max_right] (std::shared_ptr& paragraph, std::shared_ptr& curr_line) { - min_left = std::min(min_left, curr_line->m_dLeft); - max_right = std::max(max_right, curr_line->m_dRight); - paragraph->m_arLines.push_back(curr_line); - }; - // линии из которых сделаем шейпы for (size_t index = 0; index < m_arTextLines.size(); ++index) { @@ -1289,6 +1189,7 @@ namespace NSDocxRenderer } } + if (m_arTextLines.empty()) return; @@ -1304,199 +1205,319 @@ namespace NSDocxRenderer if (m_arTextLines.empty()) return; - // 1 строчка в параграфе - if (m_eTextAssociationType == TextAssociationType::tatPlainLine || - m_eTextAssociationType == TextAssociationType::tatShapeLine) - { - for (auto& curr_line : m_arTextLines) - { - add_line(paragraph, curr_line); - add_paragraph(paragraph); - } - } - - else if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || - m_eTextAssociationType == TextAssociationType::tatParagraphToShape) - { - // ar_spacing[index]- расстояние строки до строки снизу - // если 0.0 - строка последняя - std::vector ar_spacings(m_arTextLines.size(), 0.0); + auto build = [this] (const std::vector>& text_lines) { + std::vector> ar_paragraphs; - // позиции относительно других линий - std::vector ar_positions(m_arTextLines.size()); + double avg_spacing{0.0}; + size_t avg_spacing_n{0}; - // если ar_delims[index] == true, после строчки index нужно начинать новый параграф - std::vector ar_delims(m_arTextLines.size(), false); + double min_left{m_dWidth}; + double max_right{0.0}; - // calcs spacings & positions - for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) - { - ar_spacings[index] = m_arTextLines[index + 1]->m_dBaselinePos - m_arTextLines[index]->m_dTop; - avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); + // совпадает ли left, right, center со строкой ниже + struct Position { + bool left{false}; + bool center{false}; + bool right {false}; + }; - auto& left_curr = m_arTextLines[index]->m_dLeft; - auto& left_next = m_arTextLines[index + 1]->m_dLeft; + // параграф будет набиваться строчками + auto paragraph = std::make_shared(); - auto& right_curr = m_arTextLines[index]->m_dRight; - auto& right_next = m_arTextLines[index + 1]->m_dRight; + // lamda to setup and add paragpraph + auto add_paragraph = [this, &max_right, &min_left, &ar_paragraphs] (std::shared_ptr& paragraph) { - auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; - auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; + paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; + paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; + paragraph->m_dRight = max_right; + paragraph->m_dLeft = min_left; - if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) - ar_positions[index].center = true; - if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) - ar_positions[index].left = true; - if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) - ar_positions[index].right = true; - } + paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; + paragraph->m_dHeight = paragraph->m_dBaselinePos - paragraph->m_dTop; - // spacing check - for (size_t index = 0; index < ar_spacings.size(); ++index) - { - double spacing_top = 0.0; - double spacing_bot = 0.0; + paragraph->m_dRightBorder = m_dWidth - max_right; + paragraph->m_dLeftBorder = min_left; - if (index != 0) spacing_top = ar_spacings[index - 1]; - spacing_bot = ar_spacings[index]; + paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arLines.size(); + paragraph->m_bIsNeedFirstLineIndent = false; + paragraph->m_dFirstLine = 0; + paragraph->m_wsStyleId = m_pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph); - if (spacing_top == 0.0) spacing_top = spacing_bot; - if (spacing_bot == 0.0) spacing_bot = spacing_top; + paragraph->MergeLines(); - if (spacing_bot > c_dLINE_DISTANCE_MAX_MM) - ar_delims[index] = true; - else if (fabs(spacing_top - spacing_bot) < c_dLINE_DISTANCE_ERROR_MM) - ar_delims[index] = false; - else + // setting TextAlignmentType + if (paragraph->m_arLines.size() > 1) { - // берем доп строчки сверху и снизу для анализа - bool same_double_top = false; - bool same_double_bot = false; + Position position_curr = {true, true, true}; + bool first_left = false; - if (index > 1) + for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) { - double spacing_top_next = ar_spacings[index - 2]; - if (fabs(spacing_top - spacing_top_next) < c_dLINE_DISTANCE_ERROR_MM) - same_double_top = true; - } - if (index < ar_spacings.size() - 1) - { - double spacing_bot_next = ar_spacings[index + 1]; - if (fabs(spacing_bot - spacing_bot_next) < c_dLINE_DISTANCE_ERROR_MM) - same_double_bot = true; + auto& curr_line = paragraph->m_arLines[index]; + auto& prev_line = paragraph->m_arLines[index - 1]; + + // indent check + if (index == 1) + first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + else + position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + position_curr.right &= fabs(curr_line->m_dRight - prev_line->m_dRight) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + auto center_curr = curr_line->m_dLeft + curr_line->m_dWidth / 2; + auto center_prev = prev_line->m_dLeft + prev_line->m_dWidth / 2; + + position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; } + if (position_curr.left && position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; + else if (position_curr.left) + paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; + else if (position_curr.right) + paragraph->m_eTextAlignmentType = CParagraph::tatByRight; + else if (position_curr.center) + paragraph->m_eTextAlignmentType = CParagraph::tatByCenter; - // если анализ доп строчек ничего не дал - разбиваем наиболее "вероятным" способом - if ((same_double_top == same_double_bot)) + // indent check + if (paragraph->m_eTextAlignmentType == CParagraph::tatByLeft && !first_left) { - if (spacing_top > spacing_bot) - ar_delims[index - 1] = true; - else if (spacing_top < spacing_bot) - ar_delims[index] = true; + paragraph->m_bIsNeedFirstLineIndent = true; + paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; } - // прикрепляем строчку к верху или низу + } + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + if (ar_paragraphs.empty()) + paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; else - { - if (same_double_top) - ar_delims[index] = true; - else if (same_double_bot) - ar_delims[index - 1] = true; - } + paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; + } + + ar_paragraphs.push_back(std::move(paragraph)); + paragraph = std::make_shared(); + + min_left = m_dWidth; + max_right = 0.0; + }; + + // lamda to add line and setup min_left/max_right + auto add_line = [&min_left, &max_right] (std::shared_ptr& paragraph, std::shared_ptr& curr_line) { + min_left = std::min(min_left, curr_line->m_dLeft); + max_right = std::max(max_right, curr_line->m_dRight); + paragraph->m_arLines.push_back(curr_line); + }; + + // 1 строчка в параграфе + if (m_eTextAssociationType == TextAssociationType::tatPlainLine || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for (auto& curr_line : m_arTextLines) + { + add_line(paragraph, curr_line); + add_paragraph(paragraph); } } - // alignment check - bool is_first_line = false; - std::shared_ptr gap_check_line = m_arTextLines[0]; - for (size_t index = 0; index < ar_positions.size() - 1; ++index) + else if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatParagraphToShape) { - Position position_bot = ar_positions[index]; + // ar_spacing[index]- расстояние строки до строки снизу + // если 0.0 - строка последняя + std::vector ar_spacings(m_arTextLines.size(), 0.0); - auto& line_top = m_arTextLines[index]; - auto& line_bot = m_arTextLines[index + 1]; + // позиции относительно других линий + std::vector ar_positions(m_arTextLines.size()); - if (index == 0 || ar_delims[index - 1]) - is_first_line = true; - else - is_first_line = false; + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф + std::vector ar_delims(m_arTextLines.size(), false); - // первая строка может быть с отступом - if (is_first_line && line_bot->m_dLeft < line_top->m_dLeft) + // calcs spacings & positions + for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) { - // если больше трех линий - проверим третью - if (index < ar_positions.size() - 2) - { - if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) - position_bot.left = true; - else - position_bot.left = false; - } - else - position_bot.left = true; - } + ar_spacings[index] = m_arTextLines[index + 1]->m_dBaselinePos - m_arTextLines[index]->m_dTop; + avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); + + auto& left_curr = m_arTextLines[index]->m_dLeft; + auto& left_next = m_arTextLines[index + 1]->m_dLeft; - bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); - if (is_unknown) - ar_delims[index] = true; + auto& right_curr = m_arTextLines[index]->m_dRight; + auto& right_next = m_arTextLines[index + 1]->m_dRight; - if (ar_delims[index]) - gap_check_line = line_bot; + auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; + auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; + + if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) + ar_positions[index].center = true; + if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].left = true; + if (fabs(right_curr - right_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) + ar_positions[index].right = true; + } - // bla-bla-bla - // text bla-bla-bla-bla - // - // bla-bla-bla text - // bla-bla-bla-bla - else if (!ar_delims[index]) + // spacing check + for (size_t index = 0; index < ar_spacings.size(); ++index) { - double gap = 0; - std::shared_ptr cont = nullptr; + double spacing_top = 0.0; + double spacing_bot = 0.0; - if (position_bot.left) - { - gap = line_bot->m_dRight - gap_check_line->m_dRight; - cont = line_bot->m_arConts[0]; + if (index != 0) spacing_top = ar_spacings[index - 1]; + spacing_bot = ar_spacings[index]; - } - else if (position_bot.right) + if (spacing_top == 0.0) spacing_top = spacing_bot; + if (spacing_bot == 0.0) spacing_bot = spacing_top; + + if (spacing_bot > c_dLINE_DISTANCE_MAX_MM) + ar_delims[index] = true; + else if (fabs(spacing_top - spacing_bot) < c_dLINE_DISTANCE_ERROR_MM) + ar_delims[index] = false; + else { - gap = line_bot->m_dLeft - gap_check_line->m_dLeft; - cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1]; + // берем доп строчки сверху и снизу для анализа + bool same_double_top = false; + bool same_double_bot = false; + + if (index > 1) + { + double spacing_top_next = ar_spacings[index - 2]; + if (fabs(spacing_top - spacing_top_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_top = true; + } + if (index < ar_spacings.size() - 1) + { + double spacing_bot_next = ar_spacings[index + 1]; + if (fabs(spacing_bot - spacing_bot_next) < c_dLINE_DISTANCE_ERROR_MM) + same_double_bot = true; + } + + // если анализ доп строчек ничего не дал - разбиваем наиболее "вероятным" способом + if ((same_double_top == same_double_bot)) + { + if (spacing_top > spacing_bot) + ar_delims[index - 1] = true; + else if (spacing_top < spacing_bot) + ar_delims[index] = true; + } + // прикрепляем строчку к верху или низу + else + { + if (same_double_top) + ar_delims[index] = true; + else if (same_double_bot) + ar_delims[index - 1] = true; + } } + } + + // alignment check + bool is_first_line = false; + std::shared_ptr gap_check_line = m_arTextLines[0]; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position position_bot = ar_positions[index]; + + auto& line_top = m_arTextLines[index]; + auto& line_bot = m_arTextLines[index + 1]; + + if (index == 0 || ar_delims[index - 1]) + is_first_line = true; else - continue; + is_first_line = false; - if (gap < 0) + // первая строка может быть с отступом + if (is_first_line && line_bot->m_dLeft < line_top->m_dLeft) { - gap_check_line = line_bot; - continue; + // если больше трех линий - проверим третью + if (index < ar_positions.size() - 2) + { + if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) + position_bot.left = true; + else + position_bot.left = false; + } + else + position_bot.left = true; } - size_t cont_len = cont->m_oText.length(); - size_t space_pos = cont->m_oText.ToStdWString().find_first_of(L' '); - if (space_pos == std::wstring::npos) - space_pos = cont_len; - - // to save time doing it roughly - double rough_width = cont->m_dWidth / cont_len * space_pos; - if (gap > rough_width * 1.2) + bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); + if (is_unknown) ar_delims[index] = true; + + if (ar_delims[index]) + gap_check_line = line_bot; + + // bla-bla-bla + // text bla-bla-bla-bla + // + // bla-bla-bla text + // bla-bla-bla-bla + else if (!ar_delims[index]) + { + double gap = 0; + std::shared_ptr cont = nullptr; + + if (position_bot.left) + { + gap = line_bot->m_dRight - gap_check_line->m_dRight; + cont = line_bot->m_arConts[0]; + + } + else if (position_bot.right) + { + gap = line_bot->m_dLeft - gap_check_line->m_dLeft; + cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1]; + } + else + continue; + + if (gap < 0) + { + gap_check_line = line_bot; + continue; + } + + size_t cont_len = cont->m_oText.length(); + size_t space_pos = cont->m_oText.ToStdWString().find_first_of(L' '); + if (space_pos == std::wstring::npos) + space_pos = cont_len; + + // to save time doing it roughly + double rough_width = cont->m_dWidth / cont_len * space_pos; + if (gap > rough_width * 1.2) + ar_delims[index] = true; + } } - } - // на основе ar_delims разбиваем на параграфы - for (size_t index = 0; index < ar_delims.size(); ++index) - { -// if (m_arTextLines[index]->m_pDominantShape) -// { -// paragraph->m_bIsShadingPresent = true; -// paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; -// paragraph->RemoveHighlightColor(); -// } - add_line(paragraph, m_arTextLines[index]); - if (ar_delims[index] || index == ar_delims.size() - 1) - add_paragraph(paragraph); + // на основе ar_delims разбиваем на параграфы + for (size_t index = 0; index < ar_delims.size(); ++index) + { + // if (m_arTextLines[index]->m_pDominantShape) + // { + // paragraph->m_bIsShadingPresent = true; + // paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; + // paragraph->RemoveHighlightColor(); + // } + add_line(paragraph, m_arTextLines[index]); + if (ar_delims[index] || index == ar_delims.size() - 1) + add_paragraph(paragraph); + } } + + return ar_paragraphs; + }; + + std::vector> ar_paragraphs; + + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + ar_paragraphs = build(m_arTextLines); + } + + else if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + ar_paragraphs = build(m_arTextLines); } using paragraph_ptr_t = std::shared_ptr; @@ -1527,7 +1548,7 @@ namespace NSDocxRenderer pParagraph->m_dLeft = pLine->m_dLeft; pParagraph->m_dTop = pLine->m_dTop; pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - pParagraph->m_dWidth = pLine->m_dWidth; + pParagraph->m_dWidth = pLine->m_dWidth + c_dSHAPE_X_OFFSET; pParagraph->m_dHeight = pLine->m_dHeight; pParagraph->m_dRight = pLine->m_dRight; @@ -1564,7 +1585,7 @@ namespace NSDocxRenderer pShape->m_dRight = pParagraph->m_dRight; pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; pShape->m_dHeight = pParagraph->m_dHeight; - pShape->m_dWidth = pParagraph->m_dWidth; + pShape->m_dWidth = pParagraph->m_dWidth + c_dSHAPE_X_OFFSET; pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index b28ce3eae90..790021c31f8 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -14,54 +14,54 @@ namespace NSDocxRenderer m_arLines.clear(); } - void CParagraph::BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const + void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const { - oWriter.WriteString(L"<" + wsTag + L":p>"); - oWriter.WriteString(L"<" + wsTag + L":pPr>"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); // styles - if(!m_wsStyleId.empty()) oWriter.WriteString(L"<" + wsTag + L":pStyle " + wsTag + L":val=\"" + m_wsStyleId + L"\"/>"); + if(!m_wsStyleId.empty()) oWriter.WriteString(L""); - oWriter.WriteString(L"<" + wsTag + L":spacing"); + oWriter.WriteString(L" 0) { - oWriter.WriteString(L" " + wsTag + L":before=\""); + oWriter.WriteString(L" w:before=\""); oWriter.AddInt(static_cast(m_dSpaceBefore * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dSpaceAfter > 0) { - oWriter.WriteString(L" " + wsTag + L":after=\""); + oWriter.WriteString(L" w:after=\""); oWriter.AddInt(static_cast(m_dSpaceAfter * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dLineHeight > 0) { - oWriter.WriteString(L" " + wsTag + L":line=\""); + oWriter.WriteString(L" w:line=\""); oWriter.AddInt(static_cast(m_dLineHeight * c_dMMToDx)); - oWriter.WriteString(L"\" " + wsTag + L":lineRule=\"exact\""); // exact - точный размер строки + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки } oWriter.WriteString(L"/>"); //конец w:spacing - oWriter.WriteString(L"<" + wsTag + L":ind"); + oWriter.WriteString(L" 0) { - oWriter.WriteString(L" " + wsTag + L":left=\""); + oWriter.WriteString(L" w:left=\""); oWriter.AddInt(static_cast(m_dLeftBorder * c_dMMToDx)); oWriter.WriteString(L"\""); } if (m_dRightBorder > 0) { - oWriter.WriteString(L" " + wsTag + L":right=\""); + oWriter.WriteString(L" w:right=\""); oWriter.AddInt(static_cast(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края oWriter.WriteString(L"\""); } if (m_bIsNeedFirstLineIndent) { - oWriter.WriteString(L" " + wsTag + L":firstLine=\""); + oWriter.WriteString(L" w:firstLine=\""); oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToDx)); oWriter.WriteString(L"\""); } @@ -70,16 +70,16 @@ namespace NSDocxRenderer switch (m_eTextAlignmentType) { case tatByCenter: - oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"center\"/>"); + oWriter.WriteString(L""); break; case tatByRight: - oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"end\"/>"); + oWriter.WriteString(L""); break; case tatByWidth: - oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"both\"/>"); + oWriter.WriteString(L""); break; case tatByLeft: - oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"begin\"/>"); + oWriter.WriteString(L""); break; case tatUnknown: default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять @@ -88,15 +88,10 @@ namespace NSDocxRenderer if (m_bIsShadingPresent) { - oWriter.WriteString(L"<" + wsTag + L":shd " + wsTag + L":val=\"clear\" " + wsTag + L":color=\"auto\" " + wsTag + L":fill=\""); + oWriter.WriteString(L""); } - } - - void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const - { - BuildXml(oWriter, L"w"); oWriter.WriteString(L""); for(const auto& line : m_arLines) @@ -107,7 +102,54 @@ namespace NSDocxRenderer void CParagraph::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const { - BuildXml(oWriter, L"a"); + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dFirstLine * c_dMMToPt * 100)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dLineHeight * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); oWriter.WriteString(L""); for(const auto& line : m_arLines) diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index cb5ad9a8aa6..f6b7976fc80 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -44,8 +44,5 @@ namespace NSDocxRenderer void RemoveHighlightColor(); void MergeLines(); - - private: - void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const; }; } diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index 1d15c281865..5b1dedbc2c1 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -30,6 +30,7 @@ const double c_dMAX_LINE_HEIGHT_MM = 2.5; const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; const double c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH = 0.8; const double c_dLINE_DISTANCE_MAX_MM = 50.0; +const double c_dSHAPE_X_OFFSET = 2.5; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; From d5a4cd43e352834fc1673e0c16eb47a7e8cb933a Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 19 Mar 2024 11:23:58 +0300 Subject: [PATCH 450/794] Fix bug --- DocxRenderer/src/logic/elements/Paragraph.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 790021c31f8..521da880b77 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -124,13 +124,15 @@ namespace NSDocxRenderer break; } + oWriter.WriteString(L"\""); + if (m_bIsNeedFirstLineIndent) { oWriter.WriteString(L" indent=\""); - oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToPt * 100)); + oWriter.AddInt(static_cast(m_dFirstLine * c_dMMToEMU)); oWriter.WriteString(L"\""); } - oWriter.WriteString(L"\">"); + oWriter.WriteString(L">"); oWriter.WriteString(L""); oWriter.WriteString(L" Date: Tue, 19 Mar 2024 12:27:22 +0300 Subject: [PATCH 451/794] Fix right alignments --- DocxRenderer/src/logic/Page.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 32dbb8b24b5..277ab9a12c5 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1258,7 +1258,13 @@ namespace NSDocxRenderer // indent check if (index == 1) + { first_left = fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; + + // первая строчка левее правой + if (!first_left && prev_line->m_dLeft < curr_line->m_dLeft) + position_curr.left = false; + } else position_curr.left &= fabs(curr_line->m_dLeft - prev_line->m_dLeft) < c_dERROR_OF_PARAGRAPH_BORDERS_MM; @@ -1269,7 +1275,7 @@ namespace NSDocxRenderer position_curr.center &= fabs(center_curr - center_prev) < c_dCENTER_POSITION_ERROR_MM; } - if (position_curr.left && position_curr.right) + if (position_curr.left && position_curr.right && first_left) paragraph->m_eTextAlignmentType = CParagraph::tatByWidth; else if (position_curr.left) paragraph->m_eTextAlignmentType = CParagraph::tatByLeft; @@ -1344,8 +1350,10 @@ namespace NSDocxRenderer auto& right_curr = m_arTextLines[index]->m_dRight; auto& right_next = m_arTextLines[index + 1]->m_dRight; - auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth) / 2; - auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth) / 2; + auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth / 2); + auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth / 2); + + ///////////// if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) ar_positions[index].center = true; @@ -1464,7 +1472,7 @@ namespace NSDocxRenderer } else if (position_bot.right) { - gap = line_bot->m_dLeft - gap_check_line->m_dLeft; + gap = gap_check_line->m_dLeft - line_bot->m_dLeft; cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1]; } else @@ -1491,12 +1499,6 @@ namespace NSDocxRenderer // на основе ar_delims разбиваем на параграфы for (size_t index = 0; index < ar_delims.size(); ++index) { - // if (m_arTextLines[index]->m_pDominantShape) - // { - // paragraph->m_bIsShadingPresent = true; - // paragraph->m_lColorOfShadingFill = m_arTextLines[index]->m_pDominantShape->m_oBrush.Color1; - // paragraph->RemoveHighlightColor(); - // } add_line(paragraph, m_arTextLines[index]); if (ar_delims[index] || index == ar_delims.size() - 1) add_paragraph(paragraph); From 3a6f74dc828174076e5c036194eb76e9fb092487 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 19 Mar 2024 16:08:21 +0300 Subject: [PATCH 452/794] fix flags --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 45 +++++++++++------------ OOXML/XlsxFormat/Worksheets/SheetData.h | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 71f41e0f222..c0d446db5e4 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -475,7 +475,7 @@ namespace OOX } return nLen; } - _UINT32 CFormulaXLSB::toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula) + _UINT16 CFormulaXLSB::toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula) { _UINT16 nFlags = 0; if(m_oCa.ToBool()) @@ -486,7 +486,7 @@ namespace OOX oStream.WriteULONG(0);//cce oStream.WriteULONG(0);//cb - _UINT32 nFlagsExt = 0; + _UINT16 nFlagsExt = 0; nFlagsExt |= m_oT.GetValue(); nFlagsExt |= 0x4; if(m_oAca.ToBool()) @@ -693,12 +693,20 @@ namespace OOX oStream.XlsbStartRecord(nType, nLen); oStream.WriteULONG(m_nCol & 0x3FFF); - _UINT32 nStyle = m_nStyle; + _UINT32 nFlags2 = m_nStyle; if (m_oShowPhonetic.ToBool()) { - nStyle |= 0x1000000; + nFlags2 |= 0x1000000; } - oStream.WriteULONG(nStyle); + if (m_oCellMetadata.IsInit()) + { + nFlags2 |= 0x2000000; + } + if (m_oValueMetadata.IsInit()) + { + nFlags2 |= 0x4000000; + } + oStream.WriteULONG(nFlags2); //todo RkNumber switch(nType) { @@ -721,25 +729,16 @@ namespace OOX break; } - _UINT32 nFlags = 0; + _UINT16 nFlags = 0; if(m_oFormula.m_bIsInit) { nFlags = m_oFormula.toXLSB(oStream, bIsBlankFormula); } - if(m_oRichText.IsInit()) { nFlags |= 0x2000; } - if (m_oCellMetadata.IsInit()) - { - nFlags |= 0x8000; - } - if (m_oValueMetadata.IsInit()) - { - nFlags |= 0x10000; - } - oStream.WriteULONG(nFlags); + oStream.WriteUSHORT(nFlags); if(m_oFormula.m_bIsInit) { m_oFormula.toXLSBExt(oStream); @@ -1715,13 +1714,13 @@ namespace OOX m_oRow = nRow; m_oCol = (oStream.GetULong() & 0x3FFF); - _UINT32 nStyleRef = oStream.GetULong(); - if(0 != (nStyleRef & 0xFFFFFF)) + _UINT32 nFlags2 = oStream.GetULong(); + if(0 != (nFlags2 & 0xFFFFFF)) { - m_oStyle = (nStyleRef & 0xFFFFFF); + m_oStyle = (nFlags2 & 0xFFFFFF); } - if(0 != (nStyleRef & 0x1000000)) + if(0 != (nFlags2 & 0x1000000)) { m_oShowPhonetic.Init(); m_oShowPhonetic->FromBool(true); @@ -1784,7 +1783,7 @@ namespace OOX m_oFormula->fromXLSB(oStream); } //todo it breaks xslb format - _UINT32 nFlags = oStream.GetULong(); + _UINT16 nFlags = oStream.GetUShort(); if(0 != (nFlags & 0x4)) { if(!m_oFormula.IsInit()) @@ -1806,11 +1805,11 @@ namespace OOX m_oRichText.Init(); m_oRichText->fromXLSBExt(oStream); } - if (0 != (nFlags & 0x8000)) + if (0 != (nFlags2 & 0x2000000)) { m_oCellMetadata = oStream.GetULong(); } - if (0 != (nFlags & 0x10000)) + if (0 != (nFlags2 & 0x4000000)) { m_oValueMetadata = oStream.GetULong(); } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index d3effe3fb7b..fb7b09dc4be 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -61,7 +61,7 @@ namespace OOX void Clean(); void fromXML(XmlUtils::CXmlLiteReader& oReader); _UINT32 getXLSBSize(); - _UINT32 toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula); + _UINT16 toXLSB(NSBinPptxRW::CXlsbBinaryWriter& oStream, bool bIsBlankFormula); void toXLSBExt(NSBinPptxRW::CXlsbBinaryWriter& oStream); bool m_bIsInit; From 4943193ef780a0727fd09e14c67132b56c54ad52 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 19 Mar 2024 16:44:26 +0300 Subject: [PATCH 453/794] fix bug #66868 --- OOXML/XlsxFormat/Workbook/Metadata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/Metadata.cpp b/OOXML/XlsxFormat/Workbook/Metadata.cpp index 7da7a64c2c0..74cf59e79c1 100644 --- a/OOXML/XlsxFormat/Workbook/Metadata.cpp +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -824,7 +824,7 @@ namespace OOX writer.WriteString(L""); for (size_t i = 0; i < m_arrItems.size(); ++i) From 7c349dfa1828807b63737740e92c92e81cccee50 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 19 Mar 2024 18:58:52 +0300 Subject: [PATCH 454/794] Create PdfEditor --- .../graphics/pro/js/wasm/src/drawingfile.cpp | 1 - PdfFile/PdfEditor.cpp | 1235 ++++++++++++++++ PdfFile/PdfEditor.h | 71 + PdfFile/PdfFile.cpp | 1253 +---------------- PdfFile/PdfFile.pro | 2 + PdfFile/PdfWriter.cpp | 15 +- PdfFile/PdfWriter.h | 5 +- PdfFile/PdfWriter_empty.cpp | 4 +- 8 files changed, 1384 insertions(+), 1202 deletions(-) create mode 100644 PdfFile/PdfEditor.cpp create mode 100644 PdfFile/PdfEditor.h diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 5c882d4bf58..a6ac75ea299 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -260,7 +260,6 @@ WASM_EXPORT void SetCMapData(CGraphicsFileDrawing* pGraphics, BYTE* data, int si { pGraphics->SetCMapData(data, size); } - WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex) { return pGraphics->GetPageShapes(nPageIndex); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp new file mode 100644 index 00000000000..b49e53aaee3 --- /dev/null +++ b/PdfFile/PdfEditor.cpp @@ -0,0 +1,1235 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "PdfEditor.h" + +#include "../DesktopEditor/common/Path.h" + +#include "lib/xpdf/PDFDoc.h" +#include "lib/xpdf/AcroForm.h" +#include "lib/xpdf/TextString.h" + +#include "SrcWriter/Catalog.h" +#include "SrcWriter/EncryptDictionary.h" +#include "SrcWriter/Info.h" +#include "SrcWriter/ResourcesDictionary.h" +#include "SrcWriter/Streams.h" + +#define AddToObject(oVal)\ +{\ + if (pObj->GetType() == PdfWriter::object_type_DICT)\ + ((PdfWriter::CDictObject*)pObj)->Add(sKey, oVal);\ + else if (pObj->GetType() == PdfWriter::object_type_ARRAY)\ + ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ +} + +void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey, bool bUnicode = false) +{ + Object oTemp; + switch (obj->getType()) + { + case objBool: + { + bool b = obj->getBool(); + AddToObject(b) + break; + } + case objInt: + { + AddToObject(obj->getInt()) + break; + } + case objReal: + { + AddToObject(obj->getReal()) + break; + } + case objString: + { + if (bBinary) + { + GString* str = obj->getString(); + int nLength = str->getLength(); + BYTE* arrId = new BYTE[nLength]; + for (int nIndex = 0; nIndex < nLength; ++nIndex) + arrId[nIndex] = str->getChar(nIndex); + AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); + RELEASEARRAYOBJECTS(arrId); + } + else + { + TextString* s = new TextString(obj->getString()); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + AddToObject(new PdfWriter::CStringObject(sValue.c_str(), bUnicode)) + delete s; + } + break; + } + case objName: + { + AddToObject(obj->getName()) + break; + } + case objNull: + { + AddToObject(new PdfWriter::CNullObject()) + break; + } + case objArray: + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + AddToObject(pArray) + + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pArray, bBinary, ""); + oTemp.free(); + } + break; + } + case objDict: + { + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + AddToObject(pDict); + + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + char* chKey = obj->dictGetKey(nIndex); + obj->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pDict, bBinary, chKey); + oTemp.free(); + } + break; + } + case objRef: + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(obj->getRefNum(), obj->getRefGen()); + AddToObject(new PdfWriter::CProxyObject(pBase, true)) + break; + } + case objNone: + { + AddToObject("None") + break; + } + case objStream: + case objCmd: + case objError: + case objEOF: + break; + } +} +PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) +{ + PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum()); + if (pParent) + return pParent; + + if (!pParentRef || !pParentRef->isRef() || !pdfDoc) + return pParent; + XRef* xref = pdfDoc->getXRef(); + Object oParent; + if (!pParentRef->fetch(xref, &oParent)->isDict()) + { + oParent.free(); + return pParent; + } + + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); + pParent = new PdfWriter::CDictObject(); + pXref->Add(pParent, pParentRef->getRefGen()); + if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) + { + RELEASEOBJECT(pXref); + oParent.free(); + return NULL; + } + + for (int i = 0; i < oParent.dictGetLength(); ++i) + { + char* chKey = oParent.dictGetKey(i); + if (strcmp("Parent", chKey) == 0) + { + Object oParentRef; + oParent.dictGetValNF(i, &oParentRef); + PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef); + if (pParent2) + { + pParent->Add("Parent", pParent2); + oParentRef.free(); + continue; + } + oParentRef.free(); + } + Object oTemp; + oParent.dictGetValNF(i, &oTemp); + DictToCDictObject(&oTemp, pParent, false, chKey); + oTemp.free(); + } + + oParent.free(); + + return pParent; +} +HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter) +{ + if (!_pReader || !_pWriter) + return S_FALSE; + PDFDoc* pPDFDocument = _pReader->GetPDFDocument(); + if (!pPDFDocument) + return S_FALSE; + XRef* xref = pPDFDocument->getXRef(); + if (!xref) + return S_FALSE; + Object* trailerDict = xref->getTrailerDict(); + if (!trailerDict) + return S_FALSE; + + PdfWriter::CDocument* pDoc = _pWriter->m_pDocument; + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0); + PdfWriter::CXref* m_pXref = new PdfWriter::CXref(pDoc, xref->getNumObjects()); // Для новых объектов + if (!xref || !pDoc || !pXref || !m_pXref) + { + RELEASEOBJECT(pXref); + RELEASEOBJECT(m_pXref); + return S_FALSE; + } + pXref->SetPrev(m_pXref); + + for (int i = 0; i < xref->getSize(); ++i) + { + XRefEntry* pEntry = xref->getEntry(i); + if (pEntry->type == xrefEntryFree) + continue; + + if (i != pXref->GetSizeXRef()) + { + PdfWriter::CXref* pXref2 = new PdfWriter::CXref(pDoc, i); + pXref2->SetPrev(pXref); + pXref = pXref2; + } + + Object oTemp; + xref->fetch(i, pEntry->gen, &oTemp); + PdfWriter::CObjectBase* pObj = NULL; + + switch (oTemp.getType()) + { + case objBool: + { + pObj = new PdfWriter::CBoolObject(oTemp.getBool()); + break; + } + case objInt: + { + pObj = new PdfWriter::CNumberObject(oTemp.getInt()); + break; + } + case objReal: + { + pObj = new PdfWriter::CRealObject(oTemp.getReal()); + break; + } + case objString: + { + TextString* s = new TextString(oTemp.getString()); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + pObj = new PdfWriter::CStringObject(sValue.c_str()); + delete s; + break; + } + case objName: + { + pObj = new PdfWriter::CNameObject(oTemp.getName()); + break; + } + case objNull: + { + pObj = new PdfWriter::CNullObject(); + break; + } + case objArray: + { + pObj = new PdfWriter::CArrayObject(); + + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oT; + oTemp.arrayGetNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, ""); + oT.free(); + } + break; + } + case objDict: + { + pObj = new PdfWriter::CDictObject(); + + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oT; + char* chKey = oTemp.dictGetKey(nIndex); + oTemp.dictGetValNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, chKey); + oT.free(); + } + break; + } + case objRef: + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(oTemp.getRefNum(), oTemp.getRefGen()); + pObj = new PdfWriter::CProxyObject(pBase, true); + break; + } + case objStream: + { + Dict* pDict = oTemp.streamGetDict(); + Object oObjStm; + if (pDict->lookup("Type", &oObjStm)->isName("ObjStm")) + { + oObjStm.free(); + break; + } + oObjStm.free(); + + PdfWriter::CDictObject* pDObj = new PdfWriter::CDictObject(); + pObj = pDObj; + + int nLength = 0; + for (int nIndex = 0; nIndex < pDict->getLength(); ++nIndex) + { + Object oT; + char* chKey = pDict->getKey(nIndex); + if (strcmp("Length", chKey) == 0) + { + Object oLength; + nLength = pDict->getVal(nIndex, &oLength)->isInt() ? oLength.getInt() : 0; + oLength.free(); + continue; + } + pDict->getValNF(nIndex, &oT); + DictToCDictObject(&oT, pObj, false, chKey); + oT.free(); + } + + PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(); + pDObj->SetStream(m_pXref, pStream, false); + + Stream* pImage = oTemp.getStream()->getUndecodedStream(); + pImage->reset(); + for (int nI = 0; nI < nLength; ++nI) + pStream->WriteChar(pImage->getChar()); + break; + } + case objNone: + case objCmd: + case objError: + case objEOF: + default: + break; + } + oTemp.free(); + + if (pObj) + pXref->Add(pObj); + } + + PdfWriter::CDictObject* pTrailer = pXref->GetTrailer(); + for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = trailerDict->dictGetKey(nIndex); + if (strcmp("Root", chKey) == 0 || strcmp("Info", chKey) == 0) + { + trailerDict->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pTrailer, true, chKey); + } + oTemp.free(); + } + + bool bRes = pDoc->SaveNewWithPassword(pXref, m_pXref, wsPath, wsPassword, wsPassword, pTrailer); + + RELEASEOBJECT(pXref); + + return bRes ? S_OK : S_FALSE; +} + +CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) +{ + wsSrcFile = _wsSrcFile; + wsPassword = _wsPassword; + pReader = _pReader; + pWriter = _pWriter; + bEditPage = false; + nError = 0; + + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + if (!pPDFDocument) + { + nError = 1; + return; + } + + // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым + std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); + std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) + { + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + GBool bRes = pPDFDocument->makeWritable(true, owner_pswd, user_pswd); + delete owner_pswd; + delete user_pswd; + if (!bRes) + { + nError = 2; // Не удалось проверить файл для записи + return; + } + } + else + { + if (!NSFile::CFileBinary::Copy(wsSrcFile, _wsDstFile)) + { + nError = 2; + return; + } + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(_wsDstFile, true)) + { + nError = 2; + return; + } + oFile.CloseFile(); + } + + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!xref || !pDoc) + { + nError = 1; + return; + } + + // Получение каталога и дерева страниц из reader + Object catDict, catRefObj, pagesRefObj; + if (!xref->getCatalog(&catDict) || !catDict.isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) + { + pagesRefObj.free(); + catDict.free(); + nError = 3; // Не удалось получить каталог и дерево страниц + return; + } + Object* trailer = xref->getTrailerDict(); + if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj) || !catRefObj.isRef()) + { + pagesRefObj.free(); + catDict.free(); + catRefObj.free(); + nError = 3; // Не удалось получить каталог и дерево страниц + return; + } + Ref catRef = catRefObj.getRef(); + catRefObj.free(); + + // Создание каталога для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, catRef.num); + if (!pXref) + { + pagesRefObj.free(); + catDict.free(); + nError = 1; + return; + } + PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); + if (!pCatalog) + { + pagesRefObj.free(); + catDict.free(); + RELEASEOBJECT(pXref); + nError = 1; + return; + } + pXref->Add(pCatalog, catRef.gen); + PdfWriter::CResourcesDict* pDR = NULL; + PdfWriter::CXref* pDRXref = NULL; + for (int nIndex = 0; nIndex < catDict.dictGetLength(); ++nIndex) + { + Object oAcroForm; + char* chKey = catDict.dictGetKey(nIndex); + if (strcmp("AcroForm", chKey) == 0) + { + catDict.dictGetVal(nIndex, &oAcroForm); + PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + + for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) + { + Object oTemp2; + char* chKey = oAcroForm.dictGetKey(nIndex); + if (strcmp("DR", chKey) == 0) + { + oAcroForm.dictGetVal(nIndex, &oTemp2); + if (!oTemp2.isDict()) + { + oTemp2.free(); + continue; + } + + Object oDR; + oAcroForm.dictGetValNF(nIndex, &oDR); + int nDRxrefNum = oDR.isRef() ? oDR.getRefNum() : xref->getNumObjects(); + int nDRxrefGen = oDR.isRef() ? oDR.getRefGen() : 0; + oDR.free(); + pDRXref = new PdfWriter::CXref(pDoc, nDRxrefNum); + + pDR = new PdfWriter::CResourcesDict(NULL, true, false); + pDRXref->Add(pDR, nDRxrefGen); + + pAcroForm->Add(chKey, pDR); + for (int nIndex2 = 0; nIndex2 < oTemp2.dictGetLength(); ++nIndex2) + { + Object oTemp; + char* chKey = oTemp2.dictGetKey(nIndex2); + oTemp2.dictGetVal(nIndex2, &oTemp); + DictToCDictObject(&oTemp, pDR, false, chKey); + oTemp.free(); + } + oTemp2.free(); + + pDR->Fix(); + continue; + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp2); + DictToCDictObject(&oTemp2, pAcroForm, false, chKey); + oTemp2.free(); + } + + if (!pAcroForm->Get("Fields")) + pAcroForm->Add("Fields", new PdfWriter::CArrayObject()); + + oAcroForm.free(); + pCatalog->Add(chKey, pAcroForm); + continue; + } + else + catDict.dictGetValNF(nIndex, &oAcroForm); + DictToCDictObject(&oAcroForm, pCatalog, false, chKey); + oAcroForm.free(); + } + catDict.free(); + + // Проверка уникальности имён текущих цифровых подписей pdf + unsigned int nFormField = 0; + AcroForm* form = pPDFDocument->getCatalog()->getForm(); + if (form) + { + nFormField = form->getNumFields() + 1; + std::wstring sSig = L"Sig" + std::to_wstring(nFormField); + int i = 0, nFormFields = form->getNumFields(); + while (i < nFormFields) + { + int nLength; + Unicode* uName = form->getField(i)->getName(&nLength); + std::wstring sName = NSStringExt::CConverter::GetUnicodeFromUTF32(uName, nLength); + RELEASEMEM(uName); + if (sName == sSig) + { + i = 0; + nFormField++; + sSig = L"Sig" + std::to_wstring(nFormField); + } + else + i++; + } + nFormField--; + } + + // Получение шифрования из reader и применения для writer + int nCryptAlgorithm = -1; + PdfWriter::CEncryptDict* pEncryptDict = NULL; + if (xref->isEncrypted()) + { + CryptAlgorithm encAlgorithm; + GBool ownerPasswordOk; + int permFlags, keyLength, encVersion; + xref->getEncryption(&permFlags, &ownerPasswordOk, &keyLength, &encVersion, &encAlgorithm); + nCryptAlgorithm = encAlgorithm; + + Object* pTrailerDict = xref->getTrailerDict(); + if (pTrailerDict) + { + pEncryptDict = new PdfWriter::CEncryptDict(); + + // Нужно получить словарь Encrypt БЕЗ дешифровки, поэтому времено отключаем encrypted в xref + xref->offEncrypted(); + + Object encrypt, ID, ID1; + if (pTrailerDict->dictLookup("Encrypt", &encrypt) && encrypt.isDict()) + { + for (int nIndex = 0; nIndex < encrypt.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = encrypt.dictGetKey(nIndex); + encrypt.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pEncryptDict, true, chKey); + oTemp.free(); + } + } + + if (!pEncryptDict->Get("Length")) + pEncryptDict->Add("Length", 40); + + encrypt.free(); + + if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) + DictToCDictObject(&ID1, pEncryptDict, true, "ID"); + ID.free(); ID1.free(); + + xref->onEncrypted(); + + pEncryptDict->SetRef(0, 0); + pEncryptDict->Fix(); + + pEncryptDict->SetPasswords(wsPassword, wsPassword); + if (!pEncryptDict->UpdateKey(nCryptAlgorithm)) + { + pagesRefObj.free(); + RELEASEOBJECT(pXref); + RELEASEOBJECT(pDRXref); + nError = 4; // Ошибка шифрования файла + return; + } + } + } + + // Применение редактирования для writer + bool bRes = pDoc->EditPdf(_wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); + if (bRes) + { + // Воспроизведение дерева страниц во writer + GetPageTree(xref, &pagesRefObj); + + if (pDR && pDRXref) + bRes = pDoc->EditResources(pDRXref, pDR); + } + pagesRefObj.free(); + if (!bRes) + nError = 5; // Ошибка применения редактирования +} +void CPdfEditor::Close() +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!pPDFDocument || !pDoc) + return; + XRef* xref = pPDFDocument->getXRef(); + if (!xref) + return; + + // Добавляем первый элемент в таблицу xref + // он должен иметь вид 0000000000 65535 f + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0, 65535); + if (!pXref) + return; + + PdfWriter::CDictObject* pTrailer = NULL; + Object* trailerDict = xref->getTrailerDict(); + if (trailerDict) + { + pTrailer = pXref->GetTrailer(); + + for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = trailerDict->dictGetKey(nIndex); + trailerDict->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pTrailer, true, chKey); + oTemp.free(); + } + } + + Object info; + pPDFDocument->getDocInfo(&info); + PdfWriter::CXref* pInfoXref = NULL; + PdfWriter::CInfoDict* pInfoDict = NULL; + if (info.isDict()) + { + // Обновление Info + PdfWriter::CObjectBase* pInfo = pTrailer->Get("Info"); + pInfoXref = new PdfWriter::CXref(pDoc, pInfo ? pInfo->GetObjId() : 0); + if (!pInfoXref) + { + RELEASEOBJECT(pXref); + return; + } + pInfoDict = new PdfWriter::CInfoDict(); + if (!pInfoDict) + { + RELEASEOBJECT(pXref); + RELEASEOBJECT(pInfoXref); + return; + } + pInfoXref->Add(pInfoDict, pInfo ? pInfo->GetGenNo() : 0); + + for (int nIndex = 0; nIndex < info.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = info.dictGetKey(nIndex); + info.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pInfoDict, true, chKey); + oTemp.free(); + } + pInfoDict->SetTime(PdfWriter::InfoModaDate); + } + info.free(); + + if (!pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) + { + RELEASEOBJECT(pXref); + return; + } + + std::wstring wsPath = pDoc->GetEditPdfPath(); + std::string sPathUtf8New = U_TO_UTF8(wsPath); + std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) + { + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + pPDFDocument->makeWritable(false, owner_pswd, user_pswd); + delete owner_pswd; + delete user_pswd; + + NSFile::CFileBinary oFile; + if (oFile.OpenFile(wsSrcFile)) + { + pReader->ChangeLength(oFile.GetFileSize()); + oFile.CloseFile(); + } + } + + pReader = NULL; + pWriter = NULL; + bEditPage = false; +} +int CPdfEditor::GetError() +{ + return nError; +} +void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj) +{ + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!pPagesRefObj || !xref || !pDoc) + return; + + Object typeDict, pagesObj; + if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict()) + { + pagesObj.free(); + return; + } + if (pagesObj.dictLookup("Type", &typeDict)->isName() && !typeDict.isName("Pages")) + { + pagesObj.free(); + typeDict.free(); + return; + } + typeDict.free(); + + Ref topPagesRef = pPagesRefObj->getRef(); + + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); + if (!pXref) + { + pagesObj.free(); + return; + } + + PdfWriter::CPageTree* pPageT = new PdfWriter::CPageTree(); + if (!pPageT) + { + pagesObj.free(); + RELEASEOBJECT(pXref); + return; + } + pXref->Add(pPageT, topPagesRef.gen); + for (int nIndex = 0; nIndex < pagesObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pagesObj.dictGetKey(nIndex); + pagesObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pPageT, false, chKey); + oTemp.free(); + } + pDoc->CreatePageTree(pXref, pPageT); + pPageT->Fix(); + + Object kidsArrObj; + if (!pagesObj.dictLookup("Kids", &kidsArrObj)->isArray()) + { + pagesObj.free(); + kidsArrObj.free(); + return; + } + pagesObj.free(); + + for (int i = 0, count = kidsArrObj.arrayGetLength(); i < count; ++i) + { + Object kidRefObj; + if (kidsArrObj.arrayGetNF(i, &kidRefObj)) + GetPageTree(xref, &kidRefObj); + kidRefObj.free(); + } + kidsArrObj.free(); +} +bool CPdfEditor::EditPage(int nPageIndex) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!pPDFDocument || !pDoc) + return false; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (pEditPage) + { + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + return true; + } + + XRef* xref = pPDFDocument->getXRef(); + Catalog* pCatalog = pPDFDocument->getCatalog(); + if (!xref || !pCatalog) + return false; + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (pPageRef.first == 0) + return false; + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) + { + pageObj.free(); + pageRefObj.free(); + return false; + } + pageRefObj.free(); + + // Воспроизведение словаря страницы из reader для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef.first); + if (!pXref) + { + pageObj.free(); + return false; + } + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + if (!pPage) + { + pageObj.free(); + RELEASEOBJECT(pXref); + return false; + } + pXref->Add(pPage, pPageRef.second); + for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pageObj.dictGetKey(nIndex); + if (strcmp("Resources", chKey) == 0 || strcmp("Annots", chKey) == 0) + pageObj.dictGetVal(nIndex, &oTemp); + else + pageObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pPage, true, chKey); + oTemp.free(); + } + pPage->Fix(); + pageObj.free(); + + // Применение редактирования страницы для writer + if (pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) + { + bEditPage = true; + return true; + } + + RELEASEOBJECT(pXref); + return false; +} +bool CPdfEditor::DeletePage(int nPageIndex) +{ + return pWriter->m_pDocument->DeletePage(nPageIndex); +} +bool CPdfEditor::AddPage(int nPageIndex) +{ + // Применение добавления страницы для writer + if (!pWriter->AddPage(nPageIndex)) + return false; + // По умолчанию выставляются размеры первой страницы, в дальнейшем размеры можно изменить + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + pWriter->put_Width(dWidth); + pWriter->put_Height(dHeight); + return true; +} +bool CPdfEditor::EditAnnot(int nPageIndex, int nID) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!pPDFDocument || !pDoc) + return false; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (!pEditPage) + { + pEditPage = pDoc->GetCurPage(); + EditPage(nPageIndex); + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + } + + XRef* xref = pPDFDocument->getXRef(); + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (!xref || pPageRef.first == 0) + return false; + + // Получение объекта аннотации + Object pageRefObj, pageObj, oAnnots; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots.free(); + return false; + } + pageRefObj.free(); pageObj.free(); + + Object oAnnotRef, oAnnot, oType; + for (int i = 0; i < oAnnots.arrayGetLength(); ++i) + { + if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + break; + oAnnotRef.free(); + } + oAnnots.free(); + if (!oAnnotRef.isRef() || !oAnnotRef.fetch(xref, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName()) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + // Воспроизведение словаря аннотации из reader для writer + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); + if (!pXref) + { + oAnnotRef.free(); oAnnot.free(); oType.free(); + return false; + } + + bool bIsWidget = false; + PdfWriter::CAnnotation* pAnnot = NULL; + if (oType.isName("Text")) + pAnnot = new PdfWriter::CTextAnnotation(pXref); + else if (oType.isName("Ink")) + pAnnot = new PdfWriter::CInkAnnotation(pXref); + else if (oType.isName("Line")) + pAnnot = new PdfWriter::CLineAnnotation(pXref); + else if (oType.isName("Highlight") || oType.isName("Underline") || oType.isName("Squiggly") || oType.isName("StrikeOut")) + pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); + else if (oType.isName("Square") || oType.isName("Circle")) + pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); + else if (oType.isName("Polygon") || oType.isName("PolyLine")) + pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); + else if (oType.isName("FreeText")) + pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); + else if (oType.isName("Caret")) + pAnnot = new PdfWriter::CCaretAnnotation(pXref); + else if (oType.isName("Popup")) + pAnnot = new PdfWriter::CPopupAnnotation(pXref); + else if (oType.isName("Widget")) + { + bIsWidget = true; + char* sName = NULL; + Object oFT; + if (oAnnot.dictLookup("FT", &oFT)->isName()) + sName = oFT.getName(); + + if (!sName) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("FT", &oFT)->isName()) + { + sName = oFT.getName(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + if (sName) + { + if (strcmp("Btn", sName) == 0) + { + bool bPushButton = false; + oFT.free(); + int nFf = 0; + if (oAnnot.dictLookup("Ff", &oFT)->isInt()) + nFf = oFT.getInt(); + if (!nFf) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("Ff", &oFT)->isInt()) + { + nFf = oFT.getInt(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + bPushButton = (bool)((nFf >> 16) & 1); + if (bPushButton) + pAnnot = new PdfWriter::CPushButtonWidget(pXref); + else + pAnnot = new PdfWriter::CCheckBoxWidget(pXref); + } + else if (strcmp("Tx", sName) == 0) + pAnnot = new PdfWriter::CTextWidget(pXref); + else if (strcmp("Ch", sName) == 0) + pAnnot = new PdfWriter::CChoiceWidget(pXref); + else if (strcmp("Sig", sName) == 0) + pAnnot = new PdfWriter::CSignatureWidget(pXref); + else + pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); + } + oFT.free(); + } + oType.free(); + + if (!pAnnot) + { + oAnnotRef.free(); oAnnot.free(); + RELEASEOBJECT(pXref); + return false; + } + pXref->Add(pAnnot, oAnnotRef.getRefGen()); + + for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) + { + char* chKey = oAnnot.dictGetKey(nIndex); + if (strcmp("Popup", chKey) == 0) + { + Object oPopupRef; + if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) + { + PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); + if (pPopup) + { + pAnnot->Add("Popup", pPopup); + pPopup->Add("Parent", pAnnot); + } + } + continue; + } + if (strcmp("Parent", chKey) == 0 && bIsWidget) + { + Object oParentRef; + oAnnot.dictGetValNF(nIndex, &oParentRef); + PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + + if (!pParent) + { + oParentRef.free(); + continue; + } + + ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); + PdfWriter::CArrayObject* pKids = dynamic_cast(pParent->Get("Kids")); + if (!pKids) + { + oParentRef.free(); + continue; + } + + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pKid = pKids->Get(i); + if (pKid->GetObjId() == oAnnotRef.getRefNum()) + { + pKids->Insert(pKid, pAnnot, true); + break; + } + } + oParentRef.free(); + } + Object oTemp; + oAnnot.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pAnnot, false, chKey); + oTemp.free(); + } + oAnnotRef.free(); oAnnot.free(); + + if (pDoc->EditAnnot(pXref, pAnnot, nID)) + return true; + + RELEASEOBJECT(pXref); + return false; +} +bool CPdfEditor::DeleteAnnot(int nID) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + if (!pPDFDocument || !pDoc) + return false; + + XRef* xref = pPDFDocument->getXRef(); + std::pair pPageRef; + pPageRef.first = pDoc->GetCurPage()->GetObjId(); + pPageRef.second = pDoc->GetCurPage()->GetGenNo(); + if (!xref || pPageRef.first == 0) + return false; + + // Получение объекта аннотации + Object pageRefObj, pageObj, oAnnots; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots.free(); + return false; + } + pageRefObj.free(); pageObj.free(); + + bool bRes = false; + for (int i = 0; i < oAnnots.arrayGetLength(); ++i) + { + Object oAnnotRef, oAnnot; + if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + { + bRes = pWriter->m_pDocument->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); + if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) + { + Object oPopupRef; + if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) + pWriter->m_pDocument->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); + oPopupRef.free(); + } + } + else if (oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + Object oIRTRef; + if (oAnnot.dictLookupNF("IRT", &oIRTRef)->isRef() && oIRTRef.getRefNum() == nID) + DeleteAnnot(oAnnotRef.getRefNum()); + oIRTRef.free(); + } + oAnnotRef.free(); oAnnot.free(); + } + oAnnots.free(); + + return bRes; +} +bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) +{ + CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + + std::vector arrParents = pFieldInfo->GetParents(); + for (CWidgetsInfo::CParent* pParent : arrParents) + { + PdfWriter::CDictObject* pDParent = pDoc->GetParent(pParent->nID); + if (pDParent) + continue; + + Object oParentRef; + // TODO узнать gen родителя + oParentRef.initRef(pParent->nID, 0); + GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + // TODO перевыставить детей + oParentRef.free(); + } + return true; +} +int CPdfEditor::GetPagesCount() +{ + return pWriter->m_pDocument->GetPagesCount(); +} +void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) +{ + PdfWriter::CPage* pPage = pWriter->m_pDocument->GetPage(nPageIndex); + if (!pPage) + return; + + int nRotate = pPage->GetRotate(); + if (nRotate % 180 == 0) + { + *pdWidth = pPage->GetWidth(); + *pdHeight = pPage->GetHeight(); + } + else + { + *pdWidth = pPage->GetHeight(); + *pdHeight = pPage->GetWidth(); + } + + *pdDpiX = 72.0; + *pdDpiY = 72.0; +} +int CPdfEditor::GetRotate(int nPageIndex) +{ + PdfWriter::CPage* pPage = pWriter->m_pDocument->GetPage(nPageIndex); + if (!pPage) + return 0; + return pPage->GetRotate(); +} +bool CPdfEditor::EditPage() +{ + return bEditPage; +} diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h new file mode 100644 index 00000000000..65c39b2d241 --- /dev/null +++ b/PdfFile/PdfEditor.h @@ -0,0 +1,71 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_EDITOR_H +#define _PDF_EDITOR_H + +#include "PdfWriter.h" +#include "PdfReader.h" + +HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter); + +class CPdfEditor +{ +public: + CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); + + int GetError(); + void Close(); + bool EditPage(int nPageIndex); + bool DeletePage(int nPageIndex); + bool AddPage(int nPageIndex); + bool EditAnnot(int nPageIndex, int nID); + bool DeleteAnnot(int nID); + bool EditWidgets(IAdvancedCommand* pCommand); + int GetPagesCount(); + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); + int GetRotate(int nPageIndex); + bool EditPage(); + +private: + void GetPageTree(XRef* xref, Object* pPagesRefObj); + + std::wstring wsSrcFile; + std::wstring wsPassword; + + CPdfReader* pReader; + CPdfWriter* pWriter; + + int nError; + bool bEditPage; +}; + +#endif // _PDF_EDITOR_H diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index c263f5c1889..5885ce509b9 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -34,134 +34,24 @@ #include "PdfReader.h" #include "../DesktopEditor/common/File.h" -#include "../HtmlRenderer/include/HTMLRendererText.h" #include "lib/xpdf/PDFDoc.h" #ifndef BUILDING_WASM_MODULE +#include "PdfEditor.h" #include "OnlineOfficeBinToPdf.h" -#include "../DesktopEditor/common/Path.h" -#include "../DesktopEditor/common/StringExt.h" -#include "SrcReader/Adaptors.h" -#include "lib/xpdf/AcroForm.h" -#include "lib/xpdf/TextString.h" - -#include "SrcWriter/Objects.h" #include "SrcWriter/Document.h" #include "SrcWriter/Pages.h" -#include "SrcWriter/Catalog.h" -#include "SrcWriter/EncryptDictionary.h" -#include "SrcWriter/Info.h" -#include "SrcWriter/Annotation.h" -#include "SrcWriter/ResourcesDictionary.h" -#include "SrcWriter/Streams.h" - -#define AddToObject(oVal)\ -{\ - if (pObj->GetType() == PdfWriter::object_type_DICT)\ - ((PdfWriter::CDictObject*)pObj)->Add(sKey, oVal);\ - else if (pObj->GetType() == PdfWriter::object_type_ARRAY)\ - ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ -} -void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey, bool bUnicode = false) +#else +class CPdfEditor { - Object oTemp; - switch (obj->getType()) - { - case objBool: - { - bool b = obj->getBool(); - AddToObject(b) - break; - } - case objInt: - { - AddToObject(obj->getInt()) - break; - } - case objReal: - { - AddToObject(obj->getReal()) - break; - } - case objString: - { - if (bBinary) - { - GString* str = obj->getString(); - int nLength = str->getLength(); - BYTE* arrId = new BYTE[nLength]; - for (int nIndex = 0; nIndex < nLength; ++nIndex) - arrId[nIndex] = str->getChar(nIndex); - AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); - RELEASEARRAYOBJECTS(arrId); - } - else - { - TextString* s = new TextString(obj->getString()); - std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - AddToObject(new PdfWriter::CStringObject(sValue.c_str(), bUnicode)) - delete s; - } - break; - } - case objName: - { - AddToObject(obj->getName()) - break; - } - case objNull: - { - AddToObject(new PdfWriter::CNullObject()) - break; - } - case objArray: - { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - AddToObject(pArray) - - for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) - { - obj->arrayGetNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pArray, bBinary, ""); - oTemp.free(); - } - break; - } - case objDict: - { - PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); - AddToObject(pDict); - - for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) - { - char* chKey = obj->dictGetKey(nIndex); - obj->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pDict, bBinary, chKey); - oTemp.free(); - } - break; - } - case objRef: - { - PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); - pBase->SetRef(obj->getRefNum(), obj->getRefGen()); - AddToObject(new PdfWriter::CProxyObject(pBase, true)) - break; - } - case objNone: - { - AddToObject("None") - break; - } - case objStream: - case objCmd: - case objError: - case objEOF: - break; - } -} +public: + void Close() {} + int GetPagesCount() { return 0; } + int GetRotate(int nPageIndex) { return 0; } + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} +}; #endif // BUILDING_WASM_MODULE class CPdfFile_Private @@ -173,80 +63,8 @@ class CPdfFile_Private NSFonts::IApplicationFonts* pAppFonts; CPdfReader* pReader; - CPdfWriter* pWriter; - LONG lClipMode; - bool bEdit; - bool bEditPage; - -#ifndef BUILDING_WASM_MODULE - void GetPageTree(XRef* xref, Object* pPagesRefObj) - { - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; - if (!pPagesRefObj || !xref || !pDoc) - return; - - Object typeDict, pagesObj; - if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict()) - { - pagesObj.free(); - return; - } - if (pagesObj.dictLookup("Type", &typeDict)->isName() && !typeDict.isName("Pages")) - { - pagesObj.free(); - typeDict.free(); - return; - } - typeDict.free(); - - Ref topPagesRef = pPagesRefObj->getRef(); - - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); - if (!pXref) - { - pagesObj.free(); - return; - } - - PdfWriter::CPageTree* pPageT = new PdfWriter::CPageTree(); - if (!pPageT) - { - pagesObj.free(); - RELEASEOBJECT(pXref); - return; - } - pXref->Add(pPageT, topPagesRef.gen); - for (int nIndex = 0; nIndex < pagesObj.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = pagesObj.dictGetKey(nIndex); - pagesObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPageT, false, chKey); - oTemp.free(); - } - pDoc->CreatePageTree(pXref, pPageT); - pPageT->Fix(); - - Object kidsArrObj; - if (!pagesObj.dictLookup("Kids", &kidsArrObj)->isArray()) - { - pagesObj.free(); - kidsArrObj.free(); - return; - } - pagesObj.free(); - - for (int i = 0, count = kidsArrObj.arrayGetLength(); i < count; ++i) - { - Object kidRefObj; - if (kidsArrObj.arrayGetNF(i, &kidRefObj)) - GetPageTree(xref, &kidRefObj); - kidRefObj.free(); - } - kidsArrObj.free(); - } -#endif + CPdfEditor* pEditor; }; // ------------------------------------------------------------------------ @@ -258,14 +76,13 @@ CPdfFile::CPdfFile(NSFonts::IApplicationFonts* pAppFonts) m_pInternal->pAppFonts = pAppFonts; m_pInternal->pWriter = NULL; m_pInternal->pReader = NULL; - m_pInternal->wsPassword = L""; - m_pInternal->bEdit = false; - m_pInternal->bEditPage = false; + m_pInternal->pEditor = NULL; } CPdfFile::~CPdfFile() { RELEASEOBJECT(m_pInternal->pWriter); RELEASEOBJECT(m_pInternal->pReader); + RELEASEOBJECT(m_pInternal->pEditor); } NSFonts::IFontManager* CPdfFile::GetFontManager() { @@ -276,109 +93,10 @@ NSFonts::IFontManager* CPdfFile::GetFontManager() void CPdfFile::Close() { - if (!m_pInternal->bEdit) - { - if (m_pInternal->pReader) - m_pInternal->pReader->Close(); - return; - } -#ifndef BUILDING_WASM_MODULE - if (!m_pInternal->pWriter || !m_pInternal->pReader) - return; - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc) - return; - - XRef* xref = pPDFDocument->getXRef(); - if (!xref) - return; - - // Добавляем первый элемент в таблицу xref - // он должен иметь вид 0000000000 65535 f - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0, 65535); - if (!pXref) - return; - - PdfWriter::CDictObject* pTrailer = NULL; - Object* trailerDict = xref->getTrailerDict(); - if (trailerDict) - { - pTrailer = pXref->GetTrailer(); - - for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = trailerDict->dictGetKey(nIndex); - trailerDict->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pTrailer, true, chKey); - oTemp.free(); - } - } - - Object info; - pPDFDocument->getDocInfo(&info); - PdfWriter::CXref* pInfoXref = NULL; - PdfWriter::CInfoDict* pInfoDict = NULL; - if (info.isDict()) - { - // Обновление Info - PdfWriter::CObjectBase* pInfo = pTrailer->Get("Info"); - pInfoXref = new PdfWriter::CXref(pDoc, pInfo ? pInfo->GetObjId() : 0); - if (!pInfoXref) - { - RELEASEOBJECT(pXref); - return; - } - pInfoDict = new PdfWriter::CInfoDict(); - if (!pInfoDict) - { - RELEASEOBJECT(pXref); - RELEASEOBJECT(pInfoXref); - return; - } - pInfoXref->Add(pInfoDict, pInfo ? pInfo->GetGenNo() : 0); - - for (int nIndex = 0; nIndex < info.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = info.dictGetKey(nIndex); - info.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pInfoDict, true, chKey); - oTemp.free(); - } - pInfoDict->SetTime(PdfWriter::InfoModaDate); - } - info.free(); - - if (!m_pInternal->pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) - { - RELEASEOBJECT(pXref); - return; - } - - std::wstring wsPath = pDoc->GetEditPdfPath(); - std::string sPathUtf8New = U_TO_UTF8(wsPath); - std::string sPathUtf8Old = U_TO_UTF8(m_pInternal->wsSrcFile); - if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) - { - GString* owner_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GString* user_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - pPDFDocument->makeWritable(false, owner_pswd, user_pswd); - delete owner_pswd; - delete user_pswd; - - NSFile::CFileBinary oFile; - if (oFile.OpenFile(m_pInternal->wsSrcFile)) - { - m_pInternal->pReader->ChangeLength(oFile.GetFileSize()); - oFile.CloseFile(); - } - } - - m_pInternal->bEdit = false; - m_pInternal->bEditPage = false; -#endif + if (m_pInternal->pEditor) + m_pInternal->pEditor->Close(); + else if (m_pInternal->pReader) + m_pInternal->pReader->Close(); } void CPdfFile::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) { @@ -412,879 +130,51 @@ bool CPdfFile::EditPdf(const std::wstring& wsDstFile) RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - if (!pPDFDocument) - return false; - - // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым - std::string sPathUtf8New = U_TO_UTF8(wsDstFile); - std::string sPathUtf8Old = U_TO_UTF8(m_pInternal->wsSrcFile); - if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) - { - GString* owner_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GString* user_pswd = NSStrings::CreateString(m_pInternal->wsPassword); - GBool bRes = pPDFDocument->makeWritable(true, owner_pswd, user_pswd); - delete owner_pswd; - delete user_pswd; - if (!bRes) - return false; - } - else - { - if (!NSFile::CFileBinary::Copy(m_pInternal->wsSrcFile, wsDstFile)) - return false; - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(wsDstFile, true)) - return false; - oFile.CloseFile(); - } - - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!xref || !pDoc) - return false; - - // Получение каталога и дерева страниц из reader - Object catDict, catRefObj, pagesRefObj; - if (!xref->getCatalog(&catDict) || !catDict.isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) - { - pagesRefObj.free(); - catDict.free(); - return false; - } - Object* trailer = xref->getTrailerDict(); - if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj) || !catRefObj.isRef()) - { - pagesRefObj.free(); - catDict.free(); - catRefObj.free(); - return false; - } - Ref catRef = catRefObj.getRef(); - catRefObj.free(); - - // Создание каталога для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, catRef.num); - if (!pXref) - { - pagesRefObj.free(); - catDict.free(); - return false; - } - PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); - if (!pCatalog) - { - pagesRefObj.free(); - catDict.free(); - RELEASEOBJECT(pXref); - return false; - } - pXref->Add(pCatalog, catRef.gen); - PdfWriter::CResourcesDict* pDR = NULL; - PdfWriter::CXref* pDRXref = NULL; - for (int nIndex = 0; nIndex < catDict.dictGetLength(); ++nIndex) - { - Object oAcroForm; - char* chKey = catDict.dictGetKey(nIndex); - if (strcmp("AcroForm", chKey) == 0) - { - catDict.dictGetVal(nIndex, &oAcroForm); - PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); - - for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) - { - Object oTemp2; - char* chKey = oAcroForm.dictGetKey(nIndex); - if (strcmp("DR", chKey) == 0) - { - oAcroForm.dictGetVal(nIndex, &oTemp2); - if (!oTemp2.isDict()) - { - oTemp2.free(); - continue; - } - - Object oDR; - oAcroForm.dictGetValNF(nIndex, &oDR); - int nDRxrefNum = oDR.isRef() ? oDR.getRefNum() : xref->getNumObjects(); - int nDRxrefGen = oDR.isRef() ? oDR.getRefGen() : 0; - oDR.free(); - pDRXref = new PdfWriter::CXref(pDoc, nDRxrefNum); - - pDR = new PdfWriter::CResourcesDict(NULL, true, false); - pDRXref->Add(pDR, nDRxrefGen); - - pAcroForm->Add(chKey, pDR); - for (int nIndex2 = 0; nIndex2 < oTemp2.dictGetLength(); ++nIndex2) - { - Object oTemp; - char* chKey = oTemp2.dictGetKey(nIndex2); - oTemp2.dictGetVal(nIndex2, &oTemp); - DictToCDictObject(&oTemp, pDR, false, chKey); - oTemp.free(); - } - oTemp2.free(); - - pDR->Fix(); - continue; - } - else - oAcroForm.dictGetValNF(nIndex, &oTemp2); - DictToCDictObject(&oTemp2, pAcroForm, false, chKey); - oTemp2.free(); - } - - if (!pAcroForm->Get("Fields")) - pAcroForm->Add("Fields", new PdfWriter::CArrayObject()); - - oAcroForm.free(); - pCatalog->Add(chKey, pAcroForm); - continue; - } - else - catDict.dictGetValNF(nIndex, &oAcroForm); - DictToCDictObject(&oAcroForm, pCatalog, false, chKey); - oAcroForm.free(); - } - catDict.free(); - - // Проверка уникальности имён текущих цифровых подписей pdf - unsigned int nFormField = 0; - AcroForm* form = pPDFDocument->getCatalog()->getForm(); - if (form) - { - nFormField = form->getNumFields() + 1; - std::wstring sSig = L"Sig" + std::to_wstring(nFormField); - int i = 0, nFormFields = form->getNumFields(); - while (i < nFormFields) - { - int nLength; - Unicode* uName = form->getField(i)->getName(&nLength); - std::wstring sName = NSStringExt::CConverter::GetUnicodeFromUTF32(uName, nLength); - RELEASEMEM(uName); - if (sName == sSig) - { - i = 0; - nFormField++; - sSig = L"Sig" + std::to_wstring(nFormField); - } - else - i++; - } - nFormField--; - } - - // Получение шифрования из reader и применения для writer - int nCryptAlgorithm = -1; - PdfWriter::CEncryptDict* pEncryptDict = NULL; - if (xref->isEncrypted()) - { - CryptAlgorithm encAlgorithm; - GBool ownerPasswordOk; - int permFlags, keyLength, encVersion; - xref->getEncryption(&permFlags, &ownerPasswordOk, &keyLength, &encVersion, &encAlgorithm); - nCryptAlgorithm = encAlgorithm; - - Object* pTrailerDict = xref->getTrailerDict(); - if (pTrailerDict) - { - pEncryptDict = new PdfWriter::CEncryptDict(); - - // Нужно получить словарь Encrypt БЕЗ дешифровки, поэтому времено отключаем encrypted в xref - xref->offEncrypted(); - - Object encrypt, ID, ID1; - if (pTrailerDict->dictLookup("Encrypt", &encrypt) && encrypt.isDict()) - { - for (int nIndex = 0; nIndex < encrypt.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = encrypt.dictGetKey(nIndex); - encrypt.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pEncryptDict, true, chKey); - oTemp.free(); - } - } - - if (!pEncryptDict->Get("Length")) - pEncryptDict->Add("Length", 40); - - encrypt.free(); - - if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) - DictToCDictObject(&ID1, pEncryptDict, true, "ID"); - ID.free(); ID1.free(); - - xref->onEncrypted(); - - pEncryptDict->SetRef(0, 0); - pEncryptDict->Fix(); - - pEncryptDict->SetPasswords(m_pInternal->wsPassword, m_pInternal->wsPassword); - if (!pEncryptDict->UpdateKey(nCryptAlgorithm)) - { - pagesRefObj.free(); - RELEASEOBJECT(pXref); - RELEASEOBJECT(pDRXref); - return false; - } - } - } - - // Применение редактирования для writer - bool bRes = pDoc->EditPdf(wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); - if (bRes) - { - // Воспроизведение дерева страниц во writer - m_pInternal->GetPageTree(xref, &pagesRefObj); - m_pInternal->bEdit = true; - - if (pDR && pDRXref) - bRes = pDoc->EditResources(pDRXref, pDR); - } - pagesRefObj.free(); - return bRes; + RELEASEOBJECT(m_pInternal->pEditor); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, wsDstFile, m_pInternal->pWriter); + return m_pInternal->pEditor->GetError() == 0; } bool CPdfFile::EditPage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pReader) - return false; - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) - return false; - - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (pEditPage) - { - pDoc->SetCurPage(pEditPage); - m_pInternal->pWriter->EditPage(pEditPage); - return true; - } - - XRef* xref = pPDFDocument->getXRef(); - Catalog* pCatalog = pPDFDocument->getCatalog(); - if (!xref || !pCatalog) - return false; - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (pPageRef.first == 0) - return false; - - // Получение объекта страницы - Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) - { - pageObj.free(); - pageRefObj.free(); - return false; - } - pageRefObj.free(); - - // Воспроизведение словаря страницы из reader для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef.first); - if (!pXref) - { - pageObj.free(); + if (!m_pInternal->pEditor) return false; - } - PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); - if (!pPage) - { - pageObj.free(); - RELEASEOBJECT(pXref); - return false; - } - pXref->Add(pPage, pPageRef.second); - for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = pageObj.dictGetKey(nIndex); - if (strcmp("Resources", chKey) == 0 || strcmp("Annots", chKey) == 0) - pageObj.dictGetVal(nIndex, &oTemp); - else - pageObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPage, true, chKey); - oTemp.free(); - } - pPage->Fix(); - pageObj.free(); - - // Применение редактирования страницы для writer - m_pInternal->bEditPage = true; - if (m_pInternal->pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) - return true; - - RELEASEOBJECT(pXref); - return false; + return m_pInternal->pEditor->EditPage(nPageIndex); } bool CPdfFile::DeletePage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pWriter->m_pDocument || !m_pInternal->bEdit) + if (!m_pInternal->pEditor) return false; - // Применение удаления страницы для writer - return m_pInternal->pWriter->m_pDocument->DeletePage(nPageIndex); + return m_pInternal->pEditor->DeletePage(nPageIndex); } bool CPdfFile::AddPage(int nPageIndex) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->bEdit) + if (!m_pInternal->pEditor) return false; - // Применение добавления страницы для writer - bool bRes = m_pInternal->pWriter->AddPage(nPageIndex); - // По умолчанию выставляются размеры первой страницы, в дальнейшем размеры можно изменить - if (bRes) - { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - m_pInternal->pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - m_pInternal->pWriter->put_Width(dWidth); - m_pInternal->pWriter->put_Height(dHeight); - } - return bRes; -} -PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) -{ - PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum()); - if (pParent) - return pParent; - - if (!pParentRef || !pParentRef->isRef() || !pdfDoc) - return pParent; - XRef* xref = pdfDoc->getXRef(); - Object oParent; - if (!pParentRef->fetch(xref, &oParent)->isDict()) - { - oParent.free(); - return pParent; - } - - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); - pParent = new PdfWriter::CDictObject(); - pXref->Add(pParent, pParentRef->getRefGen()); - if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) - { - RELEASEOBJECT(pXref); - oParent.free(); - return NULL; - } - - for (int i = 0; i < oParent.dictGetLength(); ++i) - { - char* chKey = oParent.dictGetKey(i); - if (strcmp("Parent", chKey) == 0) - { - Object oParentRef; - oParent.dictGetValNF(i, &oParentRef); - PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef); - if (pParent2) - { - pParent->Add("Parent", pParent2); - oParentRef.free(); - continue; - } - oParentRef.free(); - } - Object oTemp; - oParent.dictGetValNF(i, &oTemp); - DictToCDictObject(&oTemp, pParent, false, chKey); - oTemp.free(); - } - - oParent.free(); - - return pParent; + return m_pInternal->pEditor->AddPage(nPageIndex); } bool CPdfFile::EditAnnot(int nPageIndex, int nID) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->bEdit) - return false; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) + if (!m_pInternal->pEditor) return false; - - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (!pEditPage) - { - pEditPage = pDoc->GetCurPage(); - EditPage(nPageIndex); - pDoc->SetCurPage(pEditPage); - m_pInternal->pWriter->EditPage(pEditPage); - } - - XRef* xref = pPDFDocument->getXRef(); - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (!xref || pPageRef.first == 0) - return false; - - // Получение объекта аннотации - Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) - { - pageRefObj.free(); pageObj.free(); oAnnots.free(); - return false; - } - pageRefObj.free(); pageObj.free(); - - Object oAnnotRef, oAnnot, oType; - for (int i = 0; i < oAnnots.arrayGetLength(); ++i) - { - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) - break; - oAnnotRef.free(); - } - oAnnots.free(); - if (!oAnnotRef.isRef() || !oAnnotRef.fetch(xref, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName()) - { - oAnnotRef.free(); oAnnot.free(); oType.free(); - return false; - } - - // Воспроизведение словаря аннотации из reader для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); - if (!pXref) - { - oAnnotRef.free(); oAnnot.free(); oType.free(); - return false; - } - - bool bIsWidget = false; - PdfWriter::CAnnotation* pAnnot = NULL; - if (oType.isName("Text")) - pAnnot = new PdfWriter::CTextAnnotation(pXref); - else if (oType.isName("Ink")) - pAnnot = new PdfWriter::CInkAnnotation(pXref); - else if (oType.isName("Line")) - pAnnot = new PdfWriter::CLineAnnotation(pXref); - else if (oType.isName("Highlight") || oType.isName("Underline") || oType.isName("Squiggly") || oType.isName("StrikeOut")) - pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); - else if (oType.isName("Square") || oType.isName("Circle")) - pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); - else if (oType.isName("Polygon") || oType.isName("PolyLine")) - pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); - else if (oType.isName("FreeText")) - pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); - else if (oType.isName("Caret")) - pAnnot = new PdfWriter::CCaretAnnotation(pXref); - else if (oType.isName("Popup")) - pAnnot = new PdfWriter::CPopupAnnotation(pXref); - else if (oType.isName("Widget")) - { - bIsWidget = true; - char* sName = NULL; - Object oFT; - if (oAnnot.dictLookup("FT", &oFT)->isName()) - sName = oFT.getName(); - - if (!sName) - { - Object oParent, oParent2; - oAnnot.dictLookup("Parent", &oParent); - while (oParent.isDict()) - { - if (oParent.dictLookup("FT", &oFT)->isName()) - { - sName = oFT.getName(); - break; - } - oFT.free(); - oParent.dictLookup("Parent", &oParent2); - oParent.free(); - oParent = oParent2; - } - oParent.free(); - } - - if (sName) - { - if (strcmp("Btn", sName) == 0) - { - bool bPushButton = false; - oFT.free(); - int nFf = 0; - if (oAnnot.dictLookup("Ff", &oFT)->isInt()) - nFf = oFT.getInt(); - if (!nFf) - { - Object oParent, oParent2; - oAnnot.dictLookup("Parent", &oParent); - while (oParent.isDict()) - { - if (oParent.dictLookup("Ff", &oFT)->isInt()) - { - nFf = oFT.getInt(); - break; - } - oFT.free(); - oParent.dictLookup("Parent", &oParent2); - oParent.free(); - oParent = oParent2; - } - oParent.free(); - } - - bPushButton = (bool)((nFf >> 16) & 1); - if (bPushButton) - pAnnot = new PdfWriter::CPushButtonWidget(pXref); - else - pAnnot = new PdfWriter::CCheckBoxWidget(pXref); - } - else if (strcmp("Tx", sName) == 0) - pAnnot = new PdfWriter::CTextWidget(pXref); - else if (strcmp("Ch", sName) == 0) - pAnnot = new PdfWriter::CChoiceWidget(pXref); - else if (strcmp("Sig", sName) == 0) - pAnnot = new PdfWriter::CSignatureWidget(pXref); - else - pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); - } - oFT.free(); - } - oType.free(); - - if (!pAnnot) - { - oAnnotRef.free(); oAnnot.free(); - RELEASEOBJECT(pXref); - return false; - } - pXref->Add(pAnnot, oAnnotRef.getRefGen()); - - for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) - { - char* chKey = oAnnot.dictGetKey(nIndex); - if (strcmp("Popup", chKey) == 0) - { - Object oPopupRef; - if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) - { - PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); - if (pPopup) - { - pAnnot->Add("Popup", pPopup); - pPopup->Add("Parent", pAnnot); - } - } - continue; - } - if (strcmp("Parent", chKey) == 0 && bIsWidget) - { - Object oParentRef; - oAnnot.dictGetValNF(nIndex, &oParentRef); - PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef); - - if (!pParent) - { - oParentRef.free(); - continue; - } - - ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); - PdfWriter::CArrayObject* pKids = dynamic_cast(pParent->Get("Kids")); - if (!pKids) - { - oParentRef.free(); - continue; - } - - for (int i = 0; i < pKids->GetCount(); ++i) - { - PdfWriter::CObjectBase* pKid = pKids->Get(i); - if (pKid->GetObjId() == oAnnotRef.getRefNum()) - { - pKids->Insert(pKid, pAnnot, true); - break; - } - } - oParentRef.free(); - } - Object oTemp; - oAnnot.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pAnnot, false, chKey); - oTemp.free(); - } - oAnnotRef.free(); oAnnot.free(); - - if (pDoc->EditAnnot(pXref, pAnnot, nID)) - return true; - - RELEASEOBJECT(pXref); - return false; + return m_pInternal->pEditor->EditAnnot(nPageIndex, nID); } bool CPdfFile::DeleteAnnot(int nID) { - // Проверка режима редактирования - if (!m_pInternal->pWriter || !m_pInternal->pWriter->m_pDocument || !m_pInternal->bEdit) + if (!m_pInternal->pEditor) return false; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - if (!pPDFDocument || !pDoc || !m_pInternal->bEdit) - return false; - - XRef* xref = pPDFDocument->getXRef(); - std::pair pPageRef; - pPageRef.first = pDoc->GetCurPage()->GetObjId(); - pPageRef.second = pDoc->GetCurPage()->GetGenNo(); - if (!xref || pPageRef.first == 0) - return false; - - // Получение объекта аннотации - Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) - { - pageRefObj.free(); pageObj.free(); oAnnots.free(); - return false; - } - pageRefObj.free(); pageObj.free(); - - bool bRes = false; - for (int i = 0; i < oAnnots.arrayGetLength(); ++i) - { - Object oAnnotRef, oAnnot; - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) - { - bRes = m_pInternal->pWriter->m_pDocument->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); - if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) - { - Object oPopupRef; - if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) - m_pInternal->pWriter->m_pDocument->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); - oPopupRef.free(); - } - } - else if (oAnnots.arrayGet(i, &oAnnot)->isDict()) - { - Object oIRTRef; - if (oAnnot.dictLookupNF("IRT", &oIRTRef)->isRef() && oIRTRef.getRefNum() == nID) - DeleteAnnot(oAnnotRef.getRefNum()); - oIRTRef.free(); - } - oAnnotRef.free(); oAnnot.free(); - } - oAnnots.free(); - - return bRes; + return m_pInternal->pEditor->DeleteAnnot(nID); } bool CPdfFile::EditWidgets(IAdvancedCommand* pCommand) { - CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - - std::vector arrParents = pFieldInfo->GetParents(); - for (CWidgetsInfo::CParent* pParent : arrParents) - { - PdfWriter::CDictObject* pDParent = pDoc->GetParent(pParent->nID); - if (pDParent) - continue; - - Object oParentRef; - // TODO узнать gen родителя - oParentRef.initRef(pParent->nID, 0); - GetWidgetParent(pPDFDocument, pDoc, &oParentRef); - // TODO перевыставить детей - oParentRef.free(); - } - - return true; + if (!m_pInternal->pEditor) + return false; + return m_pInternal->pEditor->EditWidgets(pCommand); } HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false); - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - if (!pPDFDocument) - return S_FALSE; - - XRef* xref = pPDFDocument->getXRef(); - if (!xref) - return S_FALSE; - Object* trailerDict = xref->getTrailerDict(); - if (!trailerDict) - return S_FALSE; - - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0); - PdfWriter::CXref* m_pXref = new PdfWriter::CXref(pDoc, xref->getNumObjects()); // Для новых объектов - if (!xref || !pDoc || !pXref || !m_pXref) - { - RELEASEOBJECT(pXref); - RELEASEOBJECT(m_pXref); - return S_FALSE; - } - pXref->SetPrev(m_pXref); - - for (int i = 0; i < xref->getSize(); ++i) - { - XRefEntry* pEntry = xref->getEntry(i); - if (pEntry->type == xrefEntryFree) - continue; - - if (i != pXref->GetSizeXRef()) - { - PdfWriter::CXref* pXref2 = new PdfWriter::CXref(pDoc, i); - pXref2->SetPrev(pXref); - pXref = pXref2; - } - - Object oTemp; - xref->fetch(i, pEntry->gen, &oTemp); - PdfWriter::CObjectBase* pObj = NULL; - - switch (oTemp.getType()) - { - case objBool: - { - pObj = new PdfWriter::CBoolObject(oTemp.getBool()); - break; - } - case objInt: - { - pObj = new PdfWriter::CNumberObject(oTemp.getInt()); - break; - } - case objReal: - { - pObj = new PdfWriter::CRealObject(oTemp.getReal()); - break; - } - case objString: - { - TextString* s = new TextString(oTemp.getString()); - std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - pObj = new PdfWriter::CStringObject(sValue.c_str()); - delete s; - break; - } - case objName: - { - pObj = new PdfWriter::CNameObject(oTemp.getName()); - break; - } - case objNull: - { - pObj = new PdfWriter::CNullObject(); - break; - } - case objArray: - { - pObj = new PdfWriter::CArrayObject(); - - for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) - { - Object oT; - oTemp.arrayGetNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, ""); - oT.free(); - } - break; - } - case objDict: - { - pObj = new PdfWriter::CDictObject(); - - for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) - { - Object oT; - char* chKey = oTemp.dictGetKey(nIndex); - oTemp.dictGetValNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, chKey); - oT.free(); - } - break; - } - case objRef: - { - PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); - pBase->SetRef(oTemp.getRefNum(), oTemp.getRefGen()); - pObj = new PdfWriter::CProxyObject(pBase, true); - break; - } - case objStream: - { - Dict* pDict = oTemp.streamGetDict(); - Object oObjStm; - if (pDict->lookup("Type", &oObjStm)->isName("ObjStm")) - { - oObjStm.free(); - break; - } - oObjStm.free(); - - PdfWriter::CDictObject* pDObj = new PdfWriter::CDictObject(); - pObj = pDObj; - - int nLength = 0; - for (int nIndex = 0; nIndex < pDict->getLength(); ++nIndex) - { - Object oT; - char* chKey = pDict->getKey(nIndex); - if (strcmp("Length", chKey) == 0) - { - Object oLength; - nLength = pDict->getVal(nIndex, &oLength)->isInt() ? oLength.getInt() : 0; - oLength.free(); - continue; - } - pDict->getValNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, chKey); - oT.free(); - } - - PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(); - pDObj->SetStream(m_pXref, pStream, false); - - Stream* pImage = oTemp.getStream()->getUndecodedStream(); - pImage->reset(); - for (int nI = 0; nI < nLength; ++nI) - pStream->WriteChar(pImage->getChar()); - break; - } - case objNone: - case objCmd: - case objError: - case objEOF: - default: - break; - } - oTemp.free(); - - if (pObj) - pXref->Add(pObj); - } - - PdfWriter::CDictObject* pTrailer = pXref->GetTrailer(); - for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = trailerDict->dictGetKey(nIndex); - if (strcmp("Root", chKey) == 0 || strcmp("Info", chKey) == 0) - { - trailerDict->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pTrailer, true, chKey); - } - oTemp.free(); - } - - bool bRes = pDoc->SaveNewWithPassword(pXref, m_pXref, wsPath, wsPassword, wsPassword, pTrailer); - - RELEASEOBJECT(pXref); - - return bRes ? S_OK : S_FALSE; + return _ChangePassword(wsPath, wsPassword, m_pInternal->pReader, m_pInternal->pWriter); } #endif // BUILDING_WASM_MODULE @@ -1377,7 +267,7 @@ bool CPdfFile::GetMetaData(const std::wstring& sFile, const std::wstring& sMetaN return false; } pStream += 8; - int nStreamBegin = pStream - (char*)pBuffer; + int nStreamBegin = (int)(pStream - (char*)pBuffer); pMeta += sMeta.length() + 3; char* pMetaLast = strstr(pMeta, " "); @@ -1461,68 +351,35 @@ int CPdfFile::GetPagesCount() return 0; PDFDoc* pPdfDoc = m_pInternal->pReader->GetPDFDocument(); int nPages = pPdfDoc ? pPdfDoc->getNumPages() : 0; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) + if (m_pInternal->pEditor) { - int nWPages = m_pInternal->pWriter->m_pDocument->GetPagesCount(); + int nWPages = m_pInternal->pEditor->GetPagesCount(); if (nWPages > 0) nPages = nWPages; } -#endif return nPages; } void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { if (!m_pInternal->pReader) return; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) - { - PdfWriter::CPage* pPage = m_pInternal->pWriter->m_pDocument->GetPage(nPageIndex); - if (!pPage) - return; - - int nRotate = pPage->GetRotate(); - if (nRotate % 180 == 0) - { - *pdWidth = pPage->GetWidth(); - *pdHeight = pPage->GetHeight(); - } - else - { - *pdWidth = pPage->GetHeight(); - *pdHeight = pPage->GetWidth(); - } - - *pdDpiX = 72.0; - *pdDpiY = 72.0; - } + if (m_pInternal->pEditor) + m_pInternal->pEditor->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); else -#endif m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } int CPdfFile::GetRotate(int nPageIndex) { if (!m_pInternal->pReader) return 0; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->pWriter && m_pInternal->pWriter->m_pDocument) - { - PdfWriter::CPage* pPage = m_pInternal->pWriter->m_pDocument->GetPage(nPageIndex); - if (!pPage) - return 0; - - return pPage->GetRotate(); - } - else -#endif + if (m_pInternal->pEditor) + return m_pInternal->pEditor->GetRotate(nPageIndex); return m_pInternal->pReader->GetRotate(nPageIndex); } int CPdfFile::GetMaxRefID() { if (!m_pInternal->pReader) return 0; - return m_pInternal->pReader->GetMaxRefID(); } bool CPdfFile::ValidMetaData() @@ -1667,7 +524,7 @@ HRESULT CPdfFile::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const HRESULT CPdfFile::AddToPdfFromBinary(BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams) { #ifndef BUILDING_WASM_MODULE - if (!m_pInternal->pReader || !m_pInternal->pWriter || !m_pInternal->bEdit || !NSOnlineOfficeBinToPdf::AddBinToPdf(this, pBuffer, nLen, pParams)) + if (!m_pInternal->pEditor || !NSOnlineOfficeBinToPdf::AddBinToPdf(this, pBuffer, nLen, pParams)) return S_FALSE; #endif return S_OK; @@ -1706,7 +563,7 @@ HRESULT CPdfFile::get_Type(LONG* lType) } HRESULT CPdfFile::NewPage() { - if (!m_pInternal->pWriter || m_pInternal->bEdit) + if (!m_pInternal->pWriter || m_pInternal->pEditor) return S_FALSE; return m_pInternal->pWriter->NewPage(); } @@ -1720,7 +577,7 @@ HRESULT CPdfFile::put_Height(const double& dHeight) { if (!m_pInternal->pWriter) return S_FALSE; - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor) return S_OK; return m_pInternal->pWriter->put_Height(dHeight); } @@ -1734,7 +591,7 @@ HRESULT CPdfFile::put_Width(const double& dWidth) { if (!m_pInternal->pWriter) return S_FALSE; - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor) return S_OK; return m_pInternal->pWriter->put_Width(dWidth); } @@ -2153,7 +1010,7 @@ HRESULT CPdfFile::EndCommand(const DWORD& lType) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->EndCommand(lType, m_pInternal->lClipMode); + return m_pInternal->pWriter->EndCommand(lType); } HRESULT CPdfFile::PathCommandMoveTo(const double& dX, const double& dY) { @@ -2277,13 +1134,15 @@ HRESULT CPdfFile::ResetTransform() } HRESULT CPdfFile::get_ClipMode(LONG* lMode) { - *lMode = m_pInternal->lClipMode; - return S_OK; + if (!m_pInternal->pWriter) + return S_FALSE; + return m_pInternal->pWriter->get_ClipMode(lMode); } HRESULT CPdfFile::put_ClipMode(const LONG& lMode) { - m_pInternal->lClipMode = lMode; - return S_OK; + if (!m_pInternal->pWriter) + return S_FALSE; + return m_pInternal->pWriter->put_ClipMode(lMode); } HRESULT CPdfFile::CommandLong(const LONG& lType, const LONG& lCommand) { @@ -2352,7 +1211,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; #ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) EditAnnot(pCommand->GetPage(), pCommand->GetID()); #endif return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand); @@ -2361,7 +1220,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { CAnnotFieldDelete* pCommand = (CAnnotFieldDelete*)command; #ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) DeleteAnnot(pCommand->GetID()); #endif return S_OK; @@ -2370,7 +1229,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { CWidgetsInfo* pCommand = (CWidgetsInfo*)command; #ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && EditWidgets(pCommand)) + if (m_pInternal->pEditor && EditWidgets(pCommand)) return m_pInternal->pWriter->EditWidgetParents(m_pInternal->pAppFonts, pCommand, m_pInternal->wsTempFolder); #endif return S_OK; @@ -2379,7 +1238,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { CShapeStart* pCommand = (CShapeStart*)command; #ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) m_pInternal->pWriter->m_pDocument->AddShapeXML(pCommand->GetShapeXML()); #endif return S_OK; @@ -2387,7 +1246,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { #ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && m_pInternal->bEditPage) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) m_pInternal->pWriter->m_pPage->EndMarkedContent(); #endif return S_OK; diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index e4211465d09..9de26c11ee4 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -205,9 +205,11 @@ SOURCES += \ HEADERS += PdfFile.h \ PdfWriter.h \ PdfReader.h \ + PdfEditor.h \ OnlineOfficeBinToPdf.h SOURCES += PdfFile.cpp \ PdfWriter.cpp \ PdfReader.cpp \ + PdfEditor.cpp \ OnlineOfficeBinToPdf.cpp diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index b7ea757558c..ed146d15b71 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -166,6 +166,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend m_dPageWidth = 210; m_pPage = NULL; m_pFont = NULL; + m_lClipMode = 0; m_unFieldsCounter = 0; m_bNeedUpdateTextFont = true; @@ -753,7 +754,7 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- -HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) +HRESULT CPdfWriter::EndCommand(const DWORD& dwType) { if (!IsPageValid()) return S_FALSE; @@ -766,7 +767,7 @@ HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) m_lClipDepth++; UpdateTransform(); - m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & lClipMode); + m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_lClipMode); } else if (c_nResetClipType == dwType) { @@ -1093,6 +1094,16 @@ HRESULT CPdfWriter::ResetTransform() m_oTransform.Reset(); return S_OK; } +HRESULT CPdfWriter::get_ClipMode(LONG* lMode) +{ + *lMode = m_lClipMode; + return S_OK; +} +HRESULT CPdfWriter::put_ClipMode(const LONG& lMode) +{ + m_lClipMode = lMode; + return S_OK; +} //---------------------------------------------------------------------------------------- // Дополнительные функции //---------------------------------------------------------------------------------------- diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index ab64292c354..4365d665821 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -160,7 +160,7 @@ class CPdfWriter //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- - HRESULT EndCommand(const DWORD& lType, const LONG& lClipMode); + HRESULT EndCommand(const DWORD& lType); //---------------------------------------------------------------------------------------- // Функции для работы с патом //---------------------------------------------------------------------------------------- @@ -198,6 +198,8 @@ class CPdfWriter HRESULT AddFormField (NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pFieldInfo, const std::wstring& wsTempDirectory); HRESULT AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo); HRESULT AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); + HRESULT get_ClipMode(LONG* lMode); + HRESULT put_ClipMode(const LONG& lMode); //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- @@ -271,6 +273,7 @@ class CPdfWriter double m_dPageHeight; double m_dPageWidth; LONG m_lClipDepth; + LONG m_lClipMode; std::vector m_vFonts; std::vectorm_vDestinations; unsigned int m_unFieldsCounter; diff --git a/PdfFile/PdfWriter_empty.cpp b/PdfFile/PdfWriter_empty.cpp index 0552f1f71dc..5929a6b31e6 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/PdfFile/PdfWriter_empty.cpp @@ -107,7 +107,7 @@ HRESULT CPdfWriter::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid HRESULT CPdfWriter::CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } HRESULT CPdfWriter::CommandDrawTextCHAR2 (unsigned int* unUnicode, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) { return 0; } -HRESULT CPdfWriter::EndCommand(const DWORD& lType, const LONG& lClipMode) { return 0; } +HRESULT CPdfWriter::EndCommand(const DWORD& lType) { return 0; } HRESULT CPdfWriter::PathCommandMoveTo(const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::PathCommandLineTo(const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::PathCommandLinesTo(double* pPoints, const int& nCount) { return 0; } @@ -128,6 +128,8 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con HRESULT CPdfWriter::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) { return 0; } HRESULT CPdfWriter::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) { return 0; } HRESULT CPdfWriter::ResetTransform() { return 0; } +HRESULT CPdfWriter::get_ClipMode(LONG* lMode) { return 0; } +HRESULT CPdfWriter::put_ClipMode(const LONG& lMode) { return 0; } HRESULT CPdfWriter::AddHyperlink(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsUrl, const std::wstring& wsTooltip) { return 0; } HRESULT CPdfWriter::AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage) { return 0; } HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFieldInfo* pInfo, const std::wstring& wsTempDirectory) { return 0; } From 70a4e3e792080abc7f89ae3af6897d685e673447 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 20 Mar 2024 10:55:55 +0300 Subject: [PATCH 455/794] fix bug #67008 --- .../XlsFile/Converter/xlsx_drawing_context.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp index 98d5f9a8f63..7ecadb8da0e 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp @@ -997,7 +997,7 @@ void xlsx_drawing_context::serialize_group() if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1373,7 +1373,7 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state) if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1448,7 +1448,7 @@ void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state) CP_XML_ATTR(L"name", drawing_state->name); if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { @@ -1500,7 +1500,7 @@ void xlsx_drawing_context::serialize_control(_drawing_state_ptr & drawing_state) if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } CP_XML_ATTR(L"hidden", 1); @@ -1601,7 +1601,7 @@ void xlsx_drawing_context::serialize_shape(_drawing_state_ptr & drawing_state) if (!drawing_state->description.empty()) { - CP_XML_ATTR(L"descr", drawing_state->description); + CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description)); } if (drawing_state->hidden) { From 475d0be0bf2a4f8f66d4b63450e7648d2444c16f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 20 Mar 2024 11:54:48 +0300 Subject: [PATCH 456/794] fix bug #59931 --- OdfFile/Writer/Format/ods_table_state.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index adb678bf35b..2ca0c6170b0 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -69,7 +69,7 @@ namespace utils//////////////////////////////////////////// ОБЩАЯ хрен { std::wstring convert_date(int date) { - boost::gregorian::date date_ = boost::gregorian::date(1900, 1, 1) + boost::gregorian::date_duration(date - 2); + boost::gregorian::date date_ = boost::gregorian::date(1900, 1, 1) + boost::gregorian::date_duration( date - (date < 60 ? 1 : 2)); //29.02.1900 std::wstring date_str; From c9fbe4189ced4dc215d7865d2420588c88865122 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Wed, 20 Mar 2024 13:51:18 +0300 Subject: [PATCH 457/794] Added merging of extra cells in html to ooxml conversion --- Common/3dParty/html/css/src/ConstValues.h | 85 +++---- .../html/css/src/xhtml/CDocumentStyle.cpp | 6 +- .../html/css/src/xhtml/CXmlElement.cpp | 42 ++-- HtmlFile2/htmlfile2.cpp | 213 +++++++++++++++--- 4 files changed, 249 insertions(+), 97 deletions(-) diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index ac03ac18fbe..ea8cd0772de 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -46,67 +46,68 @@ namespace NSCSS { typedef enum { - B_CustomStyle = 0, - B_StyleId = 1, - B_Type = 2, - B_Default = 3, + B_CustomStyle, + B_StyleId, + B_Type, + B_Default, - B_Name = 4, - B_BasedOn = 5, - B_QFormat = 6, - B_Link = 7, - B_UnhideWhenUsed = 8, - B_UiPriority = 9, + B_Name, + B_BasedOn, + B_QFormat, + B_Link, + B_UnhideWhenUsed, + B_UiPriority, + B_SemiHidden } BasicProperties; typedef enum { - P_Jc = 0, - P_Spacing = 1, - P_ContextualSpacing = 2, - P_Ind = 3, - P_OutlineLvl = 4, - P_Shd = 5, + P_Jc, + P_Spacing, + P_ContextualSpacing, + P_Ind, + P_OutlineLvl, + P_Shd, // - P_TopBorder = 6, - P_LeftBorder = 7, - P_BottomBorder = 8, - P_RightBorder = 9, + P_TopBorder, + P_LeftBorder, + P_BottomBorder, + P_RightBorder, // - P_KeepLines = 10, - P_KeepNext = 11, + P_KeepLines, + P_KeepNext, } ParagraphProperties; typedef enum { - R_RFonts = 0, - R_Sz = 1, - R_B = 2, - R_I = 3, - R_Color = 4, - R_U = 5, - R_Highlight = 6, - R_SmallCaps = 7, - R_Kern = 8 + R_RFonts , + R_Sz, + R_B, + R_I, + R_Color, + R_U, + R_Highlight, + R_SmallCaps, + R_Kern } RunnerProperties; typedef enum { - T_TblInd = 0, + T_TblInd , // - T_CellTop = 1, - T_CellLeft = 2, - T_CellBottom = 3, - T_CellRight = 4, + T_CellTop, + T_CellLeft, + T_CellBottom, + T_CellRight, // // - T_BorderTop = 5, - T_BorderLeft = 6, - T_BorderBottom = 7, - T_BorderRight = 8, - T_BorderInsideH = 9, - T_BorderInsideV = 10 + T_BorderTop , + T_BorderLeft, + T_BorderBottom, + T_BorderRight, + T_BorderInsideH, + T_BorderInsideV // } TableProperties; } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 5f2b8fd0309..b785cb16c6d 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -509,10 +509,14 @@ namespace NSCSS CXmlElement oXmlElement; SetPStyle(oStyle, oXmlElement); - if (!oXmlElement.Empty()) + if (oXmlElement.Empty()) return false; structStyle.setId(oXmlElement.GetStyleId()); + + if (structStyle.getId().empty()) + structStyle.setId(m_sId); + m_arStyleUsed.push_back(structStyle); m_sStyle += oXmlElement.GetPStyle(); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 3b07b4c8082..dd7607bc318 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -27,7 +27,7 @@ CXmlElement::CXmlElement(const std::wstring& sNameDefaultElement) bool CXmlElement::Empty() const { - return m_mPStyleValues.empty() && m_mRStyleValues.empty(); + return m_mPStyleValues.empty() && m_mRStyleValues.empty() && m_mBasicValues.find(CSSProperties::BasicProperties::B_BasedOn) == m_mBasicValues.end(); } void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) @@ -35,7 +35,19 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) if (!Empty()) Clear(); - if (sNameDefaultElement == L"li") + if (sNameDefaultElement == L"p") + { + AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); + AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p"); + AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Normal (Web)"); + AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); + AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"99"); + AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); + AddBasicProperties(CSSProperties::BasicProperties::B_SemiHidden, L"true"); + + AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); + } + else if (sNameDefaultElement == L"li") { AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"li"); @@ -191,23 +203,6 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddPropertiesInR(CSSProperties::RunnerProperties::R_Sz, L"15"); AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); } - else if (sNameDefaultElement == L"p-c") - { - AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character"); - AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p-c"); - AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); - AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Paragraph character"); - AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"p"); - } - else if (sNameDefaultElement == L"p") - { - AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"paragraph"); - AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"p"); - AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1"); - AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Paragraph"); - AddBasicProperties(CSSProperties::BasicProperties::B_BasedOn, L"normal"); - AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"p-c"); - } else if (sNameDefaultElement == L"div-c") { AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character"); @@ -515,7 +510,8 @@ std::wstring CXmlElement::ConvertBasicInfoStyle() const } case CSSProperties::BasicProperties::B_UnhideWhenUsed: { - sBasicInfo += L""; + if (L"true" == oItem.second) + sBasicInfo += L""; break; } case CSSProperties::BasicProperties::B_UiPriority: @@ -523,6 +519,12 @@ std::wstring CXmlElement::ConvertBasicInfoStyle() const sBasicInfo += L""; break; } + case CSSProperties::BasicProperties::B_SemiHidden: + { + if (L"true" == oItem.second) + sBasicInfo += L""; + break; + } default: break; } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index f9fce7ac582..7d8e55133c5 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -71,16 +71,19 @@ struct CTextSettings { bool bBdo; // Реверс текста bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) - bool bAddSpaces; // Не добавлять пробелы перед текстом + bool bAddSpaces; // Добавлять пробелы перед текстом? + bool bMergeText; // Объединять подяр идущий текст в 1? int nLi; // Уровень списка std::wstring sRStyle; // w:rStyle std::wstring sPStyle; // w:pStyle - CTextSettings(bool _bBdo, bool _bPre, bool _bAddSpaces, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : - bBdo(_bBdo), bPre(_bPre), bAddSpaces(_bAddSpaces), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) {} + CTextSettings(bool _bBdo, bool _bPre, bool _bAddSpaces, bool _bMergeText, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : + bBdo(_bBdo), bPre(_bPre), bAddSpaces(_bAddSpaces), bMergeText(_bMergeText), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) + {} CTextSettings(const CTextSettings& oTS) : - bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} + bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) + {} }; //Необходимые стили таблицы @@ -182,6 +185,8 @@ class CHtmlFile2_Private NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml bool m_bInP; // открыт? + bool m_bInR; // открыт? + bool m_bInT; // открыт? bool m_bWasPStyle; // записан? bool m_bWasSpace; // Был пробел? @@ -191,7 +196,7 @@ class CHtmlFile2_Private CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), - m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) + m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(false) { m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); @@ -773,6 +778,44 @@ class CHtmlFile2_Private pXml->WriteString(L""); } + bool OpenR(NSStringUtils::CStringBuilder* pXml) + { + if (m_bInR) + return false; + + pXml->WriteString(L""); + m_bInR = true; + return true; + } + + void CloseR(NSStringUtils::CStringBuilder* pXml) + { + if (!m_bInR) + return; + + pXml->WriteString(L""); + m_bInR = false; + } + + bool OpenT(NSStringUtils::CStringBuilder* pXml) + { + if (m_bInT) + return false; + + pXml->WriteString(L""); + m_bInT = true; + return true; + } + + void CloseT(NSStringUtils::CStringBuilder* pXml) + { + if (!m_bInT) + return; + + pXml->WriteString(L""); + m_bInT = false; + } + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) { m_bWasSpace = true; @@ -783,11 +826,19 @@ class CHtmlFile2_Private for (const NSCSS::CNode& item : arSelectors) if (item.m_wsName == L"a") pXml->WriteString(L""); - + + CloseT(pXml); + CloseR(pXml); + pXml->WriteString(L""); - m_bInP = false; + m_bInP = false; } - + + std::wstring GetText() + { + return ToUnicode(m_oLightReader.GetTextA()); + } + std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) { NSCSS::CNode oNode; @@ -879,26 +930,41 @@ class CHtmlFile2_Private m_oDocXml.WriteString(L"\"/>"); */ - readStream(&m_oDocXml, sSelectors, { false, false, true, -1, L"", L"" }); + readStream(&m_oDocXml, sSelectors, { false, false, true, false, -1, L"", L"" }); } void readInside (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& sName) { if(sName == L"#text") { - std::wstring sText = ToUnicode(m_oLightReader.GetTextA()); + std::wstring sText = GetText(); size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) return; - if (oTS.bAddSpaces && m_bInP && !iswspace(sText.front()) && !m_bWasSpace) + bool bInT = m_bInT; + + if (!oTS.sRStyle.empty() || oTS.bPre) + { + CloseT(oXml); + CloseR(oXml); + } + + if (oTS.bAddSpaces && m_bInP && !m_bInR && !iswspace(sText.front()) && !m_bWasSpace) + { oXml->WriteString(L" "); + m_bWasSpace = true; + } std::wstring sPStyle = wrP(oXml, sSelectors, oTS); - oXml->WriteString(L""); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); - oXml->WriteString(L""); + std::wstring sRStyle; + + if (OpenR(oXml)) + { + sRStyle = wrR(oXml, sSelectors, oTS); + OpenT(oXml); + } if(oTS.bBdo) std::reverse(sText.begin(), sText.end()); @@ -938,11 +1004,19 @@ class CHtmlFile2_Private if (std::iswspace(sText.front()) && m_bWasSpace) sText.erase(0, 1); + if (oTS.bMergeText && !m_bWasSpace && bInT) + oXml->WriteEncodeXmlString(L" "); + if (!sText.empty()) m_bWasSpace = std::iswspace(sText.back()); oXml->WriteEncodeXmlString(sText); - oXml->WriteString(L""); + + if (!oTS.bMergeText) + { + CloseT(oXml); + CloseR(oXml); + } return; } @@ -958,7 +1032,7 @@ class CHtmlFile2_Private else if(sName == L"b" || sName == L"strong") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; + oTSR.sRStyle += L""; readStream(oXml, sSelectors, oTSR); } // Направление текста @@ -1167,6 +1241,12 @@ class CHtmlFile2_Private } readStream(oXml, sSelectors, oTS); } + else if (sName == L"nobr") + { + CTextSettings oTSPre(oTS); + oTSPre.bPre = true; + readStream(oXml, sSelectors, oTSPre); + } // Без нового абзаца else if(sName == L"basefont" || sName == L"button" || sName == L"label" || sName == L"data" || sName == L"object" || sName == L"noscript" || sName == L"output" || sName == L"abbr" || sName == L"time" || sName == L"ruby" || @@ -1265,12 +1345,6 @@ class CHtmlFile2_Private oTSPre.bPre = true; readStream(oXml, sSelectors, oTSPre); } - else if (sName == L"nobr") - { - CTextSettings oTSPre(oTS); - oTSPre.bPre = true; - readStream(oXml, sSelectors, oTSPre); - } // Таблицы else if(sName == L"table") readTable(oXml, sSelectors, oTS); @@ -1345,6 +1419,71 @@ class CHtmlFile2_Private return L""; } + struct TTextReadingSettings + { + bool m_bOpenedRT; + bool m_bAddSpace; + std::wstring m_wsLastElement; + + TTextReadingSettings() + : m_bOpenedRT(false), m_bAddSpace(true) + {} + + TTextReadingSettings(bool bOpenedRT, bool bAddSpace, const std::wstring& wsLastElement) + : m_bOpenedRT(bOpenedRT), m_bAddSpace(bAddSpace), m_wsLastElement(wsLastElement) + {} + }; + + void ReadOnlyText(NSStringUtils::CStringBuilder* pXml, TTextReadingSettings& oTextReadingSettings, std::vector& sSelectors, const CTextSettings& oTS, int nDepth) + { + if (!m_oLightReader.IsValid() || m_oLightReader.IsEmptyNode()) + return; + + while (m_oLightReader.ReadNextSiblingNode2(nDepth)) + { + if (L"#text" == m_oLightReader.GetName()) + { + if (!oTextReadingSettings.m_bOpenedRT) + { + pXml->WriteString(L""); + oTextReadingSettings.m_bOpenedRT = true; + } + + pXml->WriteString(GetText()); + + if (oTextReadingSettings.m_bAddSpace) + pXml->WriteString(L" "); + } + else if (L"td" == m_oLightReader.GetName()) + ReadOnlyText(pXml, oTextReadingSettings, sSelectors, oTS, nDepth + 1); + else + { + GetSubClass(pXml, sSelectors); + if (oTextReadingSettings.m_bOpenedRT) + { + pXml->WriteString(L""); + oTextReadingSettings.m_bOpenedRT = false; + } + readStream(pXml, sSelectors, oTS); + sSelectors.pop_back(); + } + } + } + + void MergeCells(NSStringUtils::CStringBuilder* pXml) + { + if (!m_oLightReader.IsValid() || m_oLightReader.IsEmptyNode() || L"td" != m_oLightReader.GetName()) + return; + + std::vector arSelectors; + TTextReadingSettings oSettings; + + ReadOnlyText(pXml, oSettings, arSelectors, { false, false, true, false, -1, L"", L"" }, m_oLightReader.GetDepth() - 1); + + if (oSettings.m_bOpenedRT) + pXml->WriteString(L""); + } + void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const TTableStyles& oTableStyles) { const std::wstring wsName = m_oLightReader.GetName(); @@ -1543,19 +1682,20 @@ class CHtmlFile2_Private if (j - 1 == MAXCOLUMNSINTABLE) { +// MergeCells(&oTrBody); + CTextSettings oTrTS{oTS}; + oTrTS.bMergeText = true; + oTrTS.bAddSpaces = true; + m_bWasSpace = true; + while (m_oLightReader.ReadNextSiblingNode(nTrDeath) && L"td" == m_oLightReader.GetName()) { GetSubClass(&oTrBody, sSelectors); - CTextSettings oTSTd{oTS}; - oTSTd.bAddSpaces = false; - - readStream(&oTrBody, sSelectors, oTSTd); + readStream(&oTrBody, sSelectors, oTrTS); sSelectors.pop_back(); } - } - CloseP(&oTrBody, sSelectors); oTrBody.WriteString(L""); @@ -1748,7 +1888,8 @@ class CHtmlFile2_Private m_bWasPStyle = false; } // Заголовок таблицы выравнивание посередине - CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.bAddSpaces, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"" }; + CTextSettings oTSP(oTS); + oTSP.sPStyle += L""; readStream(oXml, sSelectors, oTSP); if (m_bInP) m_bWasPStyle = false; @@ -2280,12 +2421,16 @@ class CHtmlFile2_Private const std::wstring sRSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); - if (!sRStyle.empty()) + if (!sRStyle.empty() || !oTS.sRStyle.empty()) { - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - + oXml->WriteString(L""); + if (!sRStyle.empty()) + { + oXml->WriteString(L"WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + } + oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); oXml->WriteString(L""); } From e01aa641a0f57bd64f401b778525304588b9a23b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 20 Mar 2024 18:15:42 +0300 Subject: [PATCH 458/794] Remove PdfWriter_empty --- .../graphics/pro/js/drawingfile.json | 4 +- .../graphics/pro/js/qt/nativegraphics.pro | 2 +- .../graphics/pro/js/wasm/src/pdfwriter.cpp | 5 +- PdfFile/PdfEditor.cpp | 36 +++++++++------ PdfFile/PdfEditor.h | 2 + PdfFile/PdfFile.cpp | 46 +++++-------------- PdfFile/PdfFile.h | 3 -- PdfFile/PdfWriter.cpp | 20 ++++---- PdfFile/PdfWriter.h | 32 +++++-------- PdfFile/SrcWriter/States.cpp | 2 +- 10 files changed, 65 insertions(+), 87 deletions(-) rename PdfFile/PdfWriter_empty.cpp => DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp (97%) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 6f9e6ba8a52..fa8af8480ff 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -127,7 +127,7 @@ }, { "folder": "./wasm/src/", - "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp"] + "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp"] }, { "folder": "freetype-2.10.4/src/", @@ -171,7 +171,7 @@ }, { "folder": "../../../../PdfFile/", - "files": ["SrcReader/Adaptors.cpp", "SrcReader/GfxClip.cpp", "SrcReader/RendererOutputDev.cpp", "SrcReader/JPXStream2.cpp", "SrcReader/PdfAnnot.cpp", "Resources/BaseFonts.cpp", "Resources/CMapMemory/cmap_memory.cpp", "lib/fofi/FofiBase.cc", "lib/fofi/FofiEncodings.cc", "lib/fofi/FofiIdentifier.cc", "lib/fofi/FofiTrueType.cc", "lib/fofi/FofiType1.cc", "lib/fofi/FofiType1C.cc", "lib/goo/FixedPoint.cc", "lib/goo/gfile.cc", "lib/goo/GHash.cc", "lib/goo/GList.cc", "lib/goo/gmem.cc", "lib/goo/gmempp.cc", "lib/goo/GString.cc", "lib/goo/parseargs.c", "lib/goo/Trace.cc", "lib/splash/Splash.cc", "lib/splash/SplashBitmap.cc", "lib/splash/SplashClip.cc", "lib/splash/SplashFont.cc", "lib/splash/SplashFontEngine.cc", "lib/splash/SplashFontFile.cc", "lib/splash/SplashFontFileID.cc", "lib/splash/SplashFTFont.cc", "lib/splash/SplashFTFontEngine.cc", "lib/splash/SplashFTFontFile.cc", "lib/splash/SplashPath.cc", "lib/splash/SplashPattern.cc", "lib/splash/SplashScreen.cc", "lib/splash/SplashState.cc", "lib/splash/SplashXPath.cc", "lib/splash/SplashXPathScanner.cc", "lib/xpdf/AcroForm.cc", "lib/xpdf/Annot.cc", "lib/xpdf/Array.cc", "lib/xpdf/BuiltinFont.cc", "lib/xpdf/BuiltinFontTables.cc", "lib/xpdf/Catalog.cc", "lib/xpdf/CharCodeToUnicode.cc", "lib/xpdf/CMap.cc", "lib/xpdf/Decrypt.cc", "lib/xpdf/Dict.cc", "lib/xpdf/DisplayState.cc", "lib/xpdf/Error.cc", "lib/xpdf/FontEncodingTables.cc", "lib/xpdf/Function.cc", "lib/xpdf/Gfx.cc", "lib/xpdf/GfxFont.cc", "lib/xpdf/GfxState.cc", "lib/xpdf/GlobalParams.cc", "lib/xpdf/ImageOutputDev.cc", "lib/xpdf/JArithmeticDecoder.cc", "lib/xpdf/JBIG2Stream.cc", "lib/xpdf/JPXStream.cc", "lib/xpdf/Lexer.cc", "lib/xpdf/Link.cc", "lib/xpdf/NameToCharCode.cc", "lib/xpdf/Object.cc", "lib/xpdf/OptionalContent.cc", "lib/xpdf/Outline.cc", "lib/xpdf/OutputDev.cc", "lib/xpdf/Page.cc", "lib/xpdf/Parser.cc", "lib/xpdf/PDF417Barcode.cc", "lib/xpdf/PDFCore.cc", "lib/xpdf/PDFDoc.cc", "lib/xpdf/PDFDocEncoding.cc", "lib/xpdf/PreScanOutputDev.cc", "lib/xpdf/PSOutputDev.cc", "lib/xpdf/PSTokenizer.cc", "lib/xpdf/SecurityHandler.cc", "lib/xpdf/ShadingImage.cc", "lib/xpdf/SplashOutputDev.cc", "lib/xpdf/Stream.cc", "lib/xpdf/TextOutputDev.cc", "lib/xpdf/TextString.cc", "lib/xpdf/TileCache.cc", "lib/xpdf/TileCompositor.cc", "lib/xpdf/TileMap.cc", "lib/xpdf/UnicodeMap.cc", "lib/xpdf/UnicodeRemapping.cc", "lib/xpdf/UnicodeTypeTable.cc", "lib/xpdf/UTF8.cc", "lib/xpdf/WebFont.cc", "lib/xpdf/XFAScanner.cc", "lib/xpdf/XRef.cc", "lib/xpdf/Zoox.cc", "PdfFile.cpp", "PdfReader.cpp", "PdfWriter_empty.cpp"] + "files": ["SrcReader/Adaptors.cpp", "SrcReader/GfxClip.cpp", "SrcReader/RendererOutputDev.cpp", "SrcReader/JPXStream2.cpp", "SrcReader/PdfAnnot.cpp", "Resources/BaseFonts.cpp", "Resources/CMapMemory/cmap_memory.cpp", "lib/fofi/FofiBase.cc", "lib/fofi/FofiEncodings.cc", "lib/fofi/FofiIdentifier.cc", "lib/fofi/FofiTrueType.cc", "lib/fofi/FofiType1.cc", "lib/fofi/FofiType1C.cc", "lib/goo/FixedPoint.cc", "lib/goo/gfile.cc", "lib/goo/GHash.cc", "lib/goo/GList.cc", "lib/goo/gmem.cc", "lib/goo/gmempp.cc", "lib/goo/GString.cc", "lib/goo/parseargs.c", "lib/goo/Trace.cc", "lib/splash/Splash.cc", "lib/splash/SplashBitmap.cc", "lib/splash/SplashClip.cc", "lib/splash/SplashFont.cc", "lib/splash/SplashFontEngine.cc", "lib/splash/SplashFontFile.cc", "lib/splash/SplashFontFileID.cc", "lib/splash/SplashFTFont.cc", "lib/splash/SplashFTFontEngine.cc", "lib/splash/SplashFTFontFile.cc", "lib/splash/SplashPath.cc", "lib/splash/SplashPattern.cc", "lib/splash/SplashScreen.cc", "lib/splash/SplashState.cc", "lib/splash/SplashXPath.cc", "lib/splash/SplashXPathScanner.cc", "lib/xpdf/AcroForm.cc", "lib/xpdf/Annot.cc", "lib/xpdf/Array.cc", "lib/xpdf/BuiltinFont.cc", "lib/xpdf/BuiltinFontTables.cc", "lib/xpdf/Catalog.cc", "lib/xpdf/CharCodeToUnicode.cc", "lib/xpdf/CMap.cc", "lib/xpdf/Decrypt.cc", "lib/xpdf/Dict.cc", "lib/xpdf/DisplayState.cc", "lib/xpdf/Error.cc", "lib/xpdf/FontEncodingTables.cc", "lib/xpdf/Function.cc", "lib/xpdf/Gfx.cc", "lib/xpdf/GfxFont.cc", "lib/xpdf/GfxState.cc", "lib/xpdf/GlobalParams.cc", "lib/xpdf/ImageOutputDev.cc", "lib/xpdf/JArithmeticDecoder.cc", "lib/xpdf/JBIG2Stream.cc", "lib/xpdf/JPXStream.cc", "lib/xpdf/Lexer.cc", "lib/xpdf/Link.cc", "lib/xpdf/NameToCharCode.cc", "lib/xpdf/Object.cc", "lib/xpdf/OptionalContent.cc", "lib/xpdf/Outline.cc", "lib/xpdf/OutputDev.cc", "lib/xpdf/Page.cc", "lib/xpdf/Parser.cc", "lib/xpdf/PDF417Barcode.cc", "lib/xpdf/PDFCore.cc", "lib/xpdf/PDFDoc.cc", "lib/xpdf/PDFDocEncoding.cc", "lib/xpdf/PreScanOutputDev.cc", "lib/xpdf/PSOutputDev.cc", "lib/xpdf/PSTokenizer.cc", "lib/xpdf/SecurityHandler.cc", "lib/xpdf/ShadingImage.cc", "lib/xpdf/SplashOutputDev.cc", "lib/xpdf/Stream.cc", "lib/xpdf/TextOutputDev.cc", "lib/xpdf/TextString.cc", "lib/xpdf/TileCache.cc", "lib/xpdf/TileCompositor.cc", "lib/xpdf/TileMap.cc", "lib/xpdf/UnicodeMap.cc", "lib/xpdf/UnicodeRemapping.cc", "lib/xpdf/UnicodeTypeTable.cc", "lib/xpdf/UTF8.cc", "lib/xpdf/WebFont.cc", "lib/xpdf/XFAScanner.cc", "lib/xpdf/XRef.cc", "lib/xpdf/Zoox.cc", "PdfFile.cpp", "PdfReader.cpp"] }, { "folder": "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2/", diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 9ddd2d08009..52630b622ad 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -643,7 +643,6 @@ SOURCES += \ $$PDF_ROOT_DIR/Resources/BaseFonts.cpp \ $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.cpp \ $$PDF_ROOT_DIR/PdfReader.cpp \ - $$PDF_ROOT_DIR/PdfWriter_empty.cpp \ $$PDF_ROOT_DIR/PdfFile.cpp HEADERS +=\ @@ -727,5 +726,6 @@ HEADERS += \ ../wasm/src/serialize.h SOURCES += \ + ../wasm/src/pdfwriter.cpp \ ../wasm/src/drawingfile.cpp \ ../wasm/src/drawingfile_test.cpp diff --git a/PdfFile/PdfWriter_empty.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp similarity index 97% rename from PdfFile/PdfWriter_empty.cpp rename to DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index 5929a6b31e6..30c491d690c 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -29,7 +29,7 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "PdfWriter.h" +#include "../../../../../../PdfFile/PdfWriter.h" #ifdef BUILDING_WASM_MODULE CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate) : m_oCommandManager(this) {} @@ -145,6 +145,9 @@ bool CPdfWriter::AddPage(int nPageIndex) { return false; } bool CPdfWriter::EditClose() { return false; } void CPdfWriter::PageRotate(int nRotate) {} void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) {} +HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) { return 0; } +PdfWriter::CDocument* CPdfWriter::GetDocument() { return NULL; } +PdfWriter::CPage* CPdfWriter::GetPage() { return NULL; } PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) { return NULL; } bool CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return false; } bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { return false; } diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index b49e53aaee3..ed3b805b17a 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -215,7 +215,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo if (!trailerDict) return S_FALSE; - PdfWriter::CDocument* pDoc = _pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = _pWriter->GetDocument(); PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0); PdfWriter::CXref* m_pXref = new PdfWriter::CXref(pDoc, xref->getNumObjects()); // Для новых объектов if (!xref || !pDoc || !pXref || !m_pXref) @@ -434,7 +434,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!xref || !pDoc) { nError = 1; @@ -650,7 +650,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa void CPdfEditor::Close() { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return; XRef* xref = pPDFDocument->getXRef(); @@ -749,7 +749,7 @@ int CPdfEditor::GetError() } void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj) { - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPagesRefObj || !xref || !pDoc) return; @@ -816,7 +816,7 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj) bool CPdfEditor::EditPage(int nPageIndex) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -888,7 +888,7 @@ bool CPdfEditor::EditPage(int nPageIndex) } bool CPdfEditor::DeletePage(int nPageIndex) { - return pWriter->m_pDocument->DeletePage(nPageIndex); + return pWriter->GetDocument()->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { @@ -910,7 +910,7 @@ bool CPdfEditor::AddPage(int nPageIndex) bool CPdfEditor::EditAnnot(int nPageIndex, int nID) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1126,7 +1126,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) bool CPdfEditor::DeleteAnnot(int nID) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1153,12 +1153,12 @@ bool CPdfEditor::DeleteAnnot(int nID) Object oAnnotRef, oAnnot; if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) { - bRes = pWriter->m_pDocument->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); + bRes = pDoc->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) { Object oPopupRef; if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) - pWriter->m_pDocument->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); + pDoc->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); oPopupRef.free(); } } @@ -1179,7 +1179,7 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) { CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->m_pDocument; + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); for (CWidgetsInfo::CParent* pParent : arrParents) @@ -1199,11 +1199,11 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) } int CPdfEditor::GetPagesCount() { - return pWriter->m_pDocument->GetPagesCount(); + return pWriter->GetDocument()->GetPagesCount(); } void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { - PdfWriter::CPage* pPage = pWriter->m_pDocument->GetPage(nPageIndex); + PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); if (!pPage) return; @@ -1224,7 +1224,7 @@ void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, } int CPdfEditor::GetRotate(int nPageIndex) { - PdfWriter::CPage* pPage = pWriter->m_pDocument->GetPage(nPageIndex); + PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); if (!pPage) return 0; return pPage->GetRotate(); @@ -1233,3 +1233,11 @@ bool CPdfEditor::EditPage() { return bEditPage; } +void CPdfEditor::AddShapeXML(const std::string& sXML) +{ + return pWriter->GetDocument()->AddShapeXML(sXML); +} +void CPdfEditor::EndMarkedContent() +{ + pWriter->GetPage()->EndMarkedContent(); +} diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 65c39b2d241..5c9c287b972 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -54,6 +54,8 @@ class CPdfEditor void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); int GetRotate(int nPageIndex); bool EditPage(); + void AddShapeXML(const std::string& sXML); + void EndMarkedContent(); private: void GetPageTree(XRef* xref, Object* pPagesRefObj); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 5885ce509b9..5a560a09fd8 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -34,6 +34,7 @@ #include "PdfReader.h" #include "../DesktopEditor/common/File.h" +#include "../DesktopEditor/graphics/commands/DocInfo.h" #include "lib/xpdf/PDFDoc.h" #ifndef BUILDING_WASM_MODULE @@ -41,16 +42,21 @@ #include "OnlineOfficeBinToPdf.h" #include "SrcWriter/Document.h" -#include "SrcWriter/Pages.h" #else class CPdfEditor { public: void Close() {} + bool EditAnnot(int nPageIndex, int nID) { return false; } + bool DeleteAnnot(int nID) { return false; } + bool EditWidgets(IAdvancedCommand* pCommand) { return false; } int GetPagesCount() { return 0; } int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} + bool EditPage() { return false; } + void AddShapeXML(const std::string& sXML) {} + void EndMarkedContent() {} }; #endif // BUILDING_WASM_MODULE @@ -152,24 +158,6 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::EditAnnot(int nPageIndex, int nID) -{ - if (!m_pInternal->pEditor) - return false; - return m_pInternal->pEditor->EditAnnot(nPageIndex, nID); -} -bool CPdfFile::DeleteAnnot(int nID) -{ - if (!m_pInternal->pEditor) - return false; - return m_pInternal->pEditor->DeleteAnnot(nID); -} -bool CPdfFile::EditWidgets(IAdvancedCommand* pCommand) -{ - if (!m_pInternal->pEditor) - return false; - return m_pInternal->pEditor->EditWidgets(pCommand); -} HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); @@ -1210,45 +1198,35 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Annotaion: { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; -#ifndef BUILDING_WASM_MODULE if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) - EditAnnot(pCommand->GetPage(), pCommand->GetID()); -#endif + m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetID()); return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand); } case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: { CAnnotFieldDelete* pCommand = (CAnnotFieldDelete*)command; -#ifndef BUILDING_WASM_MODULE if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) - DeleteAnnot(pCommand->GetID()); -#endif + m_pInternal->pEditor->DeleteAnnot(pCommand->GetID()); return S_OK; } case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: { CWidgetsInfo* pCommand = (CWidgetsInfo*)command; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->pEditor && EditWidgets(pCommand)) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditWidgets(pCommand)) return m_pInternal->pWriter->EditWidgetParents(m_pInternal->pAppFonts, pCommand, m_pInternal->wsTempFolder); -#endif return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeStart: { CShapeStart* pCommand = (CShapeStart*)command; -#ifndef BUILDING_WASM_MODULE if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) - m_pInternal->pWriter->m_pDocument->AddShapeXML(pCommand->GetShapeXML()); -#endif + m_pInternal->pEditor->AddShapeXML(pCommand->GetShapeXML()); return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { -#ifndef BUILDING_WASM_MODULE if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) - m_pInternal->pWriter->m_pPage->EndMarkedContent(); -#endif + m_pInternal->pEditor->EndMarkedContent(); return S_OK; } default: diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index b060246605c..e7054c7dbe6 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,9 +97,6 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer bool EditPage (int nPageIndex); bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); - bool EditAnnot (int nPageIndex, int nID); - bool DeleteAnnot(int nID); - bool EditWidgets(IAdvancedCommand* pCommand); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index ed146d15b71..a9430403a5d 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -168,12 +168,8 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend m_pFont = NULL; m_lClipMode = 0; - m_unFieldsCounter = 0; - m_bNeedUpdateTextFont = true; - m_bNeedUpdateTextColor = true; - m_bNeedUpdateTextAlpha = true; - m_bNeedUpdateTextCharSpace = true; - m_bNeedUpdateTextSize = true; + m_unFieldsCounter = 0; + m_bNeedUpdateTextFont = true; } CPdfWriter::~CPdfWriter() { @@ -413,7 +409,6 @@ HRESULT CPdfWriter::put_BrushColor1(const LONG& lColor) if (lColor != m_oBrush.GetColor1()) { m_oBrush.SetColor1(lColor); - m_bNeedUpdateTextColor = true; } return S_OK; } @@ -427,7 +422,6 @@ HRESULT CPdfWriter::put_BrushAlpha1(const LONG& lAlpha) if (lAlpha != m_oBrush.GetAlpha1()) { m_oBrush.SetAlpha1(lAlpha); - m_bNeedUpdateTextAlpha = true; } return S_OK; } @@ -566,7 +560,6 @@ HRESULT CPdfWriter::put_FontSize(const double& dSize) if (fabs(dSize - m_oFont.GetSize()) > 0.001) { m_oFont.SetSize(dSize); - m_bNeedUpdateTextSize = true; } return S_OK; } @@ -604,7 +597,6 @@ HRESULT CPdfWriter::put_FontCharSpace(const double& dSpace) if (fabs(dSpace - m_oFont.GetCharSpace()) > 0.001) { m_oFont.SetCharSpace(dSpace); - m_bNeedUpdateTextCharSpace = true; } return S_OK; } @@ -2572,6 +2564,14 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi return S_OK; } +PdfWriter::CDocument* CPdfWriter::GetDocument() +{ + return m_pDocument; +} +PdfWriter::CPage* CPdfWriter::GetPage() +{ + return m_pPage; +} bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) { if (!IsValid()) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 4365d665821..c37b994284e 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -32,20 +32,17 @@ #ifndef _PDF_WRITER_H #define _PDF_WRITER_H -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Image.h" -#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" -#include "SrcWriter/States.h" - #include #include #include -#include "../../DesktopEditor/graphics/commands/DocInfo.h" +#include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/graphics/pro/Image.h" #include "../../DesktopEditor/graphics/commands/FormField.h" #include "../../DesktopEditor/graphics/commands/AnnotField.h" -#include "SrcWriter/Metadata.h" +#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" +#include "SrcWriter/States.h" #include "SrcWriter/Annotation.h" namespace PdfWriter @@ -208,7 +205,6 @@ class CPdfWriter HRESULT SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2); HRESULT SetRadialGradient(const double& dX1, const double& dY1, const double& dR1, const double& dX2, const double& dY2, const double& dR2); HRESULT DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- // Дополнительные функции для дозаписи Pdf //---------------------------------------------------------------------------------------- @@ -218,9 +214,8 @@ class CPdfWriter void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); - - PdfWriter::CDocument* m_pDocument; - PdfWriter::CPage* m_pPage; + PdfWriter::CDocument* GetDocument(); + PdfWriter::CPage* GetPage(); private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha); @@ -245,31 +240,26 @@ class CPdfWriter unsigned char* EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs = NULL); unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); - void DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); private: NSFonts::IFontManager* m_pFontManager; IRenderer* m_pRenderer; - + PdfWriter::CDocument* m_pDocument; + PdfWriter::CPage* m_pPage; PdfWriter::CFontCidTrueType* m_pFont; PdfWriter::CShading* m_pShading; PdfWriter::CExtGrState* m_pShadingExtGrState; - bool m_bNeedUpdateTextFont; - bool m_bNeedUpdateTextColor; - bool m_bNeedUpdateTextAlpha; - bool m_bNeedUpdateTextCharSpace; - bool m_bNeedUpdateTextSize; - CCommandManager m_oCommandManager; - CPenState m_oPen; CBrushState m_oBrush; CFontState m_oFont; CPath m_oPath; CTransform m_oTransform; + bool m_bNeedUpdateTextFont; double m_dPageHeight; double m_dPageWidth; LONG m_lClipDepth; diff --git a/PdfFile/SrcWriter/States.cpp b/PdfFile/SrcWriter/States.cpp index 683d0153887..98d2f220934 100644 --- a/PdfFile/SrcWriter/States.cpp +++ b/PdfFile/SrcWriter/States.cpp @@ -68,7 +68,7 @@ void CCommandManager::Flush() size_t nCommandsCount = m_vCommands.size(); if (nCommandsCount > 0) { - PdfWriter::CPage* pPage = m_pRenderer->m_pPage; + PdfWriter::CPage* pPage = m_pRenderer->GetPage(); pPage->GrSave(); pPage->SetTransform(m_oTransform.m11, m_oTransform.m12, m_oTransform.m21, m_oTransform.m22, m_oTransform.dx, m_oTransform.dy); From bb84209b055e85879a0872224c3c1ff613f7432e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 21 Mar 2024 12:02:59 +0300 Subject: [PATCH 459/794] Fix cropbox offset for AP annots --- PdfFile/SrcReader/PdfAnnot.cpp | 13 ++++++++----- PdfFile/SrcReader/PdfAnnot.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9b1ebff9f08..249110293ee 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2529,6 +2529,9 @@ void CAnnotAP::Clear() void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); + PDFRectangle* pCropBox = pPage->getCropBox(); + m_dCropX = pCropBox->x1; + m_dCropY = pCropBox->y1; double dWidth = pdfDoc->getPageCropWidth(nPageIndex + 1); double dHeight = pdfDoc->getPageCropHeight(nPageIndex + 1); @@ -2579,8 +2582,8 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLi m_gfx = new Gfx(pdfDoc, m_pRendererOut, nPageIndex + 1, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, crop ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); // Координаты внешнего вида - m_nRx1 = (int)round(m_dx1 * m_dWScale) - 1; - m_nRy1 = nRasterH - (int)round(m_dy2 * m_dHScale) - 1; + m_nRx1 = (int)round((m_dx1 - m_dCropX) * m_dWScale) - 1; + m_nRy1 = nRasterH - (int)round((m_dy2 - m_dCropY) * m_dHScale) - 1; } void CAnnotAP::Init(AcroFormField* pField) { @@ -2644,7 +2647,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo pView->sASName = oObj.dictGetKey(k); if ((oType == acroFormFieldRadioButton || oType == acroFormFieldCheckbox) && pView->sASName != "Off") pView->sASName = "Yes"; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); + m_pRenderer->SetCoordTransformOffset(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], pView->sASName.c_str()); WriteAppearance(nBackgroundColor, pView); pView->nBlendMode = GetBlendMode(); @@ -2655,7 +2658,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo { CAnnotAPView* pView = new CAnnotAPView(); pView->sAPName = arrAPName[j]; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); + m_pRenderer->SetCoordTransformOffset(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], NULL); WriteAppearance(nBackgroundColor, pView); pView->nBlendMode = GetBlendMode(); @@ -2686,7 +2689,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo pView = new CAnnotAPView(); pView->sAPName = arrAPName[j]; - m_pRenderer->SetCoordTransformOffset(-m_dx1 * m_dWScale + 1 + m_dWTale / 2, m_dy2 * m_dHScale - nRasterH + 1 + m_dHTale / 2); + m_pRenderer->SetCoordTransformOffset(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); Ref ref = oAnnotRef->getRef(); Annot* annot = new Annot(pdfDoc, oAnnot.getDict(), &ref, arrAPName[j]); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 4d053291696..683afc759ef 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -143,6 +143,7 @@ class CAnnotAP final unsigned int m_unRefNum; // Номер ссылки на объект double m_dx1, m_dy1, m_dx2, m_dy2; + double m_dCropX, m_dCropY; double m_dWScale, m_dHScale; double m_dWTale; double m_dHTale; From 03244e9e8350a6a74f71afd8eb8b635f008dc6c4 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 21 Mar 2024 14:44:44 +0500 Subject: [PATCH 460/794] For bug #65612 Fix Split/Cover transition parameter conversion --- OdfFile/Reader/Format/anim_elements.cpp | 18 ++++---- OdfFile/Writer/Converter/PptxConverter.cpp | 48 ++++++++++++++++------ OdfFile/Writer/Format/odp_page_state.cpp | 6 +-- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/OdfFile/Reader/Format/anim_elements.cpp b/OdfFile/Reader/Format/anim_elements.cpp index 5aec245829e..b83df357d4d 100644 --- a/OdfFile/Reader/Format/anim_elements.cpp +++ b/OdfFile/Reader/Format/anim_elements.cpp @@ -1185,8 +1185,6 @@ void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion else if (filter_attlist_.smil_subtype_.get() == L"combHorizontal") { type = L"comb"; dir = L"horz"; } break; case smil_transition_type::slideWipe: - type = L"pull"; - break; case smil_transition_type::boxWipe: type = L"cover"; break; @@ -1237,20 +1235,20 @@ void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion else dir = L"d"; } - if (filter_attlist_.smil_subtype_.get() == L"fromTop") dir = L"d"; + if (filter_attlist_.smil_subtype_.get() == L"fromTop") dir = L"d"; else if (filter_attlist_.smil_subtype_.get() == L"fromLeft") dir = L"r"; else if (filter_attlist_.smil_subtype_.get() == L"fromRight") dir = L"l"; - else if (filter_attlist_.smil_subtype_.get() == L"fromBottom") dir = L"u"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottom") dir = L"u"; else if (filter_attlist_.smil_subtype_.get() == L"topRight") dir = L"ld"; - else if (filter_attlist_.smil_subtype_.get() == L"bottomLeft") dir = L"lu"; - else if (filter_attlist_.smil_subtype_.get() == L"bottomRight") dir = L"ru"; - else if (filter_attlist_.smil_subtype_.get() == L"topLeft") dir = L"rd"; + else if (filter_attlist_.smil_subtype_.get() == L"bottomLeft") dir = L"lu"; + else if (filter_attlist_.smil_subtype_.get() == L"bottomRight") dir = L"ru"; + else if (filter_attlist_.smil_subtype_.get() == L"topLeft") dir = L"rd"; - else if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") dir = L"rd"; - else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft")dir = L"ru"; + else if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") dir = L"rd"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft") dir = L"ru"; else if (filter_attlist_.smil_subtype_.get() == L"fromTopRight") dir = L"ld"; - else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight")dir = L"lu"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") dir = L"lu"; } diff --git a/OdfFile/Writer/Converter/PptxConverter.cpp b/OdfFile/Writer/Converter/PptxConverter.cpp index 010c602f8bd..343efc38142 100644 --- a/OdfFile/Writer/Converter/PptxConverter.cpp +++ b/OdfFile/Writer/Converter/PptxConverter.cpp @@ -1830,22 +1830,35 @@ void PptxConverter::convert(PPTX::Logic::EightDirectionTransition *oox_transitio if (!oox_transition) return; if (oox_transition->name == L"cover") - odp_context->current_slide().set_transition_type(1); + odp_context->current_slide().set_transition_type(35); if (oox_transition->name == L"pull") odp_context->current_slide().set_transition_type(35); - if (oox_transition->dir.IsInit()) - { - if (oox_transition->dir->get() == L"d") odp_context->current_slide().set_transition_subtype(L"fromTop"); - else if (oox_transition->dir->get() == L"l") odp_context->current_slide().set_transition_subtype(L"fromRight"); - else if (oox_transition->dir->get() == L"r") odp_context->current_slide().set_transition_subtype(L"fromLeft"); - else if (oox_transition->dir->get() == L"u") odp_context->current_slide().set_transition_subtype(L"fromBottom"); + const std::wstring default_subtype = L"l"; + std::wstring dir = oox_transition->dir.get_value_or(default_subtype); + if (dir.empty()) + dir = default_subtype; + + if (dir == L"d") odp_context->current_slide().set_transition_subtype(L"fromTop"); + else if (dir == L"l") odp_context->current_slide().set_transition_subtype(L"fromRight"); + else if (dir == L"r") odp_context->current_slide().set_transition_subtype(L"fromLeft"); + else if (dir == L"u") odp_context->current_slide().set_transition_subtype(L"fromBottom"); - else if (oox_transition->dir->get() == L"rd") odp_context->current_slide().set_transition_subtype(L"horizontalLeft"); - else if (oox_transition->dir->get() == L"lu") odp_context->current_slide().set_transition_subtype(L"horizontalRight"); - else if (oox_transition->dir->get() == L"ld") odp_context->current_slide().set_transition_subtype(L"verticalRight"); - else if (oox_transition->dir->get() == L"ru") odp_context->current_slide().set_transition_subtype(L"verticalLeft"); + if(oox_transition->name == L"cover") + { + if (dir == L"rd") odp_context->current_slide().set_transition_subtype(L"fromTopLeft"); + else if (dir == L"lu") odp_context->current_slide().set_transition_subtype(L"fromBottomRight"); + else if (dir == L"ld") odp_context->current_slide().set_transition_subtype(L"fromTopRight"); + else if (dir == L"ru") odp_context->current_slide().set_transition_subtype(L"fromBottomLeft"); } + else + { + if (dir == L"rd") odp_context->current_slide().set_transition_subtype(L"horizontalLeft"); + else if (dir == L"lu") odp_context->current_slide().set_transition_subtype(L"horizontalRight"); + else if (dir == L"ld") odp_context->current_slide().set_transition_subtype(L"verticalRight"); + else if (dir == L"ru") odp_context->current_slide().set_transition_subtype(L"verticalLeft"); + } + } void PptxConverter::convert(PPTX::Logic::OptionalBlackTransition *oox_transition) { @@ -1905,8 +1918,19 @@ void PptxConverter::convert(PPTX::Logic::SplitTransition *oox_transition) { if (!oox_transition) return; //name == split + + const std::wstring& orient = oox_transition->orient.get_value_or(L"horz"); + const std::wstring& dir = oox_transition->dir.get_value_or(L"out"); + odp_context->current_slide().set_transition_type(3); - odp_context->current_slide().set_transition_subtype(L"vertical"); + + if(orient == L"horz" || orient == L"") + odp_context->current_slide().set_transition_subtype(L"horizontal"); + else if (orient == L"vert") + odp_context->current_slide().set_transition_subtype(L"vertical"); + + if (dir == L"in") + odp_context->current_slide().set_transition_direction(L"reverse"); } void PptxConverter::convert(PPTX::Logic::ZoomTransition *oox_transition) { diff --git a/OdfFile/Writer/Format/odp_page_state.cpp b/OdfFile/Writer/Format/odp_page_state.cpp index 50b52ecda16..91adaf20ce4 100644 --- a/OdfFile/Writer/Format/odp_page_state.cpp +++ b/OdfFile/Writer/Format/odp_page_state.cpp @@ -627,19 +627,19 @@ void odp_page_state::set_transition_speed(int val) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"fast"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(2000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(250); } if (val == 1) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"medium"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(3000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(500); } if (val == 2) { if (page_properties_) page_properties_->content_.presentation_transition_speed_ = L"slow"; - trans->common_attlist_.smil_dur_ = odf_types::clockvalue(4000); + trans->common_attlist_.smil_dur_ = odf_types::clockvalue(1000); } } } From aad7f089e4ea3278af15901141c7e5acf42f26fc Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 21 Mar 2024 20:31:04 +0600 Subject: [PATCH 461/794] Fix pivot tables conversion --- .../Pivot/PivotCacheDefinitionExt.cpp | 18 ++ OOXML/XlsxFormat/Pivot/Pivots.cpp | 215 ++++++++++++------ 2 files changed, 169 insertions(+), 64 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp index 22d57d25a45..4b13e626f49 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp @@ -59,9 +59,27 @@ XLS::BaseObjectPtr CPivotCacheDefinitionExt::toBin() auto ptr(new XLSB::PCD14); XLS::BaseObjectPtr objectPtr(ptr); auto ptr1(new XLSB::BeginPCD14); + if(m_oSlicerData.IsInit()) + ptr1->fSlicerData = m_oSlicerData.get(); + else + ptr1->fSlicerData = false; + if(m_oSrvSupportAddCalcMems.IsInit()) + ptr1->fSrvSupportAddCalcMems = m_oSrvSupportAddCalcMems.get(); + else + ptr1->fSrvSupportAddCalcMems = false; + if(m_oSrvSupportSubQueryCalcMem.IsInit()) + ptr1->fSrvSupportSubQueryCalcMem = m_oSrvSupportSubQueryCalcMem.get(); + else + ptr1->fSrvSupportSubQueryCalcMem = false; + if(m_oSrvSupportSubQueryNonVisual.IsInit()) + ptr1->fSrvSupportSubQueryNonVisual = m_oSrvSupportSubQueryNonVisual.get(); + else + ptr1->fSrvSupportSubQueryNonVisual = false; ptr->m_BrtBeginPCD14 = XLS::BaseObjectPtr{ptr1}; if(m_oPivotCacheId.IsInit()) ptr1->icacheId = m_oPivotCacheId.get(); + else + ptr1->icacheId = 0; return objectPtr; } void CPivotCacheDefinitionExt::fromBin(XLS::BaseObjectPtr& obj) diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 684274ac5bd..b9a3d456c75 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -400,25 +400,25 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_BrtBeginSXView = writeAttributes(); if(m_oLocation.IsInit()) ptr->m_SXLOCATION = m_oLocation->toBin(); - if(m_oPivotFields.IsInit()) - ptr->m_SXVDS = m_oPivotFields->toBin(); - if(m_oRowFields.IsInit()) + if(m_oPivotFields.IsInit()) + ptr->m_SXVDS = m_oPivotFields->toBin(); + if(m_oRowFields.IsInit()) ptr->m_ISXVDRWS = m_oRowFields->toBinRows(); - if(m_oColFields.IsInit()) - ptr->m_ISXVDCOLS = m_oColFields->toBinCols(); + if(m_oColFields.IsInit()) + ptr->m_ISXVDCOLS = m_oColFields->toBinCols(); if(m_oRowItems.IsInit()) ptr->m_SXLIRWS = m_oRowItems->toBinRows(); if(m_oColItems.IsInit()) ptr->m_SXLICOLS = m_oColItems->toBinCols(); - if(m_oDataFields.IsInit()) - ptr->m_SXDIS = m_oDataFields->toBin(); - if(m_oFormats.IsInit()) - ptr->m_SXFORMATS = m_oFormats->toBin(); - if(m_oPivotTableStyleInfo.IsInit()) - ptr->m_BrtTableStyleClient = m_oPivotTableStyleInfo->toBin(); - if(m_oPageFields.IsInit()) - ptr->m_SXPIS = m_oPageFields->toBin(); + if(m_oDataFields.IsInit()) + ptr->m_SXDIS = m_oDataFields->toBin(); + if(m_oFormats.IsInit()) + ptr->m_SXFORMATS = m_oFormats->toBin(); + if(m_oPivotTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oPivotTableStyleInfo->toBin(); + if(m_oPageFields.IsInit()) + ptr->m_SXPIS = m_oPageFields->toBin(); /*auto frt(new XLSB::FRTSXVIEW); auto sxview14(new XLSB::SXVIEW14); @@ -1143,18 +1143,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr CColumnRowItem::toBin() { auto ptr(new XLSB::SXLI); - auto size = 0; - - for(auto i:m_arrItems) - { - if(i->m_oV.IsInit()) - size++; - - } XLS::BaseObjectPtr objectPtr(ptr); auto ptr1(new XLSB::BeginSXLI); - ptr1->cisxvis = size; + ptr1->cisxvis = m_arrItems.size(); ptr->m_BrtBeginSXLI = XLS::BaseObjectPtr{ptr1}; if(m_oI.IsInit()) ptr1->iData = m_oI->GetValue(); @@ -1199,18 +1191,17 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } else { - ptr1->itmtype = XLSB::PivotItemType::PITDATA; + ptr1->itmtype = XLSB::PivotItemType::PITDEFAULT; } if(ptr1->cisxvis > 0) { - auto ptr2(new XLSB::ISXVIS(size)); - ptr2->_cisxvis = size; + auto ptr2(new XLSB::ISXVIS(ptr1->cisxvis)); + ptr2->_cisxvis = ptr1->cisxvis; ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; - auto ptr3(new XLSB::BeginISXVIs(size)); - ptr3->_cisxvis = size; + auto ptr3(new XLSB::BeginISXVIs(ptr1->cisxvis)); ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; for(auto i:m_arrItems) @@ -1423,10 +1414,16 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oBaseField.IsInit()) ptr->isxvd = m_oBaseField.get(); + else + ptr->isxvd = 0; if(m_oBaseItem.IsInit()) ptr->isxvi = m_oBaseItem->GetValue(); + else + ptr->isxvi = 0; if(m_oFld.IsInit()) ptr->isxvdData = m_oFld->GetValue(); + else + ptr->isxvdData = false; if(m_oNumFmtId.IsInit()) ptr->ifmt.ifmt = m_oNumFmtId->GetValue(); else @@ -1859,16 +1856,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oChild.IsInit()) ptr->fHasChildrenEst = m_oChild.get(); + else + ptr->fHasChildrenEst = false; if(m_oExpanded.IsInit()) ptr->fDrilledMember = m_oExpanded.get(); + else + ptr->fDrilledMember = false; if(m_oDrillAcross.IsInit()) ptr->fCollapsedMember = m_oDrillAcross.get(); + else + ptr->fCollapsedMember = false; if(m_oCalculated.IsInit()) ptr->fFormula = m_oCalculated.get(); + else + ptr->fFormula = false; if(m_oHidden.IsInit()) ptr->fHidden = m_oHidden.get(); + else + ptr->fHidden = false; if(m_oMissing.IsInit()) ptr->fMissing = m_oMissing.get(); + else + ptr->fMissing = false; if(m_oUserCaption.IsInit()) { ptr->displayName = m_oUserCaption.get(); @@ -1880,10 +1889,16 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } if(m_oCharacter.IsInit()) ptr->fOlapFilterSelected = m_oCharacter.get(); + else + ptr->fOlapFilterSelected = false; if(m_oHideDetails.IsInit()) ptr->fHideDetail = m_oHideDetails.get(); + else + ptr->fHideDetail = false; if(m_oItemIndex.IsInit()) ptr->iCache = m_oItemIndex->GetValue(); + else + ptr->iCache = 0; if(m_oItemType.IsInit()) { if(m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeData) @@ -1917,6 +1932,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) ptr->itmtype = XLSB::PivotItemType::PITBLANK; } + else + ptr->itmtype = XLSB::PivotItemType::PITDATA; return objectPtr; } void CFieldItem::fromBin(XLS::BaseObjectPtr& obj) @@ -2244,12 +2261,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) ptr->sxaxis.bData = true; } - else - ptr->sxaxis.bData = true; if(m_oCompact.IsInit()) ptr->fCompact = m_oCompact.get(); else - ptr->fCompact = false; + ptr->fCompact = true; if(m_oCountASubtotal.IsInit()) ptr->fCounta = m_oCountASubtotal.get(); @@ -2261,9 +2276,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else ptr->fCount = false; if(m_oDataField.IsInit()) - ptr->fDrilledLevel = m_oDataField.get(); - else - ptr->fDrilledLevel = false; + ptr->sxaxis.bData = m_oDataField.get(); + if(m_oDataSourceSort.IsInit()) ptr->fTensorSort = m_oDataSourceSort.get(); else @@ -2279,24 +2293,24 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oDragOff.IsInit()) ptr->fDragToHide = m_oDragOff.get(); else - ptr->fDragToHide = false; + ptr->fDragToHide = true; if (m_oDragToCol.IsInit()) ptr->fDragToColumn = m_oDragToCol.get(); else - ptr->fDragToColumn = false; + ptr->fDragToColumn = true; if (m_oDragToData.IsInit()) ptr->fDragToData = m_oDragToData.get(); else - ptr->fDragToData = false; + ptr->fDragToData = true; if (m_oDragToPage.IsInit()) ptr->fDragToPage = m_oDragToPage.get(); else - ptr->fDragToPage = false; + ptr->fDragToPage = true; if (m_oDragToRow.IsInit()) ptr->fDragToRow = m_oDragToRow.get(); else - ptr->fDragToRow = false; + ptr->fDragToRow = true; if (m_oHiddenLevel.IsInit()) ptr->fHiddenLvl = m_oHiddenLevel.get(); else @@ -2308,7 +2322,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oIncludeNewItemsInFilter.IsInit()) ptr->fFilterInclusive = m_oIncludeNewItemsInFilter.get(); else - ptr->fFilterInclusive = false; + ptr->fFilterInclusive = true; if (m_oInsertBlankRow.IsInit()) ptr->fInsertBlankRow = m_oInsertBlankRow.get(); else @@ -2321,7 +2335,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oItemPageCount.IsInit()) ptr->citmAutoShow = m_oItemPageCount->GetValue(); else - ptr->citmAutoShow = 0; + ptr->citmAutoShow = 10; if(m_oMaxSubtotal.IsInit()) ptr->fMax = m_oMaxSubtotal.get(); @@ -2331,7 +2345,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oMeasureFilter.IsInit()) ptr->fHasAdvFilter = m_oMeasureFilter.get(); else - ptr->fHasAdvFilter = false; + ptr->fHasAdvFilter = false; if(m_oMinSubtotal.IsInit()) ptr->fMin = m_oMinSubtotal.get(); @@ -2362,7 +2376,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oOutline.IsInit()) ptr->fOutline = m_oOutline.get(); else - ptr->fOutline = false; + ptr->fOutline = true; if (m_oProductSubtotal.IsInit()) ptr->fProduct = m_oProductSubtotal.get(); @@ -2372,7 +2386,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oRankBy.IsInit()) ptr->isxdiAutoShow = m_oRankBy->GetValue(); else - ptr->isxdiAutoShow = 0; + ptr->isxdiAutoShow = -1; if (m_oServerField.IsInit()) ptr->fServerBased = m_oServerField.get(); @@ -2403,15 +2417,19 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->fMemPropDisplayInTip = m_oShowPropTip.get(); else ptr->fMemPropDisplayInTip = false; + if(m_oNonAutoSortDefault.IsInit()) + ptr->fAutoSort = !m_oNonAutoSortDefault.get(); + else + ptr->fAutoSort = false; if(m_oSortType.IsInit()) { - if(m_oSortType->GetValue() != SimpleTypes::Spreadsheet::EFieldSortType::sortManual) - ptr->fAutoSort = true; if(m_oSortType->GetValue() == SimpleTypes::Spreadsheet::EFieldSortType::sortAscending) ptr->fAscendSort = true; else ptr->fAscendSort = false; } + else + ptr->fAscendSort = false; if (m_oStdDevPSubtotal.IsInit()) ptr->fStdevp = m_oStdDevPSubtotal.get(); @@ -2431,7 +2449,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oSubtotalTop.IsInit()) ptr->fSubtotalAtTop = !m_oSubtotalTop.get(); else - ptr->fSubtotalAtTop = false; + ptr->fSubtotalAtTop = true; if (m_oSumSubtotal.IsInit()) ptr->fSum = m_oSumSubtotal.get(); @@ -2441,7 +2459,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oTopAutoShow.IsInit()) ptr->fTopAutoShow = !m_oTopAutoShow.get(); else - ptr->fTopAutoShow = false; + ptr->fTopAutoShow = true; if (m_oUniqueMemberProperty.IsInit()) ptr->irstMemberPropertyCaption = m_oUniqueMemberProperty.get(); @@ -2456,7 +2474,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oVarSubtotal.IsInit()) ptr->fVar = m_oVarSubtotal.get(); else - ptr->fVar = false; + ptr->fVar = false; + if(!ptr->fVar && !ptr->fVarp && !ptr->fStdevp && !ptr->fStdevp + && !ptr->fCount && !ptr->fMin && !ptr->fMax && !ptr->fAverage + && !ptr->fCounta && !ptr->fSum ) + ptr->fDefault = true; + else + ptr->fDefault = false; return objectPtr; } @@ -2817,54 +2841,83 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr); if (m_oAvgSubtotal.IsInit()) ptr->prFilter.itmtypeAVERAGE = m_oAvgSubtotal.get(); - - if (m_oByPosition.IsInit()) - ptr->prFilter.itmtypeAVERAGE = m_oByPosition.get(); + else + ptr->prFilter.itmtypeAVERAGE = false; if (m_oCountASubtotal.IsInit()) ptr->prFilter.itmtypeCOUNTA = m_oCountASubtotal.get(); + else + ptr->prFilter.itmtypeCOUNTA = false; if (m_oCountSubtotal.IsInit()) ptr->prFilter.itmtypeCOUNT = m_oCountSubtotal.get(); + else + ptr->prFilter.itmtypeCOUNT = false; if (m_oDefaultSubtotal.IsInit()) ptr->prFilter.itmtypeDEFAULT = m_oDefaultSubtotal.get(); + else + ptr->prFilter.itmtypeDEFAULT = false; if (m_oMaxSubtotal.IsInit()) ptr->prFilter.itmtypeMAX = m_oMaxSubtotal.get(); + else + ptr->prFilter.itmtypeMAX = false; if (m_oMinSubtotal.IsInit()) ptr->prFilter.itmtypeMIN = m_oMinSubtotal.get(); + else + ptr->prFilter.itmtypeMIN = false; if (m_oProductSubtotal.IsInit()) ptr->prFilter.itmtypePRODUCT = m_oProductSubtotal.get(); + else + ptr->prFilter.itmtypePRODUCT = false; if (m_oRelative.IsInit()) ptr->prFilter.itmtypeAVERAGE = m_oRelative.get(); + else + ptr->prFilter.itmtypeAVERAGE = false; if (m_oSelected.IsInit()) ptr->prFilter.fSelected = m_oSelected.get(); + else + ptr->prFilter.fSelected = false; if (m_oStdDevPSubtotal.IsInit()) ptr->prFilter.itmtypeSTDEVP = m_oStdDevPSubtotal.get(); + else + ptr->prFilter.itmtypeSTDEVP = false; if (m_oStdDevSubtotal.IsInit()) ptr->prFilter.itmtypeSTDEV = m_oStdDevSubtotal.get(); + else + ptr->prFilter.itmtypeSTDEV = false; if (m_oSumSubtotal.IsInit()) ptr->prFilter.itmtypeSUM = m_oSumSubtotal.get(); + else + ptr->prFilter.itmtypeSUM = false; if (m_oVarPSubtotal.IsInit()) ptr->prFilter.itmtypeVARP = m_oVarPSubtotal.get(); + else + ptr->prFilter.itmtypeVARP = false; if (m_oVarSubtotal.IsInit()) ptr->prFilter.itmtypeVAR = m_oVarSubtotal.get(); + else + ptr->prFilter.itmtypeVAR = false; if (m_oField.IsInit()) ptr->prFilter.isxvd = m_oField->GetValue(); + else + ptr->prFilter.isxvd = 0; if (m_oCount.IsInit()) ptr->prFilter.cItems = m_oCount->GetValue(); + else + ptr->prFilter.cItems = 0; return objectPtr; } void CReference::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -3017,14 +3070,18 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptr(new XLSB::SXFORMAT); XLS::BaseObjectPtr objectPtr(ptr); - if(m_oDxfId.IsInit()) - { - auto ptr1(new XLSB::BeginSXFormat); - ptr->m_BrtBeginSXFormat = XLS::BaseObjectPtr{ptr1}; - ptr1->dxfid = m_oDxfId->GetValue(); - if(m_oAction.IsInit()) - ptr1->rlType = m_oAction->GetValue(); - } + + auto ptr1(new XLSB::BeginSXFormat); + ptr->m_BrtBeginSXFormat = XLS::BaseObjectPtr{ptr1}; + if(m_oDxfId.IsInit()) + ptr1->dxfid = m_oDxfId->GetValue(); + else + ptr1->dxfid = 0; + if(m_oAction.IsInit()) + ptr1->rlType = m_oAction->GetValue(); + else + ptr1->rlType = 0; + if(m_oPivotArea.IsInit()) ptr->m_PIVOTRULE = m_oPivotArea->toBin(); return objectPtr; @@ -3156,6 +3213,10 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptr(new XLSB::BeginPRule); XLS::BaseObjectPtr objectPtr(ptr); + ptr->pruleheaderdata.sxaxis.bCol = false; + ptr->pruleheaderdata.sxaxis.bPage = false; + ptr->pruleheaderdata.sxaxis.bRw = false; + ptr->pruleheaderdata.sxaxis.bData = false; if(m_oAxis.IsInit()) { if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) @@ -3169,24 +3230,43 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } if(m_oCacheIndex.IsInit()) ptr->pruleheaderdata.fCacheBased = m_oCacheIndex.get(); + else + ptr->pruleheaderdata.fCacheBased = false; if(m_oCollapsedLevelsAreSubtotals.IsInit()) ptr->pruleheaderdata.fFuzzy = m_oCollapsedLevelsAreSubtotals.get(); + else + ptr->pruleheaderdata.fFuzzy = false; if(m_oDataOnly.IsInit()) ptr->pruleheaderdata.fDataOnly = m_oDataOnly.get(); + else + ptr->pruleheaderdata.fDataOnly = true; if(m_oField.IsInit()) ptr->pruleheaderdata.isxvd = m_oField.get(); + else + ptr->pruleheaderdata.isxvd = -1; if(m_oFieldPosition.IsInit()) ptr->pruleheaderdata.iDim = m_oFieldPosition->GetValue(); + else + ptr->pruleheaderdata.iDim = 0; if(m_oGrandCol.IsInit()) ptr->pruleheaderdata.fGrandCol = m_oGrandCol.get(); + else + ptr->pruleheaderdata.fGrandCol = false; if(m_oGrandRow.IsInit()) ptr->pruleheaderdata.fGrandRw = m_oGrandRow.get(); + else + ptr->pruleheaderdata.fGrandRw = false; if(m_oLabelOnly.IsInit()) ptr->pruleheaderdata.fLabelOnly = m_oLabelOnly.get(); + else + ptr->pruleheaderdata.fLabelOnly = false; if(m_oOffsetRef.IsInit()) ptr->pruleheaderdata.rfxLoc = m_oOffsetRef.get(); if(m_oOutline.IsInit()) ptr->pruleheaderdata.fLineMode = m_oOutline.get(); + else + ptr->pruleheaderdata.fLineMode = false; + ptr->pruleheaderdata.fPart = false; if(m_oType.IsInit()) { if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaNone) @@ -3204,6 +3284,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaTopEnd) ptr->pruleheaderdata.isxrtype = 0x06; } + else + ptr->pruleheaderdata.isxrtype = 0x01; return objectPtr; } void CPivotArea::fromBin(XLS::BaseObjectPtr& obj) @@ -3601,8 +3683,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr(new XLSB::PivotCacheDefStream); XLS::BaseObjectPtr objectPtr(ptr); ptr->m_BrtBeginPivotCacheDef = writeAttributes(); - if(m_oCacheFields.IsInit()) - ptr->m_PCDFIELDS = m_oCacheFields->toBin(); + if(m_oCacheFields.IsInit()) + ptr->m_PCDFIELDS = m_oCacheFields->toBin(); if(m_oCacheSource.IsInit()) ptr->m_PCDSOURCE = m_oCacheSource->toBin(); if(m_oExtLst.IsInit()) @@ -3933,7 +4015,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr); ptr->m_BrtBeginPCDField = writeAttributes(); - if(m_oSharedItems.IsInit()) + if(m_oSharedItems.IsInit() && !m_oSharedItems->m_arrItems.empty()) ptr->m_PCDFATBL = m_oSharedItems->toBin(); if(m_oFieldGroup.IsInit()) ptr->m_PCDFGROUP = m_oFieldGroup->toBin(); @@ -4006,7 +4088,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oNumFmtId.IsInit()) ptr->ifmt = m_oNumFmtId->GetValue(); else - ptr->ifmt = 0xFFFFFFFF; + ptr->ifmt = 0; ptr->cbRgisxtmp = 0; @@ -5363,7 +5445,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->xnum.data.value = m_oValue.get(); - if(m_oBold.IsInit()) + if(m_oBold.IsInit() || m_oItalic.IsInit() || m_oStrike.IsInit() + || m_oUnderline.IsInit() || m_oFormatIndex.IsInit() || m_oForeColor.IsInit() ||m_oBackColor.IsInit()) + { + ptr->sxvcellextra.reset(new XLSB::PCDISrvFmt); + if(m_oBold.IsInit()) ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); if(m_oItalic.IsInit()) ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); @@ -5377,6 +5463,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); if(m_oForeColor.IsInit()) ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); + } return objectPtr; } } From c223714b52f1396fc7ce2f69213cc614d37e12a9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 22 Mar 2024 13:54:48 +0300 Subject: [PATCH 462/794] Fix bug 67066 --- .../graphics/pro/js/wasm/src/drawingfile.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index ccb252acb2c..c0d30a3c739 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -74,9 +74,15 @@ WASM_EXPORT int GetType(BYTE* data, LONG size) // 0 - PDF // 1 - DJVU // 2 - XPS - char* pFirst = strstr((char*)data, "%PDF-" ); - if (pFirst) - return 0; + LONG nHeaderSearchSize = 1024; + LONG nSize = size < nHeaderSearchSize ? size : nHeaderSearchSize; + char* pData = (char*)data; + for (int i = 0; i < nSize - 5; ++i) + { + int nPDF = strncmp(&pData[i], "%PDF-", 5); + if (!nPDF) + return 0; + } if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] && 0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7])) return 1; From 4a1f483315175eafb25c92a7852db000959eda65 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 24 Mar 2024 22:47:03 +0300 Subject: [PATCH 463/794] Fix alignment + fix logic --- DocxRenderer/src/logic/Page.cpp | 107 +++++++++++-------- DocxRenderer/src/logic/elements/ContText.cpp | 2 +- DocxRenderer/src/logic/elements/ContText.h | 2 + DocxRenderer/src/logic/elements/TextLine.cpp | 3 + DocxRenderer/src/resources/Constants.h | 7 +- 5 files changed, 70 insertions(+), 51 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 277ab9a12c5..4ee9bfa5f52 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1229,7 +1229,7 @@ namespace NSDocxRenderer paragraph->m_dBaselinePos = paragraph->m_arLines.back()->m_dBaselinePos; paragraph->m_dTop = paragraph->m_arLines.front()->m_dTop; - paragraph->m_dRight = max_right; + paragraph->m_dRight = max_right + c_dERROR_OF_PARAGRAPH_BORDERS_MM; paragraph->m_dLeft = min_left; paragraph->m_dWidth = paragraph->m_dRight - paragraph->m_dLeft; @@ -1335,6 +1335,9 @@ namespace NSDocxRenderer // позиции относительно других линий std::vector ar_positions(m_arTextLines.size()); + // требуется ли отступ + std::vector ar_indents(m_arTextLines.size(), false); + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф std::vector ar_delims(m_arTextLines.size(), false); @@ -1353,8 +1356,6 @@ namespace NSDocxRenderer auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth / 2); auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[index + 1]->m_dWidth / 2); - ///////////// - if (fabs(center_curr - center_next) < c_dCENTER_POSITION_ERROR_MM) ar_positions[index].center = true; if (fabs(left_curr - left_next) < c_dERROR_OF_PARAGRAPH_BORDERS_MM) @@ -1419,10 +1420,9 @@ namespace NSDocxRenderer // alignment check bool is_first_line = false; - std::shared_ptr gap_check_line = m_arTextLines[0]; for (size_t index = 0; index < ar_positions.size() - 1; ++index) { - Position position_bot = ar_positions[index]; + Position& position = ar_positions[index]; auto& line_top = m_arTextLines[index]; auto& line_bot = m_arTextLines[index + 1]; @@ -1439,60 +1439,73 @@ namespace NSDocxRenderer if (index < ar_positions.size() - 2) { if (!ar_delims[index] && !ar_delims[index + 1] && ar_positions[index + 1].left) - position_bot.left = true; - else - position_bot.left = false; + ar_indents[index] = true; + else if (!ar_delims[index] && ar_delims[index + 1]) + ar_indents[index] = true; } else - position_bot.left = true; + ar_indents[index] = true; } - bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); + bool is_unknown = !((position.left || ar_indents[index]) || position.right || position.center); if (is_unknown) ar_delims[index] = true; + } + + // gap check + // + // bla-bla-bla + // text bla-bla-bla-bla + // + // bla-bla-bla text + // bla-bla-bla-bla + + double curr_max_right = m_arTextLines[0]->m_dRight; + double curr_min_left = m_arTextLines[0]->m_dLeft; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position position = ar_positions[index]; + auto& line_top = m_arTextLines[index]; + auto& line_bot = m_arTextLines[index + 1]; if (ar_delims[index]) - gap_check_line = line_bot; - - // bla-bla-bla - // text bla-bla-bla-bla - // - // bla-bla-bla text - // bla-bla-bla-bla - else if (!ar_delims[index]) { - double gap = 0; - std::shared_ptr cont = nullptr; + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; + continue; + } - if (position_bot.left) - { - gap = line_bot->m_dRight - gap_check_line->m_dRight; - cont = line_bot->m_arConts[0]; + std::shared_ptr cont = line_bot->m_arConts[0]; + double line_with_first_right = line_top->m_dRight + cont->m_dFirstWordWidth; + double line_with_first_left = line_top->m_dLeft - cont->m_dFirstWordWidth; - } - else if (position_bot.right) - { - gap = gap_check_line->m_dLeft - line_bot->m_dLeft; - cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1]; - } - else - continue; + curr_max_right = std::max(curr_max_right, line_bot->m_dRight); + curr_min_left = std::min(curr_min_left, line_bot->m_dLeft); - if (gap < 0) - { - gap_check_line = line_bot; - continue; - } + double diff = 0; - size_t cont_len = cont->m_oText.length(); - size_t space_pos = cont->m_oText.ToStdWString().find_first_of(L' '); - if (space_pos == std::wstring::npos) - space_pos = cont_len; + if (position.right) + diff = line_with_first_left - curr_min_left; + else if (position.left || ar_indents[index]) + diff = curr_max_right - line_with_first_right; + else if (position.center) + continue; - // to save time doing it roughly - double rough_width = cont->m_dWidth / cont_len * space_pos; - if (gap > rough_width * 1.2) - ar_delims[index] = true; + if (diff <= 0) + { +// if (diff > -c_dERROR_GAP) +// { +// auto& last_cont = line_top->m_arConts[line_top->m_arConts.size() - 1]; +// last_cont->m_bIsAddBrEnd = true; +// } +// else + continue; + } + else + { + ar_delims[index] = true; + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; } } @@ -1550,7 +1563,7 @@ namespace NSDocxRenderer pParagraph->m_dLeft = pLine->m_dLeft; pParagraph->m_dTop = pLine->m_dTop; pParagraph->m_dBaselinePos = pLine->m_dBaselinePos; - pParagraph->m_dWidth = pLine->m_dWidth + c_dSHAPE_X_OFFSET; + pParagraph->m_dWidth = pLine->m_dWidth + c_dERROR_OF_PARAGRAPH_BORDERS_MM; pParagraph->m_dHeight = pLine->m_dHeight; pParagraph->m_dRight = pLine->m_dRight; @@ -1587,7 +1600,7 @@ namespace NSDocxRenderer pShape->m_dRight = pParagraph->m_dRight; pShape->m_dBaselinePos = pParagraph->m_dBaselinePos; pShape->m_dHeight = pParagraph->m_dHeight; - pShape->m_dWidth = pParagraph->m_dWidth + c_dSHAPE_X_OFFSET; + pShape->m_dWidth = pParagraph->m_dWidth; pParagraph->m_dLeftBorder = 0; pParagraph->m_dRightBorder = 0; diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 116c23349ea..71eb52a7d8b 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -167,7 +167,7 @@ namespace NSDocxRenderer } // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; + // lCalculatedSpacing -= 1; if (lCalculatedSpacing != 0) { diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 179aa73920b..fb1128e6e5c 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -73,6 +73,8 @@ namespace NSDocxRenderer bool m_bIsAddBrEnd{false}; bool m_bWriteStyleRaw{false}; + double m_dFirstWordWidth{0}; + CContText() = default; CContText(CFontManager* pManager) : m_pManager(pManager) {} CContText(const CContText& rCont); diff --git a/DocxRenderer/src/logic/elements/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 87437aab8f3..b63318a0282 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -62,6 +62,9 @@ namespace NSDocxRenderer bool bIsBigDelta = dDifference > dSpaceDefaultSize; bool bIsVeryBigDelta = dDifference > dSpaceWideSize; + if (bIsBigDelta && pFirst->m_dFirstWordWidth == 0.0) + pFirst->m_dFirstWordWidth = pFirst->m_dWidth; + if (bIsVeryBigDelta) { auto wide_space = std::make_shared(pFirst->m_pManager); diff --git a/DocxRenderer/src/resources/Constants.h b/DocxRenderer/src/resources/Constants.h index 5b1dedbc2c1..c33d0e1b19a 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -20,7 +20,8 @@ const double c_dDegreeToAngle = 60000.0; const double c_dSTANDART_STRING_HEIGHT_MM = 4.2333333333333334; const double c_dTHE_SAME_STRING_Y_PRECISION_MM = 0.01; const double c_dLINE_DISTANCE_ERROR_MM = 0.03; -const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 0.5; +const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 1.0; +const double c_dERROR_GAP = 1.5; const double c_dCENTER_POSITION_ERROR_MM = 1.5; const double c_dTHE_STRING_X_PRECISION_MM = 0.5; const double c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM = 0.1; @@ -29,8 +30,8 @@ const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3; const double c_dMAX_LINE_HEIGHT_MM = 2.5; const double c_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; const double c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH = 0.8; -const double c_dLINE_DISTANCE_MAX_MM = 50.0; -const double c_dSHAPE_X_OFFSET = 2.5; +const double c_dLINE_DISTANCE_MAX_MM = 50.0; +const double c_dSHAPE_X_OFFSET = 1.5; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; From 510a6a621d0d42201768ec5b6b39be66162e7be1 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 25 Mar 2024 18:13:10 +0300 Subject: [PATCH 464/794] fix bug #67054 --- OdfFile/Reader/Format/styles.cpp | 46 +++++++++++++++++-- OdfFile/Reader/Format/styles.h | 2 + OdfFile/Writer/Converter/XlsxConverter.cpp | 51 +++++++++++++++++++++- 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index 75cdd7736f7..cd8ba22335c 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -1433,6 +1433,34 @@ bool style_page_layout_properties::docx_background_serialize(std::wostream & str return true; } +int style_page_layout_properties::DetectPageSize(double w, double h) +{ + int result = 0; + + if (w > 209.99) // A4 and more + { + if ( w < 211 && h > 296 && h < 298) result = 9; // pagesizeA4Paper; + else if (w > 279 && w < 280 && h > 431 && h < 433) result = 3; // pagesizeTabloidPaper; + else if (w > 215 && w < 217 && h > 355 && h < 356) result = 6; // pagesizeLegalPaper; + else if (w > 296 && w < 298 && h > 419 && h < 421) result = 8; // pagesizeA3Paper; + else if (w > 256 && w < 258 && h > 363 && h < 365) result = 12; // pagesizeB4Paper; + else if (w > 215 && w < 217 && h > 329 && h < 331) result = 14; // pagesizeFolioPaper; + else if (w > 228 && w < 230 && h > 323 && h < 325) result = 30; // pagesizeC4Envelope; + else if (w > 215 && w < 217 && h > 278 && h < 280) result = 1; // pagesizeLetterPaper; + } + else + { + if (w > 183 && w < 185 && h > 265 && h < 267) result = 7; // pagesizeExecutivePaper; + else if (w > 147 && w < 149 && h > 209 && h < 211) result = 11; // pagesizeA5Paper; + else if (w > 181 && w < 183 && h > 256 && h < 259) result = 13; // pagesizeB5Paper; + else if (w > 103 && w < 106 && h > 240 && h < 243) result = 20; // pagesize10Envelope; + else if (w > 109 && w < 111 && h > 219 && h < 221) result = 27; // pagesizeDLEnvelope; + else if (w > 161 && w < 164 && h > 228 && h < 230) result = 28; // pagesizeC5Envelope; + else if (w > 97 && w < 100 && h > 189 && h < 192) result = 37; // pagesizeMonarchEnvelope; + } + + return result; +} void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xlsx_conversion_context & Context) { @@ -1525,14 +1553,26 @@ void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xls if (attlist_.fo_page_height_) { h = attlist_.fo_page_height_->get_value_unit(length::mm); - CP_XML_ATTR(L"paperHeight", (int)h); } if (attlist_.fo_page_width_) { w = attlist_.fo_page_width_->get_value_unit(length::mm); - CP_XML_ATTR(L"paperWidth", (int)w); } - CP_XML_ATTR(L"paperUnits", L"mm"); + + if (h > 0 && w > 0) + { + int paperSize = DetectPageSize(w, h); + if (0 < paperSize) + { + CP_XML_ATTR(L"paperSize", paperSize); + } + else + { + CP_XML_ATTR(L"paperHeight", (int)h); + CP_XML_ATTR(L"paperWidth", (int)w); + CP_XML_ATTR(L"paperUnits", L"mm"); + } + } if (attlist_.style_scale_to_) { diff --git a/OdfFile/Reader/Format/styles.h b/OdfFile/Reader/Format/styles.h index 8b78ced093c..61cf51eaaa8 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -967,6 +967,8 @@ class style_page_layout_properties : public office_element_implpage_layout_context()->set_page_size(width, height); From b10e482fbb8d6bb11271bf79a64481d038ce62ba Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 25 Mar 2024 22:21:22 +0600 Subject: [PATCH 465/794] Fix dxf prop conversion --- .../Format/Logic/Biff_structures/XFProp.cpp | 124 ++++++++++++++---- 1 file changed, 98 insertions(+), 26 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp index 4fa7de73c54..2235ea10d96 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp @@ -85,7 +85,6 @@ void XFProp::load(CFRecord& record) case 0x000F: case 0x0010: case 0x0011: // XFPropTextRotation - case 0x0012: // indent case 0x0013: // ReadingOrder case 0x0014: case 0x0015: @@ -112,6 +111,7 @@ void XFProp::load(CFRecord& record) xfPropDataBlob = str; return; } + case 0x0012: // indent case 0x0019: case 0x001A: case 0x001B: @@ -141,6 +141,7 @@ void XFProp::load(CFRecord& record) } void XFProp::save(CFRecord& record) { + LPWideString* strData; if (xfPropDataBlob) { cb = sizeof(cb) + sizeof(xfPropType); @@ -152,7 +153,6 @@ void XFProp::save(CFRecord& record) case 0x000F: case 0x0010: case 0x0011: // XFPropTextRotation - case 0x0012: // indent case 0x0013: // ReadingOrder case 0x0014: case 0x0015: @@ -196,9 +196,12 @@ void XFProp::save(CFRecord& record) case 0x0026: case 0x0018: { - blobSize = sizeof(*xfPropDataBlob.get()); + strData = dynamic_cast(xfPropDataBlob.get()); + if(strData) + blobSize = (strData->getSize() * 2) + 2; } break; + case 0x0012: // indent case 0x0019: case 0x001A: case 0x001B: @@ -218,9 +221,8 @@ void XFProp::save(CFRecord& record) if (xfPropType == 0x0026 || xfPropType == 0x0018) { - LPWideString* string = dynamic_cast(xfPropDataBlob.get()); - if (string) - record << *string; + if (strData) + record << *strData; } else record << *xfPropDataBlob; @@ -345,6 +347,37 @@ static void deserialize_val_prop(XmlUtils::CXmlLiteReader& oReader, const std::w } } +static void deserialize_default_val(XmlUtils::CXmlLiteReader& oReader, const std::wstring & typeName, const _UINT32& value, BiffStructurePtr & val) +{ + BiffStructurePtr biffref; + deserialize_val_prop(oReader, typeName, biffref); + if (typeName == L"BIFF_WORD") + { + auto word = new BIFF_WORD; + if(biffref.get()) + { + *word = *(reinterpret_cast(biffref.get())); + } + else + { + *word = value; + } + val.reset(word); + } + else if(typeName == L"BIFF_BYTE") + { + auto word = new BIFF_BYTE; + if(biffref.get()) + { + *word = *(reinterpret_cast(biffref.get())); + } + else + { + *word = value; + } + val.reset(word); + } +} static void deserialize_prop(XmlUtils::CXmlLiteReader& oReader, const std::wstring & typeName, BiffStructurePtr & val) { auto value = oReader.GetText(); @@ -468,10 +501,46 @@ static XFPropBorder* deserialize_border_prop(XmlUtils::CXmlLiteReader& oReader) border->color.deserialize(oReader); } } + else + { + border->color.xclrType = 0; + border->color.fValidRGBA = false; + border->color.nTintShade = 0; + } return border; } - + static void deserialize_alignment(XmlUtils::CXmlLiteReader& oReader, const unsigned short & typeName, BiffStructurePtr & val) + { + BIFF_BYTE* byte_ = new BIFF_BYTE; + if (!byte_) return; + + auto value = oReader.GetText(); + if(typeName == 0x000F) + { + if (value == L"general") *byte_ = 0; + else if (value == L"left") *byte_ = 1; + else if (value == L"center") *byte_ = 2; + else if (value == L"right") *byte_ = 3; + else if (value == L"fill") *byte_ = 4; + else if (value == L"justify") *byte_ = 5; + else if (value == L"center-across-selection") *byte_ = 6; + else if (value == L"distributed") *byte_ = 7; + else *byte_ = 0xFF; + } + else if(typeName == 0x0010) + { + if (value == L"top") *byte_ = 0; + else if (value == L"center") *byte_ = 1; + else if (value == L"bottom") *byte_ = 2; + else if (value == L"justify") *byte_ = 3; + else if (value == L"distributed") *byte_ = 4; + else *byte_ = 0; + } + else + *byte_ = 0; + val.reset(byte_); + } void XFProp::serialize_attr(CP_ATTR_NODE) { switch(xfPropType) @@ -585,25 +654,34 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) case 0x000C: xfPropDataBlob.reset(deserialize_border_prop(oReader)); break; + case 0x000F: + case 0x0010: + deserialize_alignment(oReader, xfPropType, xfPropDataBlob); + break; case 0x000D: case 0x000E: - case 0x000F: - case 0x0010: case 0x0011: // XFPropTextRotation - case 0x0012: // indent case 0x0013: // ReadingOrder case 0x0014: case 0x0015: case 0x0016: //case 0x0017: - xfPropDataBlob.reset(new BIFF_BYTE(XmlUtils::GetInteger(oReader.GetText()))); + xfPropDataBlob.reset(new BIFF_BYTE(XmlUtils::GetInteger(oReader.GetText()))); + break;// + case 0x0018: + deserialize_val_prop(oReader, L"LPWideString", xfPropDataBlob); break; - case 0x001C: - case 0x001D: - case 0x001E: - case 0x001F: - case 0x0020: - case 0x0021: + case 0x0019: + deserialize_default_val(oReader, L"BIFF_WORD", 0x02BC, xfPropDataBlob); + break; + case 0x0020: + case 0x0021: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x001F: + deserialize_default_val(oReader, L"BIFF_BYTE", 0x01, xfPropDataBlob); + break; case 0x0022: case 0x0023: xfPropDataBlob.reset(new BIFF_BYTE(1)); @@ -614,18 +692,12 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) case 0x002C: deserialize_prop(oReader, L"BIFF_BYTE", xfPropDataBlob); break; - case 0x0018: - deserialize_val_prop(oReader, L"LPWideString", xfPropDataBlob); - break; + case 0x0012: // indent case 0x0029: xfPropDataBlob.reset(new BIFF_WORD(XmlUtils::GetInteger(oReader.GetText()))); break; - case 0x0019: - xfPropDataBlob.reset(new BIFF_WORD(0x02BC1)); - deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); - break; case 0x001A: - xfPropDataBlob.reset(new BIFF_WORD(1)); + //xfPropDataBlob.reset(new BIFF_WORD(1)); case 0x001B: case 0x002A: deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); @@ -640,7 +712,7 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) } int XFProp::serialize(std::wostream & stream) { - CP_XML_WRITER(stream) + CP_XML_WRITER(stream) { switch(xfPropType) { From 9e260897b3e5a4d97bd0e0031a3b10017660c01e Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 26 Mar 2024 10:56:52 +0300 Subject: [PATCH 466/794] Fixed a bug with the percentage size of the svg file --- .../raster/Metafile/svg/CSvgFile.cpp | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index 07035af67fb..cea56425506 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -44,13 +44,34 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight dX = oWindow.m_oX .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); dY = oWindow.m_oY .ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); - dWidth = oWindow.m_oWidth .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); - dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); - if (SVG::Equals(0., dWidth)) - dWidth = (!m_oContainer.GetViewBox().m_oWidth.Empty()) ? m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel) : SVG_FILE_WIDTH; - if (SVG::Equals(0., dHeight)) - dHeight = (!m_oContainer.GetViewBox().m_oHeight.Empty()) ? m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel) : SVG_FILE_HEIGHT; + dWidth = 0.; + dHeight = 0.; + + if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero()) + { + if (NSCSS::Percent != oWindow.m_oWidth.GetUnitMeasure() && !m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel)); + else + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel); + } + else if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) + dWidth = m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel); + + if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero()) + { + if (NSCSS::Percent != oWindow.m_oHeight.GetUnitMeasure() && !m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel)); + else + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel); + } + else if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) + dHeight = m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel); + + if (0. == dWidth) + dWidth = SVG_FILE_WIDTH; + if (0. == dHeight) + dHeight = SVG_FILE_HEIGHT; return true; } From 8b16b1625fc62a2536931dc2e25cef2e4d4dc4ee Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 26 Mar 2024 11:46:30 +0300 Subject: [PATCH 467/794] Fix bug --- DocxRenderer/src/logic/elements/ContText.cpp | 21 ++++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index 71eb52a7d8b..481a127c488 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -358,20 +358,15 @@ namespace NSDocxRenderer oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); oWriter.WriteString(L"\"/>"); - if (m_bIsUnderlinePresent) + if (m_bIsUnderlinePresent && m_lUnderlineColor != m_pFontStyle->oBrush.Color1) { - if (m_lUnderlineColor != m_pFontStyle->oBrush.Color1) - { - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - oWriter.WriteString(L""); - } - else - oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); } if (m_bIsHighlightPresent) From 4cc7ec1ed07db808f3690106af9acf93ffe196f5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 26 Mar 2024 18:03:51 +0600 Subject: [PATCH 468/794] Fix dxfs conversion --- .../XlsFile/Format/Logic/Biff_structures/XFProp.cpp | 8 +++++--- .../XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp index 2235ea10d96..4473f52edb8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp @@ -605,7 +605,8 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) if (value == L"none") *byte_ = 0; else if (value == L"solid") *byte_ = 1; else if (value == L"pct50") *byte_ = 2; - else if (value == L"pct75") *byte_ = 3; + else if (value == L"pct75" || value == L"darkGray") + *byte_ = 3; else if (value == L"pct25") *byte_ = 4; else if (value == L"horzStripe") *byte_ = 5; else if (value == L"vertStripe") *byte_ = 6; @@ -621,7 +622,8 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) else if (value == L"thinDiagCross") *byte_ = 16; else if (value == L"gray125") *byte_ = 17; else if (value == L"gray0625") *byte_ = 18; - + else *byte_ = 1; + xfPropDataBlob.reset(byte_); }break; @@ -703,7 +705,7 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); break; case 0x0024: - xfPropDataBlob.reset(new BIFF_DWORD(XmlUtils::GetInteger(oReader.GetText()))); + deserialize_val_prop(oReader, L"BIFF_DWORD", xfPropDataBlob); break; case 0x0026: xfPropDataBlob.reset(new LPWideString(oReader.GetText())); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp index 2d4075c68f1..a505a8d8d5b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropColor.cpp @@ -120,11 +120,14 @@ int XFPropColor::deserialize(XmlUtils::CXmlLiteReader& oReader) dwRgba.Parse(oReader.GetText()); fValidRGBA = true; } - else if (wsPropName == L"tint") + if (wsPropName == L"tint") { nTintShade = XmlUtils::GetDouble(oReader.GetText()) * 32767.0; } - + else + { + nTintShade = 0; + } if (!oReader.MoveToNextAttribute()) break; From cbac820495f11960d9f5791b8d159f753c09ef7f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 26 Mar 2024 17:37:06 +0300 Subject: [PATCH 469/794] fix bug #67066 --- Common/OfficeFileFormatChecker2.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 2ee7f1bede9..79b51dee737 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -236,6 +236,15 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt char *pFirst = strstr((char *)pBuffer, "%PDF-"); + if (NULL == pFirst) + { + //skip special + _UINT16 sz = pBuffer[0] + (pBuffer[1] << 8); + if (sz < dwBytes - 8) + { + pFirst = strstr((char*)(pBuffer + sz), "%PDF-"); + } + } if (NULL != pFirst) { pFirst = strstr((char *)pBuffer, "%DocumentID "); From 22a255f3510568a089741bf642f00bba19da7b46 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 26 Mar 2024 17:57:31 +0300 Subject: [PATCH 470/794] Fix images bug --- DocxRenderer/src/logic/elements/Shape.cpp | 73 +++++++++++++++-------- DocxRenderer/src/logic/elements/Shape.h | 1 + 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index a42d978b8c3..f50db6cf6ac 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -737,6 +737,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); + BuildForm(oWriter); BuildGraphicProperties(oWriter); oWriter.WriteString(L""); @@ -751,6 +752,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); oWriter.WriteString(L""); + BuildForm(oWriter); BuildGraphicProperties(oWriter); oWriter.WriteString(L""); @@ -772,30 +774,6 @@ namespace NSDocxRenderer void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const { std::wstring strPath = PathToWString(); - //отвечает за размеры прямоугольного фрейма шейпа - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L" rot=\""); - oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L">"); - - oWriter.WriteString(L"(m_dLeft * c_dMMToEMU)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); //Если просто текст без графики if (strPath.empty()) @@ -876,6 +854,29 @@ namespace NSDocxRenderer } } + void CShape::BuildForm(NSStringUtils::CStringBuilder &oWriter) const + { + // отвечает за размеры прямоугольного фрейма шейпа + oWriter.WriteString(L" 0.01) + { + oWriter.WriteString(L" rot=\""); + oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + oWriter.WriteString(L""); + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); + } + void CShape::BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const { oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки. @@ -933,6 +934,30 @@ namespace NSDocxRenderer { oWriter.WriteString(L""); oWriter.WriteString(L""); + + oWriter.WriteString(L" 0.01) + { + oWriter.WriteString(L" rot=\""); + oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + oWriter.WriteString(L"(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L""); BuildGraphicProperties(oWriter); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 7de2a05b0c0..0cb7962be47 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -87,6 +87,7 @@ namespace NSDocxRenderer void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const; + void BuildForm(NSStringUtils::CStringBuilder &oWriter) const; static void ResetRelativeHeight(); From 53b93ed9f2cdf2cdcfda633bc09828479c4e6be2 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 26 Mar 2024 19:34:29 +0300 Subject: [PATCH 471/794] fix bug #67109 --- OdfFile/Reader/Format/styles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index cd8ba22335c..719295d0d03 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -1441,7 +1441,7 @@ int style_page_layout_properties::DetectPageSize(double w, double h) { if ( w < 211 && h > 296 && h < 298) result = 9; // pagesizeA4Paper; else if (w > 279 && w < 280 && h > 431 && h < 433) result = 3; // pagesizeTabloidPaper; - else if (w > 215 && w < 217 && h > 355 && h < 356) result = 6; // pagesizeLegalPaper; + else if (w > 215 && w < 217 && h > 354 && h < 356) result = 5; // pagesizeLegalPaper; else if (w > 296 && w < 298 && h > 419 && h < 421) result = 8; // pagesizeA3Paper; else if (w > 256 && w < 258 && h > 363 && h < 365) result = 12; // pagesizeB4Paper; else if (w > 215 && w < 217 && h > 329 && h < 331) result = 14; // pagesizeFolioPaper; From a31361fe05e4419cb058ae04fcc2f2b26cc6314d Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 26 Mar 2024 19:38:12 +0300 Subject: [PATCH 472/794] Added a method for equating any one to the nearest of the given ones --- .../3dParty/html/css/src/StyleProperties.cpp | 49 ++++++++++++++++++- Common/3dParty/html/css/src/StyleProperties.h | 1 + .../html/css/src/xhtml/CDocumentStyle.cpp | 2 +- .../html/css/src/xhtml/CXmlElement.cpp | 11 +++-- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index adf65ad7c0d..d9df7d923e9 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -621,9 +621,9 @@ namespace NSCSS TRGB oRGB = ConvertHEXtoRGB(*pValue); return RGB_TO_INT(oRGB.uchRed, oRGB.uchGreen, oRGB.uchBlue); } + default: + return 0; } - - return 0; } double CColor::ToDouble() const @@ -641,6 +641,47 @@ namespace NSCSS } } + std::wstring CColor::EquateToColor(const std::vector& arColors) const + { + if (arColors.empty()) + return L"none"; + + TRGB oColor; + + switch(m_oValue.m_enType) + { + case ColorRGB: oColor = *static_cast(m_oValue.m_pColor); break; + case ColorHEX: oColor = ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); break; + default: return L"none"; + } + + TRGB oTempColor; + std::wstring wsSelectedColor; + double dMinDistance = DBL_MAX; + double dDistance; + + for (const std::wstring& wsColor : arColors) + { + oTempColor = ConvertHEXtoRGB(wsColor); + dDistance = sqrt(pow(oTempColor.uchRed - oColor.uchRed, 2) + pow(oTempColor.uchGreen - oColor.uchGreen, 2) + pow(oTempColor.uchBlue - oColor.uchBlue, 2)); + + if (dDistance < dMinDistance) + { + dMinDistance = dDistance; + wsSelectedColor = wsColor; + } + } + + std::map::const_iterator oIter = + std::find_if(NSConstValues::COLORS.begin(), NSConstValues::COLORS.end(), [&wsSelectedColor](const std::pair& oPair) + { return wsSelectedColor == oPair.second; }); + + if (NSConstValues::COLORS.end() == oIter) + return std::wstring(); + + return oIter->first; + } + TRGB CColor::ToRGB() const { switch(m_oValue.m_enType) @@ -802,6 +843,8 @@ namespace NSCSS break; } + default: + break; } return true; @@ -878,6 +921,8 @@ namespace NSCSS wsValue = L"rotate("; break; } + default: + break; } return wsValue; diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index eac50a24631..9e843e874c6 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -237,6 +237,7 @@ namespace NSCSS int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; + std::wstring EquateToColor(const std::vector& arColors) const; TRGB ToRGB() const; }; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index b785cb16c6d..6d6f59a66a2 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -419,7 +419,7 @@ namespace NSCSS if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); - oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().ToWString()); + oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().EquateToColor({L"000000", L"0000FF", L"00FFFF", L"00FF00", L"FF00FF", L"FF0000", L"FFFF00", L"FFFFFF", L"00008B", L"008B8B", L"006400", L"8B008B", L"8B0000", L"8B8000", L"A9A9A9", L"D3D3D3"})); oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString()); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index dd7607bc318..e25590e4344 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -448,11 +448,12 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L""; break; } -// case CSSProperties::RunnerProperties::R_Highlight: -// { -// sRStyle += L""; -// break; -// } + case CSSProperties::RunnerProperties::R_Highlight: + { + if (!oItem.second.empty()) + sRStyle += L""; + break; + } case CSSProperties::RunnerProperties::R_SmallCaps: { if (oItem.second == L"smallCaps") From c961f00fd116e2c66ab6f9653b2f0c0dbf301fc6 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 26 Mar 2024 20:06:43 +0300 Subject: [PATCH 473/794] fix bug #67043 --- OdfFile/Reader/Format/paragraph_elements.cpp | 25 +++++++++++-------- .../Writer/Format/odt_conversion_context.cpp | 9 +++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 57e4549b0da..4b90ab12db9 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -740,16 +740,16 @@ void a::add_space(const std::wstring & Text) } void a::docx_convert(oox::docx_conversion_context & Context) { - bool pushed_style = false; + std::wstring ref = xlink_attlist_.href_.get_value_or(L""); + if (ref.empty()) return; + bool pushed_style = false; bool addNewRun = false; - Context.finish_run(); - - std::wostream & _Wostream = Context.output_stream(); - - std::wstring ref = xlink_attlist_.href_.get_value_or(L""); + + Context.finish_run(); - if (Context.is_table_content()) + std::wostream& _Wostream = Context.output_stream(); + if (Context.is_table_content() || office_target_frame_name_ || ref[0] == L'#') { size_t pos_outline = ref.find(L"|outline"); if (std::wstring::npos != pos_outline)//без # @@ -766,11 +766,14 @@ void a::docx_convert(oox::docx_conversion_context & Context) { ref = XmlUtils::EncodeXmlString(ref.substr(1)); } - _Wostream << L""; - int type = Context.get_table_content_context().get_type_current_content_template_index(); - //type == 3 (LinkStart) - Context.get_table_content_context().next_level_index(); + + if (Context.is_table_content()) + { + int type = Context.get_table_content_context().get_type_current_content_template_index(); + //type == 3 (LinkStart) + Context.get_table_content_context().next_level_index(); + } } else { diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index 89c8a3a133b..28d20c9bf80 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -590,6 +590,15 @@ void odt_conversion_context::start_hyperlink(const std::wstring& link, const std text_a* hyperlink = dynamic_cast(hyperlink_elm.get()); if (hyperlink) { + if (location == L"_top") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Top; + else if (location == L"_blank") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Blank; + else if (location == L"_self") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Self; + else if (location == L"_parent") + hyperlink->office_target_frame_name_ = odf_types::target_frame_name::Parent; + hyperlink->common_xlink_attlist_.href_ = link + (location.empty() ? L"" : (L"#" + location)); hyperlink->common_xlink_attlist_.type_ = xlink_type::Simple; From e2d278c74bd3ae7cc1d4f6a6f4b700132e08756e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 27 Mar 2024 14:54:22 +0600 Subject: [PATCH 474/794] Fix dxfs conversion --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp index 4473f52edb8..fe040d36bea 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFProp.cpp @@ -696,12 +696,12 @@ void XFProp::deserialize_attr(XmlUtils::CXmlLiteReader& oReader) break; case 0x0012: // indent case 0x0029: + case 0x002A: xfPropDataBlob.reset(new BIFF_WORD(XmlUtils::GetInteger(oReader.GetText()))); break; case 0x001A: //xfPropDataBlob.reset(new BIFF_WORD(1)); case 0x001B: - case 0x002A: deserialize_val_prop(oReader, L"BIFF_WORD", xfPropDataBlob); break; case 0x0024: From f203f73a4b2cd02fc99b9b98b5a4d770c579cc1e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 27 Mar 2024 18:40:38 +0300 Subject: [PATCH 475/794] fix bug #67087 --- .../Reader/Converter/drawing_object_description.h | 2 ++ OdfFile/Reader/Converter/pptx_drawing.cpp | 15 +++++++++++---- OdfFile/Reader/Converter/pptx_slide_context.cpp | 9 ++++++++- OdfFile/Reader/Converter/pptx_slide_context.h | 1 + OdfFile/Reader/Format/draw_frame_pptx.cpp | 7 ++++++- OdfFile/Writer/Format/odf_drawing_context.cpp | 4 ++-- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/OdfFile/Reader/Converter/drawing_object_description.h b/OdfFile/Reader/Converter/drawing_object_description.h index d29c86e4295..692fb11fd67 100644 --- a/OdfFile/Reader/Converter/drawing_object_description.h +++ b/OdfFile/Reader/Converter/drawing_object_description.h @@ -76,6 +76,8 @@ struct drawing_object_description _action_desc action_; std::vector<_hlink_desc> hlinks_; + bool hidden_; + std::vector additional_; //shape properties std::wstring xlink_href_; //ссылка на внешний объект diff --git a/OdfFile/Reader/Converter/pptx_drawing.cpp b/OdfFile/Reader/Converter/pptx_drawing.cpp index 757b27653d7..1c91de40489 100644 --- a/OdfFile/Reader/Converter/pptx_drawing.cpp +++ b/OdfFile/Reader/Converter/pptx_drawing.cpp @@ -76,7 +76,8 @@ void pptx_serialize_image(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - + if (val.hidden) CP_XML_ATTR(L"hidden", true); + oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -123,6 +124,7 @@ void pptx_serialize_media(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(), val.action); @@ -210,6 +212,7 @@ void pptx_serialize_shape(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id);//числовое значение val.rId CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(),val.action); } @@ -270,6 +273,7 @@ void pptx_serialize_connector(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id);//числовое значение val.rId CP_XML_ATTR(L"name", val.name); + if (val.hidden) CP_XML_ATTR(L"hidden", true); oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -342,7 +346,8 @@ void pptx_serialize_chart(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); @@ -379,7 +384,8 @@ void pptx_serialize_table(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); @@ -420,7 +426,8 @@ void pptx_serialize_object(std::wostream & strm, _pptx_drawing & val) { CP_XML_ATTR(L"id", val.id); CP_XML_ATTR(L"name", val.name); - } + if (val.hidden) CP_XML_ATTR(L"hidden", true); + } CP_XML_NODE(L"p:cNvGraphicFramePr"); CP_XML_NODE(L"p:nvPr"); diff --git a/OdfFile/Reader/Converter/pptx_slide_context.cpp b/OdfFile/Reader/Converter/pptx_slide_context.cpp index cc9248c690c..a2c2deae66f 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.cpp +++ b/OdfFile/Reader/Converter/pptx_slide_context.cpp @@ -290,6 +290,8 @@ void pptx_slide_context::default_set() impl_->object_description_.connector_ = false; impl_->object_description_.lined_ = false; + impl_->object_description_.hidden_ = false; + impl_->object_description_.start_shape_id = boost::none; impl_->object_description_.start_shape_glue_point = boost::none; impl_->object_description_.end_shape_id = boost::none; @@ -466,6 +468,10 @@ void pptx_slide_context::set_id(std::wstring const& id) { impl_->object_description_.xml_id_ = id; } +void pptx_slide_context::set_hidden(bool val) +{ + impl_->object_description_.hidden_ = val; +} void pptx_slide_context::start_shape(int type) { @@ -841,7 +847,8 @@ void pptx_slide_context::Impl::process_common_properties(drawing_object_descript val = (int)(0.5 + odf_types::length(pic.svg_rect_->cy, odf_types::length::pt).get_value_unit(odf_types::length::emu)); if ( val >=0 ) drawing.cy = val; } - + + drawing.hidden = pic.hidden_; drawing.additional = pic.additional_; drawing.hlinks = pic.hlinks_; drawing.action = pic.action_; diff --git a/OdfFile/Reader/Converter/pptx_slide_context.h b/OdfFile/Reader/Converter/pptx_slide_context.h index a7e0d0e7514..85f6412449c 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.h +++ b/OdfFile/Reader/Converter/pptx_slide_context.h @@ -73,6 +73,7 @@ class pptx_slide_context std::vector & get_properties(); void set_clipping (const std::wstring & str ); void set_fill (_oox_fill & fill); + void set_hidden (bool val); void set_is_line_shape(bool val); void set_is_connector_shape(bool val); diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 70bf37bf337..83927b78982 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -88,7 +88,7 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) { common_shape_draw_attlist &common_draw_attlist_ = common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_; common_presentation_attlist &common_presentation_attlist_ = common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; - + const unsigned int z_index = common_draw_attlist_.draw_z_index_.get_value_or(0); const std::wstring name = common_draw_attlist_.draw_name_.get_value_or(L""); const std::wstring textStyleName = common_draw_attlist_.draw_text_style_name_.get_value_or(L""); @@ -191,6 +191,11 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().set_placeHolder_idx(idx_in_owner); } + if (common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_) + { + Context.get_slide_context().set_hidden(true); + } + if (!textStyleName.empty()) { odf_reader::style_instance* textStyleInst = diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index adc1d3b981f..576ce8e8057 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -433,7 +433,7 @@ void odf_drawing_context::start_group() //if (!impl_->current_drawing_state_.description_.empty()) // group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_name_ = impl_->current_drawing_state_.description_; if (impl_->current_drawing_state_.hidden_) - group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; + group->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; // L"none" ??? if (!impl_->current_drawing_state_.xml_id_.empty()) group->xml_id_ = impl_->current_drawing_state_.xml_id_; @@ -630,7 +630,7 @@ void odf_drawing_context::end_drawing() if (impl_->current_drawing_state_.z_order_ >= 0) draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_z_index_ = impl_->current_drawing_state_.z_order_; if (impl_->current_drawing_state_.hidden_) - draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; + draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; // L"none" ??? if (!impl_->current_drawing_state_.xml_id_.empty()) draw->xml_id_ = impl_->current_drawing_state_.xml_id_; From db9015a3e7fd4509f75359ddcb73ebad9a0937e6 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 28 Mar 2024 14:01:38 +0500 Subject: [PATCH 476/794] Change ms placeholder presentation type --- OdfFile/DataTypes/presentationclass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/DataTypes/presentationclass.cpp b/OdfFile/DataTypes/presentationclass.cpp index 6b2e55635e0..5be0469d6f7 100644 --- a/OdfFile/DataTypes/presentationclass.cpp +++ b/OdfFile/DataTypes/presentationclass.cpp @@ -132,7 +132,7 @@ std::wstring presentation_class::get_type_ms() res = L"body"; break; case page: - res = L"sldImg"; + res = L"pic"; break; } return res; From b7a4c739ebe18b8e07b0a7313521e988d2ec220a Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 28 Mar 2024 13:40:59 +0300 Subject: [PATCH 477/794] fix bug #67121 --- .../Vml/PPTShape/Ppt2PptxShapeConverter.cpp | 8 ++--- MsBinaryFile/Common/Vml/VmlPath.cpp | 2 ++ .../ASCOfficeDrawingConverter.cpp | 34 ++++++------------- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp b/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp index 110e92af9f7..c6c4fa7db87 100644 --- a/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp +++ b/MsBinaryFile/Common/Vml/PPTShape/Ppt2PptxShapeConverter.cpp @@ -49,7 +49,7 @@ namespace NSGuidesVML point.x = lParam; if (m_eRuler != rtRMoveTo && m_eRuler != rtRLineTo && m_eRuler != rtRCurveTo) { - //point.x -= m_lX; + point.x -= m_lX; } point.y = 0; pointType.x = eParType; @@ -62,7 +62,7 @@ namespace NSGuidesVML m_arPoints.back().y = lParam; if (m_eRuler != rtRMoveTo && m_eRuler != rtRLineTo && m_eRuler != rtRCurveTo) { - //m_arPoints.back().y -= m_lY; + m_arPoints.back().y -= m_lY; } m_arPointsType.back().y = eParType; @@ -272,8 +272,8 @@ namespace NSGuidesVML m_lWidth = oPart.width; m_lHeight = oPart.height; - //m_lX = oPart.x; - //m_lY = oPart.y; + m_lX = oPart.x; + m_lY = oPart.y; } bool bFill = false; diff --git a/MsBinaryFile/Common/Vml/VmlPath.cpp b/MsBinaryFile/Common/Vml/VmlPath.cpp index a093071b190..868d5988149 100644 --- a/MsBinaryFile/Common/Vml/VmlPath.cpp +++ b/MsBinaryFile/Common/Vml/VmlPath.cpp @@ -852,6 +852,8 @@ namespace ODRAW for (size_t nIndex = 0; nIndex < oArray.size(); ++nIndex) { + if (oArray[nIndex].empty()) continue; + CPartPath part; part.x = m_lX; diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index 6fd1940e893..07ef977c65e 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -2297,7 +2297,7 @@ void CDrawingConverter::ConvertDrawing(PPTX::Logic::SpTreeElem *elem, XmlUtils:: } } } -void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CXmlNode& oNodeShape, std::wstring**& pMainProps,bool bIsTop) +void CDrawingConverter::ConvertShape(PPTX::Logic::SpTreeElem *elem, XmlUtils::CXmlNode& oNodeShape, std::wstring**& pMainProps, bool bIsTop) { if (!elem) return; @@ -3436,11 +3436,11 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L""; nullable_string sStrokeColor; - nullable_string sStrokeWeight; + nullable oStrokeWeight; nullable_string sStroked; XmlMacroReadAttributeBase(oNodeShape, L"strokecolor", sStrokeColor); - XmlMacroReadAttributeBase(oNodeShape, L"strokeweight", sStrokeWeight); + XmlMacroReadAttributeBase(oNodeShape, L"strokeweight", oStrokeWeight); XmlMacroReadAttributeBase(oNodeShape, L"stroked", sStroked); XmlUtils::CXmlNode oNodeStroke = oNodeShape.ReadNode(L"v:stroke"); @@ -3580,18 +3580,13 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L""; //textOutline - double m_dValue = 1; - if (sStrokeWeight.is_init()) + double m_dValuePt = 1; + if (oStrokeWeight.is_init()) { - std::wstring strW(*sStrokeWeight); - int p = (int)strW.find(L"pt"); - if (p >= 0) - strW.erase(p); - - m_dValue = XmlUtils::GetDouble(strW); + m_dValuePt = oStrokeWeight->GetValue(); } - std::wstring strStrokeW = std::to_wstring((int)Pt_To_Emu(m_dValue)); + std::wstring strStrokeW = std::to_wstring((int)Pt_To_Emu(m_dValuePt)); strRPr += L""; smart_ptr pSolid = new PPTX::Logic::SolidFill(); @@ -3909,7 +3904,6 @@ void CDrawingConverter::LoadCoordPos(XmlUtils::CXmlNode& oNode, CShapePtr pShape } } } - pShape->getBaseShape()->m_oPath.SetCoordpos((LONG)pShape->m_dXLogic, (LONG)pShape->m_dYLogic); } @@ -5381,22 +5375,16 @@ void CDrawingConverter::CheckPenShape(PPTX::Logic::SpTreeElem* oElem, XmlUtils:: } } - nullable_string sStrokeWeight; - XmlMacroReadAttributeBase(oNode, L"strokeweight", sStrokeWeight); - if (sStrokeWeight.is_init()) + nullable oStrokeWeight; + XmlMacroReadAttributeBase(oNode, L"strokeweight", oStrokeWeight); + if (oStrokeWeight.is_init()) { pPPTShape->m_bIsStroked = true; if (!pSpPr->ln.is_init()) pSpPr->ln = new PPTX::Logic::Ln(); - if (sStrokeWeight->length() > 0 && sStrokeWeight->at(0) == wchar_t('.')) - { - sStrokeWeight = (L"0" + *sStrokeWeight); - } - - SimpleTypes::CPoint oPoint; - int size = (int)(g_emu_koef * oPoint.FromString(*sStrokeWeight)); + int size = oStrokeWeight->ToEmu(); pSpPr->ln->w = size; pPPTShape->m_bIsStroked = true; From 8332560d061efd42f4cd84b7b7f53b31e984f001 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 29 Mar 2024 15:31:52 +0600 Subject: [PATCH 478/794] Fix data validations --- .../Format/Logic/Biff_records/DVal.cpp | 6 ++- .../XlsFile/Format/Logic/Biff_records/Dv.cpp | 52 +++++++++++++------ .../Logic/Biff_structures/DVParsedFormula.cpp | 46 +++++++++++----- .../XlsxFormat/Worksheets/DataValidation.cpp | 4 ++ 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp index c65c93fd14b..c44852c18d5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DVal.cpp @@ -62,9 +62,13 @@ void DVal::readFields(CFRecord& record) void DVal::writeFields(CFRecord& record) { _UINT16 flags = 0; + _UINT32 reserved = 0; SETBIT(flags, 0, fWnClosed); - record << flags << xLeft << yTop << idObj << idvMac; + if(record.getGlobalWorkbookInfo()->Version < 0x0800) + record << flags << xLeft << yTop << idObj << idvMac; + else + record << flags << xLeft << yTop << reserved << idvMac; } } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp index e55f2caebf3..825d8c5af48 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dv.cpp @@ -142,20 +142,33 @@ void Dv::writeFields(CFRecord& record) record << FRTheader; _UINT32 flags = 0; - - SETBITS(flags, 0, 3, valType) - SETBITS(flags, 4, 6, errStyle) - - SETBIT(flags, 7, fStrLookup) - SETBIT(flags, 8, fAllowBlank) - SETBIT(flags, 9, fSuppressCombo) - SETBITS(flags, 10, 17, mdImeMode) - SETBIT(flags, 18, fShowInputMsg) - SETBIT(flags, 19, fShowErrorMsg) - SETBITS(flags, 20, 23, typOperator) - SETBIT(flags, 24, fDVMinFmla) - SETBIT(flags, 25, fDVMaxFmla) - + if(record.getGlobalWorkbookInfo()->Version < 0x0800) + { + SETBITS(flags, 0, 3, valType) + SETBITS(flags, 4, 6, errStyle) + + SETBIT(flags, 7, fStrLookup) + SETBIT(flags, 8, fAllowBlank) + SETBIT(flags, 9, fSuppressCombo) + SETBITS(flags, 10, 17, mdImeMode) + SETBIT(flags, 18, fShowInputMsg) + SETBIT(flags, 19, fShowErrorMsg) + SETBITS(flags, 20, 23, typOperator) + SETBIT(flags, 24, fDVMinFmla) + SETBIT(flags, 25, fDVMaxFmla) + } + else + { + SETBITS(flags, 0, 3, valType) + SETBITS(flags, 4, 6, errStyle) + + SETBIT(flags, 8, fAllowBlank) + SETBIT(flags, 9, fSuppressCombo) + SETBITS(flags, 10, 17, mdImeMode) + SETBIT(flags, 18, fShowInputMsg) + SETBIT(flags, 19, fShowErrorMsg) + SETBITS(flags, 20, 23, typOperator) + } record << flags; if (record.getGlobalWorkbookInfo()->Version < 0x0800) @@ -174,10 +187,17 @@ void Dv::writeFields(CFRecord& record) XLSB::DValStrings dvalstr; dvalstr.strPromptTitle = PromptTitle; - dvalstr.strErrorTitle = ErrorTitle; + if(!PromptTitle.size()) + dvalstr.strPromptTitle.setSize(0xFFFFFFFF); + dvalstr.strErrorTitle = ErrorTitle; + if(!ErrorTitle.size()) + dvalstr.strErrorTitle.setSize(0xFFFFFFFF); dvalstr.strPrompt = Prompt; + if(!Prompt.size()) + dvalstr.strPrompt.setSize(0xFFFFFFFF); dvalstr.strError = Error; - + if(!Error.size()) + dvalstr.strError.setSize(0xFFFFFFFF); record << dvalstr; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp index ca52fba9e92..447b0e0b833 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp @@ -93,31 +93,51 @@ void DVParsedFormula::save(CFRecord& record, bool bSave) else { cce = 0; - record << cce; + auto cb = 0; + record << cce << cb; } } void DVParsedFormula::save(CFRecord& record) { - auto saving = [&](BiffStructure& rgceORrgb) + if (record.getGlobalWorkbookInfo()->Version < 0x0800) { - record << cce; + auto saving = [&](BiffStructure& rgceORrgb) + { + record << cce; - auto rdPtr = record.getRdPtr(); + auto rdPtr = record.getRdPtr(); - rgceORrgb.save(record); + rgceORrgb.save(record); - cce = record.getRdPtr() - rdPtr; + cce = record.getRdPtr() - rdPtr; - record.RollRdPtrBack(cce + 4); - record << cce; - record.skipNunBytes(cce); - }; + record.RollRdPtrBack(cce + 4); + record << cce; + record.skipNunBytes(cce); + }; - saving(rgce); - - if (record.getGlobalWorkbookInfo()->Version == 0x0800) + saving(rgce); + } + else { + _UINT32 size = 0; + auto saving = [&](BiffStructure& rgceORrgb) + { + record << size; + + auto rdPtr = record.getRdPtr(); + + rgceORrgb.save(record); + + size = record.getRdPtr() - rdPtr; + + record.RollRdPtrBack(size + 4); + record << size; + record.skipNunBytes(size); + }; + + saving(rgce); saving(rgcb); } } diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index fb9b99a69ec..c5b4acd5c6d 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -290,7 +290,11 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); ptr->typOperator = XLS::_typOperatorDv::operatorDvGreaterThanOrEqual; else if (m_oOperator->GetValue() == SimpleTypes::Spreadsheet::EDataValidationOperator::operatorLessThanOrEqual) ptr->typOperator = XLS::_typOperatorDv::operatorDvLessThanOrEqual; + else + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; } + else + ptr->typOperator = XLS::_typOperatorDv::operatorDvBetween; if(m_oShowDropDown.IsInit()) ptr->fSuppressCombo = m_oShowDropDown->GetValue(); From 90949659098cd58684dca594416d611f81937896 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 29 Mar 2024 17:04:39 +0500 Subject: [PATCH 479/794] Fix bug #60279 --- OdfFile/DataTypes/presentationclass.cpp | 2 +- OdfFile/Reader/Format/draw_frame_pptx.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/OdfFile/DataTypes/presentationclass.cpp b/OdfFile/DataTypes/presentationclass.cpp index 5be0469d6f7..614a727887e 100644 --- a/OdfFile/DataTypes/presentationclass.cpp +++ b/OdfFile/DataTypes/presentationclass.cpp @@ -102,7 +102,7 @@ std::wstring presentation_class::get_type_ms() res = L"body"; break; case object: - res = L"obj"; + res = L"body"; break; case chart: res = L"chart"; diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 55df515d82c..c3adc022247 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -469,7 +469,10 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) std::wstring folderPath = Context.root()->get_folder(); std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; - if (!href.empty()) + NSFile::CFileBinary objectFile; + objectFile.OpenFile(objectPath); + + if (!href.empty() && objectFile.SizeFile() != 0) { std::wstring prog, extension; oox::_rels_type relsType; From 2156d6e13411ca74260c0c89c050ab916c88a34f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 29 Mar 2024 17:28:02 +0300 Subject: [PATCH 480/794] fix bug #66842 --- OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index 197b67eef30..a6358c9f98a 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -284,6 +284,9 @@ class xlsx_conditionalFormatting_context::Impl case 14: CP_XML_ATTR(L"iconSet", L"5ArrowsGray"); break; case 15: CP_XML_ATTR(L"iconSet", L"5Quarters"); break; case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; + case 17: CP_XML_ATTR(L"iconSet", L"3Triangles"); break; + case 18: CP_XML_ATTR(L"iconSet", L"3Stars"); break; + case 19: CP_XML_ATTR(L"iconSet", L"5Boxes"); break; case 0: default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; break; From c44aed0e9ae341095cba1c48b0e64bae503ca8bc Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sat, 30 Mar 2024 12:53:30 +0300 Subject: [PATCH 481/794] Refactoring --- HtmlFile2/htmlfile2.cpp | 745 +++++++++++++++++++++++++++++++--------- 1 file changed, 583 insertions(+), 162 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 7d8e55133c5..7ee9de6a5fd 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -35,7 +35,7 @@ #define VALUE2STR(x) VALUE_TO_STRING(x) #endif -#define MAXCOLUMNSINTABLE 63 +#define MAXCOLUMNSINTABLE 64 #define MAXROWSINTABLE 32767 #define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips @@ -86,18 +86,396 @@ struct CTextSettings {} }; +std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) +{ + if (oBorder.EqualSides()) + { + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); + + return L"" + + L"" + + L"" + + L""; + } + else + { + std::wstring wsTable; + + if (oBorder.GetTopBorder().Valid()) + wsTable += L""; + + if (oBorder.GetLeftBorder().Valid()) + wsTable += L""; + + if (oBorder.GetBottomBorder().Valid()) + wsTable += L""; + + if (oBorder.GetRightBorder().Valid()) + wsTable += L""; + + return wsTable; + } + + return L""; +} + //Необходимые стили таблицы struct TTableStyles { - const NSCSS::NSProperties::CIndent* m_pPadding; - const NSCSS::NSProperties::CEnum* m_pCollapse; + NSCSS::NSProperties::CIndent m_oPadding; + NSCSS::NSProperties::CBorder m_oBorder; + NSCSS::NSProperties::CDigit m_oWidth; int m_nCellSpacing; bool m_bHaveBorderAttribute; + std::wstring m_wsAlign; + TTableStyles() - : m_pPadding(NULL), m_pCollapse(NULL), m_nCellSpacing(-1), m_bHaveBorderAttribute(false) + : m_nCellSpacing(-1), m_bHaveBorderAttribute(false) + {} + + bool Empty() const + { + return m_oPadding.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && false == m_bHaveBorderAttribute && m_wsAlign.empty(); + } +}; + +struct TTableCellStyle +{ + NSCSS::NSProperties::CDigit m_oWidth; + NSCSS::NSProperties::CDigit m_oHeight; + NSCSS::NSProperties::CBorder m_oBorder; + NSCSS::NSProperties::CIndent m_oPadding; + NSCSS::NSProperties::CColor m_oBackground; + + std::wstring m_wsAlign; + + TTableCellStyle() {} + + bool Empty() + { + return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsAlign.empty(); + } +}; + +class CTableCell +{ +public: + CTableCell() + : m_unColspan(1), m_unRowSpan(1) + {} + + void SetColspan(UINT unColspan, UINT unCurrentIndex) + { + if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex) + m_unColspan = std::min(MAXCOLUMNSINTABLE - 1 - unCurrentIndex, unColspan); + else + m_unColspan = 1; + } + + UINT GetColspan() const + { + return m_unColspan; + } + + void SetRowspan(UINT unRowspan) + { + m_unRowSpan = unRowspan; + } + + UINT GetRowspan() const + { + return m_unRowSpan; + } + + NSStringUtils::CStringBuilder* GetData() + { + return &m_oData; + } + + void SetWidth(const NSCSS::NSProperties::CDigit& oWidth) + { + m_oStyles.m_oWidth = oWidth; + } + + void SetHeight(const NSCSS::NSProperties::CDigit& oHeight) + { + m_oStyles.m_oHeight = oHeight; + } + + void SetBorder(const NSCSS::NSProperties::CBorder& oBorder) + { + m_oStyles.m_oBorder = oBorder; + } + + void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) + { + m_oStyles.m_oPadding = oPadding; + } + + void SetAlign(const std::wstring& wsAlign) + { + m_oStyles.m_wsAlign = wsAlign; + } + + std::wstring ConvertToOOXML(const TTableStyles& oTableStyles) + { + NSStringUtils::CStringBuilder oCell; + + oCell.WriteNodeBegin(L"w:tc"); + + if (!m_oStyles.Empty()) + { + oCell.WriteNodeBegin(L"w:tcPr"); + + if (!m_oStyles.m_oWidth.Empty()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oCell += L""; + else + oCell += L""; + } + else + oCell += L""; + + if (1 < m_unColspan) + oCell += L""; + + if (!m_oStyles.m_oBorder.Zero() && !m_oStyles.m_oBorder.Empty()) + oCell += L"" + CreateBorders(m_oStyles.m_oBorder) + L""; + else if (oTableStyles.m_bHaveBorderAttribute) + oCell += L""; + + if (!m_oStyles.m_oBackground.Empty()) + { + const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == m_oStyles.m_oBackground.GetType()) ? L"auto" : m_oStyles.m_oBackground.ToWString()}; + oCell += L""; + } + + if (!m_oStyles.m_wsAlign.empty()) + oCell += L""; + + if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding) + { + const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + + oCell += L"" + "" + "" + "" + "" + ""; + } + + oCell += L""; + oCell.WriteNodeEnd(L"w:tcPr"); + } + + oCell += m_oData.GetData(); + + oCell.WriteNodeEnd(L"w:tc"); + + return oCell.GetData(); + } + +private: + UINT m_unColspan; + UINT m_unRowSpan; + + TTableCellStyle m_oStyles; + NSStringUtils::CStringBuilder m_oData; +}; + +class CTableRow +{ +public: + CTableRow() + : m_unMaxIndex(0) {} + + ~CTableRow() + { + for (CTableCell* pCell : m_arCells) + delete pCell; + } + + void AddCell(CTableCell* pCell) + { + if (NULL == pCell) + return; + + m_arCells.push_back(pCell); + m_unMaxIndex += pCell->GetColspan(); + } + + UINT GetIndex() const + { + return m_unMaxIndex; + } + + UINT GetCountIndex() const + { + return m_arCells.size(); + } + + bool ColumnsOverflowing() const + { + return MAXCOLUMNSINTABLE == m_unMaxIndex; + } + + std::wstring ConvertToOOXML(const TTableStyles& oTableStyles) + { + if (m_arCells.empty()) + return std::wstring(); + + NSStringUtils::CStringBuilder oRow; + oRow.WriteNodeBegin(L"w:tr"); + + for (CTableCell* pCell : m_arCells) + oRow += pCell->ConvertToOOXML(oTableStyles); + + oRow.WriteNodeEnd(L"w:tr"); + + return oRow.GetData(); + } +private: + UINT m_unMaxIndex; + std::vector m_arCells; +}; + +class CTable +{ +public: + CTable() + {} + + ~CTable() + { + for (CTableRow* pRow : m_arRows) + delete pRow; + } + + void AddRow(CTableRow* pRow) + { + if (NULL == pRow) + return; + + m_arRows.push_back(pRow); + } + + void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) + { + m_oStyles.m_oPadding = oPadding; + } + + const NSCSS::NSProperties::CIndent& GetPadding() const + { + return m_oStyles.m_oPadding; + } + + void SetBorder(const NSCSS::NSProperties::CBorder& oBorder) + { + m_oStyles.m_oBorder = oBorder; + } + + void SetWidth(const NSCSS::NSProperties::CDigit& oWidth) + { + m_oStyles.m_oWidth = oWidth; + } + + void SetCellSpacing(int nCellSpacing) + { + m_oStyles.m_nCellSpacing = nCellSpacing; + } + + void SetAlign(const std::wstring& wsValue) + { + m_oStyles.m_wsAlign = wsValue; + } + + void HaveBorderAttribute() + { + m_oStyles.m_bHaveBorderAttribute = true; + } + + bool IsHaveBorderAttribute() const + { + return m_oStyles.m_bHaveBorderAttribute; + } + + void Shorten() + { + + } + + std::wstring ConvertToOOXML() + { + if (m_arRows.empty()) + return std::wstring(); + + NSStringUtils::CStringBuilder oTable; + + oTable.WriteNodeBegin(L"w:tbl"); + oTable.WriteNodeBegin(L"w:tblPr"); + + if (!m_oStyles.m_oWidth.Empty() && !m_oStyles.m_oWidth.Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oTable += L""; + else + oTable += L""; + } + else + oTable += L""; + + if (0 < m_oStyles.m_nCellSpacing) + oTable += L""; + + if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) + oTable += L"" + CreateBorders(m_oStyles.m_oBorder) + L""; + + if (!m_oStyles.m_oPadding.Empty()) + { + const int nTopPadding = std::max(0, m_oStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(0, m_oStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + const int nBottomPadding = std::max(0, m_oStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(0, m_oStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); + + oTable += L"" + "" + "" + "" + "" + ""; + } + else + oTable += L""; + + if (!m_oStyles.m_wsAlign.empty()) + oTable += L""; + + oTable += L""; + oTable.WriteNodeEnd(L"w:tblPr"); + + for (CTableRow* pRow : m_arRows) + oTable += pRow->ConvertToOOXML(m_oStyles); + + oTable.WriteNodeEnd(L"w:tbl"); + + return oTable.GetData(); + } +private: + std::vector m_arRows; + + TTableStyles m_oStyles; }; void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) @@ -850,7 +1228,7 @@ class CHtmlFile2_Private std::wstring sName = m_oLightReader.GetName(); if(sName == L"class") oNode.m_wsClass = m_oLightReader.GetText(); - else if(sName == L"id") + else if(sName == L"id" && NULL != oXml) { oNode.m_wsId = m_oLightReader.GetText(); std::wstring sCrossId = std::to_wstring(m_nCrossId++); @@ -1386,104 +1764,6 @@ class CHtmlFile2_Private return true; } - std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) - { - if (oBorder.EqualSides()) - { - const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); - - return L"" + - L"" + - L"" + - L""; - } - else - { - std::wstring wsTable; - - if (oBorder.GetTopBorder().Valid()) - wsTable += L""; - - if (oBorder.GetLeftBorder().Valid()) - wsTable += L""; - - if (oBorder.GetBottomBorder().Valid()) - wsTable += L""; - - if (oBorder.GetRightBorder().Valid()) - wsTable += L""; - - return wsTable; - } - - return L""; - } - - struct TTextReadingSettings - { - bool m_bOpenedRT; - bool m_bAddSpace; - std::wstring m_wsLastElement; - - TTextReadingSettings() - : m_bOpenedRT(false), m_bAddSpace(true) - {} - - TTextReadingSettings(bool bOpenedRT, bool bAddSpace, const std::wstring& wsLastElement) - : m_bOpenedRT(bOpenedRT), m_bAddSpace(bAddSpace), m_wsLastElement(wsLastElement) - {} - }; - - void ReadOnlyText(NSStringUtils::CStringBuilder* pXml, TTextReadingSettings& oTextReadingSettings, std::vector& sSelectors, const CTextSettings& oTS, int nDepth) - { - if (!m_oLightReader.IsValid() || m_oLightReader.IsEmptyNode()) - return; - - while (m_oLightReader.ReadNextSiblingNode2(nDepth)) - { - if (L"#text" == m_oLightReader.GetName()) - { - if (!oTextReadingSettings.m_bOpenedRT) - { - pXml->WriteString(L""); - oTextReadingSettings.m_bOpenedRT = true; - } - - pXml->WriteString(GetText()); - - if (oTextReadingSettings.m_bAddSpace) - pXml->WriteString(L" "); - } - else if (L"td" == m_oLightReader.GetName()) - ReadOnlyText(pXml, oTextReadingSettings, sSelectors, oTS, nDepth + 1); - else - { - GetSubClass(pXml, sSelectors); - if (oTextReadingSettings.m_bOpenedRT) - { - pXml->WriteString(L""); - oTextReadingSettings.m_bOpenedRT = false; - } - readStream(pXml, sSelectors, oTS); - sSelectors.pop_back(); - } - } - } - - void MergeCells(NSStringUtils::CStringBuilder* pXml) - { - if (!m_oLightReader.IsValid() || m_oLightReader.IsEmptyNode() || L"td" != m_oLightReader.GetName()) - return; - - std::vector arSelectors; - TTextReadingSettings oSettings; - - ReadOnlyText(pXml, oSettings, arSelectors, { false, false, true, false, -1, L"", L"" }, m_oLightReader.GetDepth() - 1); - - if (oSettings.m_bOpenedRT) - pXml->WriteString(L""); - } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const TTableStyles& oTableStyles) { const std::wstring wsName = m_oLightReader.GetName(); @@ -1613,28 +1893,28 @@ class CHtmlFile2_Private if (!wsVerticalAlign.empty()) wsTcPr += L""; - if (!oStyle.m_oPadding.Empty() && (NULL == oTableStyles.m_pPadding || oStyle.m_oPadding != *oTableStyles.m_pPadding)) - { - const int nTopPadding = std::max((NULL != oTableStyles.m_pPadding) ? - oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, - oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nLeftPadding = std::max((NULL != oTableStyles.m_pPadding) ? - oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, - oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - const int nBottomPadding = std::max((NULL != oTableStyles.m_pPadding) ? - oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, - oStyle .m_oPadding.GetBottom() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nRightPadding = std::max((NULL != oTableStyles.m_pPadding) ? - oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, - oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); +// if (!oStyle.m_oPadding.Empty() && (NULL == oTableStyles.m_pPadding || oStyle.m_oPadding != *oTableStyles.m_pPadding)) +// { +// const int nTopPadding = std::max((NULL != oTableStyles.m_pPadding) ? +// oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, +// oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); +// const int nLeftPadding = std::max((NULL != oTableStyles.m_pPadding) ? +// oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, +// oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); +// const int nBottomPadding = std::max((NULL != oTableStyles.m_pPadding) ? +// oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, +// oStyle .m_oPadding.GetBottom() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); +// const int nRightPadding = std::max((NULL != oTableStyles.m_pPadding) ? +// oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, +// oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - wsTcPr += L"" - "" - "" - "" - "" - ""; - } +// wsTcPr += L"" +// "" +// "" +// "" +// "" +// ""; +// } if(nRowspan > 1 && nColspan >= 1 && j < MAXCOLUMNSINTABLE) { @@ -1669,7 +1949,9 @@ class CHtmlFile2_Private { if (!readStream(&oTrBody, sSelectors, oTS)) { - oTrBody.WriteString(L""); + wrP(&oTrBody, sSelectors, oTS); + wrR(&oTrBody, sSelectors, oTS); + CloseP(&oTrBody, sSelectors); m_bInP = false; } } @@ -1682,7 +1964,6 @@ class CHtmlFile2_Private if (j - 1 == MAXCOLUMNSINTABLE) { -// MergeCells(&oTrBody); CTextSettings oTrTS{oTS}; oTrTS.bMergeText = true; oTrTS.bAddSpaces = true; @@ -1737,8 +2018,8 @@ class CHtmlFile2_Private if (0 <= oTableStyles.m_nCellSpacing) wsTrPr += L""; - else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) - wsTrPr += L""; +// else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) +// wsTrPr += L""; if (!wsTrPr.empty()) oXml->WriteString(L"" + wsTrPr + L""); @@ -1750,8 +2031,179 @@ class CHtmlFile2_Private } } + void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) + { + int nDeath = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nDeath)) + { + if (L"tr" != m_oLightReader.GetName()) + continue; + + GetSubClass(NULL, sSelectors); + + CTableRow *pRow = new CTableRow(); + + int nTrDepth = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nTrDepth)) + { + CTableCell *pCell = new CTableCell(); + + GetSubClass(pCell->GetData(), sSelectors); + + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); + + pCell->SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); + pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); + pCell->SetPadding(oStyle.m_oPadding); + pCell->SetBorder(oStyle.m_oBorder); + + while(m_oLightReader.MoveToNextAttribute()) + { + if(m_oLightReader.GetName() == L"colspan") + pCell->SetColspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1), pRow->GetIndex()); + else if(m_oLightReader.GetName() == L"rowspan") + pCell->SetRowspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + } + + m_oLightReader.MoveToElement(); + m_bWasPStyle = false; + + // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным + if(m_oLightReader.GetName() == L"th") + { + CTextSettings oTSR(oTS); + oTSR.sRStyle += L""; + readStream(pCell->GetData(), sSelectors, oTSR); + } + // Читаем td. Ячейка таблицы. Выравнивание вправо + else if(m_oLightReader.GetName() == L"td") + { + if (!readStream(pCell->GetData(), sSelectors, oTS)) + { + wrP(pCell->GetData(), sSelectors, oTS); + wrR(pCell->GetData(), sSelectors, oTS); + CloseP(pCell->GetData(), sSelectors); + m_bInP = false; + } + } + + if (pRow->ColumnsOverflowing()) + { + CTextSettings oTrTS{oTS}; + oTrTS.bMergeText = true; + oTrTS.bAddSpaces = true; + m_bWasSpace = true; + + while (m_oLightReader.ReadNextSiblingNode(nTrDepth) && L"td" == m_oLightReader.GetName()) + { + GetSubClass(pCell->GetData(), sSelectors); + readStream(pCell->GetData(), sSelectors, oTrTS); + sSelectors.pop_back(); + } + } + CloseP(pCell->GetData(), sSelectors); + + pRow->AddCell(pCell); + + sSelectors.pop_back(); + + if (pRow->ColumnsOverflowing()) + break; + } + + sSelectors.pop_back(); + + oTable.AddRow(pRow); + } + } + + void ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + { + if(m_oLightReader.IsEmptyNode()) + return; + + CTable oTable; + + //Table styles + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) + { + const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); + + if (0 >= nWidth) + sSelectors.back().m_mAttributes[L"border"] = L"none"; + else + sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; + + oTable.HaveBorderAttribute(); + } + + if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") + WriteEmptyParagraph(oXml, true); + + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); + + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) + oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); + + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) + oTable.SetCellSpacing(NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"])); + else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) + oTable.SetCellSpacing(15); + + oTable.SetWidth(oStyle.m_oDisplay.GetWidth()); + oTable.SetBorder(oStyle.m_oBorder); + oTable.SetPadding(oStyle.m_oPadding); + oTable.SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + //------ + + int nDeath = m_oLightReader.GetDepth(); + while(m_oLightReader.ReadNextSiblingNode(nDeath)) + { + std::wstring sName = m_oLightReader.GetName(); + GetSubClass(oXml, sSelectors); + // Заголовок таблицы + if(sName == L"caption") + { + if (!m_bInP) + { + oXml->WriteString(L""); + for (const NSCSS::CNode& item : sSelectors) + { + if (item.m_wsName == L"a") + oXml->WriteString(L""); + } + m_bInP = true; + m_bWasPStyle = false; + } + // Заголовок таблицы выравнивание посередине + CTextSettings oTSP(oTS); + oTSP.sPStyle += L""; + readStream(oXml, sSelectors, oTSP); + if (m_bInP) + m_bWasPStyle = false; + CloseP(oXml, sSelectors); + } +// if(sName == L"thead") +// readTr(&oHead, sSelectors, oTS, oTableStyles); + else if(sName == L"tbody") + ParseTableRows(oTable, sSelectors, oTS); +// else if(sName == L"tfoot") +// readTr(&oFoot, sSelectors, oTS, oTableStyles); + sSelectors.pop_back(); + } + + oTable.Shorten(); + oXml->WriteString(oTable.ConvertToOOXML()); + } + void readTable (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { + ParseTable(oXml, sSelectors, oTS); + + return; if(m_oLightReader.IsEmptyNode()) return; @@ -1773,9 +2225,9 @@ class CHtmlFile2_Private oTableStyles.m_bHaveBorderAttribute = true; } - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); +// oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") WriteEmptyParagraph(oXml, true); @@ -1826,7 +2278,7 @@ class CHtmlFile2_Private "" ""; - oTableStyles.m_pPadding = &oStyle.m_oPadding; +// oTableStyles.m_pPadding = &oStyle.m_oPadding; } else wsTable += L""; @@ -1837,33 +2289,6 @@ class CHtmlFile2_Private oXml->WriteString(wsTable); - /* - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); - oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - m_oXmlStyle.WriteLitePStyle(oStyleSetting); - std::wstring sPSettings = m_oXmlStyle.GetStyle(); - m_oXmlStyle.Clear(); - size_t nBdr = sPSettings.find(L""); - if (nBdr != std::wstring::npos) - { - nBdr += 8; - size_t nBdrEnd = sPSettings.find(L"", nBdr); - if (nBdrEnd != std::wstring::npos) - { - sBorders = sPSettings.substr(nBdr, nBdrEnd - nBdr); - size_t nSpace = sBorders.find(L"w:space=\""); - while (nSpace != std::wstring::npos) - { - nSpace += 9; - size_t nSpaceEnd = sBorders.find(L'\"', nSpace); - sBorders.replace(nSpace, nSpaceEnd - nSpace, L"0"); - nSpace = sBorders.find(L"w:space=\"", nSpace); - } - } - } - */ - int nDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nDeath)) { @@ -1872,17 +2297,13 @@ class CHtmlFile2_Private // Заголовок таблицы if(sName == L"caption") { - size_t nHyp = 0; if (!m_bInP) { oXml->WriteString(L""); for (const NSCSS::CNode& item : sSelectors) { if (item.m_wsName == L"a") - { oXml->WriteString(L""); - nHyp++; - } } m_bInP = true; m_bWasPStyle = false; From 3d394b173cd76799748f11415e83b0781acac259 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 9 Feb 2024 12:13:06 +0300 Subject: [PATCH 482/794] fix bugs (cherry picked from commit 97ddd35653e715aa69f0330fde9e6e3c77b96b0f) --- .../StarMath2OOXML/cstarmathpars.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index c256c4e2386..eac1e96bf80 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -153,7 +153,7 @@ namespace StarMath return SetLeft(pLeftArg,pElementWhichAdd); } default: - return false; + break; } } else return false; @@ -435,6 +435,7 @@ namespace StarMath } } +//нет phantom, rgb, 16 , гарнитуры и кегля TypeElement CAttribute::GetTypeColorAttribute(const std::wstring &wsToken) { if(L"color" == wsToken) return TypeElement::color; @@ -655,9 +656,9 @@ namespace StarMath pReader->ReadingTheNextToken(); while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { - CElement* pElementWithRightArgument = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pElementWithRightArgument); - pTempElement = pElementWithRightArgument; + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pElement); + pTempElement = pElement; pReader->ReadingTheNextToken(); } SetRightArg(pTempElement); @@ -870,7 +871,7 @@ namespace StarMath pReader->ClearReader(); } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(pTempElement!= nullptr &&( !m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType()))) + if(pTempElement != nullptr &&(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType()))) { if(CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement)) m_arBrecketValue.pop_back(); @@ -1898,16 +1899,16 @@ namespace StarMath { if(pReader->CheckIteratorPosition()) { - CElement* pTemp = CParserStarMathString::ParseElement(pReader); + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); while(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) { - CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTemp,pTempElement); - pTemp = pTempElement; + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(pTempElement,pElement); + pTempElement = pElement; pReader->ReadingTheNextToken(); } - SetValueFunction(pTemp); + SetValueFunction(pTempElement); } else SetValueFunction(nullptr); From fcd0bec3ac9e1374deeb49f84131c18d86831864 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 16 Feb 2024 11:23:46 +0300 Subject: [PATCH 483/794] conversion of unary symbols. code refactoring. (cherry picked from commit 89287887a0a6c1914f042120a9da2e335f0d3af2) --- .../StarMath2OOXML/TestSMConverter/main.cpp | 34 ++++- .../StarMath2OOXML/cstarmathpars.cpp | 135 +++++++++++------- .../Converter/StarMath2OOXML/cstarmathpars.h | 12 ++ 3 files changed, 128 insertions(+), 53 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 5914ccfd953..ecffde6bb60 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1080,7 +1080,7 @@ TEST(SMConvectorTest,OverWithoutLeft) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"\u00B12105"; + std::wstring wsXmlString =L"\u00B12105"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1090,7 +1090,37 @@ TEST(SMConvectorTest,Newline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2323102"; + std::wstring wsXmlString = L"23102"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexAndBinOp) +{ + std::wstring wsString = L"2 union 3^4 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2\u22C33410"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example7) +{ + std::wstring wsString = L" %DELTA t' = { %DELTA t } over sqrt{ 1 - v^2 over c^2 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,UnarySign) +{ + std::wstring wsString = L"3+6 over 9 newline -+5 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3+69\u2213510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index eac1e96bf80..d93794d4679 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -42,33 +42,24 @@ namespace StarMath pReader->SetBaseAttribute(pBaseAttribute); while(pReader->CheckIteratorPosition()) { - CElement* pTempElement; if(pReader->GetLocalType() == TypeElement::newline) { m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); pReader->ClearReader(); } - else - pTempElement = ParseElement(pReader); - if(nullptr == pTempElement) - continue; - if(!m_arEquation.empty() && CheckForLeftArgument(pTempElement->GetBaseType()) ) - { - if(AddLeftArgument(m_arEquation.back(),pTempElement)) - m_arEquation.pop_back(); - } - m_arEquation.push_back(pTempElement); + if(!m_arEquation.empty()) + CElementBinOperator::UnaryCheck(pReader,m_arEquation.back()); + CElement* pTempElement = ParseElement(pReader); + AddingAnElementToAnArray(m_arEquation,pTempElement); } if(!pReader->EmptyString()) { - CElement* pTempElement; if(pReader->GetLocalType() == TypeElement::newline) { m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); pReader->ClearReader(); } - else - pTempElement = ParseElement(pReader); + CElement* pTempElement = ParseElement(pReader); if(nullptr != pTempElement) m_arEquation.push_back(pTempElement); } @@ -112,12 +103,8 @@ namespace StarMath T* pTempElement = dynamic_cast(pElementWhichAdd); if(pTempElement->GetLeftArg() == nullptr) { - if(pLeftArg->GetBaseType() == TypeElement::SpecialSymbol) - { - CElementSpecialSymbol* pSpecial = dynamic_cast(pLeftArg); - if(pSpecial->GetType() == TypeElement::newline) - return false; - } + if(CParserStarMathString::CheckNewline(pLeftArg)) + return false; pTempElement->SetLeftArg(pLeftArg); pElementWhichAdd = pTempElement; return true; @@ -137,8 +124,7 @@ namespace StarMath } case TypeElement::SetOperations: { - SetLeft(pLeftArg, pElementWhichAdd); - break; + return SetLeft(pLeftArg, pElementWhichAdd); } case TypeElement::Connection: { @@ -192,6 +178,34 @@ namespace StarMath return false; } } + bool CParserStarMathString::CheckNewline(CElement* pElement) + { + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + return (pSpecial->GetType() == TypeElement::newline); + } + return false; + } + void CParserStarMathString::AddingAnElementToAnArray(std::vector &arrEquation, CElement *pAddElement) + { + if(pAddElement !=nullptr) + { + if(!arrEquation.empty() && CheckForLeftArgument(pAddElement->GetBaseType())) + { + if(AddLeftArgument(arrEquation.back(),pAddElement)) + arrEquation.pop_back(); + } + arrEquation.push_back(pAddElement); + } + } + void CParserStarMathString::ReadingElementsWithPriorities(CStarMathReader *pReader, CElement *&pLeftElement) + { + CElement* pNextElement = ParseElement(pReader); + AddLeftArgument(pLeftElement,pNextElement); + pLeftElement = pNextElement; + pReader->ReadingTheNextToken(); + } //class methods CAttribute CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0) { @@ -647,19 +661,19 @@ namespace StarMath SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); } else if(m_enTypeBinOp == TypeElement::And || m_enTypeBinOp == TypeElement::neg) + SetRightArg(CParserStarMathString::ParseElement(pReader)); + else if(pReader->GetMarkForUnar() && MixedOperators(m_enTypeBinOp)) { SetRightArg(CParserStarMathString::ParseElement(pReader)); } else { + pReader->SetMarkForUnar(true); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { - CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pElement); - pTempElement = pElement; - pReader->ReadingTheNextToken(); + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } SetRightArg(pTempElement); } @@ -779,13 +793,30 @@ namespace StarMath else if(L"and" == wsToken) return TypeElement::And; else return TypeElement::undefine; } - bool CElementBinOperator::IsBinOperatorLowPrior() + bool CElementBinOperator::MixedOperators(const TypeElement &enType) { - switch (m_enTypeBinOp) { + switch (enType) + { case TypeElement::plus: return true; + case TypeElement::plus_minus: + return true; + case TypeElement::minus_plus: + return true; case TypeElement::minus: return true; + default: + return false; + } + } + void CElementBinOperator::UnaryCheck(CStarMathReader *pReader, CElement *pLastElement) + { + pReader->ReadingTheNextToken(); + pReader->SetMarkForUnar(!(!CParserStarMathString::CheckNewline(pLastElement) && MixedOperators(pReader->GetLocalType()))); + } + bool CElementBinOperator::IsBinOperatorLowPrior() + { + switch (m_enTypeBinOp) { case TypeElement::oplus: return true; case TypeElement::ominus: @@ -795,7 +826,7 @@ namespace StarMath case TypeElement::Or: return true; default: - return false; + return MixedOperators(m_enTypeBinOp); } } void CElementBinOperator::SetAttribute(CAttribute *pAttribute) @@ -870,15 +901,11 @@ namespace StarMath m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); pReader->ClearReader(); } + if(!m_arBrecketValue.empty()) + CElementBinOperator::UnaryCheck(pReader,m_arBrecketValue.back()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - if(pTempElement != nullptr &&(!m_arBrecketValue.empty() && CParserStarMathString::CheckForLeftArgument(pTempElement->GetBaseType()))) - { - if(CParserStarMathString::AddLeftArgument(m_arBrecketValue.back(),pTempElement)) - m_arBrecketValue.pop_back(); - } - m_arBrecketValue.push_back(pTempElement); + CParserStarMathString::AddingAnElementToAnArray(m_arBrecketValue,pTempElement); } - //доработать() pReader->IteratorNullification(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -890,6 +917,8 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* pTemp:m_arBrecketValue) { + if(CParserStarMathString::CheckNewline(pTemp)) + continue; CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } pXmlWrite->WriteNodeEnd(L"m:e",false,false); @@ -899,6 +928,8 @@ namespace StarMath { for(CElement* pTemp:m_arBrecketValue) { + if(CParserStarMathString::CheckNewline(pTemp)) + continue; CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } } @@ -1137,10 +1168,10 @@ namespace StarMath m_wsType = L"\u2200"; break; case TypeElement::hbar: - m_wsType = L"\u"; + m_wsType = L"\u0127"; break; case TypeElement::lambdabar: - m_wsType = L"\u"; + m_wsType = L"\u019B"; break; case TypeElement::Re: m_wsType = L"\u211C"; @@ -1149,13 +1180,13 @@ namespace StarMath m_wsType = L"\u2111"; break; case TypeElement::wp: - m_wsType = L"\u"; + m_wsType = L"\u2118"; break; case TypeElement::laplace: - m_wsType = L"\u"; + m_wsType = L"\u2112"; break; case TypeElement::fourier: - m_wsType = L"\u0192"; + m_wsType = L"\u2131"; break; case TypeElement::backepsilon: m_wsType = L"\u03F6"; @@ -1415,10 +1446,7 @@ namespace StarMath pReader->ReadingTheNextToken(); while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) { - CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pElement); - pTempElement = pElement; - pReader->ReadingTheNextToken(); + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } SetRightArg(pTempElement); } @@ -1541,10 +1569,8 @@ namespace StarMath pReader->ReadingTheNextToken(); while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) { - CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pElement); - pTempElement = pElement; - pReader->ReadingTheNextToken(); + + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } SetRightArg(pTempElement); } @@ -2177,11 +2203,10 @@ namespace StarMath } // class methods CStarMathReader CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) - : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true) { m_itStart = itStart; m_itEnd = itEnd; - //m_pAttribute = new CAttribute(); } CStarMathReader::~CStarMathReader() { @@ -2477,6 +2502,14 @@ namespace StarMath return false; return true; } + void CStarMathReader::SetMarkForUnar(const bool &bMark) + { + m_bMarkForUnar = bMark; + } + bool CStarMathReader::GetMarkForUnar() + { + return m_bMarkForUnar; + } //class methods CElementBracketWithIndex CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType) :CElement(TypeElement::BracketWithIndex),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 954c7e6c490..470eb87b312 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -114,9 +114,12 @@ namespace StarMath void FindingTheEndOfParentheses(); void IteratorNullification(); void ReadingTheNextToken(); + void SetMarkForUnar(const bool& bMark); + bool GetMarkForUnar(); private: bool CheckTokenForGetElement(const wchar_t& cToken); bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); + bool m_bMarkForUnar; std::wstring::iterator m_itStart,m_itEnd; TypeElement m_enGlobalType; TypeElement m_enUnderType; @@ -192,7 +195,10 @@ namespace StarMath CElement* GetRightArg(); CElement* GetLeftArg(); static TypeElement GetBinOperator(const std::wstring& wsToken); + static void UnaryCheck(CStarMathReader* pReader,CElement* pLastElement); private: + //checking for signs such as -,+,-+,+-. + static bool MixedOperators(const TypeElement& enType); void SetAttribute(CAttribute* pAttribute) override; bool IsBinOperatorLowPrior(); void Parse(CStarMathReader* pReader) override; @@ -397,6 +403,12 @@ namespace StarMath static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); static bool CheckForLeftArgument(const TypeElement& enType ); static CElement* ReadingWithoutBracket(CStarMathReader* pReader); + //checking the element (true if it is newline) + static bool CheckNewline(CElement* pElement); + //adding an element to the array, checking that it is not empty and adding the left element, if there is one. + static void AddingAnElementToAnArray(std::vector& arrEquation,CElement* pAddElement); + //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. + static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); private: std::vector m_arEquation; }; From b1794fcf96152ee2ea536c592bc268261a1b86b6 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 26 Feb 2024 17:29:15 +0300 Subject: [PATCH 484/794] editing parsing of indexes with operators. adding alignment. (cherry picked from commit 1dff8bb868325ba885789802405a04e5e4ca7067) --- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 58 +++++- .../StarMath2OOXML/cconversionsmtoooxml.h | 4 +- .../StarMath2OOXML/cstarmathpars.cpp | 187 ++++++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 26 +-- .../Converter/StarMath2OOXML/typeselements.h | 3 + 5 files changed, 197 insertions(+), 81 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 4257d358360..40b3a52638d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -37,15 +37,51 @@ namespace StarMath { { } //check XMLWrite(if not nullptr == delete) - void CConversionSMtoOOXML::StartConversion(std::vector arPars) + void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); + if(iAlignment>= 0 && iAlignment <= 2) + { + std::wstring wsAlignment; + switch(iAlignment) + { + case 0: + wsAlignment = L"center"; + break; + case 1: + wsAlignment = L"left"; + break; + case 2: + wsAlignment = L"right"; + break; + default: + wsAlignment = L"center"; + break; + } + m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); + m_pXmlWrite->WriteNodeBegin(L"m:jc",true); + m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); + } m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); for(CElement* oTempElement:arPars) { if(oTempElement != nullptr) - oTempElement->ConversionToOOXML(m_pXmlWrite); + { + if(CParserStarMathString::CheckNewline(oTempElement)) + { + m_pXmlWrite->WriteNodeBegin(L"m:r",false); + m_pXmlWrite->WriteNodeBegin(L"w:br",true); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + } + else + oTempElement->ConversionToOOXML(m_pXmlWrite); + } } EndConversion(); } @@ -211,10 +247,6 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(wsNameBlock,true); pXmlWrite->WriteNodeEnd(L"",true,true); } -/* pXmlWrite->WriteNodeBegin(wsNameBlock,false); - if(pValueBlock != nullptr) - pValueBlock->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(wsNameBlock,false,false)*/; } std::wstring CConversionSMtoOOXML::GetOOXML() { @@ -389,7 +421,7 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); } - void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite,const std::wstring& wsNameNode,CElement* pValue, const TypeElement& enType,CAttribute* pAttribute,const std::wstring& wsName) + void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite,const std::wstring& wsNameNode,CElement* pValue, const TypeElement& enType,CAttribute* pAttribute,const std::wstring& wsName,CElement* pIndex) { pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); @@ -398,7 +430,17 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:e",false); CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName); pXmlWrite->WriteNodeEnd(L"m:e",false,false); - WriteNodeConversion(L"m:lim",pValue,pXmlWrite); + if(pValue!= nullptr && pIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:lim",false); + pIndex->ConversionToOOXML(pXmlWrite); + pValue->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + } + else if(pValue!=nullptr && pIndex == nullptr) + WriteNodeConversion(L"m:lim",pValue,pXmlWrite); + else if(pValue == nullptr && pIndex !=nullptr) + WriteNodeConversion(L"m:lim",pIndex,pXmlWrite); pXmlWrite->WriteNodeEnd(wsNameNode,false,false); } void CConversionSMtoOOXML::ElementConversion(XmlUtils::CXmlWriter *pXmlWrite, CElement *pElement) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 75615850397..05d61d0b83d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -41,7 +41,7 @@ namespace StarMath { { public: CConversionSMtoOOXML(); - void StartConversion(std::vector arPars); + void StartConversion(std::vector arPars, const unsigned int& iAlignment = -1); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); @@ -56,7 +56,7 @@ namespace StarMath { static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute); - static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper"); + static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); void EndConversion(); std::wstring GetOOXML(); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index d93794d4679..77d2923c873 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -40,13 +40,10 @@ namespace StarMath std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); CStarMathReader* pReader = new CStarMathReader(itStart,itEnd); pReader->SetBaseAttribute(pBaseAttribute); + if(pBaseAttribute != nullptr && (pBaseAttribute->base_alignment >= 0 && pBaseAttribute->base_alignment <= 2)) + SetAlignment(pBaseAttribute->base_alignment); while(pReader->CheckIteratorPosition()) { - if(pReader->GetLocalType() == TypeElement::newline) - { - m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); - pReader->ClearReader(); - } if(!m_arEquation.empty()) CElementBinOperator::UnaryCheck(pReader,m_arEquation.back()); CElement* pTempElement = ParseElement(pReader); @@ -69,16 +66,11 @@ namespace StarMath CElement* CParserStarMathString::ParseElement(CStarMathReader* pReader) { CElement* pElement; - pReader->ReadingTheNextToken(); - - if(TypeElement::newline == pReader->GetLocalType()) - return nullptr; - pElement = CElement::CreateElement(pReader); - if(pElement != nullptr) { + if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType())) @@ -142,21 +134,16 @@ namespace StarMath break; } } - else return false; + else + return false; } CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while(CheckForLeftArgument(pReader->GetGlobalType()) && (pReader->GetLocalType() != TypeElement::frac || pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt)) + while(CheckForLeftArgument(pReader->GetGlobalType()) && (pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) { - CElement* pSecondTempElement = CParserStarMathString::ParseElement(pReader); - if(pFirstTempElement != nullptr) - { - CParserStarMathString::AddLeftArgument(pFirstTempElement,pSecondTempElement); - } - pFirstTempElement = pSecondTempElement; - pReader->ReadingTheNextToken(); + CParserStarMathString::ReadingElementsWithPriorities(pReader,pFirstTempElement); } return pFirstTempElement; } @@ -165,13 +152,9 @@ namespace StarMath switch(enType) { case TypeElement::BinOperator: - return true; case TypeElement::Connection: - return true; case TypeElement::SetOperations: - return true; case TypeElement::BracketWithIndex: - return true; case TypeElement::Index: return true; default: @@ -202,10 +185,19 @@ namespace StarMath void CParserStarMathString::ReadingElementsWithPriorities(CStarMathReader *pReader, CElement *&pLeftElement) { CElement* pNextElement = ParseElement(pReader); - AddLeftArgument(pLeftElement,pNextElement); + if(pLeftElement != nullptr) + AddLeftArgument(pLeftElement,pNextElement); pLeftElement = pNextElement; pReader->ReadingTheNextToken(); } + void CParserStarMathString::SetAlignment(const unsigned int &iAlignment) + { + m_iAlignment = iAlignment; + } + const unsigned int& CParserStarMathString::GetAlignment() + { + return m_iAlignment; + } //class methods CAttribute CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0) { @@ -216,6 +208,10 @@ namespace StarMath { m_iSize = iSize; } + void CAttribute::SetAlignment(const unsigned int &iAlignment) + { + m_iAlignment = iAlignment; + } void CAttribute::SetBold() { m_bBold = true; @@ -372,6 +368,10 @@ namespace StarMath { return m_iSize; } + unsigned int CAttribute::GetAlignment() + { + return m_iAlignment; + } bool CAttribute::EmptyColor() { return m_wsColor.empty(); @@ -443,6 +443,10 @@ namespace StarMath m_wsNameFont = pReader->GetString(); break; } + case TypeElement::alignl: + case TypeElement::alignr: + case TypeElement::alignc: + break; default: SetFont(enTypeFont); break; @@ -490,6 +494,9 @@ namespace StarMath else if(L"ital" == wsToken) return TypeElement::ital; else if(L"phantom" == wsToken ) return TypeElement::phantom; else if(L"overstrike" == wsToken) return TypeElement::overstrike; + else if(L"alignl" == wsToken) return TypeElement::alignl; + else if(L"alignr" == wsToken) return TypeElement::alignr; + else if(L"alignc" == wsToken) return TypeElement::alignc; else return TypeElement::undefine; } //class methods CElement @@ -671,7 +678,7 @@ namespace StarMath pReader->SetMarkForUnar(true); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) + while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } @@ -896,11 +903,6 @@ namespace StarMath pReader->FindingTheEndOfParentheses(); while(pReader->CheckIteratorPosition()) { - if(pReader->GetLocalType() == TypeElement::newline) - { - m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); - pReader->ClearReader(); - } if(!m_arBrecketValue.empty()) CElementBinOperator::UnaryCheck(pReader,m_arBrecketValue.back()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -1118,12 +1120,12 @@ namespace StarMath } case TypeElement::newline: { - pXmlWrite->WriteNodeBegin(L"m:r",false); - pXmlWrite->WriteNodeBegin(L"w:br",true); - pXmlWrite->WriteNodeEnd(L"",true,true); - pXmlWrite->WriteNodeEnd(L"m:r",false,false); - pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - pXmlWrite->WriteNodeBegin(L"m:oMath",false); +// pXmlWrite->WriteNodeBegin(L"m:r",false); +// pXmlWrite->WriteNodeBegin(L"w:br",true); +// pXmlWrite->WriteNodeEnd(L"",true,true); +// pXmlWrite->WriteNodeEnd(L"m:r",false,false); +// pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); +// pXmlWrite->WriteNodeBegin(L"m:oMath",false); break; } default: @@ -1444,7 +1446,7 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType() != TypeElement::sqrt))) + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } @@ -1567,7 +1569,7 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot || pReader->GetLocalType()!=TypeElement::sqrt))) + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); @@ -1770,6 +1772,30 @@ namespace StarMath else if(L"sqrt" == wsCheckToken) return TypeElement::sqrt; else return TypeElement::undefine; } + bool CElementIndex::GetUpperIndex(const TypeElement &enType) + { + switch(enType) + { + case TypeElement::upper: + case TypeElement::csup: + case TypeElement::lsup: + return true; + default: + return false; + } + } + bool CElementIndex::GetLowerIndex(const TypeElement &enType) + { + switch(enType) + { + case TypeElement::lower: + case TypeElement::lsub: + case TypeElement::csub: + return true; + default: + return false; + } + } void CElementIndex::Parse(CStarMathReader *pReader) { if(m_enTypeIndex == TypeElement::nroot) @@ -2065,7 +2091,7 @@ namespace StarMath } //class methods CElementOperation CElementOperator::CElementOperator(const TypeElement &enType, const std::wstring& wsNameOp) - :CElement(TypeElement::Operator), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) + :CElement(TypeElement::Operator), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) { } CElementOperator::~CElementOperator() @@ -2132,6 +2158,20 @@ namespace StarMath void CElementOperator::Parse(CStarMathReader* pReader) { pReader->ReadingTheNextToken(); + while(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) + { + if(CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + pReader->ClearReader(); + m_pUpperIndex = CParserStarMathString::ParseElement(pReader); + } + if(CElementIndex::GetLowerIndex(pReader->GetLocalType())) + { + pReader->ClearReader(); + m_pLowerIndex = CParserStarMathString::ParseElement(pReader); + } + pReader->ReadingTheNextToken(); + } if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); @@ -2142,7 +2182,13 @@ namespace StarMath pReader->ClearReader(); SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } - SetValueOperator(CParserStarMathString::ParseElement(pReader)); +// SetValueOperator(CParserStarMathString::ParseElement(pReader)); + m_pValueOperator = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,m_pValueOperator); + } } void CElementOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { @@ -2151,20 +2197,25 @@ namespace StarMath pXmlWrite->WriteNodeBegin(L"m:func",false); CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:fName",false); - if(m_pValueFrom != nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName); - else if(m_pValueTo != nullptr && m_pValueFrom == nullptr) - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),m_wsName); - else if(m_pValueFrom != nullptr && m_pValueTo != nullptr) + if((m_pValueFrom != nullptr || m_pLowerIndex != nullptr) && (m_pValueTo == nullptr && m_pUpperIndex == nullptr)) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); + else if((m_pValueTo != nullptr || m_pUpperIndex != nullptr ) && (m_pValueFrom == nullptr && m_pLowerIndex == nullptr)) + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),m_wsName,m_pUpperIndex); + else if ((m_pValueFrom != nullptr || m_pLowerIndex != nullptr )&& (m_pValueTo != nullptr || m_pUpperIndex != nullptr)) { pXmlWrite->WriteNodeBegin(L"m:limUpp",false); pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); pXmlWrite->WriteNodeEnd(L"m:e",false,false); - CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueTo,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:lim",false); + if(m_pUpperIndex !=nullptr) + m_pUpperIndex->ConversionToOOXML(pXmlWrite); + if(m_pValueTo !=nullptr) + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:lim",false,false); pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); } else if(m_pValueFrom == nullptr && m_pValueTo == nullptr) @@ -2176,17 +2227,33 @@ namespace StarMath else { pXmlWrite->WriteNodeBegin(L"m:nary",false); - CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,nullptr == m_pValueFrom,nullptr == m_pValueTo,pXmlWrite,GetAttribute()); - if(m_pValueFrom == nullptr) pXmlWrite->WriteNode(L"m:sub",L""); - else + CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute()); + if(m_pValueFrom != nullptr && m_pLowerIndex != nullptr) { - CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:sub",false); + m_pLowerIndex->ConversionToOOXML(pXmlWrite); + m_pValueFrom->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sub",false); } - if(m_pValueTo == nullptr) pXmlWrite->WriteNode(L"m:sup",L""); - else + else if(m_pValueFrom == nullptr && m_pLowerIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + else if(m_pValueFrom != nullptr && m_pLowerIndex == nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueFrom,pXmlWrite); + else if(m_pValueFrom == nullptr && m_pLowerIndex == nullptr) + pXmlWrite->WriteNode(L"m:sub",L""); + if(m_pValueTo != nullptr && m_pUpperIndex != nullptr) { - CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:sup",false); + m_pUpperIndex->ConversionToOOXML(pXmlWrite); + m_pValueTo->ConversionToOOXML(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:sup",false); } + else if(m_pValueTo == nullptr && m_pUpperIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); + else if(m_pValueTo != nullptr && m_pUpperIndex == nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueTo,pXmlWrite); + else if(m_pValueTo == nullptr && m_pUpperIndex == nullptr) + pXmlWrite->WriteNode(L"m:sup",L""); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:nary",false,false); } @@ -2219,9 +2286,9 @@ namespace StarMath { m_wsToken = GetElement(); TypeElement enTypeFont =CAttribute::GetTypeFontAttribute(m_wsToken),enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); - if(enTypeFont != TypeElement::undefine ||enTypeColor != TypeElement::undefine) + if(enTypeFont != TypeElement::undefine || enTypeColor != TypeElement::undefine) m_pAttribute = new CAttribute(); - while((enTypeFont != TypeElement::undefine ||enTypeColor != TypeElement::undefine) && m_itStart != m_itEnd) + while((enTypeFont != TypeElement::undefine || enTypeColor != TypeElement::undefine) && m_itStart != m_itEnd) { if(enTypeColor == TypeElement::color) m_pAttribute->ParseColorAttribute(GetElement(),this); else if(enTypeFont != TypeElement::undefine) m_pAttribute->ParseFontAttribute(enTypeFont,this); @@ -2243,7 +2310,7 @@ namespace StarMath m_enUnderType = CElementOperator::GetFromOrTo(m_wsToken); if(m_enUnderType != TypeElement::undefine) { - m_enGlobalType = TypeElement::Operation; + m_enGlobalType = TypeElement::String; return; } m_enUnderType = CElementBracketWithIndex::GetBracketWithIndex(m_wsToken); @@ -2384,8 +2451,8 @@ namespace StarMath m_pBaseAttribute->SetFontName(pAttribute->base_font_name); if(pAttribute->base_font_size != 0) m_pBaseAttribute->SetSize(pAttribute->base_font_size); - // if(pAttribute.base_alignment != 0) - // m_pBaseAttribute-> + if(pAttribute->base_alignment >= 0 && pAttribute->base_alignment <=2) + m_pBaseAttribute->SetAlignment(pAttribute->base_alignment); } else m_pBaseAttribute = nullptr; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 470eb87b312..907b12cad6b 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -46,9 +46,9 @@ namespace StarMath struct TBaseAttribute { - int base_font_size = 12; + unsigned int base_font_size = 12; std::wstring base_font_name = L"Arial"; - int base_alignment = 1; + unsigned int base_alignment = 1;//(0 - center,1 - left,2 - right) bool base_font_bold = false; bool base_font_italic = false; }; @@ -65,12 +65,14 @@ namespace StarMath bool GetPhantom(); bool GetStrike(); unsigned int GetSize(); + unsigned int GetAlignment(); std::wstring GetColor(); const std::wstring& GetFontName(); bool EmptyColor(); void ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); void ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); void SetSize(const unsigned int& iSize); + void SetAlignment(const unsigned int& iAlignment); void SetBold(); void SetItal(); void SetPhantom(); @@ -80,13 +82,9 @@ namespace StarMath void SetFont(const TypeElement& enFont); void SetFontName(const std::wstring& wsNameFont); private: - std::wstring m_wsColor; - bool m_bBold; - bool m_bItal; - bool m_bPhantom; - bool m_bStrike; - unsigned int m_iSize; - std::wstring m_wsNameFont; + std::wstring m_wsColor,m_wsNameFont; + bool m_bBold,m_bItal,m_bPhantom,m_bStrike; + unsigned int m_iSize,m_iAlignment; }; //Сlass for working with tokens (reading, defining types, passing) class CStarMathReader @@ -121,8 +119,7 @@ namespace StarMath bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); bool m_bMarkForUnar; std::wstring::iterator m_itStart,m_itEnd; - TypeElement m_enGlobalType; - TypeElement m_enUnderType; + TypeElement m_enGlobalType,m_enUnderType; std::wstring m_wsToken; CAttribute* m_pAttribute; CAttribute* m_pBaseAttribute; @@ -159,6 +156,8 @@ namespace StarMath CElement* GetValueIndex(); CElement* GetLeftArg(); static TypeElement GetIndex(const std::wstring& wsCheckToken); + static bool GetUpperIndex(const TypeElement& enType); + static bool GetLowerIndex(const TypeElement& enType); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; @@ -230,6 +229,8 @@ namespace StarMath CElement* m_pValueOperator; CElement* m_pValueFrom; CElement* m_pValueTo; + CElement* m_pUpperIndex; + CElement* m_pLowerIndex; TypeElement m_enTypeOperator; std::wstring m_wsName; }; @@ -409,8 +410,11 @@ namespace StarMath static void AddingAnElementToAnArray(std::vector& arrEquation,CElement* pAddElement); //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); + void SetAlignment(const unsigned int& iAlignment); + const unsigned int& GetAlignment(); private: std::vector m_arEquation; + unsigned int m_iAlignment; }; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 7e24ced39f2..04c58fe3b98 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -112,6 +112,9 @@ enum class TypeElement{ overstrike, size, font, + alignl, + alignc, + alignr, //top element acute, breve, From db95af6c584745bc5f2b7a1cea873327b2bb08a3 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Wed, 6 Mar 2024 15:35:57 +0300 Subject: [PATCH 485/794] refinement of parsing and conversion of indexes. editing and writing tests. (cherry picked from commit 62b3b7b3c6b1b632fd8d74de058b7169cf10db4e) --- .../StarMath2OOXML/TestSMConverter/main.cpp | 84 ++- .../StarMath2OOXML/cstarmathpars.cpp | 582 +++++++++++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 14 +- 3 files changed, 514 insertions(+), 166 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index ecffde6bb60..40e3d171312 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -910,7 +910,7 @@ TEST(SMConvectorTest,IndexLsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3cos1527"; + std::wstring wsXmlString = L"2+3cos1527"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -920,7 +920,7 @@ TEST(SMConvectorTest,IndexLsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"22222103"; + std::wstring wsXmlString = L"22222103"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1124,6 +1124,86 @@ TEST(SMConvectorTest,UnarySign) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,Example13) +{ + std::wstring wsString = L"nroot{3}{x^3-7x^2+14x-8}+sqrt{7/8+4/9+nroot{3}{sqrt{7/8+4/9}}}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example14) +{ + std::wstring wsString = L"sum_{i=0}^{infinity} {(-1)^i over (2i+1)} x^{2i+1} = sin(x)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example15) +{ + std::wstring wsString = L"lim_{x->0} {sin(x) over x} = 1"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"limx->0sinxx=1"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example16) +{ + std::wstring wsString = L"int_0^{infinity} x^2 e^{-x} dx = 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example17) +{ + std::wstring wsString = L"{a^{2} over b} + {b^{2} over a} >= 2 sqrt{a b}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"a2b+b2a\u22652ab"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Example18) +{ + std::wstring wsString = L"10^1_2lsub5lsup4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"541021"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexWithColor) +{ + std::wstring wsString = L"bold 2 ^ 3 _4 lsup color blue 5 csub color red 6 csup 7 lsub 8"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"5867243"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FunctionWithColor) +{ + std::wstring wsString = L"func e^ 7_2 lsup 10 2over3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"10e2723"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 77d2923c873..6666b40927a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -99,6 +99,8 @@ namespace StarMath return false; pTempElement->SetLeftArg(pLeftArg); pElementWhichAdd = pTempElement; + if(pElementWhichAdd->GetBaseType() == TypeElement::Index) + pElementWhichAdd->SetAttribute(nullptr); return true; } else return false; @@ -163,12 +165,15 @@ namespace StarMath } bool CParserStarMathString::CheckNewline(CElement* pElement) { + if(pElement == nullptr) + return false; if(pElement->GetBaseType() == TypeElement::SpecialSymbol) { CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); return (pSpecial->GetType() == TypeElement::newline); } - return false; + else + return false; } void CParserStarMathString::AddingAnElementToAnArray(std::vector &arrEquation, CElement *pAddElement) { @@ -190,6 +195,26 @@ namespace StarMath pLeftElement = pNextElement; pReader->ReadingTheNextToken(); } + void CParserStarMathString::ReadingElementsWithAttributes(CStarMathReader *pReader, CElement*& pSavingElement) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + if(pElement->GetAttribute() != nullptr) + { + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pIndex = new CElementIndex(pReader->GetLocalType()); + pReader->ClearReader(); + pIndex->Parse(pReader); + AddLeftArgument(pElement,pIndex); + pSavingElement = pIndex; + } + else + pSavingElement = pElement; + } + else + pSavingElement = pElement; + } void CParserStarMathString::SetAlignment(const unsigned int &iAlignment) { m_iAlignment = iAlignment; @@ -199,7 +224,7 @@ namespace StarMath return m_iAlignment; } //class methods CAttribute - CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0) + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(-1) { } CAttribute::~CAttribute() @@ -908,6 +933,17 @@ namespace StarMath CElement* pTempElement = CParserStarMathString::ParseElement(pReader); CParserStarMathString::AddingAnElementToAnArray(m_arBrecketValue,pTempElement); } + if(!pReader->EmptyString()) + { + if(pReader->GetLocalType() == TypeElement::newline) + { + m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + pReader->ClearReader(); + } + CElement* pTempElement =CParserStarMathString::ParseElement(pReader); + if(nullptr != pTempElement) + m_arBrecketValue.push_back(pTempElement); + } pReader->IteratorNullification(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) @@ -921,6 +957,16 @@ namespace StarMath { if(CParserStarMathString::CheckNewline(pTemp)) continue; + if(CheckMline(pTemp)) + { + pXmlWrite->WriteNodeBegin(L"m:r",false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + pXmlWrite->WriteString(L"\u007C"); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + continue; + } CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } pXmlWrite->WriteNodeEnd(L"m:e",false,false); @@ -937,6 +983,18 @@ namespace StarMath } } + bool CElementBracket::CheckMline(CElement *pElement) + { + if(pElement == nullptr) + return false; + if(pElement->GetBaseType() == TypeElement::SpecialSymbol) + { + CElementSpecialSymbol* pSpecial = dynamic_cast(pElement); + return(pSpecial->GetType() == TypeElement::mline); + } + else + return false; + } void CElementBracket::SetAttribute(CAttribute *pAttribute) { SetBaseAttribute(pAttribute); @@ -981,6 +1039,7 @@ namespace StarMath if(wsToken[0] != L'%') { if(L"#" == wsToken) return TypeElement::grid; + else if(L"mline" == wsToken) return TypeElement::mline; else if(L"##" == wsToken) return TypeElement::transition; else if(L"emptyset" == wsToken) return TypeElement::emptyset; else if(L"aleph" == wsToken) return TypeElement::aleph; @@ -1735,13 +1794,19 @@ namespace StarMath } //class methods CIndex CElementIndex::CElementIndex(const TypeElement& enType) - : CElement(TypeElement::Index),m_pValueIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) + : CElement(TypeElement::Index),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) { } CElementIndex::~CElementIndex() { delete m_pValueIndex; delete m_pLeftArg; + delete m_pUpperIndex; + delete m_pLowerIndex; + delete m_pLsubIndex; + delete m_pLsupIndex; + delete m_pCsubIndex; + delete m_pCsupIndex; } void CElementIndex::SetValueIndex(CElement *pElement) { @@ -1800,70 +1865,62 @@ namespace StarMath { if(m_enTypeIndex == TypeElement::nroot) { - SetLeftArg(CParserStarMathString::ParseElement(pReader)); - SetValueIndex(CParserStarMathString::ParseElement(pReader)); - } - else - SetValueIndex(CParserStarMathString::ParseElement(pReader)); - if(m_enTypeIndex == TypeElement::sqrt) - SetLeftArg(GetValueIndex()); - } - void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) - { - switch(m_enTypeIndex) - { - case TypeElement::upper: - case TypeElement::lower: - { - std::wstring wsNameNodeIndex; - switch(m_enTypeIndex) + m_pLeftArg = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { - case TypeElement::upper: - wsNameNodeIndex = L"m:sSup"; - break; - case TypeElement::lower: - wsNameNodeIndex = L"m:sSub"; - break; + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pLeftArg,pElement); + m_pLeftArg = pElement; } - pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); - pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); - switch(m_enTypeIndex) + m_pValueIndex = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { - case TypeElement::upper: - CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); - break; - case TypeElement::lower: - CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); - break; + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement); + m_pValueIndex = pElement; } - pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); - break; } - case TypeElement::lsub: - case TypeElement::lsup: + else if(m_enTypeIndex == TypeElement::sqrt) { - pXmlWrite->WriteNodeBegin(L"m:sPre",false); - pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); - switch(m_enTypeIndex) + m_pValueIndex = CParserStarMathString::ParseElement(pReader); + m_pLeftArg = m_pValueIndex; + } + else + { + do { - case TypeElement::lsup: - CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); - break; - case TypeElement::lsub: - CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); - break; - } - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); - break; + pReader->ClearReader(); + switch(m_enTypeIndex) + { + case TypeElement::upper: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pUpperIndex); + break; + case TypeElement::lower: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLowerIndex); + break; + case TypeElement::lsub: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLsubIndex); + break; + case TypeElement::lsup: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pLsupIndex); + break; + case TypeElement::csub: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pCsubIndex); + break; + case TypeElement::csup: + CParserStarMathString::ReadingElementsWithAttributes(pReader,m_pCsupIndex); + break; + } + pReader->ReadingTheNextToken(); + m_enTypeIndex = pReader->GetLocalType(); + }while(GetUpperIndex(pReader->GetLocalType()) || GetLowerIndex(pReader->GetLocalType())); } - case TypeElement::nroot: - case TypeElement::sqrt: + } + void CElementIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(TypeElement::sqrt == m_enTypeIndex || TypeElement::nroot == m_enTypeIndex) { pXmlWrite->WriteNodeBegin(L"m:rad",false); pXmlWrite->WriteNodeBegin(L"m:radPr",false); @@ -1888,176 +1945,369 @@ namespace StarMath } CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueIndex,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:rad",false,false); - break; } - case TypeElement::csub: - case TypeElement::csup: + else if(m_pCsubIndex != nullptr || m_pCsupIndex != nullptr) { - std::wstring wsNameLim; - switch(m_enTypeIndex) + if(m_pCsubIndex != nullptr && m_pCsupIndex != nullptr) { - case TypeElement::csub: - wsNameLim = L"m:limLow"; - break; - case TypeElement::csup: - wsNameLim = L"m:limUpp"; - break; + pXmlWrite->WriteNodeBegin(L"m:limLow",false); + pXmlWrite->WriteNodeBegin(L"m:limLowPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:limLowPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + pXmlWrite->WriteNodeBegin(L"m:limUpp",false); + pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesToValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsupIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsubIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:limLow",false,false); + } + else + { + std::wstring wsNameLim; + if(m_pCsubIndex!= nullptr) + wsNameLim = L"m:limLow"; + else + wsNameLim = L"m:limUpp"; + pXmlWrite->WriteNodeBegin(wsNameLim,false); + pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesToValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + if(m_pCsubIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsubIndex,pXmlWrite); + else + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pCsupIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameLim,false,false); } - pXmlWrite->WriteNodeBegin(wsNameLim,false); - pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); - CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueIndex,pXmlWrite); - pXmlWrite->WriteNodeEnd(wsNameLim,false,false); - break; - } } + else + ConversionOfIndicesToValue(pXmlWrite); +// switch(m_enTypeIndex) +// { +// case TypeElement::upper: +// case TypeElement::lower: +// { +// std::wstring wsNameNodeIndex; +// switch(m_enTypeIndex) +// { +// case TypeElement::upper: +// wsNameNodeIndex = L"m:sSup"; +// break; +// case TypeElement::lower: +// wsNameNodeIndex = L"m:sSub"; +// break; +// } +// pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); +// pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); +// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); +// pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); +// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); +// switch(m_enTypeIndex) +// { +// case TypeElement::upper: +// CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); +// break; +// case TypeElement::lower: +// CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); +// break; +// } +// pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); +// break; +// } +// case TypeElement::lsub: +// case TypeElement::lsup: +// { +// pXmlWrite->WriteNodeBegin(L"m:sPre",false); +// pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); +// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); +// pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); +// switch(m_enTypeIndex) +// { +// case TypeElement::lsup: +// CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); +// break; +// case TypeElement::lsub: +// CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); +// break; +// } +// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); +// pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); +// break; +// } +// case TypeElement::nroot: +// case TypeElement::sqrt: +// { +// pXmlWrite->WriteNodeBegin(L"m:rad",false); +// pXmlWrite->WriteNodeBegin(L"m:radPr",false); +// if(TypeElement::sqrt == m_enTypeIndex) +// { +// pXmlWrite->WriteNodeBegin(L"m:degHide",true); +// pXmlWrite->WriteAttribute(L"m:val",1); +// pXmlWrite->WriteNodeEnd(L"",true,true); +// } +// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); +// pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); +// if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) +// { +// pXmlWrite->WriteNodeBegin(L"m:deg",false); +// m_pLeftArg->ConversionToOOXML(pXmlWrite); +// pXmlWrite->WriteNodeEnd(L"m:deg",false,false); +// } +// else +// { +// pXmlWrite->WriteNodeBegin(L"m:deg",true); +// pXmlWrite->WriteNodeEnd(L"w",true,true); +// } +// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueIndex,pXmlWrite); +// pXmlWrite->WriteNodeEnd(L"m:rad",false,false); +// break; +// } +// case TypeElement::csub: +// case TypeElement::csup: +// { +// std::wstring wsNameLim; +// switch(m_enTypeIndex) +// { +// case TypeElement::csub: +// wsNameLim = L"m:limLow"; +// break; +// case TypeElement::csup: +// wsNameLim = L"m:limUpp"; +// break; +// } +// pXmlWrite->WriteNodeBegin(wsNameLim,false); +// pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); +// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); +// pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); +// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); +// CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueIndex,pXmlWrite); +// pXmlWrite->WriteNodeEnd(wsNameLim,false,false); +// break; +// } +// } } void CElementIndex::SetAttribute(CAttribute *pAttribute) { - SetBaseAttribute(pAttribute); - if(m_pLeftArg != nullptr) + if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() == nullptr && pAttribute != nullptr) m_pLeftArg->SetAttribute(pAttribute); + if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() != nullptr) + SetBaseAttribute(m_pLeftArg->GetAttribute()); +// if(pAttribute!= nullptr) +// SetBaseAttribute(pAttribute); if(m_pValueIndex != nullptr) m_pValueIndex->SetAttribute(pAttribute); + if(m_pLowerIndex != nullptr) + m_pLowerIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pUpperIndex != nullptr) + m_pUpperIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsubIndex != nullptr) + m_pLsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsupIndex != nullptr) + m_pLsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsubIndex != nullptr) + m_pCsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsupIndex != nullptr) + m_pCsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + } + void CElementIndex::ConversionOfIndicesToValue(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pLsubIndex != nullptr || m_pLsupIndex != nullptr) + { + pXmlWrite->WriteNodeBegin(L"m:sPre",false); + pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLsubIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pLsupIndex,pXmlWrite); + pXmlWrite->WriteNodeBegin(L"m:e",false); + ConversionOfIndicesAfterValue(pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); + } + else + ConversionOfIndicesAfterValue(pXmlWrite); } -//class methods CElementFunction - CElementFunction::CElementFunction(const TypeElement &enType, const std::wstring &wsNameFunc) - :CElement(TypeElement::Function), m_pValue(nullptr),m_wsNameFunc(wsNameFunc),m_enTypeFunction(enType) - { - } - CElementFunction::~CElementFunction() - { - delete m_pValue; - } - void CElementFunction::SetValueFunction(CElement *pElement) - { - m_pValue = pElement; - } - CElement* CElementFunction::GetValueFunction() - { - return m_pValue; - } - void CElementFunction::SetNameFunc(const std::wstring &wsNameFunc) - { - m_wsNameFunc = wsNameFunc; - } - std::wstring CElementFunction::GetNameFuncInString() - { - return m_wsNameFunc; - } - void CElementFunction::Parse(CStarMathReader* pReader) + void CElementIndex::ConversionOfIndicesAfterValue(XmlUtils::CXmlWriter *pXmlWrite) { - if(pReader->CheckIteratorPosition()) + if(m_pUpperIndex !=nullptr || m_pLowerIndex != nullptr) { - CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - pReader->ReadingTheNextToken(); - while(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + std::wstring wsNameNodeIndex; + if(m_pUpperIndex != nullptr && m_pLowerIndex != nullptr) + wsNameNodeIndex = L"m:sSubSup"; + else if(m_pLowerIndex != nullptr && m_pUpperIndex == nullptr) + wsNameNodeIndex = L"m:sSub"; + else if(m_pLowerIndex == nullptr && m_pUpperIndex != nullptr) + wsNameNodeIndex = L"m:sSup"; + pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); + pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); + if(m_pUpperIndex!=nullptr && m_pLowerIndex != nullptr) { - CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(pTempElement,pElement); - pTempElement = pElement; - pReader->ReadingTheNextToken(); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); } - SetValueFunction(pTempElement); + else if(m_pLowerIndex!= nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLowerIndex,pXmlWrite); + else if(m_pUpperIndex != nullptr) + CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pUpperIndex,pXmlWrite); + pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); } else - SetValueFunction(nullptr); + m_pLeftArg->ConversionToOOXML(pXmlWrite); } - void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) +//class methods CElementFunction + CElementFunction::CElementFunction(const TypeElement &enType, const std::wstring &wsNameFunc) + :CElement(TypeElement::Function), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) { - pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeBegin(L"m:fName",false); - pXmlWrite->WriteNodeBegin(L"m:r",false); - pXmlWrite->WriteNodeBegin(L"m:rPr",false); - pXmlWrite->WriteNodeBegin(L"m:sty",true); - pXmlWrite->WriteAttribute(L"m:val",L"p"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); - pXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeFunction) { case TypeElement::cos: - pXmlWrite->WriteString(L"cos"); + m_wsNameFunc = L"cos"; break; case TypeElement::sin: - pXmlWrite->WriteString(L"sin"); + m_wsNameFunc = L"sin"; break; case TypeElement::tan: - pXmlWrite->WriteString(L"tan"); + m_wsNameFunc = L"tan"; break; case TypeElement::cot: - pXmlWrite->WriteString(L"cot"); + m_wsNameFunc = L"cot"; break; case TypeElement::sinh: - pXmlWrite->WriteString(L"sinh"); + m_wsNameFunc = L"sinh"; break; case TypeElement::cosh: - pXmlWrite->WriteString(L"cosh"); + m_wsNameFunc = L"cosh"; break; case TypeElement::tanh: - pXmlWrite->WriteString(L"tanh"); + m_wsNameFunc = L"tanh"; break; case TypeElement::coth: - pXmlWrite->WriteString(L"coth"); + m_wsNameFunc = L"coth"; break; case TypeElement::arcsin: - pXmlWrite->WriteString(L"arcsin"); + m_wsNameFunc = L"arcsin"; break; case TypeElement::arccos: - pXmlWrite->WriteString(L"arccos"); + m_wsNameFunc = L"arccos"; break; case TypeElement::arctan: - pXmlWrite->WriteString(L"arctan"); + m_wsNameFunc = L"arctan"; break; case TypeElement::arccot: - pXmlWrite->WriteString(L"arccot"); + m_wsNameFunc = L"arccot"; break; case TypeElement::arsinh: - pXmlWrite->WriteString(L"arsinh"); + m_wsNameFunc = L"arsinh"; break; case TypeElement::arcosh: - pXmlWrite->WriteString(L"arcosh"); + m_wsNameFunc = L"arcosh"; break; case TypeElement::artanh: - pXmlWrite->WriteString(L"artanh"); + m_wsNameFunc = L"artanh"; break; case TypeElement::arcoth: - pXmlWrite->WriteString(L"arcoth"); + m_wsNameFunc = L"arcoth"; break; case TypeElement::log: - pXmlWrite->WriteString(L"log"); + m_wsNameFunc = L"log"; break; case TypeElement::ln: - pXmlWrite->WriteString(L"ln"); + m_wsNameFunc = L"ln"; break; case TypeElement::exp: - pXmlWrite->WriteString(L"exp"); + m_wsNameFunc = L"exp"; break; case TypeElement::func: { - if(!m_wsNameFunc.empty()) - pXmlWrite->WriteString(GetNameFuncInString()); + m_wsNameFunc = wsNameFunc; break; } default: break; } - pXmlWrite->WriteNodeEnd(L"m:t",false,false); - pXmlWrite->WriteNodeEnd(L"m:r",false,false); - pXmlWrite->WriteNodeEnd(L"m:fName",false,false); - if(m_pValue!=nullptr) + } + CElementFunction::~CElementFunction() + { + delete m_pValue; + delete m_pIndex; + } + void CElementFunction::SetValueFunction(CElement *pElement) + { + m_pValue = pElement; + } + CElement* CElementFunction::GetValueFunction() + { + return m_pValue; + } + void CElementFunction::SetNameFunc(const std::wstring &wsNameFunc) + { + m_wsNameFunc = wsNameFunc; + } + std::wstring CElementFunction::GetNameFuncInString() + { + return m_wsNameFunc; + } + void CElementFunction::Parse(CStarMathReader* pReader) + { + pReader->ReadingTheNextToken(); + if(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) { - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); + m_pIndex = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc),m_pIndex); + return ; } + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(CParserStarMathString::CheckForLeftArgument(pReader->GetGlobalType())) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + SetValueFunction(pTempElement); + } + void CElementFunction::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + if(m_pIndex !=nullptr) + m_pIndex->ConversionToOOXML(pXmlWrite); else { - pXmlWrite->WriteNodeBegin(L"m:e",true); - pXmlWrite->WriteNodeEnd(L"",true,true); + pXmlWrite->WriteNodeBegin(L"m:func",false); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:fName",false); + pXmlWrite->WriteNodeBegin(L"m:r",false); + pXmlWrite->WriteNodeBegin(L"m:rPr",false); + pXmlWrite->WriteNodeBegin(L"m:sty",true); + pXmlWrite->WriteAttribute(L"m:val",L"p"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + pXmlWrite->WriteNodeBegin(L"m:t",false); + if(!m_wsNameFunc.empty()) + pXmlWrite->WriteString(m_wsNameFunc); + pXmlWrite->WriteNodeEnd(L"m:t",false,false); + pXmlWrite->WriteNodeEnd(L"m:r",false,false); + pXmlWrite->WriteNodeEnd(L"m:fName",false,false); + if(m_pValue!=nullptr) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); + } + else + { + pXmlWrite->WriteNodeBegin(L"m:e",true); + pXmlWrite->WriteNodeEnd(L"",true,true); + } + pXmlWrite->WriteNodeEnd(L"m:func",false,false); } - pXmlWrite->WriteNodeEnd(L"m:func",false,false); } TypeElement CElementFunction::GetFunction(const std::wstring &wsToken) { @@ -2099,6 +2349,8 @@ namespace StarMath delete m_pValueOperator; delete m_pValueFrom; delete m_pValueTo; + delete m_pLowerIndex; + delete m_pUpperIndex; } void CElementOperator::SetValueOperator(CElement *pElement) { @@ -2182,7 +2434,6 @@ namespace StarMath pReader->ClearReader(); SetToValue(CParserStarMathString::ReadingWithoutBracket(pReader)); } -// SetValueOperator(CParserStarMathString::ParseElement(pReader)); m_pValueOperator = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); while(pReader->GetGlobalType() == TypeElement::Index) @@ -2601,7 +2852,12 @@ namespace StarMath } void CElementBracketWithIndex::Parse(CStarMathReader *pReader) { - SetBracketValue(CParserStarMathString::ParseElement(pReader)); + m_pValue = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,m_pValue); + } } void CElementBracketWithIndex::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { @@ -2706,18 +2962,18 @@ namespace StarMath } void CElementGrade::Parse(CStarMathReader *pReader) { - SetValueGrade(CParserStarMathString::ParseElement(pReader)); + m_pValueGrade = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); if(pReader->GetLocalType() == TypeElement::from) { pReader->ClearReader(); - SetValueFrom(CParserStarMathString::ParseElement(pReader)); + m_pValueFrom = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); } if(pReader->GetLocalType() == TypeElement::to) { pReader->ClearReader(); - SetValueTo(CParserStarMathString::ParseElement(pReader)); + m_pValueTo = CParserStarMathString::ParseElement(pReader); } if(GetAttribute() != nullptr) SetAttribute(GetAttribute()); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 907b12cad6b..f1608b93d0a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -162,7 +162,15 @@ namespace StarMath void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + void ConversionOfIndicesToValue(XmlUtils::CXmlWriter* pXmlWrite); + void ConversionOfIndicesAfterValue(XmlUtils::CXmlWriter* pXmlWrite); CElement* m_pValueIndex; + CElement* m_pUpperIndex; + CElement* m_pLowerIndex; + CElement* m_pLsubIndex; + CElement* m_pLsupIndex; + CElement* m_pCsubIndex; + CElement* m_pCsupIndex; CElement* m_pLeftArg; TypeElement m_enTypeIndex; }; @@ -265,7 +273,8 @@ namespace StarMath private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; - void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override;// + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + bool CheckMline(CElement* pElement); TypeElement m_enTypeBracket; std::vector m_arBrecketValue; }; @@ -341,6 +350,7 @@ namespace StarMath void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; CElement* m_pValue; + CElement* m_pIndex; std::wstring m_wsNameFunc; TypeElement m_enTypeFunction; }; @@ -410,6 +420,8 @@ namespace StarMath static void AddingAnElementToAnArray(std::vector& arrEquation,CElement* pAddElement); //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); + // + static void ReadingElementsWithAttributes(CStarMathReader* pReader,CElement*& pSavingElement); void SetAlignment(const unsigned int& iAlignment); const unsigned int& GetAlignment(); private: From 110617547c5ae44d0a20b9073b720d099a04eb8a Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 15 Mar 2024 15:48:02 +0300 Subject: [PATCH 486/794] improvements to attribute parsing (cherry picked from commit 7776f15a359951b9d61ed0b1f5041f1b482e5605) --- .../StarMath2OOXML/cstarmathpars.cpp | 236 ++++++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 15 +- 2 files changed, 171 insertions(+), 80 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 6666b40927a..3a9c7f986b5 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -224,7 +224,7 @@ namespace StarMath return m_iAlignment; } //class methods CAttribute - CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(-1) + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(0) { } CAttribute::~CAttribute() @@ -253,112 +253,113 @@ namespace StarMath { m_bStrike = true; } - void CAttribute::SetColor(const TypeElement &enColor) + bool CAttribute::SetColor(const TypeElement &enColor) { if(enColor != TypeElement::undefine) { switch (enColor) { case TypeElement::black: m_wsColor = L"000000"; - break; + return true; case TypeElement::blue: m_wsColor = L"0400ff"; - break; + return true; case TypeElement::green: m_wsColor =L"00FF00"; - break; + return true; case TypeElement::red: m_wsColor =L"FF0000"; - break; + return true; case TypeElement::fuchsia: m_wsColor =L"ED0DD9"; - break; + return true; case TypeElement::aqua: m_wsColor =L"30D5C8"; - break; + return true; case TypeElement::yellow: m_wsColor =L"FFFF00"; - break; + return true; case TypeElement::gray: m_wsColor =L"808080"; - break; + return true; case TypeElement::lime: m_wsColor =L"00FF00"; - break; + return true; case TypeElement::maroon: m_wsColor =L"800000"; - break; + return true; case TypeElement::navy: m_wsColor =L"000080"; - break; + return true; case TypeElement::olive: m_wsColor =L"808000"; - break; + return true; case TypeElement::purple: m_wsColor =L"800080"; - break; + return true; case TypeElement::silver: m_wsColor =L"C0C0C0"; - break; + return true; case TypeElement::teal: m_wsColor =L"008080"; - break; + return true; case TypeElement::coral: m_wsColor =L"FF7F50"; - break; + return true; case TypeElement::midnightblue: m_wsColor =L"191970"; - break; + return true; case TypeElement::crimson: m_wsColor =L"DC143C"; - break; + return true; case TypeElement::violet: m_wsColor =L"EE82EE"; - break; + return true; case TypeElement::orange: m_wsColor =L"FFA500"; - break; + return true; case TypeElement::orangered: m_wsColor =L"FF4500"; - break; + return true; case TypeElement::seagreen: m_wsColor =L"2E8B57"; - break; + return true; case TypeElement::indigo: m_wsColor =L"4B0082"; - break; + return true; case TypeElement::hotpink: m_wsColor =L"FF69B4"; - break; + return true; case TypeElement::lavender: m_wsColor =L"FFF0F5"; - break; + return true; default: - break; + return false; } } + else return false; } void CAttribute::SetColor(const std::wstring &wsColor) { m_wsColor = wsColor; } - void CAttribute::SetFont(const TypeElement &enFont) + bool CAttribute::SetFont(const TypeElement &enFont) { switch (enFont) { case TypeElement::ital: - SetItal(); - break; + m_bItal = true; + return true; case TypeElement::bold: - SetBold(); - break; + m_bBold = true; + return true; case TypeElement::phantom: - SetPhantom(); - break; + m_bPhantom = true; + return true; case TypeElement::overstrike: - SetStrike(); - break; + m_bStrike = true; + return true; default: - break; + return false; } } void CAttribute::SetFontName(const std::wstring &wsNameFont) @@ -401,32 +402,62 @@ namespace StarMath { return m_wsColor.empty(); } - void CAttribute::ParseColorAttribute(const std::wstring &wsToken,CStarMathReader* pReader) + //hex current + bool CAttribute::ParseColorAttribute(const std::wstring &wsToken,CStarMathReader* pReader) { TypeElement enTempColor = GetTypeColorAttribute(wsToken); switch(enTempColor) { case TypeElement::hex: { - std::wstring wsTempHex; - do + pReader->SetString(L""); + std::wstring wsTempToken; + wsTempToken = pReader->TakingElementForHex(); + if(wsTempToken.empty()) + return false; + if(!m_wsColor.empty()) + m_wsColor.clear(); + if(wsTempToken.size()< 6) { - wsTempHex += pReader->GetElement(); - }while(wsTempHex.size()< 6); - m_wsColor = wsTempHex; - break; + int iZero = 6 - wsTempToken.size(); + for(int i = 0;i 6) + { + m_wsColor += wsTempToken.substr(wsTempToken.size()-6); + return true; + } } case TypeElement::rgb: { const int iTempLen = 7; wchar_t arTemp[iTempLen]; unsigned int wsRed,wsGreen,wsBlue; - pReader->GetToken(); - wsRed = std::stoi(pReader->GetString()); - pReader->GetToken(); - wsGreen = std::stoi(pReader->GetString()); - pReader->GetToken(); - wsBlue = std::stoi(pReader->GetString()); + pReader->SetString(pReader->GetElement()); + if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) + wsRed = std::stoi(pReader->GetString()); + else + return false; + if(wsRed > 255 || wsRed < 0) + return false; + pReader->SetString(pReader->GetElement()); + if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) + wsGreen = std::stoi(pReader->GetString()); + else + return false; + pReader->SetString(pReader->GetElement()); + if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) + wsBlue = std::stoi(pReader->GetString()); + else + return false; if(wsRed > 255 || wsGreen > 255 || wsBlue > 255) m_wsColor = L"000000"; else @@ -434,30 +465,36 @@ namespace StarMath swprintf(arTemp,iTempLen,L"%02X%02X%02X",wsRed,wsGreen,wsBlue); m_wsColor = std::wstring(arTemp,6); } - break; + return true; } default: - SetColor(enTempColor); - break; + return(SetColor(enTempColor)); } } - void CAttribute::ParseFontAttribute(const TypeElement& enTypeFont, CStarMathReader *pReader) + bool CAttribute::ParseFontAttribute(const TypeElement& enTypeFont, CStarMathReader *pReader) { switch(enTypeFont) { case TypeElement::size: { - pReader->GetToken(); - int iTemp = std::stoi(pReader->GetString()); - if (iTemp >= 0) + std::wstring wsSize = pReader->GetElement(); + int iTemp; + if(CElementString::GetDigit(wsSize) != TypeElement::undefine) + iTemp = std::stoi(wsSize); + else + { + pReader->SetString(wsSize); + return false; + } + if (iTemp > 0) m_iSize = iTemp*2; else m_iSize = 24; - break; + return true; } case TypeElement::font: { - pReader->GetToken(); + pReader->SetString(pReader->GetElement()); if(pReader->GetString() == L"sans") m_wsNameFont = L"Liberation Sans"; else if(pReader->GetString() == L"serif") @@ -465,24 +502,23 @@ namespace StarMath else if(pReader->GetString() == L"fixed") m_wsNameFont = L"Liberation Mono"; else - m_wsNameFont = pReader->GetString(); - break; + return false; +// m_wsNameFont = pReader->GetString(); + return true; } case TypeElement::alignl: case TypeElement::alignr: case TypeElement::alignc: - break; + return true; default: - SetFont(enTypeFont); - break; + return SetFont(enTypeFont); } } //нет phantom, rgb, 16 , гарнитуры и кегля TypeElement CAttribute::GetTypeColorAttribute(const std::wstring &wsToken) { - if(L"color" == wsToken) return TypeElement::color; - else if(L"hex"==wsToken) return TypeElement::hex; + if(L"hex"==wsToken) return TypeElement::hex; else if(L"rgb" == wsToken) return TypeElement::rgb; else if(L"black" == wsToken) return TypeElement::black; else if(L"green" == wsToken) return TypeElement::green; @@ -524,6 +560,29 @@ namespace StarMath else if(L"alignc" == wsToken) return TypeElement::alignc; else return TypeElement::undefine; } + bool CAttribute::CheckHexPosition(const wchar_t &cToken) + { + if(isdigit(cToken)) + return true; + if( L'A' == cToken) return true; + else if(L'B' == cToken) return true; + else if(L'C' == cToken) return true; + else if(L'D' == cToken) return true; + else if(L'E' == cToken) return true; + else if(L'F' == cToken) return true; + else + return false; + } + bool CAttribute::CheckAttribute() + { + if(m_bBold == true || m_bItal == true || m_bStrike == true || m_bPhantom == true) + return true; + else if(!m_wsColor.empty() || !m_wsNameFont.empty()) + return true; + else if(m_iSize != 0 || (m_iAlignment == 1 || m_iAlignment == 2)) + return true; + return false; + } //class methods CElement CElement::~CElement() { @@ -2536,21 +2595,30 @@ namespace StarMath if(CheckIteratorPosition()) { m_wsToken = GetElement(); - TypeElement enTypeFont =CAttribute::GetTypeFontAttribute(m_wsToken),enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); - if(enTypeFont != TypeElement::undefine || enTypeColor != TypeElement::undefine) + TypeElement enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); + if(enTypeFont != TypeElement::undefine || L"color" == m_wsToken) m_pAttribute = new CAttribute(); - while((enTypeFont != TypeElement::undefine || enTypeColor != TypeElement::undefine) && m_itStart != m_itEnd) + while((enTypeFont != TypeElement::undefine || L"color" == m_wsToken) && m_itStart != m_itEnd) { - if(enTypeColor == TypeElement::color) m_pAttribute->ParseColorAttribute(GetElement(),this); - else if(enTypeFont != TypeElement::undefine) m_pAttribute->ParseFontAttribute(enTypeFont,this); - - if(m_itStart != m_itEnd) + if(L"color" == m_wsToken) + { + m_wsToken = GetElement(); + if(m_pAttribute->ParseColorAttribute(m_wsToken,this)) + m_wsToken.clear(); + } + else if(enTypeFont != TypeElement::undefine) + if(m_pAttribute->ParseFontAttribute(enTypeFont,this)) + m_wsToken.clear(); + else + enTypeFont = TypeElement::undefine; + if((m_itStart != m_itEnd) && m_wsToken.empty()) { m_wsToken = GetElement(); - enTypeColor = CAttribute::GetTypeColorAttribute(m_wsToken); enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); } } + if(m_pAttribute != nullptr && !m_pAttribute->CheckAttribute()) + m_pAttribute = nullptr; if(m_wsToken == L"left") m_wsToken = GetElement(); else if(L"right" == m_wsToken ) m_wsToken = GetElement(); } @@ -2741,6 +2809,24 @@ namespace StarMath if(!m_wsElement.empty()) return m_wsElement; else return {}; } + std::wstring CStarMathReader::TakingElementForHex() + { + std::wstring wsTokenHex{}; + for(;m_itStart != m_itEnd;m_itStart++) + { + if(iswspace(*m_itStart)) + return wsTokenHex; + else if(CAttribute::CheckHexPosition(*m_itStart)) + wsTokenHex.push_back(*m_itStart); + else + return wsTokenHex; + } + return wsTokenHex; + } + void CStarMathReader::SetString(const std::wstring &wsToken) + { + m_wsToken = wsToken; + } void CStarMathReader::FindingTheEndOfParentheses() { std::wstring::iterator itStart = m_itStart,itStartBracketClose; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f1608b93d0a..94904c356bd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -69,18 +69,21 @@ namespace StarMath std::wstring GetColor(); const std::wstring& GetFontName(); bool EmptyColor(); - void ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); - void ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); + bool ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); + bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); void SetSize(const unsigned int& iSize); void SetAlignment(const unsigned int& iAlignment); void SetBold(); void SetItal(); void SetPhantom(); void SetStrike(); - void SetColor(const TypeElement& enColor); + bool SetColor(const TypeElement& enColor); void SetColor(const std::wstring& wsColor); - void SetFont(const TypeElement& enFont); + bool SetFont(const TypeElement& enFont); void SetFontName(const std::wstring& wsNameFont); + bool CheckAttribute(); + // + static bool CheckHexPosition(const wchar_t& cToken); private: std::wstring m_wsColor,m_wsNameFont; bool m_bBold,m_bItal,m_bPhantom,m_bStrike; @@ -109,6 +112,8 @@ namespace StarMath CAttribute* GetBaseAttribute(); //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); + std::wstring TakingElementForHex(); + void SetString(const std::wstring& wsToken); void FindingTheEndOfParentheses(); void IteratorNullification(); void ReadingTheNextToken(); @@ -420,7 +425,7 @@ namespace StarMath static void AddingAnElementToAnArray(std::vector& arrEquation,CElement* pAddElement); //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); - // + //method for parsing indexes with attributes. If there is an attribute present when indexes are read, then all subsequent indexes are applied to the index with the attribute. static void ReadingElementsWithAttributes(CStarMathReader* pReader,CElement*& pSavingElement); void SetAlignment(const unsigned int& iAlignment); const unsigned int& GetAlignment(); From 2b72bf3f531862e150705141ea68629be8a8149e Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Wed, 27 Mar 2024 14:47:52 +0300 Subject: [PATCH 487/794] Fix bugs (correction of indexes, without elements between them, editing of frac and binom) (cherry picked from commit 43bee348aa87d797457b58855eb9d843195e904d) --- .../StarMath2OOXML/TestSMConverter/main.cpp | 90 ++++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 54 ++-- .../StarMath2OOXML/cstarmathpars.cpp | 293 +++++++++--------- .../Converter/StarMath2OOXML/cstarmathpars.h | 15 +- .../Converter/oox_conversion_context.cpp | 3 +- 5 files changed, 274 insertions(+), 181 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 40e3d171312..75ec83fbc74 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1204,6 +1204,96 @@ TEST(SMConvectorTest,FunctionWithColor) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,IncorrectSizeAndFontInput) +{ + std::wstring wsString = L"size font bolt ital 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"bolt2"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IncorrectRGBColorInput) +{ + std::wstring wsString = L"color rgb 255 0 257 2 color rgb 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2550257210"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IncorrectHexColorInput) +{ + std::wstring wsString = L"color hex 161616FF RGB color hex 66 RGB color hex RGB color hex FFAACCFF RGB color hex 99112288FF0000 RGB "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,IndexWithoutElement) +{ + std::wstring wsString = L"2^_3 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"23"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Neg) +{ + std::wstring wsString = L"-1 neg 10 over 5 or 7"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"-1\u00AC105\u22287"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Frac) +{ + std::wstring wsString = L"sum_{n=1}^{ infty} frac{1}{n^2} + frac{1}{n^3} = frac{ pi^2}{6} + zeta(3)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,BracketIndexOnTopAndOperationOnSet) +{ + std::wstring wsString = L"3 + 10 over 5 setminus 1 overbrace 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"3+105\u221612"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,SqrtWithIndex) +{ + std::wstring wsString = L"sqrt{2}^{ log_2{8}} = 4"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2log28=4"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Binom) +{ + std::wstring wsString = L"binom 2 = 4 3 binom 2+1abc 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2=432+1abc5"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 40b3a52638d..e056cbb293a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -40,32 +40,32 @@ namespace StarMath { void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; - m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); - if(iAlignment>= 0 && iAlignment <= 2) - { - std::wstring wsAlignment; - switch(iAlignment) - { - case 0: - wsAlignment = L"center"; - break; - case 1: - wsAlignment = L"left"; - break; - case 2: - wsAlignment = L"right"; - break; - default: - wsAlignment = L"center"; - break; - } - m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); - m_pXmlWrite->WriteNodeBegin(L"m:jc",true); - m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); - m_pXmlWrite->WriteNodeEnd(L"",true,true); - m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); - } - m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); +// m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); +// if(iAlignment>= 0 && iAlignment <= 2) +// { +// std::wstring wsAlignment; +// switch(iAlignment) +// { +// case 0: +// wsAlignment = L"center"; +// break; +// case 1: +// wsAlignment = L"left"; +// break; +// case 2: +// wsAlignment = L"right"; +// break; +// default: +// wsAlignment = L"center"; +// break; +// } +// m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); +// m_pXmlWrite->WriteNodeBegin(L"m:jc",true); +// m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); +// m_pXmlWrite->WriteNodeEnd(L"",true,true); +// m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); +// } +// m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); for(CElement* oTempElement:arPars) { if(oTempElement != nullptr) @@ -83,7 +83,7 @@ namespace StarMath { oTempElement->ConversionToOOXML(m_pXmlWrite); } } - EndConversion(); +// EndConversion(); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 3a9c7f986b5..5836af722c6 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -114,7 +114,11 @@ namespace StarMath { case TypeElement::BinOperator: { - return SetLeft(pLeftArg, pElementWhichAdd); + CElementBinOperator* pBinOp = dynamic_cast(pElementWhichAdd); + if(pBinOp->GetType() == TypeElement::neg) + return false; + else + return SetLeft(pLeftArg, pElementWhichAdd); } case TypeElement::SetOperations: { @@ -139,26 +143,27 @@ namespace StarMath else return false; } - CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader) + CElement* CParserStarMathString::ReadingWithoutBracket(CStarMathReader *pReader, const bool& bConnection) { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while(CheckForLeftArgument(pReader->GetGlobalType()) && (pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) + while(CheckForLeftArgument(pReader->GetGlobalType(),bConnection) && (pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pFirstTempElement); } return pFirstTempElement; } - bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType) + bool CParserStarMathString::CheckForLeftArgument(const TypeElement &enType,const bool& bConnection) { switch(enType) { case TypeElement::BinOperator: - case TypeElement::Connection: case TypeElement::SetOperations: case TypeElement::BracketWithIndex: case TypeElement::Index: return true; + case TypeElement::Connection: + return bConnection; default: return false; } @@ -438,31 +443,56 @@ namespace StarMath } case TypeElement::rgb: { + pReader->SetString(L""); const int iTempLen = 7; wchar_t arTemp[iTempLen]; - unsigned int wsRed,wsGreen,wsBlue; - pReader->SetString(pReader->GetElement()); - if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) - wsRed = std::stoi(pReader->GetString()); - else + int iRed(-1),iGreen(-1),iBlue(-1); + iRed = pReader->TakingElementForRGB(); + if(iRed == -1) return false; - if(wsRed > 255 || wsRed < 0) - return false; - pReader->SetString(pReader->GetElement()); - if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) - wsGreen = std::stoi(pReader->GetString()); - else + iGreen = pReader->TakingElementForRGB(); + if(iGreen == -1) + { + RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); return false; - pReader->SetString(pReader->GetElement()); - if(TypeElement::undefine != CElementString::GetDigit(pReader->GetString())) - wsBlue = std::stoi(pReader->GetString()); - else + } + iBlue = pReader->TakingElementForRGB(); + if(iBlue == -1) + { + RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); return false; - if(wsRed > 255 || wsGreen > 255 || wsBlue > 255) + } +// std::wstring wsColorNumber = pReader->GetElement(); +// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) +// iRed = std::stoi(wsColorNumber); +// else +// { +// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); +// return false; +// } +// if(iRed > 255 || iRed < 0) +// return false; +// wsColorNumber = pReader->GetElement(); +// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) +// iGreen = std::stoi(wsColorNumber); +// else +// { +// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); +// return false; +// } +// wsColorNumber = pReader->GetElement(); +// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) +// iBlue = std::stoi(wsColorNumber); +// else +// { +// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); +// return false; +// } + if(iRed > 255 || iGreen > 255 || iBlue > 255) m_wsColor = L"000000"; else { - swprintf(arTemp,iTempLen,L"%02X%02X%02X",wsRed,wsGreen,wsBlue); + swprintf(arTemp,iTempLen,L"%02X%02X%02X",iRed,iGreen,iBlue); m_wsColor = std::wstring(arTemp,6); } return true; @@ -478,15 +508,15 @@ namespace StarMath case TypeElement::size: { std::wstring wsSize = pReader->GetElement(); + pReader->SetString(wsSize); int iTemp; if(CElementString::GetDigit(wsSize) != TypeElement::undefine) iTemp = std::stoi(wsSize); else { - pReader->SetString(wsSize); return false; } - if (iTemp > 0) + if (iTemp > 0 && iTemp < 127) m_iSize = iTemp*2; else m_iSize = 24; @@ -503,7 +533,6 @@ namespace StarMath m_wsNameFont = L"Liberation Mono"; else return false; -// m_wsNameFont = pReader->GetString(); return true; } case TypeElement::alignl: @@ -583,6 +612,17 @@ namespace StarMath return true; return false; } + void CAttribute::RefundOfTheAmountRGB(CStarMathReader *pReader, const int &iRed, const int &iGreen, const int &iBlue) + { + std::wstring wsSum; + if(iRed != -1) + wsSum += std::to_wstring(iRed); + if(iGreen != -1) + wsSum += std::to_wstring(iGreen); + if(iBlue != -1) + wsSum += std::to_wstring(iBlue); + pReader->SetString(wsSum); + } //class methods CElement CElement::~CElement() { @@ -748,10 +788,10 @@ namespace StarMath { if(m_enTypeBinOp == TypeElement::frac) { - SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader)); - SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); } - else if(m_enTypeBinOp == TypeElement::And || m_enTypeBinOp == TypeElement::neg) + else if(m_enTypeBinOp == TypeElement::neg) SetRightArg(CParserStarMathString::ParseElement(pReader)); else if(pReader->GetMarkForUnar() && MixedOperators(m_enTypeBinOp)) { @@ -762,7 +802,7 @@ namespace StarMath pReader->SetMarkForUnar(true); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((IsBinOperatorLowPrior() && pReader->GetGlobalType() == TypeElement::BinOperator) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) + while((IsBinOperatorLowPrior() && (pReader->GetGlobalType() == TypeElement::BinOperator || pReader->GetLocalType() == TypeElement::intersection || pReader->GetLocalType() == TypeElement::setminus || pReader->GetLocalType() == TypeElement::setquotient)) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType() != TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } @@ -835,6 +875,9 @@ namespace StarMath case TypeElement::And: pXmlWrite->WriteString(L"\u2227"); break; + case TypeElement::neg: + pXmlWrite->WriteString(L"\u00AC"); + break; default: break; } @@ -882,6 +925,7 @@ namespace StarMath else if(L"neg" == wsToken) return TypeElement::neg; else if(L"or" == wsToken) return TypeElement::Or; else if(L"and" == wsToken) return TypeElement::And; + else if(L"&" == wsToken) return TypeElement::And; else return TypeElement::undefine; } bool CElementBinOperator::MixedOperators(const TypeElement &enType) @@ -936,6 +980,10 @@ namespace StarMath { return m_pRightArgument; } + const TypeElement& CElementBinOperator::GetType() + { + return m_enTypeBinOp; + } //class methods CElementBracket CElementBracket::CElementBracket(const TypeElement& enType) :CElement(TypeElement::Bracket),m_enTypeBracket(enType) @@ -1108,6 +1156,7 @@ namespace StarMath else if(L"setR" == wsToken) return TypeElement::setR; else if(L"setc" == wsToken) return TypeElement::setC; else if(L"infinity" == wsToken) return TypeElement::infinity; + else if(L"infty" == wsToken) return TypeElement::infinity; else if(L"fact" == wsToken) return TypeElement::fact; else if(L"abs" == wsToken) return TypeElement::abs; else if(L"`" == wsToken) return TypeElement::interval; @@ -1564,7 +1613,7 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) + while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || (pReader->GetGlobalType() == TypeElement::BracketWithIndex && !(TypeElement::intersection == m_enTypeSet || TypeElement::setminus == m_enTypeSet || TypeElement::setquotient == m_enTypeSet)) || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } @@ -1657,6 +1706,10 @@ namespace StarMath if(m_pRightArgument != nullptr) m_pRightArgument->SetAttribute(pAttribute); } + const TypeElement& CElementSetOperations::GetType() + { + return m_enTypeSet; + } //class methods CElementConnection CElementConnection::CElementConnection(const TypeElement& enType) :CElement(TypeElement::Connection),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) @@ -1851,6 +1904,10 @@ namespace StarMath if(m_pRightArgument != nullptr) m_pRightArgument->SetAttribute(pAttribute); } + const TypeElement& CElementConnection::GetType() + { + return m_enTypeCon; + } //class methods CIndex CElementIndex::CElementIndex(const TypeElement& enType) : CElement(TypeElement::Index),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) @@ -1944,6 +2001,13 @@ namespace StarMath else if(m_enTypeIndex == TypeElement::sqrt) { m_pValueIndex = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) + { + CElement* pElement = CParserStarMathString::ParseElement(pReader); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement); + m_pValueIndex = pElement; + } m_pLeftArg = m_pValueIndex; } else @@ -2050,109 +2114,6 @@ namespace StarMath } else ConversionOfIndicesToValue(pXmlWrite); -// switch(m_enTypeIndex) -// { -// case TypeElement::upper: -// case TypeElement::lower: -// { -// std::wstring wsNameNodeIndex; -// switch(m_enTypeIndex) -// { -// case TypeElement::upper: -// wsNameNodeIndex = L"m:sSup"; -// break; -// case TypeElement::lower: -// wsNameNodeIndex = L"m:sSub"; -// break; -// } -// pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); -// pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); -// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); -// pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); -// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); -// switch(m_enTypeIndex) -// { -// case TypeElement::upper: -// CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); -// break; -// case TypeElement::lower: -// CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); -// break; -// } -// pXmlWrite->WriteNodeEnd(wsNameNodeIndex,false,false); -// break; -// } -// case TypeElement::lsub: -// case TypeElement::lsup: -// { -// pXmlWrite->WriteNodeBegin(L"m:sPre",false); -// pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); -// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); -// pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); -// switch(m_enTypeIndex) -// { -// case TypeElement::lsup: -// CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pValueIndex,pXmlWrite); -// break; -// case TypeElement::lsub: -// CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pValueIndex,pXmlWrite); -// break; -// } -// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); -// pXmlWrite->WriteNodeEnd(L"m:sPre",false,false); -// break; -// } -// case TypeElement::nroot: -// case TypeElement::sqrt: -// { -// pXmlWrite->WriteNodeBegin(L"m:rad",false); -// pXmlWrite->WriteNodeBegin(L"m:radPr",false); -// if(TypeElement::sqrt == m_enTypeIndex) -// { -// pXmlWrite->WriteNodeBegin(L"m:degHide",true); -// pXmlWrite->WriteAttribute(L"m:val",1); -// pXmlWrite->WriteNodeEnd(L"",true,true); -// } -// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); -// pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); -// if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) -// { -// pXmlWrite->WriteNodeBegin(L"m:deg",false); -// m_pLeftArg->ConversionToOOXML(pXmlWrite); -// pXmlWrite->WriteNodeEnd(L"m:deg",false,false); -// } -// else -// { -// pXmlWrite->WriteNodeBegin(L"m:deg",true); -// pXmlWrite->WriteNodeEnd(L"w",true,true); -// } -// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueIndex,pXmlWrite); -// pXmlWrite->WriteNodeEnd(L"m:rad",false,false); -// break; -// } -// case TypeElement::csub: -// case TypeElement::csup: -// { -// std::wstring wsNameLim; -// switch(m_enTypeIndex) -// { -// case TypeElement::csub: -// wsNameLim = L"m:limLow"; -// break; -// case TypeElement::csup: -// wsNameLim = L"m:limUpp"; -// break; -// } -// pXmlWrite->WriteNodeBegin(wsNameLim,false); -// pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); -// CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); -// pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); -// CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); -// CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValueIndex,pXmlWrite); -// pXmlWrite->WriteNodeEnd(wsNameLim,false,false); -// break; -// } -// } } void CElementIndex::SetAttribute(CAttribute *pAttribute) { @@ -2160,22 +2121,23 @@ namespace StarMath m_pLeftArg->SetAttribute(pAttribute); if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() != nullptr) SetBaseAttribute(m_pLeftArg->GetAttribute()); -// if(pAttribute!= nullptr) -// SetBaseAttribute(pAttribute); if(m_pValueIndex != nullptr) m_pValueIndex->SetAttribute(pAttribute); - if(m_pLowerIndex != nullptr) - m_pLowerIndex->SetAttribute(m_pLeftArg->GetAttribute()); - if(m_pUpperIndex != nullptr) - m_pUpperIndex->SetAttribute(m_pLeftArg->GetAttribute()); - if(m_pLsubIndex != nullptr) - m_pLsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); - if(m_pLsupIndex != nullptr) - m_pLsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); - if(m_pCsubIndex != nullptr) - m_pCsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); - if(m_pCsupIndex != nullptr) - m_pCsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLeftArg != nullptr) + { + if(m_pLowerIndex != nullptr) + m_pLowerIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pUpperIndex != nullptr) + m_pUpperIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsubIndex != nullptr) + m_pLsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pLsupIndex != nullptr) + m_pLsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsubIndex != nullptr) + m_pCsubIndex->SetAttribute(m_pLeftArg->GetAttribute()); + if(m_pCsupIndex != nullptr) + m_pCsupIndex->SetAttribute(m_pLeftArg->GetAttribute()); + } } void CElementIndex::ConversionOfIndicesToValue(XmlUtils::CXmlWriter *pXmlWrite) { @@ -2225,6 +2187,10 @@ namespace StarMath else m_pLeftArg->ConversionToOOXML(pXmlWrite); } + const TypeElement& CElementIndex::GetType() + { + return m_enTypeIndex; + } //class methods CElementFunction CElementFunction::CElementFunction(const TypeElement &enType, const std::wstring &wsNameFunc) :CElement(TypeElement::Function), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) @@ -2610,7 +2576,7 @@ namespace StarMath if(m_pAttribute->ParseFontAttribute(enTypeFont,this)) m_wsToken.clear(); else - enTypeFont = TypeElement::undefine; + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); if((m_itStart != m_itEnd) && m_wsToken.empty()) { m_wsToken = GetElement(); @@ -2823,6 +2789,29 @@ namespace StarMath } return wsTokenHex; } + int CStarMathReader::TakingElementForRGB() + { + int iTokenRGB{-1}; + std::wstring wsToken; + std::wstring::iterator itTempStart = m_itStart; + wsToken = GetElement(); + if(CElementString::GetDigit(wsToken) != TypeElement::undefine) + { + iTokenRGB = std::stoi(wsToken); + if(iTokenRGB >= 0 && iTokenRGB<256) + return iTokenRGB; + else + { + m_itStart = itTempStart; + return -1; + } + } + else + { + m_itStart = itTempStart; + return -1; + } + } void CStarMathReader::SetString(const std::wstring &wsToken) { m_wsToken = wsToken; @@ -3023,6 +3012,10 @@ namespace StarMath if(m_pLeftArg != nullptr) m_pLeftArg->SetAttribute(pAttribute); } + const TypeElement& CElementBracketWithIndex::GetType() + { + return m_enTypeBracketWithIndex; + } //class methods CElementGrade CElementGrade::CElementGrade() :CElement(TypeElement::Grade),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) @@ -3149,8 +3142,8 @@ namespace StarMath { if(m_enTypeMatrix == TypeElement::binom) { - SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); - SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader)); + SetFirstArgument(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + SetSecondArgument(CParserStarMathString::ReadingWithoutBracket(pReader,false)); } else { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 94904c356bd..38393a1e268 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -82,9 +82,10 @@ namespace StarMath bool SetFont(const TypeElement& enFont); void SetFontName(const std::wstring& wsNameFont); bool CheckAttribute(); - // + //checking an element for a number from 1 to 9 or from the letter A to F static bool CheckHexPosition(const wchar_t& cToken); private: + void RefundOfTheAmountRGB(CStarMathReader* pReader,const int& iRed, const int& iGreen, const int& iBlue); std::wstring m_wsColor,m_wsNameFont; bool m_bBold,m_bItal,m_bPhantom,m_bStrike; unsigned int m_iSize,m_iAlignment; @@ -112,7 +113,10 @@ namespace StarMath CAttribute* GetBaseAttribute(); //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); + // std::wstring TakingElementForHex(); + // + int TakingElementForRGB(); void SetString(const std::wstring& wsToken); void FindingTheEndOfParentheses(); void IteratorNullification(); @@ -163,6 +167,7 @@ namespace StarMath static TypeElement GetIndex(const std::wstring& wsCheckToken); static bool GetUpperIndex(const TypeElement& enType); static bool GetLowerIndex(const TypeElement& enType); + const TypeElement& GetType(); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; @@ -208,6 +213,7 @@ namespace StarMath CElement* GetLeftArg(); static TypeElement GetBinOperator(const std::wstring& wsToken); static void UnaryCheck(CStarMathReader* pReader,CElement* pLastElement); + const TypeElement& GetType(); private: //checking for signs such as -,+,-+,+-. static bool MixedOperators(const TypeElement& enType); @@ -293,6 +299,7 @@ namespace StarMath void SetBracketValue(CElement* pElement); CElement* GetLeftArg(); static TypeElement GetBracketWithIndex(const std::wstring& wsToken); + const TypeElement& GetType(); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; @@ -312,6 +319,7 @@ namespace StarMath void SetRightArg(CElement* pElement); CElement* GetRightArg(); static TypeElement GetSetOperation(const std::wstring& wsToken); + const TypeElement& GetType(); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; @@ -331,6 +339,7 @@ namespace StarMath void SetLeftArg(CElement* pElement); CElement* GetLeftArg(); static TypeElement GetConnection(const std::wstring& wsToken); + const TypeElement& GetType(); private: void SetAttribute(CAttribute* pAttribute) override; void Parse(CStarMathReader* pReader) override; @@ -417,8 +426,8 @@ namespace StarMath static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); - static bool CheckForLeftArgument(const TypeElement& enType ); - static CElement* ReadingWithoutBracket(CStarMathReader* pReader); + static bool CheckForLeftArgument(const TypeElement& enType, const bool& bConnection = true); + static CElement* ReadingWithoutBracket(CStarMathReader* pReader,const bool& bConnection = true); //checking the element (true if it is newline) static bool CheckNewline(CElement* pElement); //adding an element to the array, checking that it is not empty and adding the left element, if there is one. diff --git a/OdfFile/Reader/Converter/oox_conversion_context.cpp b/OdfFile/Reader/Converter/oox_conversion_context.cpp index 9ec757fcee9..15e36a90b78 100644 --- a/OdfFile/Reader/Converter/oox_conversion_context.cpp +++ b/OdfFile/Reader/Converter/oox_conversion_context.cpp @@ -277,7 +277,8 @@ void math_context::start() } math_stream_ << L"\"/>"; - math_stream_ << L""; + math_stream_ << L""; + //math_stream_ << L""; start_level(); } From 3c8604390eac5cd77b385719603a0edd230b5367 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 1 Apr 2024 16:03:16 +0600 Subject: [PATCH 488/794] Fix table styles conversion --- OOXML/XlsxFormat/Styles/TableStyles.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index 7e99b76c8ff..19d128b637f 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -91,7 +91,7 @@ namespace OOX if(m_oSize.IsInit()) ptr->size = m_oSize->GetValue(); else - ptr->size = 0; + ptr->size = 1; if(m_oType.IsInit()) { @@ -330,7 +330,7 @@ namespace OOX if(m_oTable.IsInit()) beginStyle->fIsTable = m_oTable->GetValue(); else - beginStyle->fIsTable = false; + beginStyle->fIsTable = true; if(m_oName.IsInit()) beginStyle->rgchName = m_oName.get(); else if(m_oDisplayName.IsInit()) From 083ced27c8819d58f692d7abae24151ba2d96a8f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 2 Apr 2024 12:32:04 +0300 Subject: [PATCH 489/794] fix build --- OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 5836af722c6..fa84192c54b 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1538,7 +1538,7 @@ namespace StarMath m_wsType = L"\u2209"; break; case TypeElement::dlriarrow: - m_wsType = L"\u\u226B"; + m_wsType = L"\u226B"; break; case TypeElement::dllearrow: m_wsType = L"\u226A"; From ebe0248c3fe2f5639a216971522f11f13bbffec6 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 2 Apr 2024 13:08:08 +0300 Subject: [PATCH 490/794] fix bug #67016 --- OdfFile/Projects/Windows/cpodf.vcxproj | 1 + OdfFile/Reader/Format/paragraph_elements.cpp | 35 ++++++++++++++++---- OdfFile/Reader/Format/paragraph_elements.h | 6 ++-- OdfFile/Reader/Format/styles.cpp | 20 ++++++++++- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index 05f9ae9ddda..11770cba049 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -553,6 +553,7 @@ /bigobj %(AdditionalOptions) + /bigobj %(AdditionalOptions) /bigobj %(AdditionalOptions) diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 4b90ab12db9..d4bc450363a 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -160,7 +160,16 @@ void paragraph_content_element::docx_serialize_run(office_element_ptr_array& con docx_serialize_run(content[i], Context); } } - +void paragraph_content_element::xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context) +{ + std::wstringstream val; + text_to_stream(val, true); + std::wstring val_text = val.str(); + if (val_text != L"???") + { + _Wostream << val_text; + } +} //------------------------------------------------------------------------------------------------------------ const wchar_t * text::ns = L""; const wchar_t * text::name = L""; @@ -1069,7 +1078,11 @@ void title::xlsx_convert(oox::xlsx_conversion_context & Context) { std::wstringstream val; text_to_stream(val); - Context.get_text_context()->add_text(val.str()); + std::wstring _title = val.str(); + if (_title != L"???") + { + Context.get_text_context()->add_text(_title); + } } void title::pptx_convert(oox::pptx_conversion_context & Context) { @@ -1103,11 +1116,15 @@ void subject::docx_convert(oox::docx_conversion_context & Context) docx_serialize_field(L"SUBJECT", text_, Context); } -void subject::xlsx_convert(oox::xlsx_conversion_context & Context) +void subject::xlsx_convert(oox::xlsx_conversion_context& Context) { - std::wstringstream val; - this->text_to_stream(val); - Context.get_text_context()->add_text(val.str()); + std::wstringstream val; + this->text_to_stream(val); + std::wstring _subject = val.str(); + if (_subject != L"???") + { + Context.get_text_context()->add_text(_subject); + } } void subject::pptx_convert(oox::pptx_conversion_context & Context) { @@ -1142,7 +1159,11 @@ void chapter::xlsx_convert(oox::xlsx_conversion_context & Context) { std::wstringstream val; this->text_to_stream(val); - Context.get_text_context()->add_text(val.str()); + std::wstring _chapter = val.str(); + if (_chapter != L"???") + { + Context.get_text_context()->add_text(_chapter); + } } void chapter::pptx_convert(oox::pptx_conversion_context & Context) { diff --git a/OdfFile/Reader/Format/paragraph_elements.h b/OdfFile/Reader/Format/paragraph_elements.h index 19be7cc8daa..c36d2dde590 100644 --- a/OdfFile/Reader/Format/paragraph_elements.h +++ b/OdfFile/Reader/Format/paragraph_elements.h @@ -77,10 +77,8 @@ class paragraph_content_element : public office_element_implxlsx_serialize(_Wostream, Context); } + else if (typeTextP == content_[i]->get_type()) + { + text::p* p = dynamic_cast(content_[i].get()); + for (size_t j = 0; p && j < p->paragraph_.content_.size(); j++) + { + text::paragraph_content_element* paragraph_element = dynamic_cast(p->paragraph_.content_[i].get()); + if (paragraph_element) + { + paragraph_element->xlsx_serialize(_Wostream, Context); + } + else + { + CP_SERIALIZE_TEXT(content_[i], true); + } + } + } else { CP_SERIALIZE_TEXT(content_[i], true); } - } + } } // text:notes-configuration //------------------------------------------------------------------------------------------------------- From 3d2e43b5d7dfae1cc36f68cb1b31c4423d956280 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 3 Apr 2024 11:50:09 +0300 Subject: [PATCH 491/794] fix namespace math --- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index e056cbb293a..1ce1665b91d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -73,7 +73,7 @@ namespace StarMath { if(CParserStarMathString::CheckNewline(oTempElement)) { m_pXmlWrite->WriteNodeBegin(L"m:r",false); - m_pXmlWrite->WriteNodeBegin(L"w:br",true); + m_pXmlWrite->WriteNodeBegin(L"a:br",true); m_pXmlWrite->WriteNodeEnd(L"",true,true); m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); @@ -91,58 +91,58 @@ namespace StarMath { { //тут должны быть базовые свойства шрифта, задаваемые выше - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeBegin(L"a:rPr",false); + pXmlWrite->WriteNodeBegin(L"a:rFonts",true); + pXmlWrite->WriteAttribute(L"a:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"a:ascii",L"Cambria Math"); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeBegin(L"a:sz",true); + pXmlWrite->WriteAttribute(L"a:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeBegin(L"a:szCs",true); + pXmlWrite->WriteAttribute(L"a:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + pXmlWrite->WriteNodeEnd(L"a:rPr",false,false); } else { std::wstring wsNameFont = pAttribute->GetFontName(); - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteNodeBegin(L"a:rPr",false); + pXmlWrite->WriteNodeBegin(L"a:rFonts",true); if(!wsNameFont.empty()) { - pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); - pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); + pXmlWrite->WriteAttribute(L"a:hAnsi",wsNameFont); + pXmlWrite->WriteAttribute(L"a:ascii",wsNameFont); } else { - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"a:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"a:ascii",L"Cambria Math"); } pXmlWrite->WriteNodeEnd(L"w",true,true); if(pAttribute->GetSize() == 0) { //тут должны быть базовые свойства шрифта, задаваемые выше - далее везде где не задано - аналогично - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeBegin(L"a:sz",true); + pXmlWrite->WriteAttribute(L"a:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeBegin(L"a:szCs",true); + pXmlWrite->WriteAttribute(L"a:val",L"40"); pXmlWrite->WriteNodeEnd(L"w",true,true); } else if(pAttribute->GetSize() != 0) { - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeBegin(L"a:sz",true); + pXmlWrite->WriteAttribute(L"a:val",std::to_wstring(pAttribute->GetSize())); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeBegin(L"a:szCs",true); + pXmlWrite->WriteAttribute(L"a:val",std::to_wstring(pAttribute->GetSize())); pXmlWrite->WriteNodeEnd(L"w",true,true); } if(!pAttribute->EmptyColor()) { - pXmlWrite->WriteNodeBegin(L"w:color",true); - pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); + pXmlWrite->WriteNodeBegin(L"a:color",true); + pXmlWrite->WriteAttribute(L"a:val",pAttribute->GetColor()); pXmlWrite->WriteNodeEnd(L"w",true,true); } if(pAttribute->GetBold() && pAttribute->GetItal()) @@ -154,22 +154,22 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:sty", true); pXmlWrite->WriteAttribute(L"m:val",L"b"); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:b",true); + pXmlWrite->WriteNodeBegin(L"a:b",true); pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:bCs",true); + pXmlWrite->WriteNodeBegin(L"a:bCs",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } else if(pAttribute->GetItal()) { - pXmlWrite->WriteNodeBegin(L"w:i",true); + pXmlWrite->WriteNodeBegin(L"a:i",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } if(pAttribute->GetStrike()) { - pXmlWrite->WriteNodeBegin(L"w:strike",true); + pXmlWrite->WriteNodeBegin(L"a:strike",true); pXmlWrite->WriteNodeEnd(L"w",true,true); } - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + pXmlWrite->WriteNodeEnd(L"a:rPr",false,false); } } void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) From ab4a3ef54639f428d56c43d3f50941f1dce22b0a Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 3 Apr 2024 11:53:12 +0300 Subject: [PATCH 492/794] fix bug #67231 --- OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj | 1 - .../Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters | 3 --- OdfFile/Reader/Converter/mediaitems.cpp | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj index 71e929716b2..b016c3bc601 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj @@ -82,7 +82,6 @@ - diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters index 1ac5444aa80..eb22134e169 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters @@ -161,9 +161,6 @@ - - Document - Document diff --git a/OdfFile/Reader/Converter/mediaitems.cpp b/OdfFile/Reader/Converter/mediaitems.cpp index dc07512d822..01e4e350bb1 100644 --- a/OdfFile/Reader/Converter/mediaitems.cpp +++ b/OdfFile/Reader/Converter/mediaitems.cpp @@ -64,7 +64,7 @@ bool is_internal(const std::wstring & uri, const std::wstring & packetRoot) std::wstring testRoot = pathRoot.GetPath(); std::wstring testFile = pathFile.GetPath(); - return (NSFile::CFileBinary::Exists(resultPath) || NSDirectory::Exists(mediaPath)) && (std::wstring::npos != testFile.find(testRoot)); + return (NSFile::CFileBinary::Exists(testFile) || NSDirectory::Exists(testFile)) && (std::wstring::npos != testFile.find(testRoot)); } mediaitems::item::item(std::wstring const & _href,_rels_type _type, std::wstring const & _outputName, From 91bc3063699759f3a35b30cf1f8a367626d920c8 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 3 Apr 2024 19:58:18 +0500 Subject: [PATCH 493/794] Fix bug #67089 --- OdfFile/Reader/Converter/pptx_text_context.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index ccc4b7a24e9..ac40ad33e07 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -722,8 +722,9 @@ std::wstring pptx_text_context::Impl::find_list_rename(const std::wstring & List void pptx_text_context::Impl::end_list_item() { dump_paragraph(); - - paragraphs_cout_--; + + if (paragraphs_cout_ != 0) + paragraphs_cout_--; paragraph_style_name_ = L""; in_list_ = false; @@ -739,7 +740,7 @@ void pptx_text_context::Impl::start_comment() } std::wstring pptx_text_context::Impl::end_comment() { - std::wstring str_comment = text_.str(); + std::wstring str_comment = text_.str(); text_.str(std::wstring()); in_comment = false; From 078e9afcc2653de2ebcc5e93360518bdfaffdb86 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 3 Apr 2024 21:31:09 +0600 Subject: [PATCH 494/794] Fix conditional formatting conversion --- OOXML/XlsxFormat/Styles/rPr.cpp | 3 + .../Worksheets/ConditionalFormatting.cpp | 70 +++++++++++++------ 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/rPr.cpp b/OOXML/XlsxFormat/Styles/rPr.cpp index 63be11df16b..9a73cea573a 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -520,6 +520,7 @@ namespace OOX ptr->bAlpha = 0; ptr->bAlpha = 0; ptr->bAlpha = 0; + ptr->fValidRGB = false; if(m_oAuto.IsInit()) { @@ -542,6 +543,8 @@ namespace OOX ptr->bBlue = m_oRgb->Get_B(); ptr->bGreen = m_oRgb->Get_G(); ptr->bRed = m_oRgb->Get_R(); + ptr->xColorType = 2; + ptr->fValidRGB = true; } if ( m_oTint.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 169bac34e40..443370e794e 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -247,6 +247,7 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() auto ptr1(new XLSB::CFVO); ptr->m_BrtCFVO = XLS::BaseObjectPtr{ptr1}; + ptr1->fSaveGTE = 0; if(m_oGte.IsInit()) ptr1->fGTE = m_oGte->GetValue(); else @@ -266,10 +267,19 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() if(m_oVal.IsInit()) ptr1->numParam.data.value = std::stod(m_oVal.get()); + else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) + ptr1->numParam.data.value = 0; + else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) + ptr1->numParam.data.value = 0; if(m_oFormula.IsInit()) { ptr1->formula = m_oFormula->m_sText; + ptr1->cbFmla = ptr1->formula.cce; + } + else + { + ptr1->cbFmla = 0; } return objectPtr; @@ -659,6 +669,8 @@ XLS::BaseObjectPtr CColorScale::toBin() XLS::BaseObjectPtr objectPtr(ptr); for(auto i:m_arrValues) ptr->m_arCFVO.push_back(i->toBin()); + for(auto i:m_arrColors) + ptr->m_arBrtColor.push_back(i->toBin()); return objectPtr; } EElementType CColorScale::getType () const @@ -893,7 +905,7 @@ XLS::BaseObjectPtr CDataBar::toBin() if(m_oMaxLength.IsInit()) ptr1->bLenMax = m_oMaxLength->GetValue(); else - m_oMaxLength = 100; + ptr1->bLenMax = 100; if(m_oMinLength.IsInit()) ptr1->bLenMin = m_oMinLength->GetValue(); else @@ -1737,6 +1749,15 @@ XLS::BaseObjectPtr CConditionalFormattingRule::toBin(const XLS::CellRef &cellRe { ptr->m_source = m_oIconSet->toBin(); } + if(m_oExtId.IsInit()) + { + auto extPtr(new XLSB::FRTCFRULE); + auto beginExt(new XLSB::CFRuleExt); + extPtr->m_BrtCFRuleExt = XLS::BaseObjectPtr{beginExt}; + ptr->m_FRTCFRULE = XLS::BaseObjectPtr{extPtr}; + + beginExt->guid = m_oExtId.get(); + } return objPtr; } @@ -1750,6 +1771,8 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellR { ptr->dxfId = m_oDxfId->GetValue(); } + else + ptr->dxfId = 0; if(m_oPriority.IsInit()) ptr->iPri = m_oPriority->GetValue(); if(m_oStopIfTrue.IsInit()) @@ -1771,7 +1794,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellR if(m_oText.IsInit()) ptr->strParam = m_oText.get(); else - ptr->strParam = L""; + ptr->strParam.setSize(0xFFFFFFFF); if(!m_arrFormula.empty()) { @@ -1941,11 +1964,13 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale) { ptr->iType = XLSB::CFType::CF_TYPE_GRADIENT; ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_GRADIENT; + ptr->dxfId = 0xFFFFFFFF; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar) { ptr->iType = XLSB::CFType::CF_TYPE_DATABAR; ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_DATABAR; + ptr->dxfId = 0xFFFFFFFF; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) { @@ -2636,28 +2661,29 @@ XLS::BaseObjectPtr CConditionalFormatting::toBin() { return objectPtr; } + auto ptr(new XLSB::CONDITIONALFORMATTING); + objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::CellRef formatingfirstCell; - auto ptr(new XLSB::CONDITIONALFORMATTING); - objectPtr = XLS::BaseObjectPtr{ptr}; - XLS::CellRef formatingfirstCell; - if(m_oSqRef.IsInit()) - { - auto conditionPtr(new XLSB::BeginConditionalFormatting); - ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; - conditionPtr->ccf = m_arrItems.size(); - conditionPtr->sqrfx.strValue = m_oSqRef.get(); - if(m_oPivot.IsInit()) - conditionPtr->fPivot = m_oPivot->GetValue(); - else - conditionPtr->fPivot = false; - formatingfirstCell = conditionPtr->sqrfx.getLocationFirstCell(); - - } - for(auto i: m_arrItems) - { - ptr->m_arCFRULE.push_back(i->toBin(formatingfirstCell)); - } + auto conditionPtr(new XLSB::BeginConditionalFormatting); + ptr->m_BrtBeginConditionalFormatting = XLS::BaseObjectPtr{conditionPtr}; + conditionPtr->ccf = m_arrItems.size(); + if(m_oSqRef.IsInit()) + { + conditionPtr->sqrfx.strValue = m_oSqRef.get(); + } + else + conditionPtr->sqrfx.crfx = 0; + if(m_oPivot.IsInit()) + conditionPtr->fPivot = m_oPivot->GetValue(); + else + conditionPtr->fPivot = false; + formatingfirstCell = conditionPtr->sqrfx.getLocationFirstCell(); + for(auto i: m_arrItems) + { + ptr->m_arCFRULE.push_back(i->toBin(formatingfirstCell)); + } return objectPtr; } bool CConditionalFormatting::IsUsage() From 2f7447f918b659c8faba1586f63525521f8513f0 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 4 Apr 2024 12:40:16 +0300 Subject: [PATCH 495/794] For bug #66986 --- PdfFile/PdfReader.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 4a676054673..2fdd5cc2e77 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1015,7 +1015,7 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) } } - if (!bFullFont || pField->getAcroFormFieldType() == acroFormFieldPushbutton) + if (!bFullFont) { oR.free(); oFonts.free(); oFontRef.free(); std::string sFontKey; @@ -1047,6 +1047,27 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) } } oR.free(); oFonts.free(); oFontRef.free(); + + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) + { + std::string sFontKey; + bool bFind = PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey); + if (bFind && std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) + { + bool bBold = false, bItalic = false; + wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (m_mFonts.find(wsFontName) == m_mFonts.end()) + { + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[wsFontName] = wsFileName; + } + } + } + oR.free(); oFonts.free(); oFontRef.free(); } oRes.AddInt(nFontsID, nFontsPos); From 12fd3bd3cef633f1be4f37d934462182831a0b38 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 4 Apr 2024 17:20:59 +0600 Subject: [PATCH 496/794] Comment conditional formattings ext --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index a8a2bfb9523..68dd8c83864 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -881,12 +881,12 @@ namespace OOX { if(i->m_sUri == L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}") { - auto formatPtr(new XLSB::CONDITIONALFORMATTINGS); + /*auto formatPtr(new XLSB::CONDITIONALFORMATTINGS); ptr->m_CONDITIONALFORMATTINGS = XLS::BaseObjectPtr{formatPtr}; for(auto j:i->m_arrConditionalFormatting) { formatPtr->m_arCONDITIONALFORMATTING14.push_back(j->toBin()); - } + }*/ } else if(i->m_sUri == L"{CCE6A557-97BC-4B89-ADB6-D9C93CAAB3DF}") { From 8b9c0d79bb46e187dd6f10def1dcd0cf14f03dd2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 4 Apr 2024 14:27:48 +0300 Subject: [PATCH 497/794] Fix bug #67210 --- PdfFile/SrcReader/RendererOutputDev.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 867f9e20d8a..9e39f547e44 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -4035,8 +4035,9 @@ namespace PdfReader if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || (m_bDrawOnlyText && nRenderMode == 2)) { -#ifdef BUILDING_WASM_MODULE + bool bReplace = false; std::wstring sFontPath; +#ifdef BUILDING_WASM_MODULE m_pRenderer->get_FontPath(&sFontPath); if (!unGid && !wsUnicodeText.empty() && !sFontPath.empty()) { @@ -4079,13 +4080,15 @@ namespace PdfReader return; } m_pRenderer->put_FontPath(wsFileName); - sFontPath = wsFileName; + bReplace = true; } } } } #endif m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + if (bReplace) + m_pRenderer->put_FontPath(sFontPath); } if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) From e8a69e39bc91a93680f1e9e11021b66d38c5491d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 4 Apr 2024 16:40:41 +0300 Subject: [PATCH 498/794] Fix bugs #67249, #65628 --- PdfFile/SrcWriter/Document.cpp | 9 --------- PdfFile/SrcWriter/Metadata.cpp | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 8277f5c4eb2..08812813559 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -531,9 +531,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetExtGState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = FindExtGrState(dAlphaStroke, dAlphaFill, eMode, nStrokeAdjustment); if (!pExtGrState) @@ -561,9 +558,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetStrokeAlpha(double dAlpha) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = NULL; for (unsigned int unIndex = 0, unCount = m_vStrokeAlpha.size(); unIndex < unCount; unIndex++) { @@ -584,9 +578,6 @@ namespace PdfWriter } CExtGrState* CDocument::GetFillAlpha(double dAlpha) { - if (IsPDFA()) - return NULL; - CExtGrState* pExtGrState = NULL; for (unsigned int unIndex = 0, unCount = m_vFillAlpha.size(); unIndex < unCount; unIndex++) { diff --git a/PdfFile/SrcWriter/Metadata.cpp b/PdfFile/SrcWriter/Metadata.cpp index d0cd8ebab7b..ad4211b8098 100644 --- a/PdfFile/SrcWriter/Metadata.cpp +++ b/PdfFile/SrcWriter/Metadata.cpp @@ -155,7 +155,7 @@ namespace PdfWriter if (pXref->IsPDFA()) { sXML += "\n"; - sXML += "1A\n"; + sXML += "2A\n"; sXML += ""; } From 463ca006ee0bcb543a87bf0e47f475a045fcc069 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 4 Apr 2024 16:48:52 +0300 Subject: [PATCH 499/794] Fixed bugs with tables in html to ooxml conversion --- .../html/css/src/CCssCalculator_Private.cpp | 2 + .../html/css/src/xhtml/CDocumentStyle.cpp | 24 +- HtmlFile2/htmlfile2.cpp | 288 ++++++++++++++---- 3 files changed, 253 insertions(+), 61 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 8c4170e1d70..77938ba688b 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -528,6 +528,8 @@ namespace NSCSS oStyle.m_oPadding.Clear(); } + oStyle.m_oBorder.Clear(); + CCompiledStyle oTempStyle; oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 6d6f59a66a2..816ca43c35b 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -396,7 +396,27 @@ namespace NSCSS std::wstring wsColor = oBorder.GetColor().ToWString(); std::wstring wsStyle = oBorder.GetStyle().ToWString(); - double dWidth = oBorder.GetWidth().ToDouble(Point) * 8; // Так как значение указано в восьмых долях точки + + int nWidth = static_cast(std::round(oBorder.GetWidth().ToDouble(Point) * 8.)); + + if (nWidth <= 3) + nWidth = 2; + else if (nWidth <= 5) + nWidth = 4; + else if (nWidth <= 7) + nWidth = 6; + else if (nWidth <= 9) + nWidth = 8; + else if (nWidth <= 15) + nWidth = 12; + else if (nWidth <= 21) + nWidth = 18; + else if (nWidth <= 29) + nWidth = 24; + else if (nWidth <= 41) + nWidth = 36; + else + nWidth = 48; if (wsColor.empty()) wsColor = L"auto"; @@ -404,7 +424,7 @@ namespace NSCSS if (wsStyle.empty()) wsStyle = L"single"; - return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(static_cast(dWidth)) + + L"\" w:space=\"0\" w:color=\"" + wsColor + L"\""; + return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"0\" w:color=\"" + wsColor + L"\""; } void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 7ee9de6a5fd..bdbfcad3437 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -141,6 +141,22 @@ struct TTableStyles } }; +struct TTableRowStyle +{ + UINT m_unMaxIndex; + UINT m_unMaxHeight; + bool m_bIsHeader; + + TTableRowStyle() + : m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false) + {} + + bool Empty() const + { + return 0 == m_unMaxHeight && false == m_bIsHeader; + } +}; + struct TTableCellStyle { NSCSS::NSProperties::CDigit m_oWidth; @@ -151,7 +167,7 @@ struct TTableCellStyle std::wstring m_wsAlign; - TTableCellStyle() {} + TTableCellStyle(){} bool Empty() { @@ -163,9 +179,37 @@ class CTableCell { public: CTableCell() - : m_unColspan(1), m_unRowSpan(1) + : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false) {} + CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged) + : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged) + {} + + CTableCell(CTableCell& oCell) + : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), + m_oStyles(oCell.m_oStyles) + { + m_oData.SetText(oCell.m_oData.GetData()); + } + + CTableCell* Copy() + { + return new CTableCell(*this); + } + + static CTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL) + { + CTableCell *pCell = new CTableCell(unColspan, 1, m_bIsMerged); + + if (NULL != pStyle) + pCell->m_oStyles = *pStyle; + + pCell->m_oData.SetText(L""); + + return pCell; + } + void SetColspan(UINT unColspan, UINT unCurrentIndex) { if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex) @@ -194,6 +238,11 @@ class CTableCell return &m_oData; } + const TTableCellStyle* GetStyles() const + { + return &m_oStyles; + } + void SetWidth(const NSCSS::NSProperties::CDigit& oWidth) { m_oStyles.m_oWidth = oWidth; @@ -204,6 +253,11 @@ class CTableCell m_oStyles.m_oHeight = oHeight; } + UINT GetHeight() const + { + return m_oStyles.m_oHeight.ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT); + } + void SetBorder(const NSCSS::NSProperties::CBorder& oBorder) { m_oStyles.m_oBorder = oBorder; @@ -224,61 +278,64 @@ class CTableCell NSStringUtils::CStringBuilder oCell; oCell.WriteNodeBegin(L"w:tc"); + oCell.WriteNodeBegin(L"w:tcPr"); - if (!m_oStyles.Empty()) + if (!m_oStyles.m_oWidth.Empty()) { - oCell.WriteNodeBegin(L"w:tcPr"); - - if (!m_oStyles.m_oWidth.Empty()) - { - if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) - oCell += L""; - else - oCell += L""; - } + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oCell += L""; else - oCell += L""; + oCell += L""; + } + else + oCell += L""; - if (1 < m_unColspan) - oCell += L""; + if (1 < m_unColspan) + oCell += L""; - if (!m_oStyles.m_oBorder.Zero() && !m_oStyles.m_oBorder.Empty()) - oCell += L"" + CreateBorders(m_oStyles.m_oBorder) + L""; - else if (oTableStyles.m_bHaveBorderAttribute) - oCell += L""; + if (m_bIsMerged) + oCell += L""; + else if (1 < m_unRowSpan) + oCell += L""; - if (!m_oStyles.m_oBackground.Empty()) - { - const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == m_oStyles.m_oBackground.GetType()) ? L"auto" : m_oStyles.m_oBackground.ToWString()}; - oCell += L""; - } + if (!m_oStyles.m_oBorder.Zero() && !m_oStyles.m_oBorder.Empty()) + oCell += L"" + CreateBorders(m_oStyles.m_oBorder) + L""; + else if (oTableStyles.m_bHaveBorderAttribute) + oCell += L""; - if (!m_oStyles.m_wsAlign.empty()) - oCell += L""; + if (!m_oStyles.m_oBackground.Empty()) + { + const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == m_oStyles.m_oBackground.GetType()) ? L"auto" : m_oStyles.m_oBackground.ToWString()}; + oCell += L""; + } - if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding) - { - const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), - m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); - const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), - m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); - - oCell += L"" - "" - "" - "" - "" - ""; - } + if (!m_oStyles.m_wsAlign.empty()) + oCell += L""; + else + oCell += L""; - oCell += L""; - oCell.WriteNodeEnd(L"w:tcPr"); + if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding) + { + const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), + m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + + oCell += L"" + "" + "" + "" + "" + ""; } - + + oCell += L""; + oCell.WriteNodeEnd(L"w:tcPr"); + oCell += m_oData.GetData(); oCell.WriteNodeEnd(L"w:tc"); @@ -290,6 +347,8 @@ class CTableCell UINT m_unColspan; UINT m_unRowSpan; + bool m_bIsMerged; + TTableCellStyle m_oStyles; NSStringUtils::CStringBuilder m_oData; }; @@ -298,37 +357,56 @@ class CTableRow { public: CTableRow() - : m_unMaxIndex(0) {} ~CTableRow() { for (CTableCell* pCell : m_arCells) - delete pCell; + RELEASEOBJECT(pCell); } void AddCell(CTableCell* pCell) + { + InsertCell(pCell, -1); + } + + void InsertCell(CTableCell *pCell, int nPosition) { if (NULL == pCell) return; - m_arCells.push_back(pCell); - m_unMaxIndex += pCell->GetColspan(); + if (nPosition < 0) + m_arCells.push_back(pCell); + else + m_arCells.insert(m_arCells.begin() + nPosition, pCell); + + m_oStyles.m_unMaxIndex += pCell->GetColspan(); + + if (1 == pCell->GetColspan() && 1 == pCell->GetRowspan()) + m_oStyles.m_unMaxHeight = std::max(m_oStyles.m_unMaxHeight, pCell->GetHeight()); } UINT GetIndex() const { - return m_unMaxIndex; + return m_oStyles.m_unMaxIndex; } - UINT GetCountIndex() const + UINT GetCount() const { return m_arCells.size(); } bool ColumnsOverflowing() const { - return MAXCOLUMNSINTABLE == m_unMaxIndex; + return MAXCOLUMNSINTABLE == m_oStyles.m_unMaxIndex; + } + + void RecalculateMaxIndex() + { + m_oStyles.m_unMaxIndex = 0; + + for (const CTableCell* pCell : m_arCells) + m_oStyles.m_unMaxIndex += pCell->GetColspan(); } std::wstring ConvertToOOXML(const TTableStyles& oTableStyles) @@ -339,6 +417,22 @@ class CTableRow NSStringUtils::CStringBuilder oRow; oRow.WriteNodeBegin(L"w:tr"); + if (!m_oStyles.Empty() || 0 <= oTableStyles.m_nCellSpacing) + { + oRow.WriteNodeBegin(L"w:trPr"); + + if (m_oStyles.m_bIsHeader) + oRow += L""; + + if (0 < m_oStyles.m_unMaxHeight) + oRow += L""; + + if (0 <= oTableStyles.m_nCellSpacing) + oRow += L""; + + oRow.WriteNodeEnd(L"w:trPr"); + } + for (CTableCell* pCell : m_arCells) oRow += pCell->ConvertToOOXML(oTableStyles); @@ -346,8 +440,16 @@ class CTableRow return oRow.GetData(); } + + CTableCell* operator[](UINT unIndex) + { + if (unIndex >= m_arCells.size()) + return NULL; + + return m_arCells[unIndex]; + } private: - UINT m_unMaxIndex; + TTableRowStyle m_oStyles; std::vector m_arCells; }; @@ -360,14 +462,22 @@ class CTable ~CTable() { for (CTableRow* pRow : m_arRows) - delete pRow; + RELEASEOBJECT(pRow); } void AddRow(CTableRow* pRow) { if (NULL == pRow) return; - + + for (UINT unIndex = 0; unIndex < pRow->GetCount(); ++unIndex) + { + if (unIndex >= m_arMinColspan.size()) + m_arMinColspan.push_back((*pRow)[unIndex]->GetColspan()); + else if ((*pRow)[unIndex]->GetColspan() < m_arMinColspan[unIndex]) + m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan(); + } + m_arRows.push_back(pRow); } @@ -411,9 +521,64 @@ class CTable return m_oStyles.m_bHaveBorderAttribute; } + void ApplyRowspan() + { + CTableCell* pCell = NULL; + for (UINT unRowIndex = 0; unRowIndex < m_arRows.size(); ++unRowIndex) + { + for (UINT unColumnIndex = 0; unColumnIndex < m_arRows[unRowIndex]->GetCount(); ++unColumnIndex) + { + pCell = (*m_arRows[unRowIndex])[unColumnIndex]; + + if (1 != pCell->GetRowspan()) + { + for (UINT unIndex = unRowIndex + 1; unIndex < m_arRows.size(); ++unIndex) + (*m_arRows[unIndex]).InsertCell(CTableCell::CreateEmpty(pCell->GetColspan(), true, pCell->GetStyles()), unColumnIndex); + } + } + } + } + void Shorten() { - + UINT unIndex = 0; + CTableCell* pCell = NULL; + + while (unIndex < m_arMinColspan.size()) + { + for (CTableRow* pRow : m_arRows) + { + pCell = (*pRow)[unIndex]; + + if (NULL == pCell) + continue; + + if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1) + (*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE); + else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex]) + (*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE); + } + + ++unIndex; + } + } + + void CompleteTable() + { + UINT unMaxIndex = 0; + + for (CTableRow* pRow : m_arRows) + { + pRow->RecalculateMaxIndex(); + + if (unMaxIndex > pRow->GetIndex()) + { + for (UINT unIndex = 0; unIndex < unMaxIndex - pRow->GetIndex(); ++unIndex) + pRow->AddCell(CTableCell::CreateEmpty()); + } + + unMaxIndex = std::max(pRow->GetIndex(), unMaxIndex); + } } std::wstring ConvertToOOXML() @@ -474,6 +639,7 @@ class CTable } private: std::vector m_arRows; + std::vector m_arMinColspan; TTableStyles m_oStyles; }; @@ -2050,8 +2216,10 @@ class CHtmlFile2_Private GetSubClass(pCell->GetData(), sSelectors); + std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(sSelectors.begin(), sSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), sSelectors.cend()}; + NSCSS::CCompiledStyle oStyle; - m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); + m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors); pCell->SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); @@ -2195,7 +2363,9 @@ class CHtmlFile2_Private sSelectors.pop_back(); } + oTable.ApplyRowspan(); oTable.Shorten(); + oTable.CompleteTable(); oXml->WriteString(oTable.ConvertToOOXML()); } From 7f17f3065082ee029e987b8dcc6749e92fb4bcd8 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 4 Apr 2024 20:42:29 +0300 Subject: [PATCH 500/794] for bug 67231 --- .../StarMath2OOXML/cstarmathpars.cpp | 37 ++++++++++++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 2 +- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index fa84192c54b..ec5dfd6b98f 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -648,8 +648,10 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::func) { - pReader->GetToken(); - return new CElementFunction(pReader->GetLocalType(),pReader->GetString()); + if (pReader->GetToken()) + return new CElementFunction(pReader->GetLocalType(),pReader->GetString()); + else + return nullptr; } else return new CElementFunction(pReader->GetLocalType()); @@ -660,8 +662,12 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::oper) { - pReader->GetToken(); - return new CElementOperator(pReader->GetLocalType(),pReader->GetString()); + if (pReader->GetToken()) + { + return new CElementOperator(pReader->GetLocalType(),pReader->GetString()); + } + else + return nullptr; } else return new CElementOperator(pReader->GetLocalType()); @@ -2556,7 +2562,7 @@ namespace StarMath delete m_pAttribute; } //TODO :: ParseColor and ParseFont - void CStarMathReader::GetToken() + bool CStarMathReader::GetToken() { if(CheckIteratorPosition()) { @@ -2587,8 +2593,10 @@ namespace StarMath m_pAttribute = nullptr; if(m_wsToken == L"left") m_wsToken = GetElement(); else if(L"right" == m_wsToken ) m_wsToken = GetElement(); + + return true; } - //std::wcout< Date: Fri, 5 Apr 2024 16:02:06 +0500 Subject: [PATCH 501/794] Fix bug #61378 --- OdfFile/Reader/Converter/pptx_text_context.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index ccc4b7a24e9..5559650809f 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -140,6 +140,8 @@ class pptx_text_context::Impl: boost::noncopyable //------------------------------------------------------------------------------- std::vector list_style_stack_; bool first_element_list_item_; + + _CP_OPT(odf_types::length) last_run_font_size_; int new_list_style_number_; // счетчик для нумерации имен созданных в процессе конвертации стилей @@ -451,6 +453,10 @@ void pptx_text_context::Impl::write_rPr(std::wostream & strm) strm << get_styles_context().text_style().str(); + if (text_properties_.fo_font_size_) + last_run_font_size_ = text_properties_.fo_font_size_->get_length(); + else + last_run_font_size_ = boost::none; } std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { @@ -474,7 +480,13 @@ std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) } else { - CP_XML_NODE(L"a:endParaRPr"); + CP_XML_NODE(L"a:endParaRPr") + { + if(last_run_font_size_) + { + CP_XML_ATTR(L"sz", last_run_font_size_->get_value_unit(odf_types::length::pt) * 100); + } + } } } } From 10c6def10ec20e2bb88277ba3f918a729ced37e4 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 5 Apr 2024 15:54:31 +0300 Subject: [PATCH 502/794] Bug fixed. Editing sqrt and nroot, dropping parentheses. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 270 +++++++++--------- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 41 +-- .../StarMath2OOXML/cconversionsmtoooxml.h | 1 + .../StarMath2OOXML/cstarmathpars.cpp | 207 ++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 33 ++- OdfFile/Reader/Format/math_elements.cpp | 8 +- 6 files changed, 304 insertions(+), 256 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 75ec83fbc74..f87f79e7e41 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -10,7 +10,7 @@ TEST(SMConvectorTest, BinOperatorPlus) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"2+3"; + std::wstring XmlString = L"2+3"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -20,7 +20,7 @@ TEST(SMConvectorTest,BinOperatorOver) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"23"; + std::wstring XmlString = L"23"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -30,7 +30,7 @@ TEST(SMConvectorTest,BinOperatorCdot) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"5\u00B78"; + std::wstring XmlString = L"5\u00B78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -40,7 +40,7 @@ TEST(SMConvectorTest,BinOperatorTimes) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"5\u00D78"; + std::wstring XmlString = L"5\u00D78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -50,7 +50,7 @@ TEST(SMConvectorTest,BinOperatorMultipl) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"4*2"; + std::wstring XmlString = L"4*2"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -60,7 +60,7 @@ TEST(SMConvectorTest,BinOperatorDiv) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"4\u00F72"; + std::wstring XmlString = L"4\u00F72"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -70,7 +70,7 @@ TEST(SMConvectorTest,BinOperatorDivision) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"42"; + std::wstring XmlString = L"42"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -80,7 +80,7 @@ TEST(SMConvectorTest,BinOperatorOplus) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2295179"; + std::wstring XmlString = L"226\u2295179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -90,7 +90,7 @@ TEST(SMConvectorTest,BinOperatorOdot) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2299179"; + std::wstring XmlString = L"226\u2299179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -100,7 +100,7 @@ TEST(SMConvectorTest,BinOperatorOtimes) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2297179"; + std::wstring XmlString = L"226\u2297179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -110,7 +110,7 @@ TEST(SMConvectorTest,OperatorSum) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"5"; + std::wstring XmlString = L"5"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -120,7 +120,7 @@ TEST(SMConvectorTest,OperatorSumFrom) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -130,7 +130,7 @@ TEST(SMConvectorTest,OperatorSumTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -140,7 +140,7 @@ TEST(SMConvectorTest,OperatorSumFromTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"666777567"; + std::wstring XmlString = L"666777567"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -150,7 +150,7 @@ TEST(SMConvectorTest,SetOperationUnion) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23\u22C345"; + std::wstring wsXmlString = L"23\u22C345"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -160,7 +160,7 @@ TEST(SMConvectorTest,SetOperationIntersection) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"15\u22C21234"; + std::wstring wsXmlString = L"15\u22C21234"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -170,7 +170,7 @@ TEST(SMConvectorTest,SetOperationSetminus) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"7\u221615745"; + std::wstring wsXmlString = L"7\u221615745"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -180,7 +180,7 @@ TEST(SMConvectorTest,SetOperationSetquotient) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"91\u221545"; + std::wstring wsXmlString = L"91\u221545"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -190,7 +190,7 @@ TEST(SMConvectorTest,SetOperationSubset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22822"; + std::wstring wsXmlString = L"1\u22822"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -200,7 +200,7 @@ TEST(SMConvectorTest,SetOperationSubseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"77\u228666"; + std::wstring wsXmlString = L"77\u228666"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -210,7 +210,7 @@ TEST(SMConvectorTest,SetOperationSupset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"11\u228322"; + std::wstring wsXmlString = L"11\u228322"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -220,7 +220,7 @@ TEST(SMConvectorTest,SetOperationSupseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22872"; + std::wstring wsXmlString = L"1\u22872"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -230,7 +230,7 @@ TEST(SMConvectorTest,SetOperationNsubset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"21\u22842"; + std::wstring wsXmlString = L"21\u22842"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -240,7 +240,7 @@ TEST(SMConvectorTest,SetOperationNsubseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"782\u2288250"; + std::wstring wsXmlString = L"782\u2288250"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -250,7 +250,7 @@ TEST(SMConvectorTest,SetOperationNsupset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22852"; + std::wstring wsXmlString = L"1\u22852"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -260,7 +260,7 @@ TEST(SMConvectorTest,SetOperationNsupseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22892"; + std::wstring wsXmlString = L"1\u22892"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -270,7 +270,7 @@ TEST(SMConvectorTest,SetOperationIn) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22082"; + std::wstring wsXmlString = L"1\u22082"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -280,7 +280,7 @@ TEST(SMConvectorTest,SetOperationNotin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3\u22094"; + std::wstring wsXmlString = L"3\u22094"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -290,7 +290,7 @@ TEST(SMConvectorTest,SetOperationOwns) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"5\u220B6"; + std::wstring wsXmlString = L"5\u220B6"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -300,7 +300,7 @@ TEST(SMConvectorTest,ConnectionDlarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"7\u21D08"; + std::wstring wsXmlString = L"7\u21D08"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -310,7 +310,7 @@ TEST(SMConvectorTest,ConnectionDlrarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"9\u21D410"; + std::wstring wsXmlString = L"9\u21D410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -320,7 +320,7 @@ TEST(SMConvectorTest,ConnectionDrarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"11\u21D212"; + std::wstring wsXmlString = L"11\u21D212"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -330,7 +330,7 @@ TEST(SMConvectorTest,ConnectionEquals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"13=14"; + std::wstring wsXmlString = L"13=14"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -340,7 +340,7 @@ TEST(SMConvectorTest,ConnectionNotequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"15\u226016"; + std::wstring wsXmlString = L"15\u226016"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -350,7 +350,7 @@ TEST(SMConvectorTest,ConnectionLearrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"17<18"; + std::wstring wsXmlString = L"17<18"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -360,7 +360,7 @@ TEST(SMConvectorTest,ConnectionLearrowequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"19\u226420"; + std::wstring wsXmlString = L"19\u226420"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -370,7 +370,7 @@ TEST(SMConvectorTest,ConnectionRiarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"21>22"; + std::wstring wsXmlString = L"21>22"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -380,7 +380,7 @@ TEST(SMConvectorTest,ConnectionRiarrowequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23\u226524"; + std::wstring wsXmlString = L"23\u226524"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -390,7 +390,7 @@ TEST(SMConvectorTest,ConnectionDllearrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"25\u226A26"; + std::wstring wsXmlString = L"25\u226A26"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -400,7 +400,7 @@ TEST(SMConvectorTest,ConnectionDlriarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"27\u226B28"; + std::wstring wsXmlString = L"27\u226B28"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -410,7 +410,7 @@ TEST(SMConvectorTest,ConnectionApprox) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"29\u224830"; + std::wstring wsXmlString = L"29\u224830"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -420,7 +420,7 @@ TEST(SMConvectorTest,ConnectionSim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"31\u223C32"; + std::wstring wsXmlString = L"31\u223C32"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -430,7 +430,7 @@ TEST(SMConvectorTest,ConnectionSimeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"33\u224334"; + std::wstring wsXmlString = L"33\u224334"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -440,7 +440,7 @@ TEST(SMConvectorTest,ConnectionEquiv) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"35\u226136"; + std::wstring wsXmlString = L"35\u226136"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -450,17 +450,17 @@ TEST(SMConvectorTest,ConnectionProp) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"37\u221D38"; + std::wstring wsXmlString = L"37\u221D38"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } TEST(SMConvectorTest,ConnectionParallel) { - std::wstring wsString = L"39 parallel 40"; + std::wstring wsString = L"39 parallel 30"; StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"39\u222540"; + std::wstring wsXmlString = L"39\u222530"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -470,7 +470,7 @@ TEST(SMConvectorTest,ConnectionOrtho) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"41\u22A542"; + std::wstring wsXmlString = L"41\u22A542"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -480,7 +480,7 @@ TEST(SMConvectorTest,ConnectionDivides) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"43\u222344"; + std::wstring wsXmlString = L"43\u222344"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -490,7 +490,7 @@ TEST(SMConvectorTest,ConnectionNdivides) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"45\u222446"; + std::wstring wsXmlString = L"45\u222446"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -500,7 +500,7 @@ TEST(SMConvectorTest,ConnectionToward) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"47\u219248"; + std::wstring wsXmlString = L"47\u219248"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -510,7 +510,7 @@ TEST(SMConvectorTest,ConnectionTransl) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"49\u22B750"; + std::wstring wsXmlString = L"49\u22B750"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -520,7 +520,7 @@ TEST(SMConvectorTest,ConnectionTransr) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"51\u22B652"; + std::wstring wsXmlString = L"51\u22B652"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -530,7 +530,7 @@ TEST(SMConvectorTest,ConnectionDef) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"53\u225D54"; + std::wstring wsXmlString = L"53\u225D54"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -540,7 +540,7 @@ TEST(SMConvectorTest,ConnectionPrec) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"55\u227A56"; + std::wstring wsXmlString = L"55\u227A56"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -550,7 +550,7 @@ TEST(SMConvectorTest,ConnectionSucc) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"57\u227B58"; + std::wstring wsXmlString = L"57\u227B58"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -560,7 +560,7 @@ TEST(SMConvectorTest,ConnectionPreccurlyeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"59\u227C60"; + std::wstring wsXmlString = L"59\u227C60"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -570,7 +570,7 @@ TEST(SMConvectorTest,ConnectionSucccurlyeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"61\u227D62"; + std::wstring wsXmlString = L"61\u227D62"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -580,7 +580,7 @@ TEST(SMConvectorTest,ConnectionPrecsim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"63\u227E64"; + std::wstring wsXmlString = L"63\u227E64"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -590,7 +590,7 @@ TEST(SMConvectorTest,ConnectionSuccsim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"65\u227F66"; + std::wstring wsXmlString = L"65\u227F66"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -600,7 +600,7 @@ TEST(SMConvectorTest,ConnectionNprec) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"67\u228068"; + std::wstring wsXmlString = L"67\u228068"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -610,7 +610,7 @@ TEST(SMConvectorTest,ConnectionNsucc) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"69\u228170"; + std::wstring wsXmlString = L"69\u228170"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -620,7 +620,7 @@ TEST(SMConvectorTest,BracketRound) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3"; + std::wstring wsXmlString = L"2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -630,7 +630,7 @@ TEST(SMConvectorTest,BracketSquare) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"4-5"; + std::wstring wsXmlString = L"4-5"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -640,7 +640,7 @@ TEST(SMConvectorTest,BracketLdbracket) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"6+7"; + std::wstring wsXmlString = L"6+7"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -650,7 +650,7 @@ TEST(SMConvectorTest,BracketLbrace) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"8-9"; + std::wstring wsXmlString = L"8-9"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -660,7 +660,7 @@ TEST(SMConvectorTest,BracketLangle) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1011"; + std::wstring wsXmlString = L"1011"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -670,7 +670,7 @@ TEST(SMConvectorTest,BracketLceil) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"12\u229613"; + std::wstring wsXmlString = L"12\u229613"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -680,7 +680,7 @@ TEST(SMConvectorTest,BracketLfloor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"14\u22C315"; + std::wstring wsXmlString = L"14\u22C315"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -690,7 +690,7 @@ TEST(SMConvectorTest,BracketLline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1617"; + std::wstring wsXmlString = L"1617"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -700,7 +700,7 @@ TEST(SMConvectorTest,BracketLdline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"18\u229519"; + std::wstring wsXmlString = L"18\u229519"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -710,7 +710,7 @@ TEST(SMConvectorTest,FunctionCos) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cos2+3"; + std::wstring wsXmlString = L"cos2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -720,7 +720,7 @@ TEST(SMConvectorTest,FunctionSin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sin45"; + std::wstring wsXmlString = L"sin45"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -730,7 +730,7 @@ TEST(SMConvectorTest,FunctionTan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"tan67"; + std::wstring wsXmlString = L"tan67"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -740,7 +740,7 @@ TEST(SMConvectorTest,FunctionCot) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cot89"; + std::wstring wsXmlString = L"cot89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -750,7 +750,7 @@ TEST(SMConvectorTest,FunctionSinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sinh2\u22833"; + std::wstring wsXmlString = L"sinh2\u22833"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -760,7 +760,7 @@ TEST(SMConvectorTest,FunctionCosh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cosh2+3"; + std::wstring wsXmlString = L"cosh2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -770,7 +770,7 @@ TEST(SMConvectorTest,FunctionTanh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"tanh11\u229712"; + std::wstring wsXmlString = L"tanh11\u229712"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -780,7 +780,7 @@ TEST(SMConvectorTest,FunctionCoth222) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"coth222"; + std::wstring wsXmlString = L"coth222"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -790,7 +790,7 @@ TEST(SMConvectorTest,FunctionArcsin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arcsin13\u229614"; + std::wstring wsXmlString = L"arcsin13\u229614"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -800,7 +800,7 @@ TEST(SMConvectorTest,FunctionArccos) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arccos15-16"; + std::wstring wsXmlString = L"arccos15-16"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -810,7 +810,7 @@ TEST(SMConvectorTest,FunctionArctan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arctan1718"; + std::wstring wsXmlString = L"arctan1718"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -820,7 +820,7 @@ TEST(SMConvectorTest,FunctionArccot) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arccot20+30"; + std::wstring wsXmlString = L"arccot20+30"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -830,7 +830,7 @@ TEST(SMConvectorTest,FunctionArsinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arsinh231510"; + std::wstring wsXmlString = L"arsinh231510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -840,7 +840,7 @@ TEST(SMConvectorTest,FunctionArcosh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"35+27arcosh2378"; + std::wstring wsXmlString = L"35+27arcosh2378"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -850,7 +850,7 @@ TEST(SMConvectorTest,FunctionArtanhArcoth) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arcoth30\u2282artanh27"; + std::wstring wsXmlString = L"arcoth30\u2282artanh27"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -860,7 +860,7 @@ TEST(SMConvectorTest,MatrixBinom) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"27\u2283277arcoth89"; + std::wstring wsXmlString = L"27\u2283277arcoth89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -870,7 +870,7 @@ TEST(SMConvectorTest,MatrixMatrix) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; + std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -880,7 +880,7 @@ TEST(SMConvectorTest,MatrixStack) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"210231234"; + std::wstring wsXmlString = L"210231234"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -890,7 +890,7 @@ TEST(SMConvectorTest,IndexLower) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2512"; + std::wstring wsXmlString = L"2512"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -900,7 +900,7 @@ TEST(SMConvectorTest,IndexUpper) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cos52410"; + std::wstring wsXmlString = L"cos52410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -910,7 +910,7 @@ TEST(SMConvectorTest,IndexLsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3cos1527"; + std::wstring wsXmlString = L"2+3cos1527"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -920,7 +920,7 @@ TEST(SMConvectorTest,IndexLsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"22222103"; + std::wstring wsXmlString = L"22222103"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -930,7 +930,7 @@ TEST(SMConvectorTest,BracketWithIndexOverbrace) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"231010010"; + std::wstring wsXmlString = L"231010010"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -940,7 +940,7 @@ TEST(SMConvectorTest,OperatorLllint) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2102+3100"; + std::wstring wsXmlString = L"2102+3100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -950,7 +950,7 @@ TEST(SMConvectorTest,BracketLdlineAttribute) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"10100+3+10"; + std::wstring wsXmlString = L"10100+3+10"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -960,7 +960,7 @@ TEST(SMConvectorTest,Example11) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; + std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -970,7 +970,7 @@ TEST(SMConvectorTest,AttributeGrade) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"E=mc2ba\u221E"; + std::wstring wsXmlString = L"E=mc2ba\u221E"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -980,7 +980,7 @@ TEST(SMConvectorTest,Example2) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; + std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -990,7 +990,7 @@ TEST(SMConvectorTest,Example3) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"c=a2+b2"; + std::wstring wsXmlString =L"c=a2+b2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1000,7 +1000,7 @@ TEST(SMConvectorTest,Example4) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"F=m\u00D7a"; + std::wstring wsXmlString =L"F=m\u00D7a"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1010,7 +1010,7 @@ TEST(SMConvectorTest,Example5) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"E=mc2"; + std::wstring wsXmlString =L"E=mc2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1020,7 +1020,7 @@ TEST(SMConvectorTest,Example6) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; + std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1030,7 +1030,7 @@ TEST(SMConvectorTest,Example8) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; + std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1040,7 +1040,7 @@ TEST(SMConvectorTest,Example9) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"abf'xdx=fb-fa"; + std::wstring wsXmlString =L"abf'xdx=fb-fa"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1050,7 +1050,7 @@ TEST(SMConvectorTest,Example10) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; + std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1060,7 +1060,7 @@ TEST(SMConvectorTest,LimAndCsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"lim21015244"; + std::wstring wsXmlString =L"lim21015244"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1070,7 +1070,7 @@ TEST(SMConvectorTest,LimSupAndCsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"lim sup10210100"; + std::wstring wsXmlString =L"lim sup10210100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1080,7 +1080,7 @@ TEST(SMConvectorTest,OverWithoutLeft) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"\u00B12105"; + std::wstring wsXmlString =L"\u00B12105"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1090,7 +1090,7 @@ TEST(SMConvectorTest,Newline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23102"; + std::wstring wsXmlString = L"23102"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1100,7 +1100,7 @@ TEST(SMConvectorTest,IndexAndBinOp) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2\u22C33410"; + std::wstring wsXmlString = L"2\u22C33410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1110,7 +1110,7 @@ TEST(SMConvectorTest,Example7) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; + std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1120,7 +1120,7 @@ TEST(SMConvectorTest,UnarySign) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3+69\u2213510"; + std::wstring wsXmlString = L"3+69\u2213510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1130,7 +1130,7 @@ TEST(SMConvectorTest,Example13) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; + std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1140,7 +1140,7 @@ TEST(SMConvectorTest,Example14) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; + std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1150,7 +1150,7 @@ TEST(SMConvectorTest,Example15) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"limx->0sinxx=1"; + std::wstring wsXmlString = L"limx->0sinxx=1"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1160,7 +1160,7 @@ TEST(SMConvectorTest,Example16) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; + std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1170,7 +1170,7 @@ TEST(SMConvectorTest,Example17) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"a2b+b2a\u22652ab"; + std::wstring wsXmlString = L"a2b+b2a\u22652ab"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1180,7 +1180,7 @@ TEST(SMConvectorTest,Example18) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"541021"; + std::wstring wsXmlString = L"541021"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1190,7 +1190,7 @@ TEST(SMConvectorTest,IndexWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"5867243"; + std::wstring wsXmlString = L"5867243"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1200,7 +1200,7 @@ TEST(SMConvectorTest,FunctionWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"10e2723"; + std::wstring wsXmlString = L"10e2723"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1210,7 +1210,7 @@ TEST(SMConvectorTest,IncorrectSizeAndFontInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"bolt2"; + std::wstring wsXmlString = L"bolt2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1220,7 +1220,7 @@ TEST(SMConvectorTest,IncorrectRGBColorInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2550257210"; + std::wstring wsXmlString = L"2550257210"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1230,7 +1230,7 @@ TEST(SMConvectorTest,IncorrectHexColorInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; + std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1240,7 +1240,7 @@ TEST(SMConvectorTest,IndexWithoutElement) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23"; + std::wstring wsXmlString = L"23"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1250,7 +1250,7 @@ TEST(SMConvectorTest,Neg) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"-1\u00AC105\u22287"; + std::wstring wsXmlString = L"-1\u00AC105\u22287"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1260,7 +1260,7 @@ TEST(SMConvectorTest,Frac) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; + std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1270,7 +1270,7 @@ TEST(SMConvectorTest,BracketIndexOnTopAndOperationOnSet) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3+105\u221612"; + std::wstring wsXmlString = L"3+105\u221612"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1280,7 +1280,7 @@ TEST(SMConvectorTest,SqrtWithIndex) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2log28=4"; + std::wstring wsXmlString = L"2log28=4"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1290,7 +1290,17 @@ TEST(SMConvectorTest,Binom) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2=432+1abc5"; + std::wstring wsXmlString = L"2=432+1abc5"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,UnarySignWithColor) +{ + std::wstring wsString = L"color green [color red 2 color blue + 10 setminus color red 5 over 9 underbrace 3 ]"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2+10\u2216593"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index e056cbb293a..721cb591049 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -36,36 +36,14 @@ namespace StarMath { CConversionSMtoOOXML::CConversionSMtoOOXML(): m_pXmlWrite(nullptr) { } + CConversionSMtoOOXML::~CConversionSMtoOOXML() + { + delete m_pXmlWrite; + } //check XMLWrite(if not nullptr == delete) void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; -// m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); -// if(iAlignment>= 0 && iAlignment <= 2) -// { -// std::wstring wsAlignment; -// switch(iAlignment) -// { -// case 0: -// wsAlignment = L"center"; -// break; -// case 1: -// wsAlignment = L"left"; -// break; -// case 2: -// wsAlignment = L"right"; -// break; -// default: -// wsAlignment = L"center"; -// break; -// } -// m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); -// m_pXmlWrite->WriteNodeBegin(L"m:jc",true); -// m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); -// m_pXmlWrite->WriteNodeEnd(L"",true,true); -// m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); -// } -// m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); for(CElement* oTempElement:arPars) { if(oTempElement != nullptr) @@ -83,13 +61,11 @@ namespace StarMath { oTempElement->ConversionToOOXML(m_pXmlWrite); } } -// EndConversion(); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) { if(pAttribute == nullptr) { - //тут должны быть базовые свойства шрифта, задаваемые выше pXmlWrite->WriteNodeBegin(L"w:rPr",false); pXmlWrite->WriteNodeBegin(L"w:rFonts",true); @@ -97,10 +73,10 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); } @@ -122,12 +98,11 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w",true,true); if(pAttribute->GetSize() == 0) { - //тут должны быть базовые свойства шрифта, задаваемые выше - далее везде где не задано - аналогично pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); } else if(pAttribute->GetSize() != 0) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 05d61d0b83d..e6cb1bf5e5c 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -41,6 +41,7 @@ namespace StarMath { { public: CConversionSMtoOOXML(); + ~CConversionSMtoOOXML(); void StartConversion(std::vector arPars, const unsigned int& iAlignment = -1); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 5836af722c6..f31356253c0 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -35,13 +35,17 @@ namespace StarMath { //class methods CParsStarMath - std::vector CParserStarMathString::Parse(std::wstring& wsParseString,const TBaseAttribute* pBaseAttribute) + CParserStarMathString::CParserStarMathString():m_iAlignment(0){} + CParserStarMathString::~CParserStarMathString() + { + for(CElement* pElement:m_arEquation) + delete pElement; + } + std::vector CParserStarMathString::Parse(std::wstring& wsParseString) { std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); CStarMathReader* pReader = new CStarMathReader(itStart,itEnd); - pReader->SetBaseAttribute(pBaseAttribute); - if(pBaseAttribute != nullptr && (pBaseAttribute->base_alignment >= 0 && pBaseAttribute->base_alignment <= 2)) - SetAlignment(pBaseAttribute->base_alignment); + pReader->SetBaseAttribute(m_stBaseAttribute); while(pReader->CheckIteratorPosition()) { if(!m_arEquation.empty()) @@ -73,7 +77,7 @@ namespace StarMath if(pReader->GetAttribute() != nullptr && !CheckForLeftArgument(pReader->GetGlobalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); - else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType())) + else if(pReader->GetAttribute() != nullptr && (pReader->GetLocalType() == TypeElement::plus || TypeElement::minus == pReader->GetLocalType() || TypeElement::frac == pReader->GetLocalType() || TypeElement::neg == pReader->GetLocalType())) pElement->SetBaseAttribute(pReader->GetAttribute()); pReader->ClearReader(); pElement->Parse(pReader); @@ -115,7 +119,7 @@ namespace StarMath case TypeElement::BinOperator: { CElementBinOperator* pBinOp = dynamic_cast(pElementWhichAdd); - if(pBinOp->GetType() == TypeElement::neg) + if(pBinOp->GetType() == TypeElement::neg || (pBinOp->GetAttribute()!= nullptr && pBinOp->MixedOperators(pBinOp->GetType()))) return false; else return SetLeft(pLeftArg, pElementWhichAdd); @@ -134,7 +138,10 @@ namespace StarMath } case TypeElement::Index: { - return SetLeft(pLeftArg,pElementWhichAdd); + CElementIndex * pIndex = dynamic_cast(pElementWhichAdd); + if(pIndex->GetType() != TypeElement::sqrt && pIndex->GetType() != TypeElement::nroot) + return SetLeft(pLeftArg,pElementWhichAdd); + else return false; } default: break; @@ -147,7 +154,7 @@ namespace StarMath { CElement* pFirstTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while(CheckForLeftArgument(pReader->GetGlobalType(),bConnection) && (pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) + while(CheckForLeftArgument(pReader->GetGlobalType(),bConnection) && (pReader->GetLocalType() != TypeElement::neg && pReader->GetLocalType() != TypeElement::frac && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pFirstTempElement); } @@ -228,8 +235,30 @@ namespace StarMath { return m_iAlignment; } + void CParserStarMathString::SetBaseFont(const std::wstring &wsNameFont) + { + m_stBaseAttribute.base_font_name = wsNameFont; + } + void CParserStarMathString::SetBaseSize(const unsigned int &iSize) + { + if(iSize < 130) + m_stBaseAttribute.base_font_size = iSize; + } + void CParserStarMathString::SetBaseAlignment(const unsigned int &iAlignment) + { + if(iAlignment > 0 && iAlignment < 3) + m_stBaseAttribute.base_alignment = iAlignment; + } + void CParserStarMathString::SetBaseBold(const bool &bBold) + { + m_stBaseAttribute.base_font_bold = bBold; + } + void CParserStarMathString::SetBaseItalic(const bool &bItal) + { + m_stBaseAttribute.base_font_italic = bItal; + } //class methods CAttribute - CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(0) + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(0),m_unCount(0) { } CAttribute::~CAttribute() @@ -267,7 +296,7 @@ namespace StarMath m_wsColor = L"000000"; return true; case TypeElement::blue: - m_wsColor = L"0400ff"; + m_wsColor = L"0000ff"; return true; case TypeElement::green: m_wsColor =L"00FF00"; @@ -462,32 +491,6 @@ namespace StarMath RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); return false; } -// std::wstring wsColorNumber = pReader->GetElement(); -// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) -// iRed = std::stoi(wsColorNumber); -// else -// { -// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); -// return false; -// } -// if(iRed > 255 || iRed < 0) -// return false; -// wsColorNumber = pReader->GetElement(); -// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) -// iGreen = std::stoi(wsColorNumber); -// else -// { -// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); -// return false; -// } -// wsColorNumber = pReader->GetElement(); -// if(TypeElement::undefine != CElementString::GetDigit(wsColorNumber)) -// iBlue = std::stoi(wsColorNumber); -// else -// { -// RefundOfTheAmountRGB(pReader,iRed,iGreen,iBlue); -// return false; -// } if(iRed > 255 || iGreen > 255 || iBlue > 255) m_wsColor = L"000000"; else @@ -623,10 +626,38 @@ namespace StarMath wsSum += std::to_wstring(iBlue); pReader->SetString(wsSum); } + bool CAttribute::CheckingForEmptiness() + { + if(!m_wsNameFont.empty()) + return true; + if(!m_wsColor.empty()) + return true; + if(m_bBold) + return true; + if(m_bItal) + return true; + if(m_iAlignment > 0 && m_iAlignment<=2) + return true; + if(m_iSize > 0) + return true; + return false; + } + void CAttribute::AddRef() + { + m_unCount++; + } + void CAttribute::Release() + { + m_unCount--; + if(m_unCount == 0) + delete this; + } //class methods CElement CElement::~CElement() { - delete m_pAttribute; +// delete m_pAttribute; + if(m_pAttribute != nullptr) + m_pAttribute->Release(); } CElement::CElement(): m_pAttribute(nullptr) {} @@ -693,7 +724,10 @@ namespace StarMath void CElement::SetBaseAttribute(CAttribute *pAttribute) { if(m_pAttribute == nullptr && pAttribute != nullptr) + { m_pAttribute = pAttribute; + m_pAttribute->AddRef(); + } else if(pAttribute != nullptr && pAttribute != m_pAttribute) { if(!m_pAttribute->GetBold() && pAttribute->GetBold()) @@ -790,10 +824,16 @@ namespace StarMath { SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + if(GetAttribute() != nullptr) + SetAttribute(GetAttribute()); } else if(m_enTypeBinOp == TypeElement::neg) + { SetRightArg(CParserStarMathString::ParseElement(pReader)); - else if(pReader->GetMarkForUnar() && MixedOperators(m_enTypeBinOp)) + if(GetAttribute()!= nullptr) + SetAttribute(GetAttribute()); + } + else if((pReader->GetMarkForUnar() || GetAttribute()!=nullptr)&& MixedOperators(m_enTypeBinOp)) { SetRightArg(CParserStarMathString::ParseElement(pReader)); } @@ -1613,7 +1653,7 @@ namespace StarMath { CElement* pTempElement = CParserStarMathString::ParseElement(pReader); pReader->ReadingTheNextToken(); - while((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac) || (pReader->GetGlobalType() == TypeElement::BracketWithIndex && !(TypeElement::intersection == m_enTypeSet || TypeElement::setminus == m_enTypeSet || TypeElement::setquotient == m_enTypeSet)) || (pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) + while(TypeElement::intersection != m_enTypeSet && TypeElement::setminus != m_enTypeSet && TypeElement::setquotient != m_enTypeSet && ((pReader->GetGlobalType() == TypeElement::BinOperator && pReader->GetLocalType()!=TypeElement::frac && pReader->GetLocalType()!= TypeElement::neg) || pReader->GetGlobalType() == TypeElement::BracketWithIndex || (pReader->GetGlobalType() == TypeElement::Index && pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType() != TypeElement::sqrt))) { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } @@ -1762,13 +1802,13 @@ namespace StarMath pXmlWrite->WriteString(L"\u2260"); break; case TypeElement::learrow: - pXmlWrite->WriteString(L"<"); + pXmlWrite->WriteString(L"<"); break; case TypeElement::learrowequals: pXmlWrite->WriteString(L"\u2264"); break; case TypeElement::riarrow: - pXmlWrite->WriteString(L">"); + pXmlWrite->WriteString(L">"); break; case TypeElement::riarrowequals: pXmlWrite->WriteString(L"\u2265"); @@ -2008,7 +2048,7 @@ namespace StarMath CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement); m_pValueIndex = pElement; } - m_pLeftArg = m_pValueIndex; +// m_pLeftArg = m_pValueIndex; } else { @@ -2543,10 +2583,14 @@ namespace StarMath m_pValueFrom->SetAttribute(pAttribute); if(m_pValueTo!=nullptr) m_pValueTo->SetAttribute(pAttribute); + if(m_pLowerIndex!=nullptr) + m_pLowerIndex->SetAttribute(pAttribute); + if(m_pUpperIndex!=nullptr) + m_pUpperIndex->SetAttribute(pAttribute); } // class methods CStarMathReader CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) - : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true),m_pBaseAttribute(nullptr) { m_itStart = itStart; m_itEnd = itEnd; @@ -2723,23 +2767,20 @@ namespace StarMath { return m_pAttribute; } - void CStarMathReader::SetBaseAttribute(const TBaseAttribute* pAttribute) - { - if(pAttribute!=nullptr) - { - m_pBaseAttribute = new CAttribute; - if(pAttribute->base_font_italic) - m_pBaseAttribute->SetItal(); - if(pAttribute->base_font_bold) - m_pBaseAttribute->SetBold(); - if(!pAttribute->base_font_name.empty()) - m_pBaseAttribute->SetFontName(pAttribute->base_font_name); - if(pAttribute->base_font_size != 0) - m_pBaseAttribute->SetSize(pAttribute->base_font_size); - if(pAttribute->base_alignment >= 0 && pAttribute->base_alignment <=2) - m_pBaseAttribute->SetAlignment(pAttribute->base_alignment); - } - else + void CStarMathReader::SetBaseAttribute(const TBaseAttribute& pAttribute) + { + m_pBaseAttribute = new CAttribute; + if(pAttribute.base_font_italic) + m_pBaseAttribute->SetItal(); + if(pAttribute.base_font_bold) + m_pBaseAttribute->SetBold(); + if(!pAttribute.base_font_name.empty()) + m_pBaseAttribute->SetFontName(pAttribute.base_font_name); + if(pAttribute.base_font_size != 0) + m_pBaseAttribute->SetSize(pAttribute.base_font_size); + if(pAttribute.base_alignment >= 0 && pAttribute.base_alignment <=2) + m_pBaseAttribute->SetAlignment(pAttribute.base_alignment); + if(!m_pBaseAttribute->CheckingForEmptiness()) m_pBaseAttribute = nullptr; } CAttribute* CStarMathReader::GetBaseAttribute() @@ -2969,32 +3010,34 @@ namespace StarMath CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - switch(m_enTypeBracketWithIndex) - { - case TypeElement::overbrace: - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); - break; - case TypeElement::underbrace: - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); - break; - default: - break; - } +// switch(m_enTypeBracketWithIndex) +// { +// case TypeElement::overbrace: +// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); +// break; +// case TypeElement::underbrace: +// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); +// break; +// default: +// break; +// } + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:groupChr",false,false); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeBegin(L"m:lim",false); - switch(m_enTypeBracketWithIndex) - { - case TypeElement::overbrace: - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); - break; - case TypeElement::underbrace: - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); - break; - default: - break; - } +// switch(m_enTypeBracketWithIndex) +// { +// case TypeElement::overbrace: +// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); +// break; +// case TypeElement::underbrace: +// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); +// break; +// default: +// break; +// } + CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); pXmlWrite->WriteNodeEnd(L"m:lim",false,false); pXmlWrite->WriteNodeEnd(wsNameNode,false,false); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 38393a1e268..48d66f721ef 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -46,11 +46,12 @@ namespace StarMath struct TBaseAttribute { - unsigned int base_font_size = 12; - std::wstring base_font_name = L"Arial"; - unsigned int base_alignment = 1;//(0 - center,1 - left,2 - right) - bool base_font_bold = false; - bool base_font_italic = false; + TBaseAttribute():base_font_size(0),base_alignment(0),base_font_bold(false),base_font_italic(false){}; + unsigned int base_font_size; + std::wstring base_font_name; + unsigned int base_alignment; + bool base_font_bold; + bool base_font_italic; }; class CAttribute @@ -84,11 +85,15 @@ namespace StarMath bool CheckAttribute(); //checking an element for a number from 1 to 9 or from the letter A to F static bool CheckHexPosition(const wchar_t& cToken); + bool CheckingForEmptiness(); + void AddRef(); + void Release(); private: void RefundOfTheAmountRGB(CStarMathReader* pReader,const int& iRed, const int& iGreen, const int& iBlue); std::wstring m_wsColor,m_wsNameFont; bool m_bBold,m_bItal,m_bPhantom,m_bStrike; unsigned int m_iSize,m_iAlignment; + unsigned int m_unCount; }; //Сlass for working with tokens (reading, defining types, passing) class CStarMathReader @@ -109,13 +114,13 @@ namespace StarMath bool EmptyString(); void SetAttribute(CAttribute* pAttribute); CAttribute* GetAttribute(); - void SetBaseAttribute(const TBaseAttribute* pAttribute); + void SetBaseAttribute(const TBaseAttribute& pAttribute); CAttribute* GetBaseAttribute(); //The function returns a Token from a string (the iterator pointer m_itStart is on the next element) std::wstring GetElement(); - // + //taking a token for a color in hex form std::wstring TakingElementForHex(); - // + //taking a token for a color in rgb form int TakingElementForRGB(); void SetString(const std::wstring& wsToken); void FindingTheEndOfParentheses(); @@ -214,9 +219,9 @@ namespace StarMath static TypeElement GetBinOperator(const std::wstring& wsToken); static void UnaryCheck(CStarMathReader* pReader,CElement* pLastElement); const TypeElement& GetType(); - private: //checking for signs such as -,+,-+,+-. static bool MixedOperators(const TypeElement& enType); + private: void SetAttribute(CAttribute* pAttribute) override; bool IsBinOperatorLowPrior(); void Parse(CStarMathReader* pReader) override; @@ -422,7 +427,9 @@ namespace StarMath class CParserStarMathString { public: - std::vector Parse(std::wstring& wsParseString, const TBaseAttribute* pBaseAttribute = nullptr); + CParserStarMathString(); + ~CParserStarMathString(); + std::vector Parse(std::wstring& wsParseString); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); @@ -438,7 +445,13 @@ namespace StarMath static void ReadingElementsWithAttributes(CStarMathReader* pReader,CElement*& pSavingElement); void SetAlignment(const unsigned int& iAlignment); const unsigned int& GetAlignment(); + void SetBaseFont(const std::wstring& wsNameFont); + void SetBaseSize(const unsigned int& iSize); + void SetBaseAlignment(const unsigned int& iAlignment); + void SetBaseItalic(const bool& bItal); + void SetBaseBold(const bool& bBold); private: + TBaseAttribute m_stBaseAttribute; std::vector m_arEquation; unsigned int m_iAlignment; }; diff --git a/OdfFile/Reader/Format/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index aa46882f156..0ec2c0ff374 100644 --- a/OdfFile/Reader/Format/math_elements.cpp +++ b/OdfFile/Reader/Format/math_elements.cpp @@ -114,7 +114,13 @@ void math_semantics::oox_convert(oox::math_context & Context) /*parser.set*/ /*?*/ /*converter.set*/ Context.base_alignment_; /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_italic_; /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_bold_; - + + parser.SetBaseFont(Context.base_font_name_); + parser.SetBaseSize(Context.base_font_size_); + parser.SetBaseAlignment(Context.base_alignment_); + parser.SetBaseItalic(Context.base_font_italic_); + parser.SetBaseBold(Context.base_font_bold_); + /*result = */converter.StartConversion(parser.Parse(annotation_text)); Context.output_stream() << converter.GetOOXML(); From bb858cc24a8ed36ce0cf1f3e9f74cb6a0a1a829f Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Fri, 5 Apr 2024 16:59:03 +0300 Subject: [PATCH 503/794] . --- OdfFile/Projects/Windows/cpodf.vcxproj.filters | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index c5800a52592..68c27b33cff 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -945,7 +945,6 @@ oox\pptx -<<<<<<< HEAD starmath @@ -954,8 +953,6 @@ starmath -======= ->>>>>>> origin/fix/bug61378 elements From 8c522aa006f64b320d2506fb9dfce7ae61611d8c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 5 Apr 2024 17:21:51 +0300 Subject: [PATCH 504/794] Fix repeat fonts --- PdfFile/PdfReader.cpp | 6 +- PdfFile/SrcReader/PdfAnnot.cpp | 450 +++++++++++++++++---------------- PdfFile/SrcReader/PdfAnnot.h | 10 +- 3 files changed, 243 insertions(+), 223 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 57bb2b9164e..c5973719808 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1114,8 +1114,8 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) Object oAnnotRef; oAnnots.arrayGetNF(i, &oAnnotRef); - std::vector arrRC = PdfReader::CAnnotMarkup::ReadRC(sRC); - std::map mFreeText = PdfReader::CAnnotMarkup::SetFont(m_pPDFDocument, &oAnnotRef, m_pFontManager, m_pFontList, arrRC, nTypeFonts); + std::vector arrRC = PdfReader::AnnotMarkup::ReadRC(sRC); + std::map mFreeText = PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, &oAnnotRef, m_pFontManager, m_pFontList, arrRC, nTypeFonts); for (std::map::iterator it = mFreeText.begin(); it != mFreeText.end(); ++it) { if (m_mFonts.find(it->first) != m_mFonts.end()) @@ -1126,6 +1126,8 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) m_mFonts[it->first] = it->second; } oAnnotRef.free(); + for (int j = 0; j < arrRC.size(); ++j) + RELEASEOBJECT(arrRC[j]); } oAnnots.free(); } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index b878a3bbd76..15cafb8f9fb 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -450,6 +450,13 @@ GList* tokenize(GString *s) } return toks; } +bool isBaseFont(const std::wstring& wsName) +{ + return wsName == L"Courier" || wsName == L"Courier-Bold" || wsName == L"Courier-BoldOblique" || wsName == L"Courier-Oblique" || + wsName == L"Helvetica" || wsName == L"Helvetica-Bold" || wsName == L"Helvetica-BoldOblique" || + wsName == L"Helvetica-Oblique" || wsName == L"Symbol" || wsName == L"Times-Bold" || wsName == L"Times-BoldItalic" || + wsName == L"Times-Italic" || wsName == L"Times-Roman" || wsName == L"ZapfDingbats"; +} //------------------------------------------------------------------------ // Widget @@ -1068,12 +1075,10 @@ std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CP } Ref oEmbRef; - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(gfxFont->getName()); std::wstring wsFileName; - if (((nTypeFonts & 1) && gfxFont->getEmbeddedFontID(&oEmbRef)) || ((nTypeFonts & 2) && GetBaseFont(wsFontBaseName, pData14, nSize14))) + if (((nTypeFonts & 1) && gfxFont->getEmbeddedFontID(&oEmbRef)) || ((nTypeFonts & 2) && isBaseFont(wsFontBaseName))) { std::wstring wsFontName; GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName); @@ -2125,7 +2130,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : std::string sRC = DictLookupString(&oAnnot, "RC", 3); // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock - m_arrRC = ReadRC(sRC); + m_arrRC = AnnotMarkup::ReadRC(sRC); if (m_arrRC.empty()) m_unFlags &= ~(1 << 3); else @@ -2162,15 +2167,101 @@ CAnnotMarkup::~CAnnotMarkup() for (int i = 0; i < m_arrRC.size(); ++i) RELEASEOBJECT(m_arrRC[i]); } -std::vector CAnnotMarkup::ReadRC(const std::string& sRC) +void ReadFontData(const std::string& sData, CAnnotMarkup::CFontData* pFont) { - std::vector arrRC; + size_t nSemicolon = 0; + size_t nColon = sData.find(':'); + while (nColon != std::string::npos && nColon > nSemicolon) + { + std::string sProperty = sData.substr(nSemicolon, nColon - nSemicolon); + nSemicolon = sData.find(';', nSemicolon); + nColon++; + std::string sValue = sData.substr(nColon, nSemicolon - nColon); + nColon = sData.find(':', nSemicolon); + nSemicolon++; + + if (sProperty == "font-size") + pFont->dFontSise = std::stod(sValue); + else if (sProperty == "text-align") + { + // 0 start / left + if (sValue == "center" || sValue == "middle") + pFont->nAlign = 1; + else if (sValue == "right" || sValue == "end") + pFont->nAlign = 2; + else if (sValue == "justify") + pFont->nAlign = 3; + } + else if (sProperty == "color") + { + if (sValue[0] == '#') + { + sValue = sValue.substr(1); + BYTE nColor1 = 0, nColor2 = 0, nColor3 = 0; + if (sValue.length() == 6) + sscanf(sValue.c_str(), "%2hhx%2hhx%2hhx", &nColor1, &nColor2, &nColor3); + else if (sValue.length() == 3) + { + sscanf(sValue.c_str(), "%1hhx%1hhx%1hhx", &nColor1, &nColor2, &nColor3); + nColor1 *= 17; + nColor2 *= 17; + nColor3 *= 17; + } + + pFont->dColor[0] = (double)nColor1 / 255.0; + pFont->dColor[1] = (double)nColor2 / 255.0; + pFont->dColor[2] = (double)nColor3 / 255.0; + } + } + else if (sProperty == "font-weight") + { + // 0 normal / 300 / 400 / 500 + if (sValue == "normal" || sValue == "300" || sValue == "400" || sValue == "500") + pFont->unFontFlags &= ~(1 << 0); + else if (sValue == "bold" || sValue == "bolder" || sValue == "600" || sValue == "700" || sValue == "800" || sValue == "900") + pFont->unFontFlags |= (1 << 0); + } + else if (sProperty == "font-style") + { + // 0 normal + if (sValue == "normal") + pFont->unFontFlags &= ~(1 << 1); + else if (sValue == "italic" || sValue.find("oblique") != std::string::npos) + pFont->unFontFlags |= (1 << 1); + } + else if (sProperty == "font-family") + pFont->sFontFamily = sValue[0] == '\'' ? sValue.substr(1, sValue.length() - 2) : sValue; + else if (sProperty == "text-decoration") + { + if (sValue.find("line-through") != std::string::npos) + pFont->unFontFlags |= (1 << 3); + if (sValue.find("word") != std::string::npos || sValue.find("underline") != std::string::npos) + pFont->unFontFlags |= (1 << 4); + if (sValue.find("none") != std::string::npos) + { + pFont->unFontFlags &= ~(1 << 3); + pFont->unFontFlags &= ~(1 << 4); + } + } + else if (sProperty == "vertical-align") + { + pFont->unFontFlags |= (1 << 5); + pFont->dVAlign = std::stod(sValue); + if (pFont->dVAlign == 0 && sValue[0] == '-') + pFont->dVAlign = -0.01; + } + // font-stretch + } +} +std::vector AnnotMarkup::ReadRC(const std::string& sRC) +{ + std::vector arrRC; XmlUtils::CXmlLiteReader oLightReader; if (sRC.empty() || !oLightReader.FromStringA(sRC) || !oLightReader.ReadNextNode() || oLightReader.GetNameA() != "body") return arrRC; - CFontData oFontBase; + CAnnotMarkup::CFontData oFontBase; while (oLightReader.MoveToNextAttribute()) { if (oLightReader.GetNameA() == "style") @@ -2196,7 +2287,7 @@ std::vector CAnnotMarkup::ReadRC(const std::string& sR std::string sName = oLightReader.GetNameA(); if (sName == "span") { - CFontData* pFont = new CFontData(oFontBase); + CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase); while (oLightReader.MoveToNextAttribute()) { if (oLightReader.GetNameA() == "style") @@ -2212,7 +2303,7 @@ std::vector CAnnotMarkup::ReadRC(const std::string& sR } else if (sName == "#text") { - CFontData* pFont = new CFontData(oFontBase); + CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase); pFont->sText = oLightReader.GetTextA(); arrRC.push_back(pFont); } @@ -2223,9 +2314,9 @@ std::vector CAnnotMarkup::ReadRC(const std::string& sR } void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { - SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); + AnnotMarkup::SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); } -std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, const std::vector& arrRC, int nTypeFonts) +std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector& arrRC, int nTypeFonts) { std::map mRes; if (arrRC.empty()) @@ -2236,249 +2327,174 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec oAnnotRef->fetch(pXref, &oAnnot); Object oAP, oN, oR, oFonts; - if (oAnnot.dictLookup("AP", &oAP)->isDict() && oAP.dictLookup("N", &oN)->isStream() && oN.streamGetDict()->lookup("Resources", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream() || !oN.streamGetDict()->lookup("Resources", &oR)->isDict() || !oR.dictLookup("Font", &oFonts)->isDict()) { - CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); - std::vector arrFontFreeText; + oAP.free(); oN.free(); oR.free(); oFonts.free(); + return mRes; + } - for (int i = 0; i < oFonts.dictGetLength(); ++i) + CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); + std::vector arrFontFreeText; + + for (int i = 0, nFonts = oFonts.dictGetLength(); i < nFonts; ++i) + { + Object oFontRef; + if (!oFonts.dictGetValNF(i, &oFontRef)->isRef()) { - Object oFontRef; - if (oFonts.dictGetValNF(i, &oFontRef)->isRef()) - { - std::string sFontName, sActual; - bool bBold = false, bItalic = false; - std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); - - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; - CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); - if (pFontStream && !GetBaseFont(sFontPath, pData14, nSize14)) - { - bool bNew = true; - std::vector* arrFontList = pAppFontList->GetFonts(); - for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) - { - if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || - (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && - (*arrFontList)[nIndex]->m_bBold == bBold && - (*arrFontList)[nIndex]->m_bItalic == bItalic) - { - bNew = false; - break; - } - } - if (bNew) - pAppFontList->Add(sFontPath, pFontStream); - arrFontFreeText.push_back(sFontPath); - } - } oFontRef.free(); + continue; } - for (int i = 0; i < arrRC.size(); ++i) + std::string sFontName, sActual; + bool bBold = false, bItalic = false; + std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); + if (sFontPath.empty()) { - if (arrRC[i]->bFind) - continue; + oFontRef.free(); + continue; + } - std::string sFontName = arrRC[i]->sFontFamily; - bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); - bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); - bool bBase = sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats"; - if ((nTypeFonts & 2) && bBase) + CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); + if (pFontStream && !isBaseFont(sFontPath)) + { + bool bNew = true; + std::vector* arrFontList = pAppFontList->GetFonts(); + for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) { - if (sFontName == "Times New Roman") - { - if (bBold && bItalic) - sFontName = "Times-BoldItalic"; - else if (bBold) - sFontName = "Times-Bold"; - else if (bItalic) - sFontName = "Times-Italic"; - else - sFontName = "Times-Roman"; - } - else if (sFontName == "Courier" || sFontName == "Helvetica") + if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || + (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && + (*arrFontList)[nIndex]->m_bBold == bBold && + (*arrFontList)[nIndex]->m_bItalic == bItalic) { - if (bBold && bItalic) - sFontName += "-BoldOblique"; - else if (bBold) - sFontName += "-Bold"; - else if (bItalic) - sFontName += "-Oblique"; + bNew = false; + break; } + } + if (bNew) + pAppFontList->Add(sFontPath, pFontStream); + arrFontFreeText.push_back(sFontPath); + } + oFontRef.free(); + } - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; - std::wstring wsFontName = UTF8_TO_U(sFontName); - if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) - NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); - std::string sFontNameBefore = arrRC[i]->sFontFamily; - arrRC[i]->sFontFamily = sFontName; - arrRC[i]->bFind = true; - mRes[wsFontName] = wsFontName; + for (int i = 0; i < arrRC.size(); ++i) + { + if (arrRC[i]->bFind) + continue; - for (int j = i; j < arrRC.size(); ++j) + std::string sFontName = arrRC[i]->sFontFamily; + bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); + bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); + bool bBase = sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats"; + if ((nTypeFonts & 2) && bBase) + { + if (sFontName == "Times New Roman") + { + if (bBold && bItalic) + sFontName = "Times-BoldItalic"; + else if (bBold) + sFontName = "Times-Bold"; + else if (bItalic) + sFontName = "Times-Italic"; + else + sFontName = "Times-Roman"; + } + else if (sFontName == "Courier" || sFontName == "Helvetica") + { + if (bBold && bItalic) + sFontName += "-BoldOblique"; + else if (bBold) + sFontName += "-Bold"; + else if (bItalic) + sFontName += "-Oblique"; + } + + const unsigned char* pData14 = NULL; + unsigned int nSize14 = 0; + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); + std::string sFontNameBefore = arrRC[i]->sFontFamily; + arrRC[i]->sFontFamily = sFontName; + arrRC[i]->bFind = true; + mRes[wsFontName] = wsFontName; + + for (int j = i; j < arrRC.size(); ++j) + { + if (arrRC[j]->sFontFamily == sFontNameBefore && bBold == (bool)((arrRC[j]->unFontFlags >> 0) & 1) && bItalic == (bool)((arrRC[j]->unFontFlags >> 1) & 1)) { - if (arrRC[j]->sFontFamily == sFontNameBefore) - { - arrRC[j]->sFontFamily = sFontName; - arrRC[j]->bFind = true; - } + arrRC[j]->sFontFamily = sFontName; + arrRC[j]->bFind = true; } } - if ((nTypeFonts & 1) && !bBase) + } + if ((nTypeFonts & 1) && !bBase) + { + NSFonts::CFontSelectFormat oFontSelect; + if (bBold) + oFontSelect.bBold = new INT(1); + if (bItalic) + oFontSelect.bItalic = new INT(1); + oFontSelect.wsName = new std::wstring(UTF8_TO_U(sFontName)); + + NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); + if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { - NSFonts::CFontSelectFormat oFontSelect; - if (bBold) - oFontSelect.bBold = new INT(1); - if (bItalic) - oFontSelect.bItalic = new INT(1); - oFontSelect.wsName = new std::wstring(UTF8_TO_U(sFontName)); - - NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); - if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) + bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); + std::wstring wsFontBaseName = pFontInfo->m_wsFontName; + if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') { - bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); - std::wstring wsFontBaseName = pFontInfo->m_wsFontName; - if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; nIndex++) + wchar_t nChar = wsFontBaseName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') { - wchar_t nChar = wsFontBaseName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } + bIsRemove = false; + break; } - if (bIsRemove) - wsFontBaseName.erase(0, 7); } + if (bIsRemove) + wsFontBaseName.erase(0, 7); + } - if (bFreeText) - { - arrRC[i]->sFontFamily = U_TO_UTF8(wsFontBaseName); - mRes[wsFontBaseName] = pFontInfo->m_wsFontPath; - } - else - { - arrRC[i]->unFontFlags |= (1 << 6); - arrRC[i]->sActualFont = U_TO_UTF8(wsFontBaseName); - } - arrRC[i]->bFind = true; + if (bFreeText) + { + arrRC[i]->sFontFamily = U_TO_UTF8(wsFontBaseName); + mRes[wsFontBaseName] = pFontInfo->m_wsFontPath; + } + else + { + arrRC[i]->unFontFlags |= (1 << 6); + arrRC[i]->sActualFont = U_TO_UTF8(wsFontBaseName); + } + arrRC[i]->bFind = true; - std::string sFontNameNew = bFreeText ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont; - for (int j = i; j < arrRC.size(); ++j) + std::string sFontNameNew = bFreeText ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont; + for (int j = i; j < arrRC.size(); ++j) + { + if (arrRC[j]->sFontFamily == sFontName && bBold == (bool)((arrRC[j]->unFontFlags >> 0) & 1) && bItalic == (bool)((arrRC[j]->unFontFlags >> 1) & 1)) { - if (arrRC[j]->sFontFamily == sFontName) + if (bFreeText) + arrRC[j]->sFontFamily = sFontNameNew; + else { - if (bFreeText) - arrRC[j]->sFontFamily = sFontNameNew; - else - { - arrRC[j]->unFontFlags |= (1 << 6); - arrRC[j]->sActualFont = sFontNameNew; - } - arrRC[j]->bFind = true; + arrRC[j]->unFontFlags |= (1 << 6); + arrRC[j]->sActualFont = sFontNameNew; } + arrRC[j]->bFind = true; } } } } } + + oAP.free(); oN.free(); oR.free(); oFonts.free(); oAnnot.free(); return mRes; } -void CAnnotMarkup::ReadFontData(const std::string& sData, CFontData* pFont) -{ - size_t nSemicolon = 0; - size_t nColon = sData.find(':'); - while (nColon != std::string::npos && nColon > nSemicolon) - { - std::string sProperty = sData.substr(nSemicolon, nColon - nSemicolon); - nSemicolon = sData.find(';', nSemicolon); - nColon++; - std::string sValue = sData.substr(nColon, nSemicolon - nColon); - nColon = sData.find(':', nSemicolon); - nSemicolon++; - - if (sProperty == "font-size") - pFont->dFontSise = std::stod(sValue); - else if (sProperty == "text-align") - { - // 0 start / left - if (sValue == "center" || sValue == "middle") - pFont->nAlign = 1; - else if (sValue == "right" || sValue == "end") - pFont->nAlign = 2; - else if (sValue == "justify") - pFont->nAlign = 3; - } - else if (sProperty == "color") - { - if (sValue[0] == '#') - { - sValue = sValue.substr(1); - BYTE nColor1 = 0, nColor2 = 0, nColor3 = 0; - if (sValue.length() == 6) - sscanf(sValue.c_str(), "%2hhx%2hhx%2hhx", &nColor1, &nColor2, &nColor3); - else if (sValue.length() == 3) - { - sscanf(sValue.c_str(), "%1hhx%1hhx%1hhx", &nColor1, &nColor2, &nColor3); - nColor1 *= 17; - nColor2 *= 17; - nColor3 *= 17; - } - - pFont->dColor[0] = (double)nColor1 / 255.0; - pFont->dColor[1] = (double)nColor2 / 255.0; - pFont->dColor[2] = (double)nColor3 / 255.0; - } - } - else if (sProperty == "font-weight") - { - // 0 normal / 300 / 400 / 500 - if (sValue == "normal" || sValue == "300" || sValue == "400" || sValue == "500") - pFont->unFontFlags &= ~(1 << 0); - else if (sValue == "bold" || sValue == "bolder" || sValue == "600" || sValue == "700" || sValue == "800" || sValue == "900") - pFont->unFontFlags |= (1 << 0); - } - else if (sProperty == "font-style") - { - // 0 normal - if (sValue == "normal") - pFont->unFontFlags &= ~(1 << 1); - else if (sValue == "italic" || sValue.find("oblique") != std::string::npos) - pFont->unFontFlags |= (1 << 1); - } - else if (sProperty == "font-family") - pFont->sFontFamily = sValue[0] == '\'' ? sValue.substr(1, sValue.length() - 2) : sValue; - else if (sProperty == "text-decoration") - { - if (sValue.find("line-through") != std::string::npos) - pFont->unFontFlags |= (1 << 3); - if (sValue.find("word") != std::string::npos || sValue.find("underline") != std::string::npos) - pFont->unFontFlags |= (1 << 4); - if (sValue.find("none") != std::string::npos) - { - pFont->unFontFlags &= ~(1 << 3); - pFont->unFontFlags &= ~(1 << 4); - } - } - else if (sProperty == "vertical-align") - { - pFont->unFontFlags |= (1 << 5); - pFont->dVAlign = std::stod(sValue); - if (pFont->dVAlign == 0 && sValue[0] == '-') - pFont->dVAlign = -0.01; - } - // font-stretch - } -} CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) { bFind = oFont.bFind; diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 12ee43c04f1..277493c33c7 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -345,8 +345,7 @@ class CAnnotMarkup : public CAnnot }; void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); - static std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, const std::vector& arrRC, int nTypeFonts = 3); - static std::vector ReadRC(const std::string& sRC); + protected: CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); virtual ~CAnnotMarkup(); @@ -354,8 +353,6 @@ class CAnnotMarkup : public CAnnot virtual void ToWASM(NSWasm::CData& oRes) override; private: - static void ReadFontData(const std::string& sData, CFontData* pFont); - BYTE m_nRT; // Тип аннотации-ответа unsigned int m_unRefNumPopup; // Номер ссылки на всплывающую аннотацию unsigned int m_unRefNumIRT; // Номер ссылки на аннотацию-ответ @@ -365,6 +362,11 @@ class CAnnotMarkup : public CAnnot std::string m_sSubj; // Краткое описание std::vector m_arrRC; // Форматированный текст }; +namespace AnnotMarkup +{ +std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, std::vector& arrRC, int nTypeFonts = 3); +std::vector ReadRC(const std::string& sRC); +} //------------------------------------------------------------------------ // PdfReader::CAnnotText From 2ab2cb7cf2bfcf6ebd2f63c1f52a5d4ef90b509d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 8 Apr 2024 18:45:59 +0600 Subject: [PATCH 505/794] Fix connections conversion --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 2 +- OOXML/XlsxFormat/Table/Connections.cpp | 61 +++++++++++++++++++++++-- OOXML/XlsxFormat/Table/Connections.h | 1 + 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 68dd8c83864..bdd0eb0e1e3 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -712,7 +712,7 @@ namespace OOX { if(i->m_sUri == L"{DE250136-89BD-433C-8126-D09CA5730AF9}") { - ptr->m_EXTCONN15 = i->m_oConnection->toBin(); + ptr->m_EXTCONN15 = i->m_oConnection->toBin15(); } } return XLS::BaseObjectPtr{ptr}; diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index 9230e719796..545002a6eb6 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -318,7 +318,12 @@ namespace OOX { auto ptr(new XLSB::RangePr15); if(m_oSourceName.IsInit()) - ptr->irstSourceName = m_oSourceName.get(); + { + auto tempStr = m_oSourceName.get(); + ptr->irstSourceName = tempStr.substr(0, tempStr.size()-2); + } + else + ptr->irstSourceName.setSize(0xFFFFFFFF); return XLS::BaseObjectPtr{ptr}; } EElementType CRangePr::getType() const @@ -378,14 +383,29 @@ namespace OOX { auto ptr1(new XLSB::ECDBPROPS); auto ptr(new XLSB::BeginECDbProps); + ptr1->m_BrtBeginECDbProps = XLS::BaseObjectPtr{ptr}; if(m_oConnection.IsInit()) ptr->stConn = m_oConnection.get(); + else + ptr->stConn = false; if(m_oCommand.IsInit()) ptr->stCmd = m_oCommand.get(); + else + { + ptr->stCmd = false; + ptr->fLoadCmd = false; + } if(m_oServerCommand.IsInit()) ptr->stCmdSvr = m_oServerCommand.get(); + else + { + ptr->fLoadCmdSvr = false; + ptr->stCmdSvr = false; + } if(m_oCommandType.IsInit()) ptr->icmdtype = m_oCommandType.get(); + else + ptr->icmdtype = 0; return XLS::BaseObjectPtr{ptr1}; } EElementType CDbPr::getType() const @@ -491,15 +511,15 @@ namespace OOX if(m_oServerNumberFormat.IsInit()) ptr->fSrvFmtNum = m_oServerNumberFormat.get(); else - ptr->fSrvFmtNum = false; + ptr->fSrvFmtNum = true; if(m_oServerFont.IsInit()) ptr->fSrvFmtFlags = m_oServerFont.get(); else - ptr->fSrvFmtFlags = false; + ptr->fSrvFmtFlags = true; if(m_oServerFontColor.IsInit()) ptr->fSrvFmtFore = m_oServerFontColor.get(); else - ptr->fSrvFmtFore = false; + ptr->fSrvFmtFore = true; return XLS::BaseObjectPtr{ptr1}; } EElementType COlapPr::getType() const @@ -981,6 +1001,31 @@ namespace OOX } } } + XLS::BaseObjectPtr CConnection::toBin15() + { + XLS::BaseObjectPtr objectPtr; + + auto ptr(new XLSB::EXTCONN15); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConn15); + ptr1->fAutoDelete = false; + ptr1->fExcludeFromRefreshAll = false; + ptr1->fSandbox = false; + ptr1->fUsedByAddin = false; + if(m_oIdExt.IsInit() && !m_oIdExt.get().empty()) + ptr1->irstId = m_oIdExt.get(); + else + { + ptr1->fSandbox = true; + ptr1->irstId.setSize(0xFFFFFFFF); + } + + ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; + if(m_oRangePr.IsInit()) + ptr->m_source = m_oRangePr->toBin(); + return objectPtr; + + } XLS::BaseObjectPtr CConnection::toBin() { XLS::BaseObjectPtr objectPtr; @@ -1021,12 +1066,16 @@ namespace OOX if(m_oType.IsInit()) ptr1->idbtype = m_oType.get(); + else + ptr1->idbtype = 0; if(m_oName.IsInit()) ptr1->stConnName = m_oName.get(); else ptr1->stConnName = L""; if(m_oId.IsInit()) ptr1->dwConnID = m_oId->GetValue(); + else + ptr1->dwConnID = 1; if(m_oCredentials.IsInit()) ptr1->iCredMethod = m_oCredentials->GetValue(); else @@ -1081,10 +1130,12 @@ namespace OOX ptr1->fRefreshOnLoad = false; if(m_oSaveData.IsInit()) ptr1->fSaveData = m_oSaveData.get(); + else + ptr1->fSaveData = false; if(m_oSavePassword.IsInit()) ptr1->pc = m_oSavePassword.get(); else - ptr1->pc = 0; + ptr1->pc = 2; if(m_oSingleSignOnId.IsInit()) ptr1->stSso = m_oSingleSignOnId.get(); else diff --git a/OOXML/XlsxFormat/Table/Connections.h b/OOXML/XlsxFormat/Table/Connections.h index 00107d26f2f..5a903fbb620 100644 --- a/OOXML/XlsxFormat/Table/Connections.h +++ b/OOXML/XlsxFormat/Table/Connections.h @@ -328,6 +328,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin15(); virtual EElementType getType() const; From 4ddde8246d839c8a78765ac2e5fe5541c01c3707 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 8 Apr 2024 17:17:06 +0300 Subject: [PATCH 506/794] Add ctPageRotate, AddPage and RemovePage --- DesktopEditor/graphics/IRenderer.h | 1 + DesktopEditor/graphics/MetafileToRenderer.cpp | 6 ++++++ DesktopEditor/graphics/MetafileToRenderer.h | 1 + DesktopEditor/graphics/MetafileToRendererReader.cpp | 1 + DesktopEditor/graphics/commands/AnnotField.cpp | 9 +++++++++ DesktopEditor/graphics/commands/AnnotField.h | 13 +++++++++++++ PdfFile/OnlineOfficeBinToPdf.cpp | 9 ++++++++- PdfFile/PdfFile.cpp | 8 ++++++++ 8 files changed, 47 insertions(+), 1 deletion(-) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 10537695936..1162cfad9d2 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -149,6 +149,7 @@ class IAdvancedCommand WidgetsInfo = 6, ShapeStart = 7, ShapeEnd = 8, + PageRotate = 9, Undefined = 255 }; diff --git a/DesktopEditor/graphics/MetafileToRenderer.cpp b/DesktopEditor/graphics/MetafileToRenderer.cpp index cb222a7c851..35683b3f23e 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -927,6 +927,7 @@ namespace NSOnlineOfficeBinToPdf case ctWidgetsInfo: case ctShapeStart: case ctShapeEnd: + case ctPageRotate: { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Undefined; switch (eCommand) @@ -937,6 +938,7 @@ namespace NSOnlineOfficeBinToPdf case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break; case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break; case ctShapeEnd: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; break; + case ctPageRotate: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::PageRotate; break; default: break; } @@ -1256,6 +1258,10 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: case ctAnnotField: case ctAnnotFieldDelete: + case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: + case ctPageRotate: default: { BYTE* cur = oReader.GetCurrentBuffer(); diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index 836cd7a6909..825f5f1d439 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -191,6 +191,7 @@ namespace NSOnlineOfficeBinToPdf ctPageStart = 202, ctPageEnd = 203, + ctPageRotate = 204, // gradients diff --git a/DesktopEditor/graphics/MetafileToRendererReader.cpp b/DesktopEditor/graphics/MetafileToRendererReader.cpp index 46827f59b47..0eeceb1e188 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -60,6 +60,7 @@ namespace NSOnlineOfficeBinToPdf case ctWidgetsInfo: return Read_Command (this, pCorrector); case ctShapeStart: return Read_Command (this, pCorrector); case ctShapeEnd: return Read_Command (this, pCorrector); + case ctPageRotate: return Read_Command (this, pCorrector); default: break; } diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index d85547551f6..f8b65d6e91e 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1011,3 +1011,12 @@ bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafile CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { return true; } + +CPageRotate::CPageRotate() : IAdvancedCommand(AdvancedCommandType::PageRotate) {} +int CPageRotate::GetPageRotate() { return m_nPageRotate; } +bool CPageRotate::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_nPageRotate = pReader->ReadInt(); + return true; +} + diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 2ddf3f24a83..43e042246b1 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -529,4 +529,17 @@ class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); }; +class GRAPHICS_DECL CPageRotate : public IAdvancedCommand +{ +public: + CPageRotate(); + + int GetPageRotate(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + int m_nPageRotate; +}; + #endif // _BUILD_ANNOTFIELD_H_ diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 326ade47197..fdc6bc08ad2 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -191,9 +191,16 @@ namespace NSOnlineOfficeBinToPdf break; } case AddCommandType::AddPage: + { + pPdf->AddPage(nPageNum); + + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 9) , &oCorrector); + oReader.Skip(nLen - 9); + break; + } case AddCommandType::RemovePage: { - // TODO: version 7.6+ + pPdf->DeletePage(nPageNum); break; } case AddCommandType::WidgetInfo: diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 5a560a09fd8..1878491675c 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1158,6 +1158,7 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: case IAdvancedCommand::AdvancedCommandType::ShapeStart: case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + case IAdvancedCommand::AdvancedCommandType::PageRotate: return S_OK; default: break; @@ -1229,6 +1230,13 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) m_pInternal->pEditor->EndMarkedContent(); return S_OK; } + case IAdvancedCommand::AdvancedCommandType::PageRotate: + { + CPageRotate* pCommand = (CPageRotate*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + m_pInternal->pWriter->PageRotate(pCommand->GetPageRotate()); + return S_OK; + } default: break; } From e33e659c22550d23cd99eafc88a7dc40b0e3c13c Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 8 Apr 2024 17:35:40 +0300 Subject: [PATCH 507/794] Restore write xfrm to docx shapes. Add pptx shapes to wasm module --- DesktopEditor/cximage/png/pnglibconf.h | 2 +- .../pro/js/wasm/js/drawingfile_base.js | 4 +- .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 +- .../graphics/pro/js/wasm/src/drawingfile.h | 8 +++- DocxRenderer/src/logic/elements/Shape.cpp | 42 +++++++------------ DocxRenderer/src/logic/elements/Shape.h | 2 +- 6 files changed, 28 insertions(+), 34 deletions(-) diff --git a/DesktopEditor/cximage/png/pnglibconf.h b/DesktopEditor/cximage/png/pnglibconf.h index db81a16d46a..a0c12ae94d7 100644 --- a/DesktopEditor/cximage/png/pnglibconf.h +++ b/DesktopEditor/cximage/png/pnglibconf.h @@ -128,7 +128,7 @@ #define PNG_READ_TEXT_SUPPORTED #define PNG_WRITE_BGR_SUPPORTED #define PNG_USER_CHUNKS_SUPPORTED -//#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED #define PNG_WRITE_PACK_SUPPORTED #define PNG_READ_FILLER_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 6096fdffc5f..48fd77d701f 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1575,9 +1575,9 @@ return res; }; - CFile.prototype["scanPage"] = function(page) + CFile.prototype["scanPage"] = function(page, mode) { - let data = Module["_ScanPage"](this.nativeFile, page); + let data = Module["_ScanPage"](this.nativeFile, page, (mode === undefined) ? 0 : mode); if (data == 0) return []; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index e2b371753b1..9b7a44e44ed 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -262,9 +262,9 @@ WASM_EXPORT void SetCMapData(CGraphicsFileDrawing* pGraphics, BYTE* data, int si pGraphics->SetCMapData(data, size); } -WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex) +WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex, int mode) { - return pGraphics->GetPageShapes(nPageIndex); + return pGraphics->GetPageShapes(nPageIndex, mode); } #ifdef __cplusplus diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index 5ff3c25dbb4..0f159b34a0e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -187,12 +187,16 @@ class CGraphicsFileDrawing RELEASEOBJECT(pTextRenderer); } - BYTE* GetPageShapes(const int& nPageIndex) + BYTE* GetPageShapes(const int& nPageIndex, int mode) { CDocxRenderer oRenderer(pApplicationFonts); oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); - std::vector arShapes = oRenderer.ScanPage(pReader, nPageIndex); + std::vector arShapes; + if (0 == mode) + arShapes = oRenderer.ScanPage(pReader, nPageIndex); + else + arShapes = oRenderer.ScanPagePptx(pReader, nPageIndex); int nLen = (int)arShapes.size(); diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index f50db6cf6ac..44137f4ebd4 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -695,7 +695,7 @@ namespace NSDocxRenderer //не работает //oWriter.WriteString(L""); //shape styles. http://officeopenxml.com/drwSp-styles.php - + BuildForm(oWriter); BuildGraphicProperties(oWriter); oWriter.WriteString(L""); @@ -854,7 +854,7 @@ namespace NSDocxRenderer } } - void CShape::BuildForm(NSStringUtils::CStringBuilder &oWriter) const + void CShape::BuildForm(NSStringUtils::CStringBuilder &oWriter, const bool& bIsLT) const { // отвечает за размеры прямоугольного фрейма шейпа oWriter.WriteString(L""); - oWriter.WriteString(L""); + if (!bIsLT) + { + oWriter.WriteString(L""); + } + else + { + oWriter.WriteString(L"(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + } + oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); @@ -935,29 +947,7 @@ namespace NSDocxRenderer oWriter.WriteString(L""); oWriter.WriteString(L""); - oWriter.WriteString(L" 0.01) - { - oWriter.WriteString(L" rot=\""); - oWriter.AddInt(static_cast(m_dRotate * c_dDegreeToAngle)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L">"); - - oWriter.WriteString(L"(m_dLeft * c_dMMToEMU)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast(m_dTop * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L""); + BuildForm(oWriter, true); BuildGraphicProperties(oWriter); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index 0cb7962be47..e6b2477b2a4 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -87,7 +87,7 @@ namespace NSDocxRenderer void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const; - void BuildForm(NSStringUtils::CStringBuilder &oWriter) const; + void BuildForm(NSStringUtils::CStringBuilder &oWriter, const bool& bIsLT = false) const; static void ResetRelativeHeight(); From 229c88a7be7f82a93a7a3e8d08353edbc54fa5ae Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 8 Apr 2024 19:55:08 +0300 Subject: [PATCH 508/794] fix build --- X2tConverter/src/lib/pdf_image.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/X2tConverter/src/lib/pdf_image.h b/X2tConverter/src/lib/pdf_image.h index 58f4282131f..464b703a282 100644 --- a/X2tConverter/src/lib/pdf_image.h +++ b/X2tConverter/src/lib/pdf_image.h @@ -926,7 +926,7 @@ namespace NExtractTools CDocxRenderer oDocxRenderer(pApplicationFonts); - NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::tatPlainLine; + NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::TextAssociationType::tatPlainLine; if (params.m_oTextParams) { InputParamsText *oTextParams = params.m_oTextParams; @@ -936,16 +936,16 @@ namespace NExtractTools switch (*oTextParams->m_nTextAssociationType) { case 0: - taType = NSDocxRenderer::tatBlockChar; + taType = NSDocxRenderer::TextAssociationType::tatBlockChar; break; case 1: - taType = NSDocxRenderer::tatBlockLine; + taType = NSDocxRenderer::TextAssociationType::tatBlockLine; break; case 2: - taType = NSDocxRenderer::tatPlainLine; + taType = NSDocxRenderer::TextAssociationType::tatPlainLine; break; case 3: - taType = NSDocxRenderer::tatPlainParagraph; + taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; break; default: break; From 2277feb87d53b0ae8fd5c9ae9697d74989c9146f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 8 Apr 2024 19:55:37 +0300 Subject: [PATCH 509/794] fix bug #67327 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 37 ++++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index a0734f7135a..8a091c24ca7 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -698,14 +698,14 @@ namespace OOX { nFlags2 |= 0x1000000; } - if (m_oCellMetadata.IsInit()) - { - nFlags2 |= 0x2000000; - } - if (m_oValueMetadata.IsInit()) - { - nFlags2 |= 0x4000000; - } + //if (m_oCellMetadata.IsInit()) + //{ + // nFlags2 |= 0x2000000; + //} + //if (m_oValueMetadata.IsInit()) + //{ + // nFlags2 |= 0x4000000; + //} oStream.WriteULONG(nFlags2); //todo RkNumber switch(nType) @@ -748,14 +748,14 @@ namespace OOX m_oRichText->toXLSBExt(oStream); } //it's not by XLSB format - if (m_oCellMetadata.IsInit()) - { - oStream.WriteULONG(*m_oCellMetadata); - } - if (m_oValueMetadata.IsInit()) - { - oStream.WriteULONG(*m_oValueMetadata); - } + //if (m_oCellMetadata.IsInit()) + //{ + // oStream.WriteULONG(*m_oCellMetadata); + //} + //if (m_oValueMetadata.IsInit()) + //{ + // oStream.WriteULONG(*m_oValueMetadata); + //} oStream.XlsbEndRecord(); } @@ -1714,13 +1714,14 @@ namespace OOX m_oRow = nRow; m_oCol = (oStream.GetULong() & 0x3FFF); + _UINT32 nFlags2 = oStream.GetULong(); - if(0 != (nFlags2 & 0xFFFFFF)) + if (0 != (nFlags2 & 0xFFFFFF)) { m_oStyle = (nFlags2 & 0xFFFFFF); } - if(0 != (nFlags2 & 0x1000000)) + if (0 != (nFlags2 & 0x1000000)) { m_oShowPhonetic.Init(); m_oShowPhonetic->FromBool(true); From 2038ace911d1dedff444b7138aa219e0f02f4919 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 9 Apr 2024 10:03:19 +0300 Subject: [PATCH 510/794] Fix build --- DocxRenderer/src/logic/Page.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 4ee9bfa5f52..c3839e45ab3 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1216,9 +1216,19 @@ namespace NSDocxRenderer // совпадает ли left, right, center со строкой ниже struct Position { - bool left{false}; - bool center{false}; - bool right {false}; + Position() { + left = false; + center = false; + right = false; + } + Position(bool bLeft, bool bCenter, bool bRight) { + left = bLeft; + center = bCenter; + right = bRight; + } + bool left = false; + bool center = false; + bool right = false; }; // параграф будет набиваться строчками From f5ca81240b553f28d5defbc497ab16d30abae3a6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 9 Apr 2024 14:13:29 +0600 Subject: [PATCH 511/794] Fix connection conversion --- OOXML/XlsxFormat/Table/Connections.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index 545002a6eb6..fe144fc3485 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -319,8 +319,7 @@ namespace OOX auto ptr(new XLSB::RangePr15); if(m_oSourceName.IsInit()) { - auto tempStr = m_oSourceName.get(); - ptr->irstSourceName = tempStr.substr(0, tempStr.size()-2); + ptr->irstSourceName = m_oSourceName.get(); } else ptr->irstSourceName.setSize(0xFFFFFFFF); @@ -1053,17 +1052,6 @@ namespace OOX auto ptr1(new XLSB::BeginExtConnection); ptr->m_BrtBeginExtConnection = XLS::BaseObjectPtr{ptr1}; - if(m_oDbPr.IsInit()) - ptr->m_ECDBPROPS = m_oDbPr->toBin(); - if(m_oOlapPr.IsInit()) - ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); - if(m_oTextPr.IsInit()) - ptr->m_ECTXTWIZ = m_oTextPr->toBin(); - if(m_oWebPr.IsInit()) - ptr->m_ECWEBPROPS = m_oWebPr->toBin(); - if(m_oExtLst.IsInit()) - ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); - if(m_oType.IsInit()) ptr1->idbtype = m_oType.get(); else @@ -1144,6 +1132,17 @@ namespace OOX ptr1->stDataFile = m_oSourceFile.get(); else ptr1->fLoadSourceDataFile = false; + + if(m_oDbPr.IsInit()) + ptr->m_ECDBPROPS = m_oDbPr->toBin(); + if(m_oOlapPr.IsInit()) + ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); + if(m_oTextPr.IsInit()) + ptr->m_ECTXTWIZ = m_oTextPr->toBin(); + if(m_oWebPr.IsInit()) + ptr->m_ECWEBPROPS = m_oWebPr->toBin(); + //if(m_oExtLst.IsInit()) + //ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); } return objectPtr; From 2481f7f257826acc9f25fa87c91af67bde834ac5 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Tue, 9 Apr 2024 13:09:01 +0300 Subject: [PATCH 512/794] Fix build with old compilers --- DocxRenderer/src/logic/Page.cpp | 8 ++++++-- DocxRenderer/src/resources/VectorGraphics.h | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 4ee9bfa5f52..1413360a0a5 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -660,7 +660,7 @@ namespace NSDocxRenderer } if (num_of_lines > 1) { - auto drop_cap = std::make_unique(); + auto drop_cap = std::make_shared(); *static_cast(drop_cap.get()) = *drop_cap_cont; drop_cap->nLines = num_of_lines; drop_cap->wsFont = drop_cap_cont->m_pFontStyle->wsFontName; @@ -1248,7 +1248,11 @@ namespace NSDocxRenderer // setting TextAlignmentType if (paragraph->m_arLines.size() > 1) { - Position position_curr = {true, true, true}; + Position position_curr; + position_curr.left = true; + position_curr.center = true; + position_curr.right = true; + bool first_left = false; for (size_t index = 1; index < paragraph->m_arLines.size(); ++index) diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index 404c2ba9f62..89802ee95b0 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -16,8 +16,8 @@ namespace NSDocxRenderer struct Point { - double x{0}; - double y{0}; + double x; + double y; }; struct PathCommand From 471c9a4ebdcf87a3e2b8123b278396901e42aaec Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Tue, 9 Apr 2024 16:18:46 +0300 Subject: [PATCH 513/794] Improved work with caption tables when html to ooxml conversion --- .../html/css/src/xhtml/CDocumentStyle.cpp | 2 +- HtmlFile2/htmlfile2.cpp | 296 ++++++++++++++---- 2 files changed, 242 insertions(+), 56 deletions(-) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 816ca43c35b..9948bb9e724 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -317,7 +317,7 @@ namespace NSCSS oXmlElement.AddPropertiesInP(PProperties::P_ContextualSpacing, L"true"); } - if (!oStyle.m_oBackground.Empty() && oStyle.HaveThisParent(L"table")) + if (!oStyle.m_oBackground.Empty() && !oStyle.HaveThisParent(L"table")) oXmlElement.AddPropertiesInP(PProperties::P_Shd, oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()); if (!oStyle.m_oBorder.Empty() && !oStyle.HaveThisParent(L"table")) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index bdbfcad3437..ee91b818e4f 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -41,6 +41,8 @@ #define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips #define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips +#define SAVE_NORMALIZED_HTML 0 + std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym "; //struct CTree @@ -273,6 +275,11 @@ class CTableCell m_oStyles.m_wsAlign = wsAlign; } + void SetBackground(const NSCSS::NSProperties::CColor& oColor) + { + m_oStyles.m_oBackground = oColor; + } + std::wstring ConvertToOOXML(const TTableStyles& oTableStyles) { NSStringUtils::CStringBuilder oCell; @@ -285,12 +292,25 @@ class CTableCell if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) oCell += L""; else - oCell += L""; + { + if (!m_oStyles.m_oWidth.Zero()) + { + int nWidth; + if (NSCSS::UnitMeasure::None != m_oStyles.m_oWidth.GetUnitMeasure()) + nWidth = m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips); + else + nWidth = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(m_oStyles.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5); + + oCell += L""; + } + else + oCell += L""; + } } else oCell += L""; - if (1 < m_unColspan) + if (1 != m_unColspan) oCell += L""; if (m_bIsMerged) @@ -465,6 +485,29 @@ class CTable RELEASEOBJECT(pRow); } + CTableRow* operator[](UINT unIndex) + { + if (unIndex < m_arRows.size()) + return m_arRows[unIndex]; + + return NULL; + } + + bool Empty() const + { + return m_arRows.empty(); + } + + bool HaveCaption() + { + return 0 != m_oCaption.GetCurSize(); + } + + UINT GetRowCount() const + { + return m_arRows.size(); + } + void AddRow(CTableRow* pRow) { if (NULL == pRow) @@ -481,6 +524,11 @@ class CTable m_arRows.push_back(pRow); } + void SetCaption(const NSStringUtils::CStringBuilder& oCaption) + { + m_oCaption = oCaption; + } + void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) { m_oStyles.m_oPadding = oPadding; @@ -521,6 +569,16 @@ class CTable return m_oStyles.m_bHaveBorderAttribute; } + UINT GetMaxColumns() + { + UINT unMaxColumns = 0; + + for (const CTableRow* pRow : m_arRows) + unMaxColumns = std::max(unMaxColumns, pRow->GetIndex()); + + return unMaxColumns; + } + void ApplyRowspan() { CTableCell* pCell = NULL; @@ -553,6 +611,12 @@ class CTable if (NULL == pCell) continue; + if (1 != pCell->GetColspan() && unIndex + pCell->GetColspan() > m_arMinColspan[unIndex]) + { + pCell->SetColspan(m_arMinColspan[unIndex] - unIndex, MAXCOLUMNSINTABLE); + continue; + } + if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1) (*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE); else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex]) @@ -596,12 +660,23 @@ class CTable if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) oTable += L""; else - oTable += L""; + { + int nWidth; + if (NSCSS::UnitMeasure::None != m_oStyles.m_oWidth.GetUnitMeasure()) + nWidth = m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips); + else + nWidth = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(m_oStyles.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5); + + oTable += L""; + } } else oTable += L""; - if (0 < m_oStyles.m_nCellSpacing) + if (!m_oStyles.m_wsAlign.empty()) + oTable += L""; + + if (0 <= m_oStyles.m_nCellSpacing) oTable += L""; if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) @@ -624,12 +699,28 @@ class CTable else oTable += L""; - if (!m_oStyles.m_wsAlign.empty()) - oTable += L""; - oTable += L""; oTable.WriteNodeEnd(L"w:tblPr"); + if (HaveCaption()) + { + oTable.WriteNodeBegin(L"w:tr"); + oTable.WriteNodeBegin(L"w:trPr"); + oTable += L""; + oTable.WriteNodeEnd(L"w:trPr"); + oTable.WriteNodeBegin(L"w:tc"); + oTable.WriteNodeBegin(L"w:tcPr"); + oTable += L""; + oTable += L""; + oTable += L""; + oTable += L""; + oTable += L""; + oTable.WriteNodeEnd(L"w:tcPr"); + oTable.WriteString(m_oCaption.GetData()); + oTable.WriteNodeEnd(L"w:tc"); + oTable.WriteNodeEnd(L"w:tr"); + } + for (CTableRow* pRow : m_arRows) oTable += pRow->ConvertToOOXML(m_oStyles); @@ -641,6 +732,8 @@ class CTable std::vector m_arRows; std::vector m_arMinColspan; + NSStringUtils::CStringBuilder m_oCaption; + TTableStyles m_oStyles; }; @@ -1074,13 +1167,16 @@ class CHtmlFile2_Private std::wstring sRes = htmlToXhtml(sFileContent); -// NSFile::CFileBinary oWriter; -// if (oWriter.CreateFileW(m_sTmp + L"/res.html")) -// { -// oWriter.WriteStringUTF8(sRes); -// oWriter.CloseFile(); -// } - + #ifdef SAVE_NORMALIZED_HTML + #if 1 == SAVE_NORMALIZED_HTML + NSFile::CFileBinary oWriter; + if (oWriter.CreateFileW(m_sTmp + L"/res.html")) + { + oWriter.WriteStringUTF8(sRes); + oWriter.CloseFile(); + } + #endif + #endif return m_oLightReader.FromString(sRes); } @@ -1892,7 +1988,7 @@ class CHtmlFile2_Private // Таблицы else if(sName == L"table") readTable(oXml, sSelectors, oTS); - // Текст с границами + // Текст с границами else if(sName == L"textarea" || sName == L"fieldset") { CTextSettings oTSP(oTS); @@ -2197,6 +2293,51 @@ class CHtmlFile2_Private } } + void CalculateCellStyles(CTableCell* pCell, const std::vector& arSelectors) + { + if (NULL == pCell) + return; + + std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(arSelectors.begin(), arSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), arSelectors.cend()}; + + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors); + + pCell->SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + pCell->SetBackground(oStyle.m_oBackground.GetColor()); + pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); + pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); + pCell->SetPadding(oStyle.m_oPadding); + pCell->SetBorder(oStyle.m_oBorder); + } + + struct TTableCaption + { + UINT m_unPrevRows; + NSStringUtils::CStringBuilder m_oData; + + TTableCaption(UINT unPrevRows = 0) : m_unPrevRows(unPrevRows) + {} + }; + + void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, std::vector& arCaptions) + { + GetSubClass(NULL, sSelectors); + + TTableCaption *pData = new TTableCaption(oTable.GetRowCount()); + + CTextSettings oTSCaption{oTS}; + oTSCaption.sPStyle += L""; + + wrP(&(pData->m_oData), sSelectors, oTSCaption); + readStream(&(pData->m_oData), sSelectors, oTSCaption); + CloseP(&(pData->m_oData), sSelectors); + + arCaptions.push_back(pData); + sSelectors.pop_back(); + return; + } + void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) { int nDeath = m_oLightReader.GetDepth(); @@ -2215,17 +2356,7 @@ class CHtmlFile2_Private CTableCell *pCell = new CTableCell(); GetSubClass(pCell->GetData(), sSelectors); - - std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(sSelectors.begin(), sSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), sSelectors.cend()}; - - NSCSS::CCompiledStyle oStyle; - m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors); - - pCell->SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); - pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); - pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); - pCell->SetPadding(oStyle.m_oPadding); - pCell->SetBorder(oStyle.m_oBorder); + CalculateCellStyles(pCell, sSelectors); while(m_oLightReader.MoveToNextAttribute()) { @@ -2242,8 +2373,11 @@ class CHtmlFile2_Private if(m_oLightReader.GetName() == L"th") { CTextSettings oTSR(oTS); + oTSR.sPStyle += L""; oTSR.sRStyle += L""; + wrP(pCell->GetData(), sSelectors, oTS); readStream(pCell->GetData(), sSelectors, oTSR); + CloseP(pCell->GetData(), sSelectors); } // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") @@ -2291,7 +2425,7 @@ class CHtmlFile2_Private { if(m_oLightReader.IsEmptyNode()) return; - + CTable oTable; //Table styles @@ -2327,6 +2461,8 @@ class CHtmlFile2_Private oTable.SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); //------ + std::vector arCaptions; + int nDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nDeath)) { @@ -2334,35 +2470,79 @@ class CHtmlFile2_Private GetSubClass(oXml, sSelectors); // Заголовок таблицы if(sName == L"caption") - { - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - { - if (item.m_wsName == L"a") - oXml->WriteString(L""); - } - m_bInP = true; - m_bWasPStyle = false; - } - // Заголовок таблицы выравнивание посередине - CTextSettings oTSP(oTS); - oTSP.sPStyle += L""; - readStream(oXml, sSelectors, oTSP); - if (m_bInP) - m_bWasPStyle = false; - CloseP(oXml, sSelectors); - } + ParseTableCaption(oTable, sSelectors, oTS, arCaptions); // if(sName == L"thead") // readTr(&oHead, sSelectors, oTS, oTableStyles); - else if(sName == L"tbody") + if(sName == L"tbody") ParseTableRows(oTable, sSelectors, oTS); // else if(sName == L"tfoot") // readTr(&oFoot, sSelectors, oTS, oTableStyles); sSelectors.pop_back(); } + if (!arCaptions.empty() && !oTable.Empty()) + { + std::vector arUnnecessaryCaptions; + + for (TTableCaption* pCaption : arCaptions) + { + if (0 == pCaption->m_unPrevRows || oTable.GetRowCount() == pCaption->m_unPrevRows) + { + arUnnecessaryCaptions.push_back(&pCaption->m_oData); + continue; + } + + if (arUnnecessaryCaptions.empty() && !oTable.HaveCaption()) + { + oTable.SetCaption(pCaption->m_oData); + continue; + } + + CTableRow* pRow = oTable[pCaption->m_unPrevRows - 1]; + + if (NULL == pRow) + continue; + + CTableCell *pCell = new CTableCell; + + if (NULL == pCell) + continue; + + pCell->GetData()->SetText(pCaption->m_oData.GetData()); + pRow->AddCell(pCell); + } + + if (!arUnnecessaryCaptions.empty()) + { + oTable.SetCaption(*arUnnecessaryCaptions.back()); + arUnnecessaryCaptions.pop_back(); + } + + if (!oTable.Empty()) + { + CTableRow* pRow = oTable[0]; + if (NULL != pRow) + { + CTableCell *pCell = (*pRow)[0]; + if (NULL != pCell) + { + NSStringUtils::CStringBuilder oData; + + for (NSStringUtils::CStringBuilder* pData : arUnnecessaryCaptions) + oData += pData->GetData(); + + arCaptions.clear(); + + oData += pCell->GetData()->GetData(); + pCell->GetData()->SetText(oData.GetData()); + } + } + } + } + + for (TTableCaption* pCaption : arCaptions) + delete pCaption; + oTable.ApplyRowspan(); oTable.Shorten(); oTable.CompleteTable(); @@ -2958,12 +3138,12 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - + std::wstring sPStyle = GetStyle(oStyle, true); - if (sPStyle.empty()) + if (sPStyle.empty() && oTS.sPStyle.empty()) return L""; - + m_oXmlStyle.WriteLitePStyle(oStyleSetting); std::wstring sPSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); @@ -2987,11 +3167,17 @@ class CHtmlFile2_Private } } - oXml->WriteString(L"WriteString(sPStyle); - oXml->WriteString(L"\"/>"); + oXml->WriteNodeBegin(L"w:pPr"); + + if (!sPStyle.empty()) + { + oXml->WriteString(L"WriteString(sPStyle); + oXml->WriteString(L"\"/>"); + } + oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); - oXml->WriteString(L""); + oXml->WriteNodeEnd(L"w:pPr"); m_bWasPStyle = true; return sPStyle; } From 85980186aca80ae24485c3b88b7c102ba59384cd Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 9 Apr 2024 16:46:52 +0300 Subject: [PATCH 514/794] Fix bug 66286 --- PdfFile/SrcReader/RendererOutputDev.cpp | 6 ++---- PdfFile/SrcReader/RendererOutputDev.h | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 9e39f547e44..42c225a2cfc 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3082,7 +3082,7 @@ namespace PdfReader pFrame->put_Data(pBgraData); pFrame->put_Width(nWidth); pFrame->put_Height(nHeight); - pFrame->put_Stride(4 * nWidth); + pFrame->put_Stride(-4 * nWidth); NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); pRenderer->SetFontManager(m_pFontManager); @@ -3102,7 +3102,6 @@ namespace PdfReader Gfx* m_gfx = new Gfx(gfx->getDoc(), this, pResourcesDict, &box, NULL); m_gfx->display(pStream); - // pBgraData будет передано oImage pFrame->ClearNoAttack(); RELEASEOBJECT(m_gfx); RELEASEOBJECT(pRenderer); @@ -3116,7 +3115,7 @@ namespace PdfReader m_pRenderer->get_BrushType(&brush); m_pRenderer->put_BrushType(c_BrushTypeTexture); m_pRenderer->put_BrushTextureImage(oImage); - m_pRenderer->put_BrushTextureMode(1); // TODO Tile 1 или TileCenter 2 + m_pRenderer->put_BrushTextureMode(1); m_pRenderer->put_BrushTextureAlpha(alpha); #ifdef BUILDING_WASM_MODULE if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) @@ -3135,7 +3134,6 @@ namespace PdfReader m_pRenderer->put_BrushType(brush); pGState->clearPath(); - RELEASEINTERFACE(oImage); } void RendererOutputDev::StartTilingFill(GfxState *pGState) diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index 263a1aaa0de..541e53b9334 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -136,11 +136,7 @@ namespace PdfReader } virtual GBool useTilingPatternFill() { - // TODO Доделать поддержку различных параметров TilingPattern - if (m_bDrawOnlyText) - return true; - - return false; + return true; } virtual GBool useFunctionalShadedFills() { From 30ae04fd6e632c51f958feccb1f7114c44f613ab Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 9 Apr 2024 20:31:09 +0600 Subject: [PATCH 515/794] Update test files --- .../test/ExampleFiles/xlsb2xlsx/simple1.xlsx | Bin 7310 -> 7309 bytes .../test/ExampleFiles/xlsb2xlsx/simple2.xlsx | Bin 18503 -> 18494 bytes .../test/ExampleFiles/xlsx2xlsb/simple1.xlsb | Bin 4928 -> 4940 bytes .../test/ExampleFiles/xlsx2xlsb/simple2.xlsb | Bin 17943 -> 18007 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx index 6f10ff38a5c0f1f5178ac2415bc6c29d267998b1..173807f5668eef6c2b2b46a63830f5ed0bb40546 100644 GIT binary patch delta 1055 zcmV+)1mOFQIgL3IP)h>@6aWAK00000ApntR&qT2jRsxgG1c|d~0%-!XS_L2v1)h$k z`Y)4z6fOhTb`q1Y6gLAO4Mvmd6f1w>(DDjuW(TN2k!OXbW{!?#J+#^YE5oB&4v$Bp zvtiAI$|J(1c@GAzR)WJ7@}>smB8UOW9A$4Sq3s^+XZbF?(y$#>y3ePV;#Kr?ct_(` zc(vdLEw0>vW1UiaUFBpr`K`{HzbCPpnN6cV5U{4=3L%ASLyo(jVd_X@PHk3{DW}10LPU+Aw^ldvonhv)VnkVZO-K2{)_(q*?NI3fhBXAnR{g4q0 z))G&#L_fvXVd=t=(^}IHMQXkT2UJK?t2l|#LS@8b)L+lnZ|B~FXz3mZWl1Oc7oz2+ z)nI7$Hhp9F3X6X!^Ei-yT5Qohcu`2Z!AT;FNHZTheT#epWlF2FJ}UXr?s`nI_OMR(RR^qS`4*5tYH7NOc+%siVGqT3`BmnNf`UaBqU#%SyQQ*j4L`gAC1m0 z&c~$f=i`gf$?-TX@f$uGIIEz47~Xk2dGYc6Lid*Q zAb*Xf8KRCY#WStb#CPGa&MRT8^PBmtsf(m8K^N0H?2p|hP*dsloe5cy9IA&3)E)6g zoi~DLOG2-yNrnm9+d?wF`J~DqLUAw+OESl)y$h`Uza8rpNkN`97Or1r<$qj^K`))9 zuv)Sf%6=2Cv>>@B8udDOuyE8ODY3Z})Y2di-9NnfFHlPZ1QY-O00;m803iSbJxrOC zLB%2~>wjzhf6~n7`^RE+=sWR-iQ3>5R7D8_y$QDUje?i$)6G2yV(qQ& zf=2}d60DYsXY4fR5pr!Lkuy9gaLn;RN-_?6O+|?4^G_X8uQ|)q$f(UuHz;Ric_-62 z11>X#SX%{YZ7UGlA>x0+LtVE9AA@=A(ep1`9daMijvONAP@NiN1!s%o@u`ZO3i1z{ z*_1S#XYq&RC{N~fh}$V4h=(q(^h|NmSNrFa_B)->ZaC$G8)J;^ZyI@Vb;~bMO927^ z02BZK0000003iU8XwO8m3>xkM1)h$k`Y)6J8$lcdJxrPI0002L0ssIS0000000001 Z000000MQte?id`CcpMN0_Za{H004-o+T;KL delta 1060 zcmV+<1l#+KIgU9JP)h>@6aWAK00000AppAh0KKsiRsyr}0%-!1YXXLo&IAXuUIiQv z1v!;r>@bsm6fOfdwiA=E6gLBpj)s%!6f1wh!14-eW{*&VBF_p<%^V%gdSJByR)$Bl z92^gaXM>svl}Ch2^BxRbtptZF`uXe@|jHGn+<#AYe_!6+#Nvh8%kdvDZlNPl*We z4(T;h?}8bVoE3rr=93>5L;(krWENb1$3AVTnpv)VpCpAs?ZYlW(mZ^k7u>)7LUGT= zdG?H0FKJZhl#bnCA6q{~VuY_CEuw;Om;{f&1V0{fsk8W05E$x_*e#RkQq}qmf#Fb^~e1 z#z$ih8l{stHlG^YWkfJBlrEf7?%bOeWBRt8kEVkyh33h6MK|f94ZdOL8xYPu!3dm& za6e?kg0;j`EYVN#by&J^il_1n4kAX>TyLRr#@ z{)K3{X*C#{y-nZPy~5&O$~+E#q!wFr4_*|~Zg7$aBht*rPTwNmK$+6&tdB~*w0mA6 z3L2MIRvV$*oenyaRkU67n-)W@4=dO|EfYr7iQ<9?1Ot)ZZ4$=5F$u|6X4X_{CgX}8 zoeziS7w2Qr_Ve+@@Z@-$miP@HjdAdtjwWXpr^A!UNxYP21v-cI8_p_!D28_)PhNa{ zztFwqJjh?8X@;m{OYuzWH1S-=VZYw9AYOVGu%4*O%b3Di`&eP=>eB!}vu z0(D2cQRj^y+LF*~YLa1s_O_6WZ$7Cqh)^6%!;;K#YVQJT|8K{7MN*JwjfLx%S@|Cq zW6(=yDXf;Pg|gqoD=kPUu7Y(oSX%{YZRa4iL&X2ULtVE9?}K^n(ep1eTO>K1&~7;8*HH%R)F3Mum5WRT z`G-w4rOiI19XUiknf#PKUGq_0w3$t5!?_nvCdc?yyex4&>4JFZ@O(4J{5@Zee%UTvkMyT0R=ggVeBxI{u@CY-0QQr?f?J)zXAXN8UO$Q e000000RR91007b$lkFHBlXn~t2KX5O0000jvEwiR diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx index 7cf898ccb1827f299b1e4e46ed552d6f71433dcd..0d577fe0801a0567f59413e9c0dcb5275a315407 100644 GIT binary patch delta 2700 zcmY+GcTm&I7RQs&+ci=`NkD=W2_Q{sP)ZCO}wGBa?otq`3h?4cvh5Aj5V$E1EP9Don#1&eV7sdwSFi zDW_NRi+b~fzA1+99qqp*rtb;+OI)s-?&P?Ln0>RB*WGGKce`9`D@w~AzHHBxRIO06UkoxU)tT$R815hGALkXw+l zBk~9O)B6{^xCsvoU8J{ffN#MtN0zYAn!iCziItPai#l8TS~dMcrvGcmd?Eo7L}@;2 z#=*cyoSdwraL8jJgau>tvk{FCjX3r+PO4BVeZo;-!sc+l)4RXliKaTmowJ!nDc4Q; zR(G@p<~X?9+dU1?Pk9v;_;QIAeLYTFGIh9bMn5Oobb`@u-n_FVk0}RY^B( zotaX9nv=uYALhcEkM8d!TnhFpO41rj2zE`7XB8|D9LiIh zR3ctj$!NP8H2J%8iBUV`gJtncmR;cGA)gi&cD6^w&bfTtDaQfgkA0D}Tp58JUT4try;jV!VDcY+YryIH+V~35r zS4dOnyh2gcNYhLMysCc8;OzxW-i>1OGm(*#a9rYT3q(ctg2h3novL2bXxG=(f!9X4 zX@!ZO36=)y$S2eH+7~bdZ%~NkFcYG(wOWVGHG#?bk?QSw=bV%)uI4wsR|nZGHZPrG z*tTEhkg7RHg)!Flib(31+gM=hHu%Tp(zjEp^!YIS+2N9ghyIqcNnOZP6i3d0-OOT5 z7P(xe@~XlW4DI|c!QTh0rxiRV!jn18T*>7z&qdQ9X?=|{0!B_D8Z|Ut{yl%0UveZ^7 zNlANn#pb}c@_Ja$z7tzL=As~##PNQYmBc?2zY@tzVv1tj32A&-{KI~sdg9f{Wami7 z{K0iE?*48f`}5sc5(<78+j4)r4oz53kZw;>`l|v*8ut+0o1id+@wPxC%k&lq3hKt{ zi|16Mw|bMj0(k-q%l$g0MhaSR)oh&x817wW8V5^$zrL#wbq zAt?(RLq4m>+73Bdxqvc(sYF64os&X-fY&rUWOhQXE+-1#LtNUI&C0U_ zU*-Q}>~=^;^8xWo{n&GeC$oB^cui*-W-gvf6Q7iBXtB|xFy9>NN`Mu;Yie>g@gKKr zz9nmHNuHl}Pnfwl$)PUGoHgRV3CS0Qf<;iJLo;4WUhF@mPdLYNx8i73fcnxObJVqV;1TCMX^7gHm15}K4OU6VlC*H5z={AB&mqVwS*d%uRnqs=%iB1Tf4%)>WtP%R}! z*r#4A%k(*`2rZXGuuXkia5U|=HW;2mC8^qPp_+T&KCH4P*MF>_$4DsjJ`RNsg9i%? zbHIH+Y;?>C*gN6xm)J*EORkqW<$pq6N3}JC$hP%yUh)6h{xVu=4q!S|!;c1LUsX$1 zuF#tK!gM1|Sxu*>Tg5?e2HMa&nshr$e->GC|HmB6-0^nu5%e7rnI0B@EKv|%^@;Xl z=)wNqA?X?!JMi+9iR{Sh4+#aS-Xdk&5n)F^KN|Zwp81MtS(UEd=lvxyK*I`9>NJ)i z3|)Sw2jM`0rW|1wM~CFrBg7YmyFT<8$i*GHxKnK`G(n5QVnKPJ)NflA-^wh}RYMwe zD(h{kaWhL8DQfvnwUXHK1-cll?M!}4+{*5|SAx(p%^41Mv0{GXJ#LpGb^0(GO9hQP zqMm%tI$S#8W4XK>KATk=xQ-SQ zVbEOt$a;Z#PbEeC$3z$D-PUI}`OH=U3`>?!eR{;ivHKv4>)0AkVz##4$A{1V|ft&eh~t{oq?hOIWz*8#-bqiH2|{4 z1wi#O3Y-eKU$%y%Tmot@i2)0jp@@I_eR9h>9SC&xw*t|cC!63vhbAk`%!q;US5Dw$ N7&C!DZ?%4{{sSbD(oz5b delta 2690 zcmY*bc|6pM7M~dm#(GI4yTl-jU4t28W*A!{5?P{)u~(MKHnNu{@k5p&mndr(#Eoo~ z^~$bDg^;80c?EgLH4hVYLEH z5Fj7MK~rMmg3z)#$Y7c_`*koN4+{k(I5}yf5C;fw63P!0%5Ve5?B+CXEqd$;}VYd+tD>$bcP9EwyMRyxsHr#YP+1qxjWltEMf;!Q>Pu)5BzfE$0K(snp zTOKxNTTO*0G#CO8A-}Lfw)~~P*l5L_Dlj7PoHg+%DDk%(O6%(z-2|~#j`P(uc4~DW z=?xPfotwIR{gnF0dCF>Y&#m2U9956{OjFN;)ixy3--jiIPU6F536(NQTXV^UA?!(- zd~|yIFbXy?IC*Ro@(k5BF}kbJh%4k?{$_N;c3_@hESt3gBVz!${FkvZ8dFCUo1w+@ zZ{NGLWNnhne$Uh{;`VM*@h*s4&rH8AY@P14i_$#eS!ox9bBSU0)Q>_|PHt%4tRZ^o zO7NaO>QMN+iK-KcSBC!3OCfk=aF@>a-tI4=!x_aX*c=E#~kJQeb63d;a46Pqt8iC0A~=q8inK}N$u~Jy zsaxUl0Kn?CPEcRwVJGmv=r-Zoo)ny~E6_<9)E#kgCZx$-pq1T;PR90MjVW*-bcJc5J zP;^Sml?5T(RHsyy!zrA?SD!x9MuYk0lL9XgLYy87U7IR6VjIN=iO_v{zGQY&R|$ET zDG*w}aKRk!(=&~0xqqyi@YJp&PEIgAkx*tO1J4>;He>QcG6esjQjj!=*JI-clnn$z z@&J5@6Erq$B?x)?G0Rnrot!m6wu>!80ZZAP`W78B!;P-(fvP*L7YCVIcVP~pQ>(A{ z^AI|u2EQub28>WJ^WC1eVo1rG;9O4~>UskjIW{V7Ic4qg6rG#qOnQ-o4sU;~cFxQ9 zYi}Fd2T|u43!e9f2UQP4@mG{D_ZD78nU>epqMr0~oOw>}3h0^3bBJ^NiiKI?V(*WR4Tyu^5@@#y$P!1 zQ{s7AY;tj^7;nAQi^YpNv!|$bc-A7mIO}|I79EI~Om}b~Mv9k`*-8Vsp2zI*f@4ej>g-T=Ok;xRO1f?v>?O z$+|cqv5Fa&Y=3^EtKH0prSlX&nHih;-j3}!`t(6*P2*f%o7DAwH8#DV?I)K$q&Y*V zs>!m5gXL;cU3VE*MV28VTxBw(R^hTjcSnMh#SB^4^BU>Iket3vWyQ>G+q}mOT|HmV z=p;ehZ}~^@1&nGX1ZYI!+}X>*$F8qgw#}^ZeM2bIqxHQ_uB5_kjzXv8k_k&;eu~WFb-MOU$Nv?4s@{{K?qj*sZ={(W);T!GM1lDD>YWI)m*nlSU||$_y_TNGCvx&;|f??|LFGGRQ=Tkv9CTOOu-<~cUBMxP((_RJFL3YxD#FF`tnQ9 z)L44Y@LHHY?i%Yx;yYgI zvGF?hG>yof!dJVpl4Qry3;GZdvY$sh013qpndk8 zo;miEm3mdBNCG%a6;8=`)DIT?aBU|53uauu242{K^yL_)>MK>aD5{Z4oo{7KOZyBI z-w<(EKONs4MPT}UEU9Iun|Mr+8v^KDAiv*UIAgNOzhu*nsfdao zhE~|DmY#0C%1dP;xKqZH0tl&tIuk)XL?|nzz8oQxw6r=uF3v9*f4-;zs<$%K<rn97p&o?q;ro)G<|=@=4FMv4J% z@QUCJ;2Yi*oCP?V*n=~HS`%%t|J?c~*$N8?B>T%)G76xgyne&& diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple1.xlsb index 7a984b15fdefc057f782ac73c254492a73eecb1d..e4aea47f12fc7a989fea2d84be6c156011c04d8b 100644 GIT binary patch delta 1261 zcmX@0c1BGoz?+#xgaHJ63OXZ-^K4gb6mnyptizHtIfA)pav#g8$s#NglTR^w$?1nw z7Ni#2!E|tdbqF`C7ghr5cA6ZhYmDiC3rynTHZypfEYvFy&)fVfseaNz-)lBP8mKHa9$}H#Gi}$j7kJVIChNTaJ)HMzCa) zq?d%&L7jL7KSs7tRy6VNlHF5&}ytun5*LubL7Fv35OC+ z9NBpwac}g_AQrZ8UAhG zmo=yH^7k26Ef)IqCphg8mNaj0oh>0L`oji1ZSks~ z<}SM{;FNJwk0Uc&f?q&rd*?N^z&DJw)r)+4{E|AH{V%>hG2dP_F4wL-ZcnnBd~?&X zRgMV;7k^#Qthj4?_fE6IwS%wh*g_1H4yNs`Iu=))srX#D^AN|91BT1lHBVZ|n1mW8 zYMAGqX?`YDtUlSS`tHJ*D_`fH39e_0F>1XL#afvyEwJ10Vf}-RxqA;D&){Qb`6y_5el)A`kMhGB8X&Bw)%5iY-JI zV-Yl!2ZJUK#8CI+Mikun(=_+ipudN~^dLq(2$d45rLQht86UQ%Wr z!VQo(Ku%NwP|d*f1q2?GF9^zm9dRYvgUcEySO|2zAc~rb$$UZzU^SJ=o)1Bp-xsKc z8%52d$-Y8T;G{Y^TS$uW%j7m8B?Z*9$-p21)dHa|@=dy;ACc2 z)5#(%l9MBu6DRAitdi3YsVqn>wu2eN0W?XGL9zL{ggl5fIgHgpikSgbc1sM?Wi zo1FNA<>EU15Ar9A7};3c&g<~#Cl;LuYkCs5(O^&82}zHGM;sm1jwhXXboSA?ByJVm z$a@W{cI|++csI&|Nno#_~HNm)|xy#I@@@71bqrB+q(GN z+UnfeEPK2Zc}Yi1r%%UEr;SHgLh_lB*TE}_%mV*Kow=3K z19Wp3yAC4@DBw4@ail?6A2|7-EGF)o%zPkOyN|o?Oa{71lyUM)KArk1CFN$V33m@L zs$7wfU~x=R_`v98Z1B;*F*3*D%sJ*@2BygplJkr{8x$BZOcYY~STc3u!pVW>*dqm- znFW?Bd`vf3)$k;;VTP#I5ss&ak2vh;p181g;zPd8j$2PyeQyt&$7f)b(H`?U+cDq5 zHd~Ej#-W$hXR;i`4gaJ&u=emsyjajVkr6G}9>0(886E%7qxMYfVO`gTIj zhUG??o3G2Ba*e%zqUKzEgJy8Y+RzExzeyd*^Z6lPkrSQ&!EV;!hQ@kJ=Si0(-wHo3 zvertNYn{S6x#;U7<`djzXXlvZ8@@lO`03=6nX+Fsz+69?bX#7_#kTv E02R4}wEzGB diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/simple2.xlsb index 6aac6466dfa0cc1bbc50ae378559a2570c8a0888..d05c3eaf06155da1ee11e75d8b634717dabad448 100644 GIT binary patch delta 4118 zcmZ8kc_5ov*MG7gB6cE)Er=kLh+UDyQfg_{Qd(6BYAdC5RK1i~QZ${Wy|k%nht^DW zo3Rbr87-oU34_vQYTl{VbeV3xc9yDZZ78Qr%H{kTQT8Uv4J^?07yzZjO`-!W$noE z`qwN5N`uXIMZ7+K5~fgs09iPE(bQp2Y#)RxXVSy{^?KJ=kqxVw?p8ew{rKe=J4;JR z^LePt?!VGY?wtRK^|~>nKWH`-v|a0{#FeOb(33M#ZL44FJBiU%s?zlOqNTVYy7b!E z{N#Tz*KMl9k|~$ZU11p_Vnzq1x?;B6A6kgs9Y(NNy!L4GbbEfq-i>buFB&;GB(wGX zl|}-74{}ex5hglfxi^pC@+c+o<6@7>GI43Vf?Z<&4ugr$0fuTy(PMRCH?$fcnQzCb zA|R+44MD0fFfZLMXV1R$9XYn~sk=@N^v{XP%TMrl?3e{L6tdagJB6A{o{qLmm;7(U%hpHAW;h~GRf@$)PiV%_l* zV!xT@a`T4!kXV#w0;8Roz|+%W^;zT;vr8f$!4botz;iW9(ObffoW;eD*Prx# z{J1xaK!{E!5==!8umqYrfjCbjKBm)ndE`?ztZn@dhJ<~b!5(a4P+N4fYpZJup-;!Y z!II&v>Q6=%u0bAbC70YA1ePG{m-iPr6&-&bW<*s z@}Z)V9UBETCOl+nWFen%_y+u7ej-1j{__8^HY-P;65u6`R|H{n)cBgb8)H3^v3{Jh z+Dy7OKPid7E=h5RP(z%K;JYEiKBQdTQlAz=j38_!5NrJ(ae83qR_99Fl)4Q9ElsO7 z1JSuI#P@={I_=A2W)yn5l3E9%@y0+IA=m)Qy`GGj@`_YrE+ zSz^IxeGm$Qj$%NTF|jShWGhNeVt^8hl#{ivFhs~mpdAs7dteeJV3Vb-^c1VHxf*^y z7rw6AXug%!i@fIB@O7KIb+gUzldrn%OZdZ0tb_)kS$8gVM6J^*2>9cxEE5ys?m=fMQxijQKjaSCucOw#O&5Rh?R1% z*w-=Ro9AIMKJ2#<1h%lrpvfw(sCSSIX$dkDxet&NWIahjpIKXRCD%z?W$;B!u!lwv znWL*MCQgAK?HMXVcZMTFblFL)Qq&S!8H*PgE-HY%0=;6J~`2()@YyYH}M3cAyG0(zu3P2PfR;E>7~_20Ke#1V+{& zM*REL`ky26cKaEX!ian%D7W@WF|-?$RGyNB|nPM z6GOhNWUJg$ogxBhi(@bW&70QX`|>I9iHYEI>K_Kuf6}W6FTQ<@G0Py>PjlkCyhwSo zN=BbiZ=>1VTgoscdJaNMnuBMwrw1;;R0fa`M1X*X5274>2w2m@ zgJVOMOL_0Au$1?6)h7<{0HUIrHBU${<4m;FY1ArM4q%)*PNJyJnuEHDCA0s{1ljfyTtE+^B3$^+fe^`hbBQHE>&BP8xz`X+{-5nSzVkZ%If)0Z z4##Rlhl%N$0oXp=Je1IkrPo8MO1VbsC|+yTTm5h)bhkRi6gT+$nTmquWL=JTrPGbEVn?C)1O8yi*l=;Q0hSXoS3{CW?F8mT@w*=f=4Ky ziSFtsQhJ@w=-3ed>h}8ndr5J4Taiq<}KfD$4;M#rfu#Xy{YXN^Iq|1&;L34@GRw^ZsRXceZDc-*_v$k_s53| z3Zr4x$=xCLp&cLC9`zv`#tPWVQODCOw#GkM#~jX!7(8auouN53(@9WB%+-u%P|9u= zve%w@7G(I3GuJ((uy#wp_OWrroeAx~Z?8RYJ;dKpb5oxC5A7S*-r9Q8f8m|pnKoa& zxaH_dbMvf+lf13~mh&swEe{wjFXY#~sVj16&C>0?e9glBwX#%tbN`-RQ+Ly=8HXrmPoE+ikWo zqI@jvO$uLz*BwbY_zc=$Z@%H&RFdFnkX?Wa(&?lYt+~6T?8(_|Jht_ClE!R4fpqZRhoZLEP1RrO+S*d}*z2utB+po2<63XnQ3dbmLVGC4Ak{lT2G?Eo=aMhE9cnPLFjf&Iqb!%BCbxY8XfVylQp~3g3D!Ye(j$K;8iNl;`d}9mC(rBsOcJuf7(8I= zg727`G6Tz9ko4A;k0s~8Z%hlh9F|2wJO$<~nrsJdKR)&56^z^f<5u%t4|cKSygxNe zFvem@t^AP&T3F7eQr@3>7&oqfU~!mJn>?^Nr+gG z=WQwv+-YwT(wz>jdOOQpSY7T{nri{-J{GdwTwO+2VvaE220<6>^wE_0DytZ9cn`w$ zmb8R}U*Yl60bFx109`&fnMT8hy`4AV&xhevV;SJz{LOX(flel%$ye^70rO9XW*9(& zf&XrZTw^Yv`#Q*!O{8u*{T+;2nPalN3V?nc@oVM(ih9zFW T=V&#hP;lSRS+T`Ks`LK=DSn4% delta 4041 zcmZWs2{=^i8$V}ejBV^=nX!$XF*L?5VGPq`YbtKqWEpO-U}a`^|$a_*fRK$o52I@Q`Te zK#y5beRYbaXmAo8493K_BbPYH72gP&#J&K!SR%-g#(;5gG4K)-0Di*`fcMg&U;{=C z%%bB!j8q7S!$g3q63Pvpl2$O-CUF-yp|=79>1fa=J#gh-V!r zcV>3@C^EYa0WMC3w)l*3+Za-Dju1-qSJgPL`JX#&)ZNz8U8&oKpR}SQl@)Y~x*$E7v}3C8-uM z@LATJC7(P2&yih=>kw*1vXa7rxS{dxKf;_1v=j%~y0oObc8+ zs-8U$AN&POU>Ap+c;Hf^4-#?`u#?%wgBA<5xsy~G7=rv!5F{f6MJ|g^*cBNXZyp>T zU7dH`L*OFM|07JiIHY;EJl(z4w>oW@E>B6SbuDX2@moVz@W3Z4>{U3@lD0Z9rZKJ2 zNX&iBi|&q`%~DcdbBb>EG&K|#ZN?5BwkvhKr?ajuhc{JvHteKkwtcz#rl?)h$5FO) z)PLN;?6Z%4`k1rM=TG&5aN_~xF}I8Um9MW`AM|_eXTkHWw3(Lkb8ubVZoZ;vr2fgQ z&2ITq;KO94-Oi*#k^%cWt&TbO$E|jCzG;?K`OYRK_S~(i$gcB`l?f8#K9tYTrxIii zzptpSHq-pmX`Q#OdGc?ScTdTF@G5Q|J;!f388KO*;rHMYT62}#(a;tR(30#tVtvB< zw(S?^+6zg0x(1qZ=w0~r@X+GQsS9QlI+2R4g2CUi`n<+^d*1BqQ2g`R+2tlU9HkM5 zQ}E*M;%CY-`TLlB`z#NV7E4cBUezLrcABb2t3^HPr>Ib}DLxcF)!oZDGmDKUz{+n^ z@D>%uw6I}Ry?aU~&Od8|M#^a!c_MV@L~B=RjVaVWp)FyTnm}d9G7K3s2ALh>nB#|P zT*+oiSB05Z;JeRtLG8R7y{+B7?Km6RpevFLOG}2HWjc*@FsKm{Xuu}>te#TXm#T1N zoLLrb$$n^0i<|MNRSoB;8EED9Sl#FDaYRaZ#x&Xh{TE=gH? z_lW6U1h4`It)`6NE#t0CIN^e-1#OTM4A(_l7Ey!i)H}pYZgPyTQzvDWSVl_l$;yX2 zo&^VQ_r3IZ9!r4Ab+D39j%7K<7W zD++htLzL^yGe{80NZr*Sz-AD65gbmfLU2l&zmLQn6g~vgPa3=fD;2jHw_?IvAXc2N zUOJh5F%``^YeAKu(O)^WdU4*Q))l6zxtm!=U!nwR>E(B3)&Q|BMoOFCm>SB8;3ZEzaPM>BeV5d!5?Gl^D@B(+SyD~;x7H|aB#9BE!_Ot640uvvppz!Y zyX~LkpW>^KZp4sE*Ac{VY7_)+Ost8ggXLXq}FA*U?-_G60}@S zDPK&{-9o$yci28GP|FKeFBG@TkbbIRm=OQ)`D!=^E79ZX^&K2(OX@Gh18X zgX?mpEYMZrwt5=}BTZ#5aYLddjp` z1F_c~H%nl{dT58jwp%F06Sp$+|H&d$)zOU8r*Kc~)e_@a6BXeG!Kq}cpocfE*QTe_ z50w3XFDm@2c(reyl{xQL|IP<8%DvR2oWhUir{L{7pAZ`x!&m3WjKir>T`JxxB?Z?a zWYLAGv?UHd3U=C)x|XzM z;y}FpLBF+&-%X9RLmUh z%a-ueb0+sDg}O%H9~cItLk1j=3wtZ+J8A+}*hvi?9UJ+5w%D_81a;?_FE^vWdX3&A zhrS~;t$y0+Ycl1GB(F^!&EqO^k`v*B9jcIj`iXU%?yvV^ZjP3OzX&*fGsjA6r$N;I z=@R?)<}WcB@0UqG|Jau8@Y&S4Dt(&Xth3jB>K{5n;0-v?? z##@1pm1cXDcoj`(!L3X=8NKvZnm zmMC*pWTUFNc08+p;_lRx;_o3JC_dQOOp92Drx*DL_x+ugKt{8HMHy{M!_j{3Wc`7};#N?#h4uVS5|NhoO$(VKLmg~dp*M$F$`wU& z;cqcGxk6(Ov%rcVNNxdu%l_)I2FFav?JjBi|LW>iJs)?2V{PI>NS%%}@~v^9k@3sS zg}+M`t#SmQ!ATWf2W~rw671a?9Ya8LI}z5QyvURhka5l8W4-Z0p+xTD z0oz%RB+TeL5khPb=Iw}X!&(418;PpW;!H&OYXg#tG8lJOm@~dWd4#=MG(^U2fws%M zo`(w&z6?TL$a5+KuTOp&Ly$fQZgI>6P~#$s`8zv8Fh=ucMK=d9;bKD)#{8X(AOihG z7*!MCY+?wa=(stDiwVh($VgB~H`5gw`%VN9G3iGL^a~j|_@gl-^QEh?lpQQ+iJQ)I z1y5H|1PlCNVF^U=D3Iu?C#vpAS0bzdF1zZA9-p}qQU5Lj)2=piNi06y7kohw7p!I& zk%UPsJ~)5Gc+(I*AUZ~C8KRixjtZo_hs6*+H;+Xgkx>qwFic27gPJd{HwphS96 Date: Tue, 9 Apr 2024 20:31:24 +0600 Subject: [PATCH 516/794] Add fmla test case --- OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb | Bin 0 -> 6779 bytes OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx | Bin 0 -> 9838 bytes OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb | Bin 0 -> 6779 bytes OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx | Bin 0 -> 11989 bytes OOXML/test/xlsb2xlsx/conversion.cpp | 83 +++++++++++++++ OOXML/test/xlsx2xlsb/conversion.cpp | 111 ++++++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb create mode 100644 OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb create mode 100644 OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsb new file mode 100644 index 0000000000000000000000000000000000000000..7126d603d010801152cef2cca44f8b3b7299b7e8 GIT binary patch literal 6779 zcmcIp2{=^k+aHZ3JCP+zV@t9xdF{m52_ai*#+YnlhMCC{C6axQsO)>;rR2-`Tg$o+|P6040XZ8j3C0HiVZeD5!FiBLjnR3 zP6psRD>V!nk3{1ynRvP&an>Rp&L{B#v8Ii9%tI0s?^1I7M!IJl;i4R1}A>M>@lCA{ZAW8hCOU zgLQ`Efm^Jds0$q71h+$qN{ER`iz2?MA&e)e!L6hKMP7zqLE#|~bq_$jZ<@F}U*?AV zr7uC2BDaGxfxttU@I>@rkPF)GKoH^kUqBpPkOyP-9{d6X7`IOj+{FdufPmuxFNzYL z{sM?aqHzC$bVJ+jbDr>DjuQcpd+a!S2N#^+zlgALK>wZu%;n1t2&63ram5+P4G|0q zX<*}sMBoWF7yy}pb+AQ3Ack-({w&-Xh=VBbQ$sAq1t$s^O~|4DlQ<+HcYsI@w?_PQT|OBoa>m zz_Fep&Ts@4qmG8#ppdq}4Uo&f%0j>bf;5~xfW`p<0xsgeBld6b??{mNf0rQnUrP|( zE6GZRe=Pxr_m%)_Q|?WEp!DkiCt+bYD3|Ydwbr%P)`IHm)2Y~1PTl27;fmzC#TCvK zpXOf|1t;QZ@U~$j0{xRX8XvB8g9rpVK@I{@|3&*J3oLg%u{Rht%|=;!08ob?p%bupJo+cr>l3bHq%?|VEvE0p<)|;VS7Kt$utssNzKx;h zWDmCAZnHpub#m*GU4L@o_aCheYV!QcmwbWi=QKnr8v`7F8RqZ4=8Y+llBnb%=zb|@D< z@8*4-S^N-|;L}_3I-%^dzx1+HhEVZT2He{C&7h!A_gKm?qq67e$*n2JdIqVApBv+s z#$6_gcu=A7TbgdS5P=me1tl#>1Bu2Qt1T^=Bac_w!q+)jBd?aBq$zpY%ImdGg=OwO z_&Tl8BlyoyEwp$*;(!nd9Rh)9zlG}O_tfdKZ9-dXMs00t?NCD_=+HtK)iMhbx3jbR zY`T7T*Zmv|i#dvwg&PtBGkjUs+TGPE7HCA?h#k`)J_ECXw4kGO->0u1%uY>X(g~~@6ag8eH{l2N;3gBacR(F`x4tXqcl zmRvHziY10cz130uWw}D++T?4aW@(MuvjyczWRlfFAF^LE+EE$FTSZ@K)ABtpm*spZ z8nN~GDz~~`{V8~2Q%DC(TSSAV3#VESODH=Gp&k&seW&Ln8N0erF{-$yQY<7EKJ#E+ zPI&3vgah>c3>d){Vyv2HSg?IW>-v%M>6KB#$qD4Mjn^-frdr1!>gAwlyM) zvzx#^Hr4+OexaKo2z|`Xms&}GuJF`~QcCvv$t7Qhx?>q>s`88W=i-OYq1m6vA?irT zm4ew91j>(E2EqiIlMBy?r>F-;jQ7YisXnPXS{8;Gq;QFzE;l~|^CJn6hdGjQ%Rxwv zN39K=R#b7JqCVMOhlru~{!Hrf{F3lYoMcW6+-~gQ>Pec91@Si@IS=J?toA3Qyz6@1 zZl&ya>Poo)O|A$@&M*;WbKh~S@p!RUd3C@Su~6NMI&_iMPbWX&JX!26QE&%~&nT@J zS%f7gPaB&sdy1c3_TZedg<>dlTFnMl(|3qX0#EGnMhH}9eAx)|Abxf2V|$_D?xBBr z*At;VHVb%FAMh?EaJ@v>)rk^zXt;uyIv^3LRD7CdMr0OXVMgWg5;Fy1AHgP8+ImOY z2j}kWeC>cCINE36n(aNkx4W;(hu^%K6{|=FZhuIsUiWx8?erqn+fw1ibHBQ=T3@OQ zCmY;~uV)iw#ZJ6v$*1741t)2Fzmgk@(C9d-Nimr-CY2s*=XeD=gwVZeI+Ih7?SSdDdUV8>S2a&{Vr&G?V2bhYNA ztliYI+yGi(CHGNeC8Ps$uSt-kx3;Epv(f$D)YG>gH3hS|ct39iNgV&9lb&fRe14$Y zbk>HJ?Z#S@=_@H~ftz`E_)s$%;}n!dvF=i3+#^6#Is}oVnp^irTxR^)<^XZMPrNZ~h&6>^UKlCeD zV*|%qp9RUGp1XgLp%Iv=W)6Ixv9!F@yYwcNlQmd7uV{CdU=*o1J9ItP3=hms2OnOJZ)i zRTpTB;kus_TXvqwa|$nAyHMCiUUKJVKV{y6&NWV{qlxrRUL|hkIr}5M|6u zMu$6QS&2?YGu()4TW^dNjqkipyC6P7qLOG}h_B(&B;tgyxd=nGBN-4kWkh0CZ+M?b ztu{P`r$lZjZ$4-=aF}W&<<@0EcJLxtnr;bT!DTXB&WG>cR*~+sdiT6T&-=@V*Gpr) z?;A!Vjw>rEZOih-25^o2`EDTklkHNW&&GHPhLhE2_w&L$|D`!s?ohAQ-kiegyEs<& zb7@XG+ zlepOV=c0FxomcZoX%No^4^yqjmVT&Eh=qbH7OqmjZi`nnSGc_{=b?Fx46MoEZ)*6k zU43|AUZynrNDc$3p$~LAebNTWI>h++ud1Y`I?^5wm9W#$ z60TuBMOn5dXB7rVqa$Q8qmHz9ZZ#jvkaKr_QplaEK;KtcYeK%O&!{uuVCJuIPaOrB zonv|=IbQY{uBu8Zn;?;g)V>(ru6{Aq znqld!&=f-4zelB6`nDxjuV65jdMkMQmIFQo=2?T7;Y`deW)M3@Uiqh#xN%n~JqIKo zSN2?SQrcn?djFbJT1IR?DXF;EjZGG|b*26>^V-Xzb9X3n#^w5(J~N$j;&t3g^$#}> za6EGBaF&T%Q3KQBFuOiSD$j&hkmzT;U2e85S*GvW++g~eVWr&RNE&9vO5w3INzd1A z(J?hfRx|UqjbE4hm0;^5pwO=HTa+I=9u2EAcAagtCVqI<{V7N)kvjajd_bV(wu++3 z=OKIjV1vjF%D9dhCgriTWSLSHmElvdjB_!uI}jAk&1ii@IrQ(28qViP_Y z*oeq^iQJmZDtf|rXV(iZ`!dGCeQF`Me5L&*Q5s$|;^YXOI6aZw`Dc_#t~}D%&3n== zW8&9zy(D5v9zy~%HeSEeyRMp9{XQKe!-#N?(E2JedY?c~Vr+e7_Szu(|$Xj7Xz zrM3^1I#vQa@p+bVxkC9Kk)_3n_obV&F0W(}d=afNdD%4ad{DQ zX=l=P*nUy)lbo-;r7Nw>^|5AA!BL7S%gCYslmz>{psta31N8A{GWONJJFcK<)k=zf z6r)rpk#|{urYNYGTP}e9%67IxJ3eP*!-J|K%9(eVn1Plr;kNIDx^LrfYU546cGTtJ zB%!{PBGEf@w`lKP&sgNr7`=CvPk{wy^nCn=7e4JdCHhn% z9e(QMHuqIAy?N6w6mI8Qf=ESluC}`tSZGU0Tq;b)YF%X4pRvGIq~HW5DKF@(Vg>kz z3oK*@a8=BI&fIyFIvm9i9X%Xn?5?Kh^T!i4?Ym>L1!dVD=a&`YYq#cyA3kqFbOWk<0$R(U9 zF(#HF7+}52{9|QO0Y+d$voB43fi;>KSgTop>#w>-CtKTu`jfRcNG(}eEs z5HTf1c7pUG1W9sbh=^Zr-9=#IOrYNi)CS{NXIs5OHHPLwby4RubEZmZDVV< z%(xoprwuPb?Rrizc|4%*D_|4%3$^!J(f>;A6Nj|VB!tk4k>*G|6jU0N^pz5ap7}zi z(#We3Am2es=S#LG_U1i2u2pV5(8W?Rd$-#xT+*c~I6BR>af5N6rv3}V@2>$`;>mug z>0V2_U@Wc+HljK!vi_mZ&7;YWL#Hm?kUoSX>1t5wS2CKnjDH+$YHOpQs0tc?*FE}f zf>tK6;EEA5y}Zm&Q{|NP)^jiSerx-R3nN=Gx;2#A;IU(TMHSugjPvC6tW0yn0UP=E zo4=CU#T~b30;#GssdUkwrB@Q5)_#|h>+RC^DeUa4J~FPl7__NY3D+g9mO}~}LiZqF zp_VM}T>Lf`43F|J3OV(tJ`U5f)QX6Xy)|*I)xM_LfLu@u8^uPg^J37y%9M<;C2o<) zpNn!WlKC1xYAlgdEEUGO^`MZ>GIroX2j|0!C;OdG<&`~1RAj2YWn@I(MO+w*(|{H^ znS{s>FbKbRWHvYZ-mG|CbrHI#mEkeBH_C22rfSpBUJv&o2`6Qf5)Q_XtD!v)J}F|X=3tZ%+-Hhp!Uh1-ul$Zys!7^q^H z&R#irq5E2{s|iU2{jv9*9GH(DxZSa-ou5KR7z;mamW-nSLUxfD1UmNZo%pte{kbdL z+s;0XZ9fb2Rq8%X_Y_@YRL|t1nIW0zH1FDXdgHml9G)FKK9PMPQ94pK^jDB?ojQ{; zmJp?19NCu6Bsm&}U(laJsgBLf<^tdq~p*f1|%Qs{7&l zd#@jGGoTgwsT11|+~1=706I|ZnY@1h`!m5oD+z(%+W`jtxALoXWk1XQ!v38D1gbii zWv|TdXW3tLf3VmBDSCh|dnNd1mV@d5f#q8$n3?uieo+++bxD8(1A(Xre_#;Ef|+pl EAAr@*i~s-t literal 0 HcmV?d00001 diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/fmla.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7a6b0736966edcdb24ad254b1979af63a69335b4 GIT binary patch literal 9838 zcmc(F1yqz>*EUE=hqOo|(ka~?0z-&|#4rpnG|bQn0@Bi;fRwb-EiDbwHAt5mzt8)xXFcCq->~i(X6|)eXPH% z1r8y4S||)?Zw|C|um_9Ndw`+zk`h>AKUioHV0)-Iy%h}RD8j`B1zCaZfKW~cN3cEO zj)jA>9T0~2>TJp72n5*xEx}y8+}r|Opx-RvfL&QaFCiuewg9@=!f0vb-4Pc4W{I1f z1wHNWCSSEBP7krWB5>!py2JHrkfXijFF{wo{|&_25&Ub+j~jmjLUit0J3vQATL=gU zLwJ$v>h9kFox!%y|AKV2H^1gQj^7=}i9r5fhgv}#p=|%92{VZOKWo9k!U6&Un>&D9 z>=5C>>0k@iFtY}OU{`(6KtzT!#2idZ3jjL9)PZ)0ao}>d<$_uPox$eXFlR)VK(9jS zUo{DJbOr;>p;llp%+8kcC+nVE@VgPYvPyKQZLbh(pZxe{BHxD%+WZ&Hq8{{pqgXhvVNz!M_*|GY1Eof9-^y z+y4<`oOVEn{U7nb^`p>80DiA+HxZSL4he`^C>4wNuL^NpRlHwir2FC0crCO9^2IV1 z4iF=9&@;{lV!qVRK2$KV$bxee9Jn|iH(nm>_n!3Udjgkrx>^R0(xYTTLM*T&&$b=W z+ZS0*D+vrvXj|8C%JVFU4E5xy!r)Y-y{UC&bd{E@_q`x`mVJiuG#=7%^&6nMG}v*7 zR6tp51#4c)Ftl?s&5%}@fs;5?`(?A0lftFI%*QX-KX<}d8u|MU3KCK&0TL4K@16KF zwQTG4*)ItYc#}xiz+Y~4L5RByMqP1GZ%($~Mf1#NR56o{W>p4n8y!x!Hp`GX{NWDn^}4#4H-bKFzMh=^tc%Hq*4^N zR1sluNbuvYlAu;tV``rq;+#g%1Q<&bkjW-#45K%+EvhO31lskqwo<$qCD$O zm#Dbep5>jMWlE|Z)t1zp&{+Nnb))x50a+ZjVsl67F%?1JJJ)8W3`RmZf8lpGXAIn} zw^SGzN7LlbKd`4SjZf;L^5#ho1hz~w5)i7?DXAG@w-Lt0w)hoFJ5H`n*@aI%_0=uq zkH}EigAbU~?4$F0Dnms}r051+c~hRwP_CfYslM+@e;pKW`bH>2=ure@+FpB|x>`4s zK{|B5q-ZFVp?%Z;U3%sn&Co{}E`SnxE|ckIb^zTLc!Y|CnzEks z@q$hw1QXhH`PY-q0MUt1agEUL3B& zIA_f8wkU*p{@FUujf3yG{T#k5I3r$9#-_Tp2wdHI#@jw(-EF;H1X#_qhsGq~34U`< zslG8*oeqx(sGW+{j=>2Ir&wOU)9;!%_1TfaqHASyQ@gU;#QC@o3eWCg+)?fj867Hr z@ksaa6C)`K^PwynxD$J(XbkCpD%}l`Y&lnVn ze2&dmsxScDRJ9zW5~41Wf(8#Ec%L&BHp^?zGLQ7f2427|T_o=m&N`YW?c$kDw^yt$ zS--X&v_a<2TF+-1FkOz_QCB}N760_rc@RUF7?W`zEii1%`Dl5_?f|7Y4BN*%pSHEKO`m!x?KWY9DyB?=*zRQ}%_vM{aCOe|XN?1+W@@FDZ3sm=Y zW)441-?=&NnR{x~d^So%t2b*L&S!k-AbXDgb7o+#`n)=M0|{vsv2@4(Ei+st{y*|< zcHE}=6gP3F3Ddq?7aHYIsGpu@rOJm|r?aie-0(-85w^LnBByM&o699v8njb~$e&|H*ES-#>Z-*Y!m8v`OJJk4(0#t`2c z2Opj>RdlQtPV$)T6JbokTL17OTn_-B$8H9)lTPBIDS6WsV6S|n{e;{EFT=ygDuv%- zvE^|F2%wMfd)-}@VnegNZH?VMa~A=C1A^Kt8`Z^FP}4298!uh!c)TeJzXU9LPB43UL^u=+ z_VBCT;%9F?HFkV-s00r`$O4kctK8te7(?&iYR zrO3{-H=_KJ?jtO&;l^AH$(VR$%!5D$v7^BzvNj=Sjdv=w8=EqUhm z?0m4Z-9{KUV@ew3z>8a&vyVhv12M@9?v~`)26&$Se=5wSI54UGem5OqbX__?b5B}t1FUiXA%uMEAyn6f6&4T zOl}YDCGU=CRdl459VQQ>G6l&8#+|<$zK202&t7g@K3u~c8V6i^yD7r4H~$$T_j(Nl zbURdACLd6EPNd{bRK0pQ2Uz|LZaSIhmsoZBC0@1aMuwvnN3Epn)*kDgUyi=4vm$hG9} z2x5j4qi;TGeb_`eh(n+L@hGf{K+3^qVeV&t)y9E7b0K{75Rp0v|I=T8Y>&cYdhA=c z3FLj4_9dLC)_PR@Ms*89b>3F!%;+B@k?zS>O?{Xf$0U#fYj)p0n-zvyes(T~WUES0WD<3|}6s5(J+FBv0PYBIl_yl_Vyefp)R7;t&xXYY!+kw~u~ysC!q zE;i!Rt7RG3*qVV86yHx2uE2_q%FSF;8{q(x)9J#b_CcaJ}JKXc^E2*^8 zVh8mT+oUJoh{|UBfm#l6VXIcA6BX(A3|u9S(Npp9!$bk{+#<7ul7%f-4n)T7#SZgIBWq}T z9g^DF&_+Hq_MNu5C9O2fd{Jb}p<~=X3+AN}>?0&y3Evzae7J6gfBV^S`@>OwBNqSs zmrS;63X53SCHNqe4spge-FNZ_hLH7+@*c7hTfYnncF1vW#7V_PZ|ktL2%`1G zGIEn~Vzz};no`&xci!l2vx<+26w_NhIom51QW>oVc@^lDIBy4#LVEiZ~$b=U}F7!@i=9;7d0R>b(b))gvqLkB;i8uUr$+k{sh zKQ11_ta#}U$IjnYc}mTnx}&v-5B(rhscYYNb9j9VIdhXQI@~(jkZU>m*0cETuWfN$ zull_4w|QpKq>?oNutqvXWNO;mjvR8zk+(qpLY#3j&z{^(uLH2cu)!yir*GRdAS-R? z^s40GUPcgkdjN|wN|g|u-ObmrQUZO3^B;R3Jo&aYv9~a?)H)YIBPk(qF3c1cNViZl zKOVhfzE|vXvY6&TP2qF7zrD$9vf)G@=5;iZTkL%arEt@Fb2c`VpR35#bg@-TlV)X_ zPjysQVzdYZPB&w87_CSn@#8r~rs3CY(r3^{W8cJ0XD~u@w0xdte?h4$>yy^XlZP^m z^EIw=>%CZ<9LoD`Pb|||p4yK0t`pS^coX2D#!Tk+)~)lpo72ZkkD4_;$Uz*r&PZ2%)Sf zqMp994$4dsH@o^``gAeEv6>G$n3rnADxV>bo{J^P+tRLYke2c-R+Rx|WYC2Zcr!;j zW!6dzpJcJG3Q)zK!X~pAG~^wX14Y`<&Dg`N%7H!d#_2}4_GZ{uKs?Wfr8)#+4V)ho ze#*l=3po#fz|u@T8bNE+$$90sxG6Dfiuif72f_&N&=x?eK8i03=r7B?eroe3GY*c9 z&g1p$l>GKr3HXBE2Mex^m)N$CLd;d+7AL;*LmbzDnYNq48I)b6A+ zeD(_F+J{-@<(Ok+`5te4$~Xqph}?|CBNMOTSa`$dG2t2=)2L~{Qxdu`gIm5 zY#=-U`%7=>v^?>EdY2LEJ9W1PB>rUF@Qjf%LZ z{iCZ><0)bNt&qwZs|z0hs7iCq0rcLOi)kghtv)VcN5hO$#EUavIlH8u_~oS+P)hcJB|v2m?FAj@^kQBF(o)jMw;rYmKaOiZZ=z3q!6gUc@)~iUBN4gTV3m$!FBj9 z{yE2I;Za@52`{$PDB9t+nq5YNdKBvyDtu=AAyS#n3(8ppz2@J<{P;FM1gHu~(tT;% z6|?3i&DMm#S$U~8*;F;3w91w3V^AH9y>voam8rpk+Yqu#=2N{IFSEbrSko!;i}*JEojox(nrR>JjiBLF|qJ9C##VJ=CX zNsQdouzx*~e}sqBuk=o}kLjUR*ABg&Ba`xm1YtU|3NvnMx7!i-gUyHEuw1n|gV8xv zJbRo9^_BT~O^Q>Um5iy>*7Tw8)1WNN*pF3?oLQKs3-yJ^p|xa1YcEUFr=xB~M^8s- zyUB|C2-eFgCoTvVR^_cR6 zI;S?%Q|!HjwZIni5+gO0gL5yD!j6v9PbPQiII?&bxHH)TjV{T4F4PZT2_K9Rx{5nO zDs|j5cAh=+o7O%t)Dn)^`A_)qUb3&l69&{gBoZg+XDG1qeVWNmQ zKP_ThnwPRnSW-TPpEk~neFuB z4a>q7Kj~?*hFhL74B7OCh{-wy+l#l%z`T(gDn%H2vhpvf9(Lo}jolrsypdWXn~k%y zuq(n|lb2wbkf$odJs^*z`rtJY>yk3Dl6{w#QLq8cCvS7IJ#gsGyXT z<|o-oB-XuswC!as+x#D2@8*zMCK@m5b&siP`_L{X`Kdl9w%BD@)AW3X=r_B)I-#O zse8!IOL{mOa9U-IGQkK1zYTus+YHKP4P3Y4QW^b|1&8%qh-Al7&W&%PY$oN-r*p{j zf#NytDQoE&PM|3XgR0Hdwma?NlG8*PFpZj;zb^t%s8#82Nl{CQJ+xXepTAI z7veCV($^n?y4QX~*U<{P(~@(De!rR_+a(e$d62_h@X_AhEDi2q6PB|j_UcGUUG>t@ zg2bbu#8jOqN8Gsl9eTd@7c($nv7n(lv%U??D(zO>Wvt%hj;*WO0d*fNr=JpN-+PO8 zFY{pCm0GQp!y~3@jXAR8DQsaVU!wMKEibZ2Ddc%YIqq52faU$2e(Tw^vGdlV^hBxo~ya=#yw0Xhug$klW<@#pa z$RA?Ox=lH1Q16$|^>oyv1~B@fcWt1 zz8gAzv(jHIABKOt$C(#R)IIWQiWREe?1Co_+n!c_n?kBL`Bi(0P!k!O5;vdE*jLNS zQvWWD;~OghrI4|UJr|Tu<$|ds8b5fQK zoxm5daQ=?=w{!A`pr4|%fRHu_yyJT>AxT<;QpyB3cvwquH3hQ1Lz7iO3!izX?CxDw zjeiQ;;+YS3b)5vj)!qdYx4V(~e4TN#>}1A|$0AJ+ZxaCynReaCLt80JW!mc5ZlCoc zCGXixW-Firs&a2Jh8vE4%|R_e-Y!;aQL%Zw#Lb`aJoGiP06;rS%E(DICp92v=mWIr zt=58-kQfddrwyErYSW0j;It6xY5<9C_bW)EM=2ExtsPRfR7+f9U9B^Xnd(o7M|<&^gah{KCtg=d#up5;G> z+ZLc~xJPVPDqy#qqDXf($9*ye*sO%Up52q~Iah&8rRE(>n|cLq#3T#?HyY-iop`GD z=tCU#u&_2Y*#~mc@8N$I-{^bn`=xLInt!hyrVq{&iK4=icmxOMn&+K~xn);y+r3BH zF#z1h%%72BQ3(iF^+H!++KOvw*-in>w(?+86Xw62S5L7Lnl6$2ww`Q7F!A=Tj5u2&u=>((0prc!M!CL9FST|(0q)auhvf;J5z?RMye!R0r zyQ1;$^}9jq1{f5AQU){K(=RbaH}0Rmiu82HEYe_XcjtE1ukCqenA$-(m99N~$(^C~ z92%7Yd7P!ul3%`cAR4|{qO>HhGKUs@>u`AGeji>TU8#h#cx)x6jv%qW|5!o+ zobiQ8cu+C*hJGO2>?qB2-Et63kKpq zfmn);k@}PrL1Sp0#x{zR?G4sw&~vFcr3!h}(9!B6PpV=)ujv^znNzrNCfPdAyh4f* z^IiTzVnUYTbN8liE3YTiB4}7idZllN90kiaNMNUvCiHlUm{kj|dhO_&vKK>(N&*QD z{eYd2GO4EyDoD2nzfHc-gV^!m$TFzpyth`P}a=w;2b!_JU)Qr%Kxxm~W{)#cXGbKeAzYa?-+cwq8D5E*XOE-MQ^ zCA+PLX=O&$%(ABYVa9;UmQ2CosW*I!&{4JztfgFcNF{i4&n|0*#c7Dnj;-?61Af}| z)nSf)KAm%w0)IRp!Du;&32B`8Vm5n*iMq|cAY z{EGZpoSf7%6ItwQKVWbisOqE0X9zflhatA8Vt4~w)<(cmGu*#14eFp3%mKBMR$j*$_uw@4*x1ya4Cf8DwPIAO$XnlHL zmYY5roB}X-Uk-ZbC1l#{)@DurUYmL2tKhlD#rxcm_Pgr&s*P=lkG8=3p&ARt$zII7 zZC+&LX9~&=a{}GB`KQHM*gVlhmR$KVCF!`+7d z7hyEv+_E;Mry6C4Z0j*R5Cd9{uai(#S1ylJjGsf8!Q{9N7avq1X_Sz7wfQxNw3s|^U%i=KSvs9hqWJOKd5<$kClo)uy2sCx}R2+97(HtDG^%@7({cD4&{u3ZEoj z-;=l%XBEnba(Bjw9)DqPsYlu}1a2<%U&Py`BagZ6ZdZ$#UbN9kbkKDSQfJqs#&oPr zPU{=hFep2G2Xw{y0FQ71s>q0W|MySRAUydWuU|Y{^B2Ldk1Vgyh+#pzrV+{IR|lBa z8LpofUSWS@c!Tj9!=I;z*P+)B6#jzNA*8I|7s!7cFI)#-mtp?`x8VK1qU?3_by4y! z^giNf<4;NV4~g(5eLC%C?i_>15hq7?ky zrs6uw^@Y!0Ea6nYWcjfSy3TUF4*kUf8SSbi=ZP literal 0 HcmV?d00001 diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsb new file mode 100644 index 0000000000000000000000000000000000000000..7126d603d010801152cef2cca44f8b3b7299b7e8 GIT binary patch literal 6779 zcmcIp2{=^k+aHZ3JCP+zV@t9xdF{m52_ai*#+YnlhMCC{C6axQsO)>;rR2-`Tg$o+|P6040XZ8j3C0HiVZeD5!FiBLjnR3 zP6psRD>V!nk3{1ynRvP&an>Rp&L{B#v8Ii9%tI0s?^1I7M!IJl;i4R1}A>M>@lCA{ZAW8hCOU zgLQ`Efm^Jds0$q71h+$qN{ER`iz2?MA&e)e!L6hKMP7zqLE#|~bq_$jZ<@F}U*?AV zr7uC2BDaGxfxttU@I>@rkPF)GKoH^kUqBpPkOyP-9{d6X7`IOj+{FdufPmuxFNzYL z{sM?aqHzC$bVJ+jbDr>DjuQcpd+a!S2N#^+zlgALK>wZu%;n1t2&63ram5+P4G|0q zX<*}sMBoWF7yy}pb+AQ3Ack-({w&-Xh=VBbQ$sAq1t$s^O~|4DlQ<+HcYsI@w?_PQT|OBoa>m zz_Fep&Ts@4qmG8#ppdq}4Uo&f%0j>bf;5~xfW`p<0xsgeBld6b??{mNf0rQnUrP|( zE6GZRe=Pxr_m%)_Q|?WEp!DkiCt+bYD3|Ydwbr%P)`IHm)2Y~1PTl27;fmzC#TCvK zpXOf|1t;QZ@U~$j0{xRX8XvB8g9rpVK@I{@|3&*J3oLg%u{Rht%|=;!08ob?p%bupJo+cr>l3bHq%?|VEvE0p<)|;VS7Kt$utssNzKx;h zWDmCAZnHpub#m*GU4L@o_aCheYV!QcmwbWi=QKnr8v`7F8RqZ4=8Y+llBnb%=zb|@D< z@8*4-S^N-|;L}_3I-%^dzx1+HhEVZT2He{C&7h!A_gKm?qq67e$*n2JdIqVApBv+s z#$6_gcu=A7TbgdS5P=me1tl#>1Bu2Qt1T^=Bac_w!q+)jBd?aBq$zpY%ImdGg=OwO z_&Tl8BlyoyEwp$*;(!nd9Rh)9zlG}O_tfdKZ9-dXMs00t?NCD_=+HtK)iMhbx3jbR zY`T7T*Zmv|i#dvwg&PtBGkjUs+TGPE7HCA?h#k`)J_ECXw4kGO->0u1%uY>X(g~~@6ag8eH{l2N;3gBacR(F`x4tXqcl zmRvHziY10cz130uWw}D++T?4aW@(MuvjyczWRlfFAF^LE+EE$FTSZ@K)ABtpm*spZ z8nN~GDz~~`{V8~2Q%DC(TSSAV3#VESODH=Gp&k&seW&Ln8N0erF{-$yQY<7EKJ#E+ zPI&3vgah>c3>d){Vyv2HSg?IW>-v%M>6KB#$qD4Mjn^-frdr1!>gAwlyM) zvzx#^Hr4+OexaKo2z|`Xms&}GuJF`~QcCvv$t7Qhx?>q>s`88W=i-OYq1m6vA?irT zm4ew91j>(E2EqiIlMBy?r>F-;jQ7YisXnPXS{8;Gq;QFzE;l~|^CJn6hdGjQ%Rxwv zN39K=R#b7JqCVMOhlru~{!Hrf{F3lYoMcW6+-~gQ>Pec91@Si@IS=J?toA3Qyz6@1 zZl&ya>Poo)O|A$@&M*;WbKh~S@p!RUd3C@Su~6NMI&_iMPbWX&JX!26QE&%~&nT@J zS%f7gPaB&sdy1c3_TZedg<>dlTFnMl(|3qX0#EGnMhH}9eAx)|Abxf2V|$_D?xBBr z*At;VHVb%FAMh?EaJ@v>)rk^zXt;uyIv^3LRD7CdMr0OXVMgWg5;Fy1AHgP8+ImOY z2j}kWeC>cCINE36n(aNkx4W;(hu^%K6{|=FZhuIsUiWx8?erqn+fw1ibHBQ=T3@OQ zCmY;~uV)iw#ZJ6v$*1741t)2Fzmgk@(C9d-Nimr-CY2s*=XeD=gwVZeI+Ih7?SSdDdUV8>S2a&{Vr&G?V2bhYNA ztliYI+yGi(CHGNeC8Ps$uSt-kx3;Epv(f$D)YG>gH3hS|ct39iNgV&9lb&fRe14$Y zbk>HJ?Z#S@=_@H~ftz`E_)s$%;}n!dvF=i3+#^6#Is}oVnp^irTxR^)<^XZMPrNZ~h&6>^UKlCeD zV*|%qp9RUGp1XgLp%Iv=W)6Ixv9!F@yYwcNlQmd7uV{CdU=*o1J9ItP3=hms2OnOJZ)i zRTpTB;kus_TXvqwa|$nAyHMCiUUKJVKV{y6&NWV{qlxrRUL|hkIr}5M|6u zMu$6QS&2?YGu()4TW^dNjqkipyC6P7qLOG}h_B(&B;tgyxd=nGBN-4kWkh0CZ+M?b ztu{P`r$lZjZ$4-=aF}W&<<@0EcJLxtnr;bT!DTXB&WG>cR*~+sdiT6T&-=@V*Gpr) z?;A!Vjw>rEZOih-25^o2`EDTklkHNW&&GHPhLhE2_w&L$|D`!s?ohAQ-kiegyEs<& zb7@XG+ zlepOV=c0FxomcZoX%No^4^yqjmVT&Eh=qbH7OqmjZi`nnSGc_{=b?Fx46MoEZ)*6k zU43|AUZynrNDc$3p$~LAebNTWI>h++ud1Y`I?^5wm9W#$ z60TuBMOn5dXB7rVqa$Q8qmHz9ZZ#jvkaKr_QplaEK;KtcYeK%O&!{uuVCJuIPaOrB zonv|=IbQY{uBu8Zn;?;g)V>(ru6{Aq znqld!&=f-4zelB6`nDxjuV65jdMkMQmIFQo=2?T7;Y`deW)M3@Uiqh#xN%n~JqIKo zSN2?SQrcn?djFbJT1IR?DXF;EjZGG|b*26>^V-Xzb9X3n#^w5(J~N$j;&t3g^$#}> za6EGBaF&T%Q3KQBFuOiSD$j&hkmzT;U2e85S*GvW++g~eVWr&RNE&9vO5w3INzd1A z(J?hfRx|UqjbE4hm0;^5pwO=HTa+I=9u2EAcAagtCVqI<{V7N)kvjajd_bV(wu++3 z=OKIjV1vjF%D9dhCgriTWSLSHmElvdjB_!uI}jAk&1ii@IrQ(28qViP_Y z*oeq^iQJmZDtf|rXV(iZ`!dGCeQF`Me5L&*Q5s$|;^YXOI6aZw`Dc_#t~}D%&3n== zW8&9zy(D5v9zy~%HeSEeyRMp9{XQKe!-#N?(E2JedY?c~Vr+e7_Szu(|$Xj7Xz zrM3^1I#vQa@p+bVxkC9Kk)_3n_obV&F0W(}d=afNdD%4ad{DQ zX=l=P*nUy)lbo-;r7Nw>^|5AA!BL7S%gCYslmz>{psta31N8A{GWONJJFcK<)k=zf z6r)rpk#|{urYNYGTP}e9%67IxJ3eP*!-J|K%9(eVn1Plr;kNIDx^LrfYU546cGTtJ zB%!{PBGEf@w`lKP&sgNr7`=CvPk{wy^nCn=7e4JdCHhn% z9e(QMHuqIAy?N6w6mI8Qf=ESluC}`tSZGU0Tq;b)YF%X4pRvGIq~HW5DKF@(Vg>kz z3oK*@a8=BI&fIyFIvm9i9X%Xn?5?Kh^T!i4?Ym>L1!dVD=a&`YYq#cyA3kqFbOWk<0$R(U9 zF(#HF7+}52{9|QO0Y+d$voB43fi;>KSgTop>#w>-CtKTu`jfRcNG(}eEs z5HTf1c7pUG1W9sbh=^Zr-9=#IOrYNi)CS{NXIs5OHHPLwby4RubEZmZDVV< z%(xoprwuPb?Rrizc|4%*D_|4%3$^!J(f>;A6Nj|VB!tk4k>*G|6jU0N^pz5ap7}zi z(#We3Am2es=S#LG_U1i2u2pV5(8W?Rd$-#xT+*c~I6BR>af5N6rv3}V@2>$`;>mug z>0V2_U@Wc+HljK!vi_mZ&7;YWL#Hm?kUoSX>1t5wS2CKnjDH+$YHOpQs0tc?*FE}f zf>tK6;EEA5y}Zm&Q{|NP)^jiSerx-R3nN=Gx;2#A;IU(TMHSugjPvC6tW0yn0UP=E zo4=CU#T~b30;#GssdUkwrB@Q5)_#|h>+RC^DeUa4J~FPl7__NY3D+g9mO}~}LiZqF zp_VM}T>Lf`43F|J3OV(tJ`U5f)QX6Xy)|*I)xM_LfLu@u8^uPg^J37y%9M<;C2o<) zpNn!WlKC1xYAlgdEEUGO^`MZ>GIroX2j|0!C;OdG<&`~1RAj2YWn@I(MO+w*(|{H^ znS{s>FbKbRWHvYZ-mG|CbrHI#mEkeBH_C22rfSpBUJv&o2`6Qf5)Q_XtD!v)J}F|X=3tZ%+-Hhp!Uh1-ul$Zys!7^q^H z&R#irq5E2{s|iU2{jv9*9GH(DxZSa-ou5KR7z;mamW-nSLUxfD1UmNZo%pte{kbdL z+s;0XZ9fb2Rq8%X_Y_@YRL|t1nIW0zH1FDXdgHml9G)FKK9PMPQ94pK^jDB?ojQ{; zmJp?19NCu6Bsm&}U(laJsgBLf<^tdq~p*f1|%Qs{7&l zd#@jGGoTgwsT11|+~1=706I|ZnY@1h`!m5oD+z(%+W`jtxALoXWk1XQ!v38D1gbii zWv|TdXW3tLf3VmBDSCh|dnNd1mV@d5f#q8$n3?uieo+++bxD8(1A(Xre_#;Ef|+pl EAAr@*i~s-t literal 0 HcmV?d00001 diff --git a/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx b/OOXML/test/ExampleFiles/xlsx2xlsb/fmla.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7e76bb99c99ce7b989f698674fd034afc009bfa3 GIT binary patch literal 11989 zcmeHN1y>x~vc@gAySqDq;O;KL0)x9dBte2}aCdhIPH-o|g8N_rg1f_;RIFgP$UFfy>9g>&~Ha4@iV7%(slFgOTZF?%}~ zQ#%&}bx#LVXMJW5TN~0`C*?4t(zEN(bj~uLer|P4o5cK%B*VPT(Fw+Paz&3{WV>wG(1XT5U&f`FP5Jgq>oiB1ldV86t z37=gzwmXTC)RG(m8m|NfA&Vh~wyi4*J1S*uHByCsPlxFy++)451;>i-d>7N1km)r% z7}(PjB$)C)=v%MBN^uVINqG=EUx4Uq;ACp!%)8L8*roG3ZG8 zK6vnIdN~GFRL)&Qx|K}*ov+LiN_}J=CBbqB4I!#JegLG@`?h!Y!;8!Okv|5>F4sBB z!_hHcQ8c($1SQ=%y28>^J0(gwmap}qxlLb8U#3XOdeXYJMbnox73atetx`x%o`~0= zjxlTD!($W>24M@N`04a3Xs;MuSAtKAsvT4WRX6fv|A-q)dq104xQiqd!YjZ3Ed^`P z*~omp(r3_y?BWJrL(PKMvf3!qiI3dVz{IBWOgyav#oD=<;eN1YAD*NKS zP95jTmkiHd9{8TJ!Q&zSaFXH`P$c_LlE@<@eUE|!1JeVAJQUE(c-XMG+dEks+1p$H zjBn){%XaCKnC(?l?!rsP$!q4|cv5Bn4LL=l=E}+Ngk0@pE(%C7a~PJygz!tQQ*zIU z%}6g8w^_G+%}O?O(?`e5i@A;M-9NX6K7r=Zqsm%)1aTXgG=@(EvJ6|nykEVtP(I$s6=(_pG zs%plU7Bss|7byJF6IEa39Ftf+#3ZRjJb&OP5J)>5a> zonk9RS`LXU&*i2IRWM3UW9f9Lzatj*?G3&MB5ti-}%QgIp8h2~qjy~s-?sM*GX4J6n;kIsZg2!+0dFvy{jkk>qo zC?4LC$Vk@yj9ItgRHEjn?I4nLwEFaT=~B|UXet;}ShfpcM42SU1dBLgbt7EAX&H78 zyBsSD+Y@9VA5nC2^$~oXe8uui9v-rvW}fczSk)%Xn-`oac5ydQnUKvSi=w?d8$?c` z{5{TN-JUzzZ(hDAx9}5SK-^wq>u%n-4Oaq2z^(hoz0uGmv)Ji9zc+7Ki3KzUq&Jyw z2}Hg!zcb%`Y&C1Vl6h4ww?dUi;K_m~z!ij2&U8b~#*`oU?#`nHk4LClRU?~MsMoAHu%;;_8OS+G4d%Tdv4&IQsM@Yv)cugpXhM##H zqzd+%u=1Hnzqs(IhQ&FoSewx0Kg5jAM*D4r7+O4_MJeTT?H~OHR zxm8jnk=-GD@}v?xz#s0O#XV9>E~*cws@DU1l3uAsE>dqiXal^9vH1~PvH>As?}wcj zOgF(7lvD(i<_jO2jqDu9jAZjV0gEV>d7iBvKb}#H;BmC=hxJPq+iQ$p^ z4n`i42=Laa*j=RF-znUoUg6PPk!|+yjs}bgeptu(lS_%zmP7M`q5%dd8sPqp2F@0yrY_Dbzb{Z(r2*P-*(%f#DfhHSH@qLfCRXN2^yp77OoJT_ODHY>X<3 zF|+2jGrf;aMvl#JUep0(ol~yoDtK6p;1kG{GzH(?vXx!1eG8%_Lt_UBu5d)!`$v-m z>6T<(q_PG0l1&J{A&B#e%G*ut6Q4C5M)$yw!NP!)t9NoK#f3i;t8qw;l$;HPS90hA zmRP?u!E_v^jx}SGlNZTNCWSfQ<5If#$W%Bx-X|_#ZW%fJ5;}|uXKCMAHNxn}h*qe& z2_5NC#v(Q50p@+`@hV@?&CF@!0gbBHD-QSrQWBUHtLM++@(H3o0*21QCbAdaNLR%x!}( z8;13VPk<@q)G-nP2bm9lfc%9VF(fgWubSk`_kxmXTS1SN%7f&w@MpA*?h#cpFx?G% zMAB1yeJ`#s3h7>Biq7iNtYH{Qv#L9VXD?@~74^O$o^`hEVj)HfnzAEqj_Ia$2p)xT znSk`t%^soWV;hPVY`a?sAh15B+IKE}~D zn`^>|&RCy)qGI%;<{qRg5`jL~d(9({&>nmQ5ofIqibt5S<#)_fhV}OpEXVVE`M}2! zfMIa!;2RZ-V>+(aojBrX6kWIbR21EA;D>LhrNOqOyJ@+ZgN#U6Q4?_X+kTV-N~x+! z19Y8KVZ%GhASd-%=&2Ykg{Q)3@ZqtyHgbbM(o@UkA&*HGx`mu~*2`H&L`0Wy`6%GU z!@?j+evJR#i0?nZv*2%ycbc&K6tyU62z9bAarfAHCvix~$Yn%TXM5_N>!C|Y1 zcF;h(6IRd){(sPo{TJQh7NgQwQG<>cE{OD2F_6hj0(>=)BU^A1N=pygjA5!Fk{3p0 zG*}j9cf!xv+*XSr;oJ(&$#vkr7JOJoe3?HKD=rm>I-QeJ)H3f`i{c7Q=f3_|W$68d5V6cuImfLm8Ge1UQLcP}c9tlnENGMB-i zy;4DN-p!6z=l2=3E}5$oUp1dKPfy1ZB#zpRDfE7yP=c-}!^FWMQoC&3-q2Bv!@WVV zyYQrdJKKmwDBh?#QAx=U-A&=aR9&u{dgI-M7`l{)-)q%o2 zlX2uZ<5jP7Cjw-|ao(m;$W;d-HCBfBGZxAvEyzq^jq!lfJdjh{G9BhGHIfjs1_vy1 z#dj{2k|GvSl;<#h^lv!7BHpPN_NHu)fW2)fTTu$jkEs!}6#Oy?i|Pre*0>)+)UP*1 zD@;PNh`IVYw084kY-6>^K&fNd zU5=;r6D1$@OA-~j0ly^?=d5A?ua5~mPCYf1Nk%F!RVmKCJS%stCD*9Rts*`}89>9( z9KuZUA>Kqa6)=%GF}F7)1X`2-(~Xu|kaZM5ZWQx>yAj7PH;Nyzn_@*BIFkMxZ~~7^ zVE=j7jYn2BL0|JA2OR>zyozJ~wZgigw-9|V_?rNnHMRvFqjcIu*)3&_unk9>C$q;5 z$JkF|`X7mK%Ut5VvEr&hL{2qZanrRu*5Z%Q)+ll|7rQ{xwL!~`)y`JMwsG?`Ksi9c zM=DtE>Jf05nZnms``P7mrHH2Kyd+FT`cwh_(LL=)*vW~wPVFaWLA?niSd$M4#aMmKis}swQs2?!f@@XH|dqI8>L_a z>}_e;N_5bsa)|Ag;O+x-vBK_gsdyKB>8UB&cB5Q1`W~7-Y#hc|LW?L|yG+G>U$+-} zaOG;*QUYBD>?C|vAR(D`wOs*!9C~xT;_T`zSBA+Sbp=+89F>k;x0;nmuT{t%LuNK3Q z^x!|KL{ed4W-O@5%4fwm`Zi2fjCGZ06%f(mNm8x&bPBTy#bfHU0)S({YnGwMKW-z@ z_x$*LV8Os{NPnhEe{CaOEKF@pS$_Tg(hU3BBX)#5=po_zWse^V zkg2ds##1$Iu~Z)mwVbZOCQT$pI7A4iQ)T>`vHv&c*g!A_PuGX^e+`gyufOGhdvTzB@&o84J3`dP;Zua23jigQaa z{7A#C5~hYxuL1&-*O2jV_*|}jv{}t}6Wo?rb2o}zSg&!>PLq_c!3HpUOmtf-hoQ_K z1B&K%=Wn@a`(|g3FH~D`rkEb^F;!v-%X8!a6$|>6ZqO;LEe9WXdJL7TOop8?O?v1T zr!X-R2S0s(6LH8P2nJ3i{gE=128V-RghKk9IoBi$!#-G^Lb?}EHraPgwSbdWW3B2I z={zBdb)kDOM$^sT)W}wPemfM6hGYJ;%1?9Em;dQxz&tuj(EGmU)0m+5<@KG7UBz(h zqU6w2y!Xvj)w_qiq7{~>>)Wk3p#rt6{udZe>#bu3_j^KBswfPj`X~2e11y=uLQh|C zo*phk#k|w<-eL$+vSF_v`D`wmu`!MVgjTlgso5e>YbceWT8K*T*lT@xutQoLh-_Mq znPF!f!K+4(bQ=yOe3(OxzwfEofV<=65%p&vH&uRT=jTtSQM=mov0JyJaM?+14M%6_ ze7Hf}NorDeqp(Tw49^wMrBkdvpW<-ytuc1Jf~&c2k&{e^=l-}NuLJvWmPy@DV9qbHtMF z@yF1;7w{i5jfOuz;=WjmZ5{%&Nsd=R_B8dh%i+{SZpIQexg3)A%bP?Kxlmw^rE|wo zve%G=LrSY`E*pJ=UNyZW$UP)Ork%$3^5&eQs zWUi0hmRNUx;d^fiQO3=b>;X{(9iOOiMB6KpSByK=DO+btJJx8`!`yCEGh8Oyr7cR; zotc%+GjvYDa15qb$MLq+=I)MR9@w;@Xsh`*FyhOy`g2?9>RxeC$nroW2rTl=@JTuz z=pEMB)()Ay3OH@=q!ye*AAJXgcjlf0z_!m%g-29_K%PW!BcV_BK_NOAoA4as%7#rl z*y82K+vHXT(?-rkOTF(b&sc?XOr~G4$-L3MPp9|p7Ao9##9`f5K5oK#%2YMSD6q+* zci>)og#D6AoJ!Nkx=*>6?y54ar_S~G^j723u6}#5DYI2dxK97Y#f73(%4Z+HVd|sX z9b#pl@7UuXlv`+UFpuDtq0x^6Ify&6?X-4@zn4n93Egvo`B8FgCNB&tgR*zXAXuP#mGk|CnV=|R+)3M2KrIP@^6W&l2|u_pL4Km% zYh_utWcJ}($>A_Fl5(xR(Fe8^Tk&at_*-5$70(1TFVk%!iAjKjScyT96<%KgLuZ|a zIuK(i0Ocx?1jaHLFV$JOGFl`3o7owA3;oM&{9T37d@~r~p|-ES{NEHz_xiU=rVC2k zf~0jNad*uK0QmqYl74NsRHmD=2v-i264OklzEj)5kz$?|iE^xx^mUljWO)&cqvEaE zQZmBci1G3*rR)I2q!UCZsp2YD@gfIRj#&P;YpX%pW_p9f=qf)P6!_=}dc}hCqU$HkpP8Y=X_MLp~ztsyEt+xLr%ACPVgK}F}|xfzRl^0h$+DK&TBsE2n5yq2lu z{ou`lPvUv!GHOpDT~qx=6PXYL92S0SD$N*z#*~5l%h}OXfBZzHr+R@iEs>N9c8-k{ z+Yo=CHM)LE-jSvt>tQWdfY_{llaL0%{?Ur7L5Bvz7+!wLQ3`fhvHqk&;gMY&Px&y9 z%9qmkmJ6PS!RE^5O+IP$ZRV3y{VPNQe}Il)ifL-CM@A5qxp`iL<@Re-+{|Lz<3+1z z2d{No_jfU`GU}}YUeBcPom|khdLoQo9zlAZ1Nj{l3&wLkaM(s=@5m|9sxA0xZTfw+ z5^p;Fo?dq!Tu@Eq!T@Mgw)*fOs*EHXC^=V&y#RR4bk*ZjGF!s$A1NW}$SbdO4eO9E zf-}$CL2U49FFL7+J4up}nf>htgQ=jsPmfN0e0xgK*KIj`LstS2`DfLdc${S;iWTGK z4X}aPvzC~t%Q{8lWv+W|B2@(3sR2^$?!{dqtqVw250W{Whi)%KD)PVDbH2F9R<(q^ zaLXg9BQZ5aEaxwX{)z*9V>_F$`bWKp+<65z3EGfQA%lS-{S~a8T|8|}oqvkNeXXvj zGH%Retsg?9X1Yd(zCmyvR%pQwp zVbIytxF#YNrfvM+I`g)-Z(rZW`piv#^&+j!@h@uNakLFT7LAXuQo9>yT}oNd%wuI? z!${A+%;dZb-ruW=l{~;}UPjGj^aUzd*~c%8qFRL^l{j*s>2|MW$qwQ(BoA|0HN*mI zCs?KtZz>6L@YU?x;XbuALFM zBeS|N1VA%>TcfD(f(~D$1RhAPqESc6(i5o?;ov9^u{lfTN#^tr*LJkY@DYM?2y*&- zURxEu62AJWImINv%^Qr18*tTM0x3-Dzhs^^vvJBLNbGox0HB6(G?kU&S9~e zLaY!a6)H&CbbxF@r$ZZ=w=oy$oIfFKt**5nNK3|~wW_Dzj4{h){&WK$h;&Yuw5MUU z-Apo;6uz~0wvt5BoA*;o4@TNm@@|+fz+;)_W7iaqLsh zGIrx5^m6Bk_ocmbUAz0ri>W~99|B`fIhh~Z{nz-u9aLK?A~*88kW-a7e3@Ea8=Df0 z>Y$;rwSEF#K)yvC7S6wPyq9s8edA(50;tew_--`Q7TBC^u!2Z|W8%}9v_Dk@Q>pEt zQ;}ct@MYwF(Ze(DZgeU`DFc}LL6LAYNfDRv`xjH<*7nwG*Qv>loIIW^Qf-K~({jN0 z)fYjnw?TH%4O7GlEz4F+cvzB}+zL|rT4h^!Q&K@oV52Yr^tiXv4L zT(y6%zv;Qm^8r~folXZs@<#YV_;?P1u;<)>+Yg3%{N#@Lj^Izb#jGLy%S;gKn?NV# zzu0d9a56Pfb8)h?Gyk;+a7KzCbhDyLT=|1I)@Z38BAv<%rIZZ|H&lnj8JC(8wzAUX zaPzo*^7U9T+zYUlToPPqDMEHbNUk8jf7sZAhZ&v+Oq8GNfyIMqUBxp~nWj1frSe&H zK4r1-+MR}}XR#%1<{PDORzd3n@l?L$M%#LS8 z#gw>$d=&HWj++TY6jS3NZ_?O?G`d}YSxkz#!hG=lL}=Q%wdF9j#hrG?UqWDp{E>00 z1tM_M7{{Xe*n5GgL!{>Ak0nfaCjJ<}By)Qzq@tp1=s?VCtQR$bDwGenJ@0zwYog#w zVg$d>%Y=He4&8(kjF*>M*`6A}*0CtoA2Dve)e7JfP}P3ik9teOZbgOrXT$;nqxowF96+Da#neg7 z)WzlJH)VNt&&F(IX}7OFBDi^Ef&VqWpmY+m{v~*e8(AN$L*8~F$6R7g1W@w&aI1B7On{f?D#nMK+(#q~ z3h#iy>9hYAeo?(%-m+37AY@_WxAe<%nkAftH1w&@deZcex7%~{NxO~1_*yT>=A9~c z)f4Zq1NAQ8%yTupe(s;hLbY zwKqAJU#(_z*`P(@z-oR_Nxq#Bf%}38F&Pji2}r*>qYYi-djqs}f$#t%BD#m;i<#%= z!YmB2${d)WK1MyZFI!>l>;?%m-|co=+)$BqSl}PDY^tA!3*2q~m>($kG;@M7Q+`5B z@2-bXcA8M5b;DOtbSiQD2!HpL*=-I|-F&xpwb%}rJ4V|>e5Hm6_lUFWz>hwHzhsv!vujww(%#HhFV0 z=g7YUO?79b@MOWyGtgwZ3c%Me_eHL2p*HawU*Mt$Rn1u+MawBO@7=QeaY({m7rVkB z&(;EEx6nW(E)#oWWhZ+FXBK07C)1x}0yT2{x3UGAx`@9uGSFXfEAX`EHpGD)^iooC z3oqsNF6MGs#zVC{cz<(akl65z4?mcVHqae1_tuawFw7`-^^=axh2yLWoJxbJNIbj7 zmKfz=daYqiI}T2mnvjIU%M(9~ooQ>^=>^Y>KzTsR1HIs7Pum}5FT$1t6^PvDYKwJ7 zR!3liyIO+;WK^iCff$22Lu~AvLlk!rM-U_(DXQS}1>({xXSelGl3h#fbUk7_e7 z4$ewt>=@lq&MP1eqWj|ff4mwmw8Am{#%mDSM(>w#>L+bM%YGV0&m4&dPMU#|nX z+rN(VxGuZJpY1b{m&iefk?AJ1LBg7B`9xlG)nGE-vnG6K^m6{a_(OJ!uF=&v^TwR^ zoC}hAMMQ3Mk()~Q*V3}VCnG9N12_eAcPRO9F>qJvk-*NNZZZdqeyTmUC8mpi#!ka0(c^E$ zR4+6L?ivxGOWvIC?OvVSoeZ250jI`sS{;^NMUA}TJ;JAbX>Wt%g^E6k#skBY&oV75 zasT4PM}CRz{PT9iB-=WecdFr~QoR&$^sH@!ut7G{TcY?^F|6WQ5#G}7fQ>4w?p^$C ziJFxXI4UBCrWs|_Mwbu^-MB5qW~TU}%vsSpx5GOW@}i_TpUlZmxYJPY9}!M}HuC%> zl)xdFKqBwY4XywFivPa;p}kdE?wOah$??;uzPO!yv^vh=_ZJQ&zg>& z8~?M>;kPLmSQf%Bh^D>Q^fy$iT|i|KSz09wEK+$07cz@4dw4Bze;$| zQJ&Xqexnql{}JU^1?M@+^R)YK6b6tM1ij1iB>Z!L=c$0-0CR-D0DdP1o|``3NBlOO zA^pqr`L5zQ!gJ;R8=;Ww`5gRF$3F*rE`)yr7L)%1d?thcD2tziK9^O$L8~Z#f&N2e zJ-7a+g86L=2Ifx%2KFC%=DGPlBhlZ@Z$L`_f6f0Dmz3q8L2UZj$cF-U3?k$h{m;Aq E0e1zpx&QzG literal 0 HcmV?d00001 diff --git a/OOXML/test/xlsb2xlsx/conversion.cpp b/OOXML/test/xlsb2xlsx/conversion.cpp index 92dd5e9091f..f5677e1ffc6 100644 --- a/OOXML/test/xlsb2xlsx/conversion.cpp +++ b/OOXML/test/xlsb2xlsx/conversion.cpp @@ -92,8 +92,29 @@ class SimpleTests2 : public ::testing::Test static std::wstring tempDir; }; +class FmlaTest : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"fmla.xlsb", L"result.xlsx", L"fmla.xlsx"); + } + + + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; + std::wstring SimpleTests1::tempDir = L""; std::wstring SimpleTests2::tempDir = L""; +std::wstring FmlaTest::tempDir = L""; _UINT32 readFiles(const std::wstring &filePath, const std::wstring &examplePath, std::wstring &fileContent, std::wstring &exampleContent ) { @@ -243,3 +264,65 @@ TEST_F(SimpleTests2, WorksheetsTest) ASSERT_TRUE(boost::algorithm::equals(content1, content2)); } +TEST_F(FmlaTest, ContentTypesTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, WorkbookTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, StylesTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, SharedStringsTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} + +TEST_F(FmlaTest, WorksheetsTest) +{ + auto tempDir = FmlaTest::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.xml"); + std::wstring content1; + std::wstring content2; + ASSERT_EQ(readFiles(path1, path2, content1, content2), 0); + ASSERT_TRUE(boost::algorithm::equals(content1, content2)); +} \ No newline at end of file diff --git a/OOXML/test/xlsx2xlsb/conversion.cpp b/OOXML/test/xlsx2xlsb/conversion.cpp index 2b0d8dec0bd..64ec2e7a31c 100644 --- a/OOXML/test/xlsx2xlsb/conversion.cpp +++ b/OOXML/test/xlsx2xlsb/conversion.cpp @@ -86,6 +86,25 @@ class XlsbSimpleTests2 : public ::testing::Test } + static void TearDownTestCase() + { + RemoveWorkDir(tempDir); + } + + static std::wstring tempDir; +}; +class XlsbFmlaTests : public ::testing::Test +{ +public: + + static void SetUpTestCase() + { + + tempDir = GetWorkDir(); + processTestFile(tempDir, L"fmla.xlsx", L"result.xlsb", L"fmla.xlsb"); + } + + static void TearDownTestCase() { RemoveWorkDir(tempDir); @@ -96,6 +115,7 @@ class XlsbSimpleTests2 : public ::testing::Test std::wstring XlsbSimpleTests1::tempDir = L""; std::wstring XlsbSimpleTests2::tempDir = L""; +std::wstring XlsbFmlaTests::tempDir = L""; _UINT32 readBinaryFiles(const std::wstring &filePath, const std::wstring &examplePath, std::vector &fileContent, std::vector &exampleContent) { @@ -361,4 +381,95 @@ TEST_F(XlsbSimpleTests2, ChartSheetTest) ASSERT_EQ(fileContent, exampleContent); } + +TEST_F(XlsbFmlaTests, ContentTypesTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR + L"example_unpacked"+ FILE_SEPARATOR_STR + L"[Content_Types].xml"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorkbookTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"workbook.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, StylesTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"styles.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, SharedStringsTest) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"sharedStrings.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest1) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet1.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest2) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet2.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + +TEST_F(XlsbFmlaTests, WorksheetsTest3) +{ + auto tempDir = XlsbFmlaTests::tempDir; + std::wstring path1(tempDir + FILE_SEPARATOR_STR + L"result_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet3.bin"); + std::wstring path2(tempDir + FILE_SEPARATOR_STR +L"example_unpacked"+ FILE_SEPARATOR_STR + L"xl" + + FILE_SEPARATOR_STR + L"worksheets" + FILE_SEPARATOR_STR + L"sheet3.bin"); + std::vector fileContent; + std::vector exampleContent; + ASSERT_EQ(readBinaryFiles(path1, path2, fileContent, exampleContent), 0); + ASSERT_EQ(fileContent, exampleContent); +} + + } \ No newline at end of file From a9dd41884142254fd1495c0c6b97a7e1cd9c2f03 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 9 Apr 2024 17:39:45 +0300 Subject: [PATCH 517/794] Fix build --- .../graphics/pro/js/qt/nativegraphics.pro | 47 +++++++++++++++++++ DocxRenderer/src/logic/elements/BaseItem.h | 2 +- DocxRenderer/src/logic/elements/DropCap.cpp | 2 +- DocxRenderer/src/logic/elements/Paragraph.cpp | 4 +- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 64639466634..c4dc51d725e 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -672,6 +672,53 @@ HEADERS +=\ $$PDF_ROOT_DIR/PdfReader.h \ $$PDF_ROOT_DIR/PdfFile.h +# DocxRenderer +DOCX_RENDERER_ROOT_DIR = $$CORE_ROOT_DIR/DocxRenderer +HEADERS += \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Image.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ImageManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ParagraphStyleManager.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/FontStyle.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/ParagraphStyle.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/ColorTable.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/Constants.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/ImageInfo.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/LinesTable.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/VectorGraphics.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/resources.h \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/utils.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Page.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Document.h \ + $$DOCX_RENDERER_ROOT_DIR/DocxRenderer.h + +SOURCES += \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Image.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ImageManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ParagraphStyleManager.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/FontStyle.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Page.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/Document.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/styles/ParagraphStyle.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/VectorGraphics.cpp \ + $$DOCX_RENDERER_ROOT_DIR/DocxRenderer.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/resources/resources.cpp + HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index cd70f383e64..9632d1abfe5 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,6 +1,6 @@ #pragma once #include "../../../../DesktopEditor/common/StringBuilder.h" -#include "src/resources/Constants.h" +#include "../../resources/Constants.h" #include #include diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp index e3ecfb11169..22e42426d63 100644 --- a/DocxRenderer/src/logic/elements/DropCap.cpp +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -1,5 +1,5 @@ #include "DropCap.h" -#include "src/resources/Constants.h" +#include "../../resources/Constants.h" namespace NSDocxRenderer { diff --git a/DocxRenderer/src/logic/elements/Paragraph.cpp b/DocxRenderer/src/logic/elements/Paragraph.cpp index 521da880b77..36494e905a5 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -1,6 +1,6 @@ #include "Paragraph.h" -#include "src/resources/ColorTable.h" -#include "src/resources/utils.h" +#include "../../resources/ColorTable.h" +#include "../../resources/utils.h" namespace NSDocxRenderer { From e728a582220fd8fed797144ad62cb280f0052be9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 9 Apr 2024 22:17:25 +0600 Subject: [PATCH 518/794] Fix cond fmt conversion from xlsb to xlsx --- OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 443370e794e..6cb4a3d5b0c 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1548,7 +1548,7 @@ bool CConditionalFormattingRule::isValid () const } bool CConditionalFormattingRule::isExtended() { - if (m_oDxf.IsInit()) return true; + //if (m_oDxf.IsInit()) return true; if (m_oDataBar.IsInit()) return m_oDataBar->isExtended(); if (m_oIconSet.IsInit()) return m_oIconSet->isExtended(); @@ -2652,6 +2652,7 @@ void CConditionalFormatting::fromBin(XLS::BaseObjectPtr& obj) for(auto &pCFRULE14: ptr->m_arCFRULE14) m_arrItems.push_back(new CConditionalFormattingRule(pCFRULE14)); } + IsExtended(); } XLS::BaseObjectPtr CConditionalFormatting::toBin() From 5708517a0e20a72bc4b1e4e3046b2609e41ff2cc Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 9 Apr 2024 21:02:22 +0300 Subject: [PATCH 519/794] fix bug #67016 --- OOXML/XlsxFormat/Styles/Borders.cpp | 9 +++++++-- OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 2 +- OdfFile/Reader/Format/paragraph_elements.cpp | 15 +++++++++++++++ OdfFile/Reader/Format/paragraph_elements.h | 4 +++- OdfFile/Reader/Format/styles.cpp | 6 +++--- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index f3d7e40e979..301658ce3d9 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -225,7 +225,9 @@ namespace OOX m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDouble)); else if (*sLineStyle == L"Continuous") { - m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThin)); + if (iWeight.IsInit()) m_oStyle.reset(); + else + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleHair)); bBorderContinuous = true; } } @@ -243,8 +245,11 @@ namespace OOX if (false == sLineStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThick)); }break; - default://2: //Medium + case 2: + default: //Medium { + if (false == sLineStyle.IsInit()) + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMedium)); }break; } } diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index c9baa4c890c..f0a974d7b07 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -125,7 +125,7 @@ namespace OOX WritingElement_ReadAttributes_Read_if(oReader, L"ss:ID", m_sId) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Name", m_sName) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Parent", m_sParentId) - WritingElement_ReadAttributes_End(oReader) + WritingElement_ReadAttributes_End(oReader) } //---------------------------------------------------------------------------------------------------------------------- diff --git a/OdfFile/Reader/Format/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index d4bc450363a..8ae6163db6e 100644 --- a/OdfFile/Reader/Format/paragraph_elements.cpp +++ b/OdfFile/Reader/Format/paragraph_elements.cpp @@ -1084,6 +1084,21 @@ void title::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_text_context()->add_text(_title); } } +void title::xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context) +{ + std::wstringstream val; + text_to_stream(val); + std::wstring _title = val.str(); + + if (_title == L"???") + { + _Wostream << L"&F"; + } + else + { + _Wostream << _title; + } +} void title::pptx_convert(oox::pptx_conversion_context & Context) { std::wstringstream val; diff --git a/OdfFile/Reader/Format/paragraph_elements.h b/OdfFile/Reader/Format/paragraph_elements.h index c36d2dde590..7551c1ecf52 100644 --- a/OdfFile/Reader/Format/paragraph_elements.h +++ b/OdfFile/Reader/Format/paragraph_elements.h @@ -620,7 +620,9 @@ class title : public paragraph_content_element virtual void xlsx_convert(oox::xlsx_conversion_context & Context); virtual void pptx_convert(oox::pptx_conversion_context & Context) ; - _CP_OPT(odf_types::Bool) text_fixed_; + virtual void xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context); + + _CP_OPT(odf_types::Bool) text_fixed_; office_element_ptr text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index 95be324126d..1128147ca7d 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -1508,11 +1508,11 @@ void style_page_layout_properties::xlsx_serialize(std::wostream & strm, oox::xls { if (horizontal_margins.fo_margin_left_ && horizontal_margins.fo_margin_left_->get_type() == odf_types::length_or_percent::Length) CP_XML_ATTR(L"left" , horizontal_margins.fo_margin_left_->get_length().get_value_unit(odf_types::length::inch)); - else CP_XML_ATTR(L"left", 0); + else CP_XML_ATTR(L"left", 0.7875); if (horizontal_margins.fo_margin_right_ && horizontal_margins.fo_margin_right_->get_type() == odf_types::length_or_percent::Length) CP_XML_ATTR(L"right" , horizontal_margins.fo_margin_right_->get_length().get_value_unit(odf_types::length::inch)); - else CP_XML_ATTR(L"right", 0); + else CP_XML_ATTR(L"right", 0.7875); if (vertical_margins.fo_margin_top_ && vertical_margins.fo_margin_top_->get_type() == odf_types::length_or_percent::Length) { @@ -2097,7 +2097,7 @@ void header_footer_impl::xlsx_serialize(std::wostream & _Wostream, oox::xlsx_con text::p* p = dynamic_cast(content_[i].get()); for (size_t j = 0; p && j < p->paragraph_.content_.size(); j++) { - text::paragraph_content_element* paragraph_element = dynamic_cast(p->paragraph_.content_[i].get()); + text::paragraph_content_element* paragraph_element = dynamic_cast(p->paragraph_.content_[j].get()); if (paragraph_element) { paragraph_element->xlsx_serialize(_Wostream, Context); From b4556c02549f6ae9fb0ddeacb0bc4d77dd892bb7 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Tue, 9 Apr 2024 22:55:42 +0300 Subject: [PATCH 520/794] Refactoring --- Common/base.pri | 5 ++ DesktopEditor/common/IGrObject.h | 2 + DesktopEditor/fontengine/MemoryStream.h | 2 + DesktopEditor/graphics/IRenderer.h | 83 ++++++++++++++++++------- DesktopEditor/graphics/Matrix.cpp | 8 +-- DesktopEditor/graphics/Matrix.h | 8 +-- 6 files changed, 77 insertions(+), 31 deletions(-) diff --git a/Common/base.pri b/Common/base.pri index eb6a1ec793d..ea437129535 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -304,6 +304,11 @@ core_ios { CONFIG(iphonesimulator, iphoneos|iphonesimulator): { message("iphonesimulator") CORE_BUILDS_PLATFORM_PREFIX = ios_simulator + + QMAKE_CFLAGS += -fembed-bitcode + QMAKE_CXXFLAGS += -fembed-bitcode + QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CXXFLAGS += -fobjc-arc } else { QMAKE_IOS_DEPLOYMENT_TARGET = 11.0 diff --git a/DesktopEditor/common/IGrObject.h b/DesktopEditor/common/IGrObject.h index 953c67ce32b..b0a8d318048 100644 --- a/DesktopEditor/common/IGrObject.h +++ b/DesktopEditor/common/IGrObject.h @@ -38,6 +38,8 @@ #include #endif +#define UNUSED_VARIABLE(x) (void)((x)) + class IGrObject { protected: diff --git a/DesktopEditor/fontengine/MemoryStream.h b/DesktopEditor/fontengine/MemoryStream.h index 753620c7ad0..4abebc12907 100644 --- a/DesktopEditor/fontengine/MemoryStream.h +++ b/DesktopEditor/fontengine/MemoryStream.h @@ -45,7 +45,9 @@ #include #endif +#ifndef _ARM_ALIGN_ #define _ARM_ALIGN_ +#endif static void LOGGING(const std::string& strFile, const std::wstring& strMessage) { diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index feb28daab37..90149fc5989 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -164,13 +164,13 @@ namespace Aggplus { class CImage; } class IRenderer : public IGrObject { public: - bool m_bUseTransformCoordsToIdentity; + bool m_bUseTransformCoordsToIdentity; public: - IRenderer() - { - m_bUseTransformCoordsToIdentity = false; - } + IRenderer() + { + m_bUseTransformCoordsToIdentity = false; + } public: // тип рендерера----------------------------------------------------------------------------- @@ -261,6 +261,7 @@ class IRenderer : public IGrObject virtual HRESULT CommandDrawTextCHAR2(unsigned int* codepoints, const unsigned int& codepointscount, const unsigned int& gid, const double& x, const double& y, const double& w, const double& h) { + UNUSED_VARIABLE(codepointscount); LONG c = (NULL == codepoints) ? 32 : codepoints[0]; return CommandDrawTextExCHAR(c, (LONG)gid, x, y, w, h); } @@ -295,6 +296,12 @@ class IRenderer : public IGrObject // transform -------------------------------------------------------------------------------- virtual HRESULT GetCommandParams(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags) { + UNUSED_VARIABLE(dAngle); + UNUSED_VARIABLE(dLeft); + UNUSED_VARIABLE(dTop); + UNUSED_VARIABLE(dWidth); + UNUSED_VARIABLE(dHeight); + UNUSED_VARIABLE(lFlags); return S_OK; } virtual HRESULT SetCommandParams(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags) @@ -327,7 +334,16 @@ class IRenderer : public IGrObject SetTransform(mass[0], mass[1], mass[2], mass[3], mass[4], mass[5]); return S_OK; } - virtual HRESULT SetBaseTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) { return S_OK; }; + virtual HRESULT SetBaseTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) + { + UNUSED_VARIABLE(m1); + UNUSED_VARIABLE(m2); + UNUSED_VARIABLE(m3); + UNUSED_VARIABLE(m4); + UNUSED_VARIABLE(m5); + UNUSED_VARIABLE(m6); + return S_OK; + }; virtual HRESULT SetTransform(const double& m1, const double& m2, const double& m3, const double& m4, const double& m5, const double& m6) = 0; virtual HRESULT GetTransform(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF) = 0; virtual HRESULT ResetTransform() = 0; @@ -352,29 +368,50 @@ class IRenderer : public IGrObject return S_OK; } - virtual HRESULT IsExistAdditionalParam(const int& type) {return S_FALSE;} - virtual HRESULT GetAdditionalParam(const int& type, std::string& result) {return S_FALSE;} + virtual HRESULT IsExistAdditionalParam(const int& type) + { + UNUSED_VARIABLE(type); + return S_FALSE; + } + virtual HRESULT GetAdditionalParam(const int& type, std::string& result) + { + UNUSED_VARIABLE(type); + UNUSED_VARIABLE(result); + return S_FALSE; + } - virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) { return S_FALSE; } - virtual HRESULT AdvancedCommand(IAdvancedCommand* command) { return S_FALSE; } + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) + { + UNUSED_VARIABLE(type); + return S_FALSE; + } + virtual HRESULT AdvancedCommand(IAdvancedCommand* command) + { + UNUSED_VARIABLE(command); + return S_FALSE; + } // graphics layer settings - virtual HRESULT put_LayerOpacity(double dValue) { return S_FALSE; } + virtual HRESULT put_LayerOpacity(double dValue) + { + UNUSED_VARIABLE(dValue); + return S_FALSE; + } }; #define PROPERTY_RENDERER(NameBase, Name, Type) \ - STDMETHOD(get_##NameBase##Name)(Type* pVal) \ - { \ - if (NULL == pVal) \ - return S_FALSE; \ - *pVal = m_o##NameBase.##Name; \ - return S_OK; \ - } \ - STDMETHOD(put_##NameBase##Name)(Type Val) \ - { \ - m_o##NameBase.##Name = Val; \ - return S_OK; \ - } + STDMETHOD(get_##NameBase##Name)(Type* pVal) \ + { \ + if (NULL == pVal) \ + return S_FALSE; \ + *pVal = m_o##NameBase.##Name; \ + return S_OK; \ + } \ + STDMETHOD(put_##NameBase##Name)(Type Val) \ + { \ + m_o##NameBase.##Name = Val; \ + return S_OK; \ + } // exapmle: // PROPERTY_RENDERER(Pen, Color, LONG) diff --git a/DesktopEditor/graphics/Matrix.cpp b/DesktopEditor/graphics/Matrix.cpp index c8e1043d8d8..ae15b65e111 100644 --- a/DesktopEditor/graphics/Matrix.cpp +++ b/DesktopEditor/graphics/Matrix.cpp @@ -96,7 +96,7 @@ namespace Aggplus } } - void CMatrix::TransformVectors(PointF* pts, int count) + void CMatrix::TransformVectors(PointF* pts, int count) const { // Store matrix to an array [6] of double double M[6]; m_internal->m_agg_mtx.store_to(M); @@ -111,7 +111,7 @@ namespace Aggplus } } - void CMatrix::TransformPoints(PointF* pts, int count) + void CMatrix::TransformPoints(PointF* pts, int count) const { for (int i = 0; i < count; ++i) { @@ -123,7 +123,7 @@ namespace Aggplus } } - void CMatrix::TransformPoint(double& x, double& y) + void CMatrix::TransformPoint(double& x, double& y) const { m_internal->m_agg_mtx.transform(&x, &y); } @@ -281,7 +281,7 @@ namespace Aggplus return agg::rad2deg(m_internal->m_agg_mtx.rotation()); } - void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) + void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) const { agg::trans_affine& m = m_internal->m_agg_mtx; for(int i = 0; i < count; ++i) diff --git a/DesktopEditor/graphics/Matrix.h b/DesktopEditor/graphics/Matrix.h index be917d7db54..bcb4ebc9781 100644 --- a/DesktopEditor/graphics/Matrix.h +++ b/DesktopEditor/graphics/Matrix.h @@ -52,10 +52,10 @@ namespace Aggplus void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend); double Determinant() const; - void TransformVectors(PointF* pts, int count); - void TransformPoints(PointF* pts, int count); - void TransformPoint(double& x, double& y); - void TransformPoints(PointF* dst, const PointF* src, int count); + void TransformVectors(PointF* pts, int count) const; + void TransformPoints(PointF* pts, int count) const; + void TransformPoint(double& x, double& y) const; + void TransformPoints(PointF* dst, const PointF* src, int count) const; void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend); void RotateAt(double angle, const PointF ¢er, MatrixOrder order = MatrixOrderPrepend); From cecf3fe9a823fede48c666c190a61a229d8181f4 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 10 Apr 2024 11:41:15 +0300 Subject: [PATCH 521/794] Fix bug with headers in zip --- OfficeUtils/src/ZipUtilsCP.cpp | 50 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/OfficeUtils/src/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index 3517610f41d..a4fedb41e08 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -551,16 +551,15 @@ namespace ZLibZipUtils /*========================================================================================================*/ - int oneZipFile(zipFile & zf, zip_fileinfo* zi, std::wstring & file_name, std::wstring & zip_file_name, int method, int compressionLevel, bool bDateTime) + int oneZipFile(zipFile & zf, std::wstring & file_name, std::wstring & zip_file_name, int method, int compressionLevel, bool bDateTime) { int err = -1; - NSFile::CFileBinary oFile; zip_fileinfo zinfo; - zinfo.dosDate = zinfo.external_fa = zinfo.internal_fa = 0; - - zip_fileinfo* zi_new = zi ? zi : &zinfo; + zinfo.dosDate = 0; + zinfo.external_fa = 0; + zinfo.internal_fa = 0; if (bDateTime) { @@ -568,20 +567,21 @@ namespace ZLibZipUtils bool ok = NSFile::CFileBinary::GetTime(file_name, &edited); if (ok) { - zi_new->tmz_date.tm_sec = edited.tm_sec; - zi_new->tmz_date.tm_min = edited.tm_min; - zi_new->tmz_date.tm_hour = edited.tm_hour; - zi_new->tmz_date.tm_mday = edited.tm_mday; - zi_new->tmz_date.tm_mon = edited.tm_mon - 1; - zi_new->tmz_date.tm_year = edited.tm_year; + zinfo.tmz_date.tm_sec = edited.tm_sec; + zinfo.tmz_date.tm_min = edited.tm_min; + zinfo.tmz_date.tm_hour = edited.tm_hour; + zinfo.tmz_date.tm_mday = edited.tm_mday; + zinfo.tmz_date.tm_mon = edited.tm_mon - 1; + zinfo.tmz_date.tm_year = edited.tm_year; } } + zip_fileinfo* zi_new = bDateTime ? &zinfo : NULL; - if(oFile.OpenFile(file_name)) + if (oFile.OpenFile(file_name)) { DWORD dwSizeRead; BYTE* pData = new BYTE[oFile.GetFileSize()]; - if(oFile.ReadFile(pData, oFile.GetFileSize(), dwSizeRead)) + if (oFile.ReadFile(pData, oFile.GetFileSize(), dwSizeRead)) { std::string zipFileNameA = codepage_issue_fixToOEM(zip_file_name); @@ -591,7 +591,7 @@ namespace ZLibZipUtils } RELEASEARRAYOBJECTS(pData); } - return 0; + return err; } int ZipDir( const WCHAR* dir, const WCHAR* outputFile, const OnProgressCallback* progress, bool sorted, int method, int compressionLevel, bool bDateTime ) { @@ -669,7 +669,7 @@ namespace ZLibZipUtils file = NSSystemPath::Combine(szText, cFileName); zipFileName = zipDir + cFileName; - oneZipFile(zf, NULL, file, zipFileName, 0, compressionLevel, bDateTime); + oneZipFile(zf, file, zipFileName, 0, compressionLevel, bDateTime); aCurFiles.erase(aCurFiles.begin() + i, aCurFiles.begin() + i + 1); break; @@ -682,7 +682,7 @@ namespace ZLibZipUtils file = NSSystemPath::Combine(szText, cFileName); zipFileName = zipDir + cFileName; - oneZipFile(zf, NULL, file, zipFileName, method, compressionLevel, bDateTime); + oneZipFile(zf, file, zipFileName, method, compressionLevel, bDateTime); if ( progress != NULL ) { @@ -719,13 +719,14 @@ namespace ZLibZipUtils { int err = -1; - if ( ( inputFile != NULL ) && ( outputFile != NULL ) ) + if (( inputFile != NULL) && (outputFile != NULL)) { NSFile::CFileBinary oFile; zip_fileinfo zinfo; - zinfo.external_fa = zinfo.internal_fa = 0; zinfo.dosDate = 0; + zinfo.external_fa = 0; + zinfo.internal_fa = 0; if (bDateTime) { @@ -741,6 +742,7 @@ namespace ZLibZipUtils zinfo.tmz_date.tm_year = edited.tm_year; } } + zip_fileinfo* zi_new = bDateTime ? &zinfo : NULL; if (oFile.OpenFile(inputFile)) { @@ -750,11 +752,11 @@ namespace ZLibZipUtils { zipFile zf = zipOpenHelp(outputFile); if (zf) - { + { wstring zipFileName = NSFile::GetFileName(inputFile); std::string zipFileNameA = codepage_issue_fixToOEM(zipFileName); - err = zipOpenNewFileInZip( zf, zipFileNameA.c_str(), &zinfo, NULL, 0, NULL, 0, NULL, method, compressionLevel ); + err = zipOpenNewFileInZip( zf, zipFileNameA.c_str(), zi_new, NULL, 0, NULL, 0, NULL, method, compressionLevel ); err = zipWriteInFileInZip( zf, pData, dwSizeRead ); err = zipCloseFileInZip( zf ); err = zipClose( zf, NULL ); @@ -837,13 +839,13 @@ namespace ZLibZipUtils int UnzipToDir(unzFile uf, const WCHAR* unzipDir, const OnProgressCallback* progress, const WCHAR* password, bool opt_extract_without_path, bool clearOutputDirectory ) { int err = -1; - + if ( uf != NULL && unzipDir != NULL ) { - if (NSDirectory::Exists(unzipDir)) - err = 0; + if (NSDirectory::Exists(unzipDir)) + err = 0; - if ( clearOutputDirectory ) + if ( clearOutputDirectory ) { ClearDirectory( unzipDir ); } From 82d577c335914c3acc25449cff02249db1acf8b9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 10 Apr 2024 12:40:25 +0300 Subject: [PATCH 522/794] ShapeStart, ShapeEnd to DocInfo --- .../graphics/commands/AnnotField.cpp | 20 ----------- DesktopEditor/graphics/commands/AnnotField.h | 34 ------------------ DesktopEditor/graphics/commands/DocInfo.cpp | 21 +++++++++++ DesktopEditor/graphics/commands/DocInfo.h | 36 +++++++++++++++++++ 4 files changed, 57 insertions(+), 54 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index f8b65d6e91e..3b6df74fcd9 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1000,23 +1000,3 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil return true; } - -CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} -const std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } -bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) -{ - m_sShapeXML = pReader->ReadStringA(); - return true; -} - -CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} -bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { return true; } - -CPageRotate::CPageRotate() : IAdvancedCommand(AdvancedCommandType::PageRotate) {} -int CPageRotate::GetPageRotate() { return m_nPageRotate; } -bool CPageRotate::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) -{ - m_nPageRotate = pReader->ReadInt(); - return true; -} - diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 43e042246b1..a3ce19756ac 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -508,38 +508,4 @@ class GRAPHICS_DECL CWidgetsInfo : public IAdvancedCommand std::vector m_arrParents; }; -class GRAPHICS_DECL CShapeStart : public IAdvancedCommand -{ -public: - CShapeStart(); - - const std::string& GetShapeXML(); - - bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); - -private: - std::string m_sShapeXML; -}; - -class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand -{ -public: - CShapeEnd(); - - bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); -}; - -class GRAPHICS_DECL CPageRotate : public IAdvancedCommand -{ -public: - CPageRotate(); - - int GetPageRotate(); - - bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); - -private: - int m_nPageRotate; -}; - #endif // _BUILD_ANNOTFIELD_H_ diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index 723f50c37b1..b1d0faab7d8 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -128,3 +128,24 @@ bool CDocInfoCommand::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta m_sKeywords = pReader->ReadString(); return true; } + +CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} +void CShapeStart::SetShapeXML(const std::string& sShapeXML) { m_sShapeXML = sShapeXML; } +const std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } +bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_sShapeXML = pReader->ReadStringA(); + return true; +} + +CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} +bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { return true; } + +CPageRotate::CPageRotate() : IAdvancedCommand(AdvancedCommandType::PageRotate) {} +int CPageRotate::GetPageRotate() { return m_nPageRotate; } +bool CPageRotate::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) +{ + m_nPageRotate = pReader->ReadInt(); + return true; +} + diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index a9df8a230fc..40b8470dc02 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -132,4 +132,40 @@ class GRAPHICS_DECL CDocInfoCommand : public IAdvancedCommand bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); }; +class GRAPHICS_DECL CShapeStart : public IAdvancedCommand +{ +public: + CShapeStart(); + + void SetShapeXML(const std::string& sShapeXML); + const std::string& GetShapeXML(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + std::string m_sShapeXML; +}; + +class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand +{ +public: + CShapeEnd(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); +}; + +class GRAPHICS_DECL CPageRotate : public IAdvancedCommand +{ +public: + CPageRotate(); + + int GetPageRotate(); + + bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + +private: + int m_nPageRotate; +}; + + #endif // _BUILD_DOCINFO_H_ From 5c7ebcd3fff01fcbada79ea78676ddb9b798c6e9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 10 Apr 2024 12:42:32 +0300 Subject: [PATCH 523/794] BMC replaced by BDC for marked content --- PdfFile/SrcWriter/Document.cpp | 5 ++++- PdfFile/SrcWriter/Pages.cpp | 10 ++++++++++ PdfFile/SrcWriter/Pages.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 95dfa6edb06..4a7b7048559 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1805,6 +1805,9 @@ namespace PdfWriter } pArrayMeta->Add(new CStringObject(sXML.c_str())); - m_pCurPage->BeginMarkedContent("MetaOForm"); + CDictObject* pBDC = new CDictObject(); + pBDC->Add("MCID", pArrayMeta->GetCount() - 1); + m_pCurPage->BeginMarkedContentDict("MetaOForm", pBDC); + RELEASEOBJECT(pBDC); } } diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 5eeead9f111..08744c5934d 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1591,6 +1591,16 @@ namespace PdfWriter m_pStream->WriteEscapeName(sName.c_str()); m_pStream->WriteStr(" BMC\012"); } + void CPage::BeginMarkedContentDict(const std::string& sName, CDictObject* pBDC) + { + // Operator : BDC + // Description: Начало маркированного контента со списком свойств + + m_pStream->WriteEscapeName(sName.c_str()); + m_pStream->WriteChar(' '); + m_pStream->Write(pBDC, NULL); + m_pStream->WriteStr(" BDC\012"); + } void CPage::EndMarkedContent() { // Operator : EMC diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 46e53b3c7a9..053056055a0 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -139,6 +139,7 @@ namespace PdfWriter void SetStrokeAlpha(unsigned char unAlpha); void SetFillAlpha(unsigned char unAlpha); void BeginMarkedContent(const std::string& sName); + void BeginMarkedContentDict(const std::string& sName, CDictObject* pBDC); void EndMarkedContent(); void BeginText(); From aa83a2dda2b12d0f51b99c45f6ad8dfeb49ca611 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 10 Apr 2024 12:44:03 +0300 Subject: [PATCH 524/794] ShapeStart, ShapeEnd for RendererOutputDev --- PdfFile/SrcReader/RendererOutputDev.cpp | 21 +++++++++++++++++++++ PdfFile/SrcReader/RendererOutputDev.h | 3 +++ PdfFile/lib/xpdf/Gfx.cc | 12 +++++++----- PdfFile/lib/xpdf/OutputDev.h | 4 ++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index a4489cb3ab2..7def635bdc1 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -53,6 +53,7 @@ #include "../../DesktopEditor/common/Path.h" #include "../../DesktopEditor/common/Array.h" #include "../../DesktopEditor/graphics/BaseThread.h" +#include "../../DesktopEditor/graphics/commands/DocInfo.h" #include "../Resources/BaseFonts.h" #include @@ -4144,6 +4145,26 @@ namespace PdfReader { return; } + GBool RendererOutputDev::beginMarkedContent(GfxState *state, GString* s) + { + IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType)) + { + CShapeStart* pCommand = new CShapeStart(); + pCommand->SetShapeXML(s->getCString()); + m_pRenderer->AdvancedCommand(pCommand); + } + return gFalse; + } + void RendererOutputDev::endMarkedContent(GfxState *state) + { + IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType)) + { + IAdvancedCommand* pCommand = new CShapeEnd(); + m_pRenderer->AdvancedCommand(pCommand); + } + } void RendererOutputDev::drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight,GBool bInvert, GBool bInlineImage, GBool interpolate) { if (m_bDrawOnlyText) diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index b41544b757d..6da24d327bb 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -262,6 +262,9 @@ namespace PdfReader void endType3Char(GfxState *pGState); void Type3D0(GfxState *pGState, double dWx, double dWy); void Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy); + //----- Дополнительные функции + virtual GBool beginMarkedContent(GfxState *state, GString *s) override; + virtual void endMarkedContent(GfxState *state) override; //----- Вывод картинок virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; virtual void setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 26c6c0aa1c4..ca40ff2ed1a 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,11 +5053,13 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); - } else if (args[0].isName("MetaOForm") && res->lookupPropertiesNF("MetaOForm", &obj)) { - Object oMetaOForm, oID, oTID, oID2; + } else if (args[0].isName("MetaOForm") && numArgs == 2 && args[1].isDict() && res->lookupPropertiesNF("MetaOForm", &obj)) { + Object oMetaOForm, oID, oTID, oID2, oMCID, oMetadata, oMetadataCur; if (obj.fetch(xref, &oMetaOForm)->isDict("MetaOForm") && oMetaOForm.dictLookup("ID", &oID)->isString() && xref->getTrailerDict()->dictLookup("ID", &oTID)->isArray() && - oTID.arrayGet(1, &oID2)->isString() && oID2.getString()->cmp(oID.getString()) == 0) { - oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); obj.free(); + oTID.arrayGet(1, &oID2)->isString() && oID2.getString()->cmp(oID.getString()) == 0 && args[1].dictLookup("MCID", &oMCID)->isInt() && + oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray() && oMetadata.arrayGet(oMCID.getInt(), &oMetadataCur)->isString() && + out->beginMarkedContent(state, oMetadataCur.getString())) { + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); getContentObj(&obj); while (!obj.isEOF() && !obj.isCmd("EMC")) { obj.free(); @@ -5066,7 +5068,7 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { obj.free(); return; } - oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); obj.free(); + oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); diff --git a/PdfFile/lib/xpdf/OutputDev.h b/PdfFile/lib/xpdf/OutputDev.h index 6fe7eeedb4e..a770dfd6ff7 100644 --- a/PdfFile/lib/xpdf/OutputDev.h +++ b/PdfFile/lib/xpdf/OutputDev.h @@ -186,6 +186,10 @@ class OutputDev { virtual void beginActualText(GfxState *state, Unicode *u, int uLen) {} virtual void endActualText(GfxState *state) {} + //----- additional + virtual GBool beginMarkedContent(GfxState *state, GString *s) { return gFalse; } + virtual void endMarkedContent(GfxState *state) {} + //----- image drawing virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, From 5e02d5d943c4923a4e771d5fe391a92360d9b0ac Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 10 Apr 2024 13:07:21 +0300 Subject: [PATCH 525/794] Fix begin/end-MarkedContent --- PdfFile/SrcReader/RendererOutputDev.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 7def635bdc1..a0f912884c8 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -4148,21 +4148,25 @@ namespace PdfReader GBool RendererOutputDev::beginMarkedContent(GfxState *state, GString* s) { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; - if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType)) + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) { CShapeStart* pCommand = new CShapeStart(); pCommand->SetShapeXML(s->getCString()); - m_pRenderer->AdvancedCommand(pCommand); + bool bRes = m_pRenderer->AdvancedCommand(pCommand) == S_OK; + RELEASEOBJECT(pCommand); + if (bRes) + return gTrue; } return gFalse; } void RendererOutputDev::endMarkedContent(GfxState *state) { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; - if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType)) + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) { - IAdvancedCommand* pCommand = new CShapeEnd(); + CShapeEnd* pCommand = new CShapeEnd(); m_pRenderer->AdvancedCommand(pCommand); + RELEASEOBJECT(pCommand); } } void RendererOutputDev::drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight,GBool bInvert, GBool bInlineImage, GBool interpolate) From defbcd77fbede5101918605c9c0cc2d52a24f7e8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 10 Apr 2024 13:12:08 +0300 Subject: [PATCH 526/794] Add originIndex for drawingfile --- .../pro/js/wasm/js/drawingfile_base.js | 21 +++++++++++++++---- PdfFile/lib/xpdf/Gfx.cc | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 74f373352e3..a5a29584b14 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -261,6 +261,7 @@ rec["H"] = reader.readInt(); rec["Dpi"] = reader.readInt(); rec["Rotate"] = reader.readInt(); + rec["originIndex"] = i; rec.fonts = []; rec.fontsUpdateType = UpdateFontsSource.Undefined; rec.text = null; @@ -308,9 +309,20 @@ return this.StartID; }; + function getOriginPage(pages, originIndex) + { + for (let i = 0; i < pages.length; ++i) + { + if (pages[i]["originIndex"] == originIndex) + return pages[i]; + } + return null; + } + CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor) { - if (this.pages[pageIndex].fonts.length > 0) + let page = getOriginPage(this.pages, pageIndex); + if (!page || page.fonts.length > 0) { // waiting fonts return null; @@ -320,7 +332,7 @@ let retValue = Module["_GetPixmap"](this.nativeFile, pageIndex, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor); this.unlockPageNumForFontsLoader(); - if (this.pages[pageIndex].fonts.length > 0) + if (page.fonts.length > 0) { // waiting fonts Module["_free"](retValue); @@ -330,7 +342,8 @@ }; CFile.prototype["getGlyphs"] = function(pageIndex) { - if (this.pages[pageIndex].fonts.length > 0) + let page = getOriginPage(this.pages, pageIndex); + if (!page || page.fonts.length > 0) { // waiting fonts return null; @@ -343,7 +356,7 @@ // you need to call destroyTextInfo() this.unlockPageNumForFontsLoader(); - if (this.pages[pageIndex].fonts.length > 0) + if (page.fonts.length > 0) { // waiting fonts retValue = null; diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index ca40ff2ed1a..8879323061e 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5066,6 +5066,7 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { getContentObj(&obj); } obj.free(); + out->endMarkedContent(state); return; } oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); From 13b0458d474fa1e21cedc50e5bb30ac7738478ab Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 10 Apr 2024 15:30:52 +0300 Subject: [PATCH 527/794] Add support for external headers --- DesktopEditor/doctrenderer/json/json.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesktopEditor/doctrenderer/json/json.h b/DesktopEditor/doctrenderer/json/json.h index 179fb2b3a54..efd9ac6ae6f 100644 --- a/DesktopEditor/doctrenderer/json/json.h +++ b/DesktopEditor/doctrenderer/json/json.h @@ -6,6 +6,7 @@ #include #include +#ifndef JSON_DECL #ifdef JSBASE_NO_USE_DYNAMIC_LIBRARY #define JSON_DECL #else @@ -16,6 +17,7 @@ #define JSON_DECL Q_DECL_IMPORT #endif #endif +#endif // uncomment to enable exceptions throwing //#define JSON_DEBUG From d733af03aa92735f5ac55adf86d11775c6af9460 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 10 Apr 2024 20:30:26 +0600 Subject: [PATCH 528/794] Fix icon set conversion --- .../Biff_structures/CFVOParsedFormula.cpp | 1 + OOXML/XlsbFormat/Biff12_records/CFVO.cpp | 12 +- .../Worksheets/ConditionalFormatting.cpp | 224 ++++++++++++------ .../Worksheets/ConditionalFormatting.h | 2 +- 4 files changed, 157 insertions(+), 82 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp index 36de0127471..d9a124c7493 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVOParsedFormula.cpp @@ -112,6 +112,7 @@ void CFVOParsedFormula::save(CFRecord& record) }; saving(rgce); + cce = size; saving(rgcb); } } diff --git a/OOXML/XlsbFormat/Biff12_records/CFVO.cpp b/OOXML/XlsbFormat/Biff12_records/CFVO.cpp index a21b557c2b5..8afa7c88624 100644 --- a/OOXML/XlsbFormat/Biff12_records/CFVO.cpp +++ b/OOXML/XlsbFormat/Biff12_records/CFVO.cpp @@ -62,8 +62,16 @@ namespace XLSB { record << iType << numParam << fSaveGTE << fGTE << cbFmla; - if (cbFmla) - record << formula; + if (cbFmla) + { + auto rdPtr = record.getRdPtr(); + record << formula; + auto size = record.getRdPtr() - rdPtr; + record.RollRdPtrBack(size + 4); + _UINT32 cce = formula.cce; + record << cce; + record.skipNunBytes(size); + } } } // namespace XLSB diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 6cb4a3d5b0c..43b98d19819 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -240,18 +240,18 @@ void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) m_oFormula = oReader; } } -XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() +XLS::BaseObjectPtr CConditionalFormatValueObject::toBin(bool isIcon) { auto ptr(new XLSB::uCFVO); XLS::BaseObjectPtr objectPtr(ptr); auto ptr1(new XLSB::CFVO); ptr->m_BrtCFVO = XLS::BaseObjectPtr{ptr1}; - ptr1->fSaveGTE = 0; + ptr1->fSaveGTE = isIcon; if(m_oGte.IsInit()) ptr1->fGTE = m_oGte->GetValue(); else - ptr1->fGTE = false; + ptr1->fGTE = true; if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) ptr1->iType = XLSB::CFVOtype::CFVONUM; else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) @@ -264,18 +264,20 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin() ptr1->iType = XLSB::CFVOtype::CFVOPERCENTILE; else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) ptr1->iType = XLSB::CFVOtype::CFVOFMLA; + else + ptr1->iType = XLSB::CFVOtype::CFVONUM; - if(m_oVal.IsInit()) + if(m_oVal.IsInit() && ptr1->iType != XLSB::CFVOtype::CFVOFMLA) ptr1->numParam.data.value = std::stod(m_oVal.get()); else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) ptr1->numParam.data.value = 0; else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) ptr1->numParam.data.value = 0; - if(m_oFormula.IsInit()) + if(static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oVal.IsInit()) { - ptr1->formula = m_oFormula->m_sText; - ptr1->cbFmla = ptr1->formula.cce; + ptr1->formula = m_oVal.get(); + ptr1->cbFmla = 1; } else { @@ -1150,85 +1152,149 @@ XLS::BaseObjectPtr CIconSet::toBin() auto beginPtr(new XLSB::BeginIconSet); ptr->m_BrtBeginIconSet = XLS::BaseObjectPtr{beginPtr}; if(m_oShowValue.IsInit()) - beginPtr->fIcon = !m_oShowValue->GetValue(); + beginPtr->fIcon = !m_oShowValue->GetValue(); + else + beginPtr->fIcon = false; if(m_oReverse.IsInit()) - beginPtr->fReverse = m_oReverse->GetValue(); - - if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::NoIcons) - { - beginPtr->iSet.set = KPISets::KPINIL; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows3) - { - beginPtr->iSet.set = KPISets::KPI3ARROWS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows3Gray) - { - beginPtr->iSet.set = KPISets::KPI3ARROWSGRAY; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Flags3) - { - beginPtr->iSet.set = KPISets::KPI3FLAGS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights1) - { - beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights2) - { - beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS2; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Signs3) - { - beginPtr->iSet.set = KPISets::KPI3SIGNS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Symbols3) - { - beginPtr->iSet.set = KPISets::KPI3SYMBOLS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Symbols3_2) - { - beginPtr->iSet.set = KPISets::KPI3SYMBOLS2; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows4) - { - beginPtr->iSet.set = KPISets::KPI4ARROWS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows4Gray) - { - beginPtr->iSet.set = KPISets::KPI4ARROWSGRAY; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::RedToBlack4) - { - beginPtr->iSet.set = KPISets::KPI4REDTOBLACK; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Rating4) - { - beginPtr->iSet.set = KPISets::KPI4RATING; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Traffic4Lights) - { - beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows5) - { - beginPtr->iSet.set = KPISets::KPI5ARROWS; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Arrows5Gray) - { - beginPtr->iSet.set = KPISets::KPI5ARROWSGRAY; - } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Rating5) + beginPtr->fReverse = m_oReverse->GetValue(); + else + beginPtr->fReverse = false; + if(m_oIconSet.IsInit()) { - beginPtr->iSet.set = KPISets::KPI5RATING; + switch (m_oIconSet->GetValue()) + { + case SimpleTypes::Spreadsheet::EIconSetType::NoIcons: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3: + { + beginPtr->iSet.set = KPISets::KPI3ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows3Gray: + { + beginPtr->iSet.set = KPISets::KPI3ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Flags3: + { + beginPtr->iSet.set = KPISets::KPI3FLAGS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights1: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic3Lights2: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS2; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Signs3: + { + beginPtr->iSet.set = KPISets::KPI3SIGNS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3: + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Symbols3_2: + { + beginPtr->iSet.set = KPISets::KPI3SYMBOLS2; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4: + { + beginPtr->iSet.set = KPISets::KPI4ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows4Gray: + { + beginPtr->iSet.set = KPISets::KPI4ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::RedToBlack4: + { + beginPtr->iSet.set = KPISets::KPI4REDTOBLACK; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating4: + { + beginPtr->iSet.set = KPISets::KPI4RATING; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Traffic4Lights: + { + beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5: + { + beginPtr->iSet.set = KPISets::KPI5ARROWS; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Arrows5Gray: + { + beginPtr->iSet.set = KPISets::KPI5ARROWSGRAY; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Rating5: + { + beginPtr->iSet.set = KPISets::KPI5RATING; + break; + } + case SimpleTypes::Spreadsheet::EIconSetType::Quarters5: + { + beginPtr->iSet.set = KPISets::KPI5QUARTERS; + break; + } + default: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + } } - else if (m_oIconSet == SimpleTypes::Spreadsheet::EIconSetType::Quarters5) + else { - beginPtr->iSet.set = KPISets::KPI5QUARTERS; + switch(m_arrValues.size()) + { + case 0: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + case 3: + { + beginPtr->iSet.set = KPISets::KPI3TRAFFICLIGHTS1; + break; + } + case 4: + { + beginPtr->iSet.set = KPISets::KPI4TRAFFICLIGHTS; + break; + } + case 5: + { + beginPtr->iSet.set = KPISets::KPI5QUARTERS; + break; + } + default: + { + beginPtr->iSet.set = KPISets::KPINIL; + break; + } + } + } for(auto i:m_arrValues) - ptr->m_arCFVO.push_back(i->toBin()); + ptr->m_arCFVO.push_back(i->toBin(true)); return objectPtr; } void CIconSet::ReadAttributes(XLS::BaseObjectPtr& obj) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h index cb0ab73bc6d..1918b3aac28 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h @@ -107,7 +107,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toBin(const bool isIcon = false); virtual EElementType getType () const; bool isExtended (); From 897c7493daab93a2a541926efce63e38a3a74c09 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 10 Apr 2024 20:31:35 +0300 Subject: [PATCH 529/794] Fixes for .m files --- Common/base.pri | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Common/base.pri b/Common/base.pri index ea437129535..6cf2958beb3 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -308,6 +308,7 @@ core_ios { QMAKE_CFLAGS += -fembed-bitcode QMAKE_CXXFLAGS += -fembed-bitcode QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CFLAGS += -fobjc-arc QMAKE_CXXFLAGS += -fobjc-arc } else { @@ -316,6 +317,7 @@ core_ios { QMAKE_CFLAGS += -fembed-bitcode QMAKE_CXXFLAGS += -fembed-bitcode QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CFLAGS += -fobjc-arc QMAKE_CXXFLAGS += -fobjc-arc bundle_xcframeworks { From de2ecb08a0dbc7f7534f46cd15f0587287372eb4 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 10 Apr 2024 22:09:51 +0300 Subject: [PATCH 530/794] . --- OOXML/XlsxFormat/Styles/Borders.cpp | 52 +++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/Borders.cpp b/OOXML/XlsxFormat/Styles/Borders.cpp index 301658ce3d9..47f085bc528 100644 --- a/OOXML/XlsxFormat/Styles/Borders.cpp +++ b/OOXML/XlsxFormat/Styles/Borders.cpp @@ -207,7 +207,7 @@ namespace OOX WritingElement_ReadAttributes_Read_else_if(oReader, L"ss:Position", m_oType) WritingElement_ReadAttributes_Read_else_if(oReader, L"ss:Weight", iWeight) WritingElement_ReadAttributes_End(oReader) - + if (sColor.IsInit()) { m_oColor.Init(); m_oColor->m_oRgb.Init(); @@ -219,10 +219,16 @@ namespace OOX m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDotted)); else if (*sLineStyle == L"Dash") m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashed)); - else if (*sLineStyle == L"None") - m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleNone)); + else if (*sLineStyle == L"DashDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashDot)); + else if (*sLineStyle == L"DashDotDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDashDotDot)); else if (*sLineStyle == L"Double") m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleDouble)); + else if (*sLineStyle == L"None") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleNone)); + else if (*sLineStyle == L"SlantDashDot") + m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleSlantDashDot)); else if (*sLineStyle == L"Continuous") { if (iWeight.IsInit()) m_oStyle.reset(); @@ -237,19 +243,28 @@ namespace OOX { case 1: //Thin { - if (false == sLineStyle.IsInit()) + if (false == m_oStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThin)); }break; case 3: //Thick { - if (false == sLineStyle.IsInit()) + if (false == m_oStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleThick)); }break; case 2: default: //Medium { - if (false == sLineStyle.IsInit()) + if (false == m_oStyle.IsInit()) m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMedium)); + else + { + switch (m_oStyle->GetValue()) + { + case SimpleTypes::Spreadsheet::borderstyleDashed: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashed)); break; + case SimpleTypes::Spreadsheet::borderstyleDashDot: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashDot)); break; + case SimpleTypes::Spreadsheet::borderstyleDashDotDot: m_oStyle.reset(new SimpleTypes::Spreadsheet::CBorderStyle(SimpleTypes::Spreadsheet::borderstyleMediumDashDotDot)); break; + } + } }break; } } @@ -344,10 +359,26 @@ namespace OOX if ((border) && (border->m_oType.IsInit())) { - if (*border->m_oType == L"Bottom") m_oBottom = border; - else if (*border->m_oType == L"Top") m_oTop = border; - else if (*border->m_oType == L"Left") m_oStart = border; - else if (*border->m_oType == L"Right") m_oEnd = border; + if (*border->m_oType == L"Bottom") m_oBottom = border; + else if (*border->m_oType == L"Top") m_oTop = border; + else if (*border->m_oType == L"Left") m_oStart = border; + else if (*border->m_oType == L"Right") m_oEnd = border; + else if (*border->m_oType == L"DiagonalLeft") + { + if (false == m_oDiagonal.IsInit()) + { + m_oDiagonal = border; + } + m_oDiagonalUp = true; + } + else if (*border->m_oType == L"DiagonalRight") + { + if (false == m_oDiagonal.IsInit()) + { + m_oDiagonal = border; + } + m_oDiagonalDown = true; + } if (border->bBorderContinuous) bBorderContinuous = true; @@ -357,7 +388,6 @@ namespace OOX delete border; } } - } } void CBorder::fromBin(XLS::BaseObjectPtr& obj) From 8309c5bbfeb2aebb45d9eb18762f854968b18f19 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 11 Apr 2024 15:12:26 +0500 Subject: [PATCH 531/794] End every paragraph with a:endParaRPr --- OdfFile/Reader/Converter/pptx_text_context.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index 5559650809f..7d32a3fc8b8 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -478,14 +478,12 @@ std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { CP_XML_STREAM() << run_.str(); } - else + + CP_XML_NODE(L"a:endParaRPr") { - CP_XML_NODE(L"a:endParaRPr") + if(last_run_font_size_ && false) { - if(last_run_font_size_) - { - CP_XML_ATTR(L"sz", last_run_font_size_->get_value_unit(odf_types::length::pt) * 100); - } + CP_XML_ATTR(L"sz", last_run_font_size_->get_value_unit(odf_types::length::pt) * 100); } } } From b7ca461ba590674e908cd62300682f7a78544d77 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 11 Apr 2024 14:42:11 +0300 Subject: [PATCH 532/794] Fix coord shift --- PdfFile/SrcReader/RendererOutputDev.cpp | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 42c225a2cfc..cd5ae7bf4da 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3055,25 +3055,11 @@ namespace PdfReader if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) return; - double xMin, yMin, xMax, yMax; - pGState->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); - pGState->moveTo(xMin, yMin); - pGState->lineTo(xMax, yMin); - pGState->lineTo(xMax, yMax); - pGState->lineTo(xMin, yMax); - pGState->closePath(); - - DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); - - // Image - long brush; - int alpha = pGState->getFillOpacity() * 255; + if (abs(pBBox[2] - pBBox[0] - dXStep) > 0.001 || abs(pBBox[3] - pBBox[1] - dYStep) > 0.001) + return; - double dDpiX, dDpiY; - m_pRenderer->get_DpiX(&dDpiX); - m_pRenderer->get_DpiY(&dDpiY); - int nWidth = dXStep * dDpiX / 72.0; - int nHeight = dYStep * dDpiY / 72.0; + int nWidth = round(dXStep); + int nHeight = round(dYStep); BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; memset(pBgraData, 0, nWidth * nHeight * 4); @@ -3111,12 +3097,26 @@ namespace PdfReader Aggplus::CImage* oImage = new Aggplus::CImage(); oImage->Create(pBgraData, nWidth, nHeight, 4 * nWidth); - m_pRenderer->BrushRect(true, xMin, yMin, xMax, yMax); + double xMin, yMin, xMax, yMax; + pGState->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + + pGState->moveTo(xMin + pBBox[0], yMin + pBBox[1]); + pGState->lineTo(xMax + pBBox[2], yMin + pBBox[1]); + pGState->lineTo(xMax + pBBox[2], yMax + pBBox[3]); + pGState->lineTo(xMin + pBBox[0], yMax + pBBox[3]); + pGState->closePath(); + + DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); + + long brush; m_pRenderer->get_BrushType(&brush); + + int alpha = pGState->getFillOpacity() * 255; m_pRenderer->put_BrushType(c_BrushTypeTexture); m_pRenderer->put_BrushTextureImage(oImage); - m_pRenderer->put_BrushTextureMode(1); + m_pRenderer->put_BrushTextureMode(c_BrushTextureModeTile); m_pRenderer->put_BrushTextureAlpha(alpha); + m_pRenderer->BeginCommand(c_nImageType); #ifdef BUILDING_WASM_MODULE if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer)) { @@ -3129,8 +3129,8 @@ namespace PdfReader m_pRenderer->DrawPath(c_nWindingFillMode); #endif - m_pRenderer->EndCommand(c_nPathType); - m_pRenderer->BrushRect(false, 0, 0, 1, 1); + m_pRenderer->PathCommandEnd(); + m_pRenderer->EndCommand(c_nImageType); m_pRenderer->put_BrushType(brush); pGState->clearPath(); From 1929e2e5c9c975c2f99578beba11eaa59106d657 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 11 Apr 2024 16:02:48 +0300 Subject: [PATCH 533/794] Fix page scale --- PdfFile/SrcReader/RendererOutputDev.cpp | 30 +++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index cd5ae7bf4da..d0d8bc507f6 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -41,6 +41,7 @@ #include "../lib/xpdf/CMap.h" #include "../lib/xpdf/Dict.h" #include "../lib/xpdf/Stream.h" +#include "../lib/xpdf/PDFDoc.h" //#include "FontFileTrueType.h" //#include "FontFileType1C.h" #include "../lib/xpdf/CharCodeToUnicode.h" @@ -654,6 +655,9 @@ namespace PdfReader } void RendererOutputDev::startPage(int nPageIndex, GfxState *pGState) { + if (nPageIndex < 0) + return; + m_pRenderer->BeginCommand(c_nPageType); // Переводим пункты в миллиметры @@ -3058,8 +3062,16 @@ namespace PdfReader if (abs(pBBox[2] - pBBox[0] - dXStep) > 0.001 || abs(pBBox[3] - pBBox[1] - dYStep) > 0.001) return; - int nWidth = round(dXStep); - int nHeight = round(dYStep); + double dWidth, dHeight, dDpiX, dDpiY; + m_pRenderer->get_Width(&dWidth); + m_pRenderer->get_Height(&dHeight); + m_pRenderer->get_DpiX(&dDpiX); + m_pRenderer->get_DpiY(&dDpiY); + dWidth = dWidth * dDpiX / 25.4; + dHeight = dHeight * dDpiY / 25.4; + + int nWidth = round(dXStep * dWidth / pGState->getPageWidth()); + int nHeight = round(dYStep * dHeight / pGState->getPageHeight()); BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; memset(pBgraData, 0, nWidth * nHeight * 4); @@ -3073,11 +3085,8 @@ namespace PdfReader NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); pRenderer->SetFontManager(m_pFontManager); pRenderer->CreateFromBgraFrame(pFrame); - pRenderer->put_Width (dXStep * 25.4 / 72.0); - pRenderer->put_Height(dYStep * 25.4 / 72.0); - - IRenderer* pOldRenderer = m_pRenderer; - m_pRenderer = pRenderer; + pRenderer->put_Width (nWidth * 25.4 / 72.0); + pRenderer->put_Height(nHeight * 25.4 / 72.0); PDFRectangle box; box.x1 = pBBox[0]; @@ -3085,15 +3094,18 @@ namespace PdfReader box.x2 = pBBox[2]; box.y2 = pBBox[3]; - Gfx* m_gfx = new Gfx(gfx->getDoc(), this, pResourcesDict, &box, NULL); + RendererOutputDev* m_pRendererOut = new RendererOutputDev(pRenderer, m_pFontManager, m_pFontList); + m_pRendererOut->NewPDF(gfx->getDoc()->getXRef()); + + Gfx* m_gfx = new Gfx(gfx->getDoc(), m_pRendererOut, -1, pResourcesDict, dDpiX, dDpiY, &box, NULL, 0); m_gfx->display(pStream); pFrame->ClearNoAttack(); RELEASEOBJECT(m_gfx); RELEASEOBJECT(pRenderer); + RELEASEOBJECT(m_pRendererOut); RELEASEOBJECT(pFrame); - m_pRenderer = pOldRenderer; Aggplus::CImage* oImage = new Aggplus::CImage(); oImage->Create(pBgraData, nWidth, nHeight, 4 * nWidth); From 3015aff49145e38d15d60230d56647d9fb8518c5 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Thu, 11 Apr 2024 16:35:23 +0300 Subject: [PATCH 534/794] . --- OdfFile/DataTypes/borderstyle.cpp | 8 ++++ OdfFile/DataTypes/borderstyle.h | 7 +++- OdfFile/Reader/Converter/xlsx_borders.cpp | 43 +++++++++++++++++++--- OdfFile/Writer/Converter/XlsxConverter.cpp | 26 ++++++------- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/OdfFile/DataTypes/borderstyle.cpp b/OdfFile/DataTypes/borderstyle.cpp index 7c37ae92421..2ca43a3561c 100644 --- a/OdfFile/DataTypes/borderstyle.cpp +++ b/OdfFile/DataTypes/borderstyle.cpp @@ -52,6 +52,10 @@ std::wostream & operator << (std::wostream & _Wostream, const border_style & bor case border_style::dotted: _Wostream << L" dotted "; break; case border_style::dashed: _Wostream << L" dashed "; break; case border_style::dot_dashed: _Wostream << L" dot-dashed "; break; + case border_style::dash_dot: _Wostream << L" dash-dot "; break; + case border_style::dash_dot_dot: _Wostream << L" dash-dot-dot "; break; + case border_style::fine_dashed: _Wostream << L" fine-dashed "; break; + case border_style::double_thin: _Wostream << L" double-thin "; break; case border_style::solid: default: _Wostream << L" solid "; break; @@ -126,6 +130,10 @@ border_style::border_style(const std::wstring & Value) : initialized_(false), no if (splitted[1] == L"dotted") style_ = dotted; if (splitted[1] == L"dashed") style_ = dashed; if (splitted[1] == L"dot-dashed") style_ = dot_dashed; + if (splitted[1] == L"dash-dot") style_ = dash_dot; + if (splitted[1] == L"dash-dot-dot") style_ = dash_dot_dot; + if (splitted[1] == L"fine-dashed") style_ = fine_dashed; + if (splitted[1] == L"double-thin") style_ = double_thin; } if (splitted.size() > 2) diff --git a/OdfFile/DataTypes/borderstyle.h b/OdfFile/DataTypes/borderstyle.h index ec77b9f0c07..610607724b0 100644 --- a/OdfFile/DataTypes/borderstyle.h +++ b/OdfFile/DataTypes/borderstyle.h @@ -56,8 +56,11 @@ class border_style ridge, inset, outset, - hidden - + hidden, + dash_dot, + dash_dot_dot, + fine_dashed, + double_thin }; border_style(){none_ = true;} diff --git a/OdfFile/Reader/Converter/xlsx_borders.cpp b/OdfFile/Reader/Converter/xlsx_borders.cpp index f8639ac6c42..6857dc64e14 100644 --- a/OdfFile/Reader/Converter/xlsx_borders.cpp +++ b/OdfFile/Reader/Converter/xlsx_borders.cpp @@ -55,19 +55,52 @@ std::wstring convert_border_style(const odf_types::border_style& borderStyle) { std::wstring retVal = L"none"; - if (borderStyle.initialized()) + if (borderStyle.initialized()) { + double pt = borderStyle.get_length().get_value_unit(odf_types::length::pt); + if (borderStyle.get_style() == odf_types::border_style::none || borderStyle.is_none()) - retVal = L"none"; + { + retVal = L"none"; + } else if (borderStyle.get_style() == odf_types::border_style::double_) + { retVal = L"double"; + } else if (borderStyle.get_style() == odf_types::border_style::dotted) + { retVal = L"dotted"; + } else if (borderStyle.get_style() == odf_types::border_style::dashed) - retVal = L"dashed"; + { + if (pt > 1.5) retVal = L"mediumDashed"; + else retVal = L"dashed"; + } + else if (borderStyle.get_style() == odf_types::border_style::dash_dot) + { + if (pt > 1.5) retVal = L"mediumDashDot"; + else retVal = L"dashDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::dash_dot_dot) + { + if (pt > 1.5) retVal = L"mediumDashDotDot"; + else retVal = L"dashDotDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::fine_dashed) + { + retVal = L"slantDashDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::double_thin) + { + retVal = L"double"; + } else - - retVal = L"thin"; + { + if (pt > 2.) retVal = L"thick"; + else if (pt > 1.5) retVal = L"medium"; + else if (pt < 0.1) retVal = L"hair"; + else retVal = L"thin"; + } } return retVal; } diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index f963d5c6161..0cff665696d 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -2556,47 +2556,47 @@ void XlsxConverter::convert(OOX::Spreadsheet::CBorderProp *borderProp, std::wstr switch(borderProp->m_oStyle->GetValue()) { case SimpleTypes::Spreadsheet::borderstyleDashDot: - border_style = L"1pt dot-dashed"; + border_style = L"0.74pt dash-dot"; break; case SimpleTypes::Spreadsheet::borderstyleDashDotDot: - border_style = L"1pt dot-dashed"; + border_style = L"0.74pt dash-dot-dot"; break; case SimpleTypes::Spreadsheet::borderstyleDashed: - border_style = L"1pt dashed"; + border_style = L"0.74pt dashed"; break; case SimpleTypes::Spreadsheet::borderstyleDotted: - border_style = L"1pt dotted"; + border_style = L"0.74pt dotted"; break; case SimpleTypes::Spreadsheet::borderstyleDouble: - border_style = L"1pt double"; + border_style = L"0.74pt double"; break; case SimpleTypes::Spreadsheet::borderstyleHair: - border_style = L"1pt solid"; + border_style = L"0.06pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleMedium: - border_style = L"2.49pt solid"; + border_style = L"1.76pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashDot: - border_style = L"2.49pt dot-dashed"; + border_style = L"1.76pt dash-dot"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashDotDot: - border_style = L"2.49pt dot-dashed"; + border_style = L"1.76pt dash-dot-dot"; break; case SimpleTypes::Spreadsheet::borderstyleMediumDashed: - border_style = L"2.49pt dashed"; + border_style = L"1.76pt dashed"; break; case SimpleTypes::Spreadsheet::borderstyleNone: border_style = L"none"; return; break; case SimpleTypes::Spreadsheet::borderstyleSlantDashDot: - border_style = L"1pt solid"; + border_style = L"1.76pt fine-dashed"; break; case SimpleTypes::Spreadsheet::borderstyleThick: - border_style = L"1pt solid"; + border_style = L"2.49pt solid"; break; case SimpleTypes::Spreadsheet::borderstyleThin: - border_style = L"1pt solid"; + border_style = L"0.74pt solid"; break; } } From 43c05c6041e13232c035228f0b6bb0cff69b6ae8 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Thu, 11 Apr 2024 17:02:21 +0300 Subject: [PATCH 535/794] Fix fromJS method --- DesktopEditor/doctrenderer/json/serialization.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesktopEditor/doctrenderer/json/serialization.h b/DesktopEditor/doctrenderer/json/serialization.h index d7a8a11f38a..07a75a38681 100644 --- a/DesktopEditor/doctrenderer/json/serialization.h +++ b/DesktopEditor/doctrenderer/json/serialization.h @@ -68,6 +68,8 @@ namespace NSJSON static CValue fromJS(JSSmart jsValue) { + if (!jsValue.is_init()) + return CValue::CreateUndefined(); if (jsValue->isUndefined()) return CValue::CreateUndefined(); if (jsValue->isNull()) From 2e32a1b70a8855541012523489afedcbbc9f0a32 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 12 Apr 2024 12:50:07 +0300 Subject: [PATCH 536/794] Remove GetShapes --- .../graphics/pro/js/drawingfile.json | 1 - .../pro/js/wasm/js/drawingfile_base.js | 41 ------------------- .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 -- .../graphics/pro/js/wasm/src/drawingfile.h | 6 --- PdfFile/PdfFile.cpp | 6 --- PdfFile/PdfFile.h | 1 - 6 files changed, 59 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index fa8af8480ff..9b77693ad47 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -36,7 +36,6 @@ "_GetButtonIcons", "_GetAnnotationsInfo", "_GetAnnotationsAP", - "_GetShapes", "_InitializeFontsBin", "_InitializeFontsBase64", "_InitializeFontsRanges", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index a5a29584b14..88a03169d6a 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1537,47 +1537,6 @@ Module["_free"](ext); return res; }; - CFile.prototype["getShapes"] = function(pageIndex) - { - let res = []; - let ext = Module["_GetShapes"](this.nativeFile, pageIndex); - if (ext == 0) - return res; - - let lenArray = new Int32Array(Module["HEAP8"].buffer, ext, 4); - if (lenArray == null) - { - Module["_free"](ext); - return res; - } - - let len = lenArray[0]; - len -= 4; - if (len <= 0) - { - Module["_free"](ext); - return res; - } - - let buffer = new Uint8Array(Module["HEAP8"].buffer, ext + 4, len); - let reader = new CBinaryReader(buffer, 0, len); - - if (!reader.isValid()) - { - Module["_free"](ext); - return res; - } - - while (reader.isValid()) - { - let n = reader.readInt(); - for (let i = 0; i < n; ++i) - res.push(reader.readString()); - } - - Module["_free"](ext); - return res; - }; CFile.prototype["getStructure"] = function() { let res = []; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 74c88d37601..2221c4c86e3 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -250,10 +250,6 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) } return NULL; } -WASM_EXPORT BYTE* GetShapes(CGraphicsFileDrawing* pGraphics, int nPageIndex) -{ - return pGraphics->GetShapes(nPageIndex); -} WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { return pGraphics->DestroyText(); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index d48193b1ef2..0f159b34a0e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -149,12 +149,6 @@ class CGraphicsFileDrawing return ((CPdfFile*)pReader)->GetAnnots(nPageIndex); return NULL; } - BYTE* GetShapes(int nPageIndex) - { - if (nType == 0) - return ((CPdfFile*)pReader)->GetShapes(nPageIndex); - return NULL; - } BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL) { if (nType == 0) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 1878491675c..6307e0c8121 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -431,12 +431,6 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) return NULL; return m_pInternal->pReader->GetAnnots(nPageIndex); } -BYTE* CPdfFile::GetShapes(int nPageIndex) -{ - if (!m_pInternal->pReader) - return NULL; - return m_pInternal->pReader->GetShapes(nPageIndex); -} BYTE* CPdfFile::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pInternal->pReader) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index e7054c7dbe6..4877d8362f1 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -132,7 +132,6 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer BYTE* GetWidgetEmbeddedFonts(); BYTE* GetWidgetStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); - BYTE* GetShapes (int nPageIndex); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); From 52a07814f4b05ef066027d33b4ac9806ae7b84b1 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 12 Apr 2024 13:17:13 +0300 Subject: [PATCH 537/794] Improving the quality of converting html tables to ooxml and refactoring --- .../3dParty/html/css/src/CCompiledStyle.cpp | 8 +- .../3dParty/html/css/src/StaticFunctions.cpp | 46 ++ Common/3dParty/html/css/src/StaticFunctions.h | 1 + .../3dParty/html/css/src/StyleProperties.cpp | 33 +- Common/3dParty/html/css/src/StyleProperties.h | 2 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 34 +- .../html/css/src/xhtml/CDocumentStyle.h | 5 +- HtmlFile2/htmlfile2.cpp | 579 ++---------------- 8 files changed, 154 insertions(+), 554 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index e28fa3ecc0d..83a6d161be3 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -12,7 +12,7 @@ #include "StaticFunctions.h" #include "ConstValues.h" -#define DEFAULTFONTSIZE 28 // 14 * 2 +#define DEFAULT_FONT_SIZE 28 // 14 * 2 namespace NSCSS { @@ -66,9 +66,7 @@ namespace NSCSS bool CCompiledStyle::operator== (const CCompiledStyle& oStyle) const { - return GetId()[0] == oStyle.GetId()[0] && - m_arParentsStyles == oStyle.m_arParentsStyles && - m_oBackground == oStyle.m_oBackground && + return m_oBackground == oStyle.m_oBackground && m_oBorder == oStyle.m_oBorder && m_oFont == oStyle.m_oFont && m_oMargin == oStyle.m_oMargin && @@ -112,7 +110,7 @@ namespace NSCSS void CCompiledStyle::AddStyle(const std::map& mStyle, const unsigned int unLevel, const bool& bHardMode) { const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true; - const double dFontSize = m_oFont.GetSize().ToDouble(NSCSS::Twips); + const double dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Twips) : DEFAULT_FONT_SIZE; for (std::pair pPropertie : mStyle) { diff --git a/Common/3dParty/html/css/src/StaticFunctions.cpp b/Common/3dParty/html/css/src/StaticFunctions.cpp index 3a70addd453..ae49a17baeb 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.cpp +++ b/Common/3dParty/html/css/src/StaticFunctions.cpp @@ -80,6 +80,52 @@ namespace NS_STATIC_FUNCTIONS return arValues; } + std::vector ParseCSSPropertie(const std::wstring& wsInput) + { + std::vector arResult; + std::wstring wsCurrent; + bool bInQuotes = false; + bool bInFunction = false; + int nParenDepth = 0; + + for (wchar_t c : wsInput) + { + if (c == ' ' && !bInQuotes && !bInFunction) + { + if (!wsCurrent.empty()) + { + arResult.push_back(wsCurrent); + wsCurrent.clear(); + } + } + else if (c == '"' || c == '\'') + { + bInQuotes = !bInQuotes; + wsCurrent += c; + } + else if (c == '(') + { + bInFunction = true; + nParenDepth++; + wsCurrent += c; + } + else if (c == ')') + { + nParenDepth--; + if (nParenDepth == 0) + bInFunction = false; + wsCurrent += c; + } + else + wsCurrent += c; + } + + if (!wsCurrent.empty()) + arResult.push_back(wsCurrent); + + return arResult; + } + std::vector GetWordsW(const std::wstring& wsLine, bool bWithSigns, const std::wstring& wsDelimiters) { if (wsLine.empty()) diff --git a/Common/3dParty/html/css/src/StaticFunctions.h b/Common/3dParty/html/css/src/StaticFunctions.h index b4a13fa78ed..2bb29fe20e4 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.h +++ b/Common/3dParty/html/css/src/StaticFunctions.h @@ -20,6 +20,7 @@ namespace NSCSS double ReadDouble(const std::wstring& wsValue); std::vector ReadDoubleValues(const std::wstring& wsValue); + std::vector ParseCSSPropertie(const std::wstring& wsInput); std::vector GetWordsW(const std::wstring& wsLine, bool bWithSigns = false, const std::wstring& wsDelimiters = L" \n\r\t\f\v:;,!"); std::vector GetWeightSelector(const std::wstring& sSelector); std::map GetRules(const std::wstring& wsStyles); diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index d9df7d923e9..dc4e1eb9c02 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -641,45 +641,36 @@ namespace NSCSS } } - std::wstring CColor::EquateToColor(const std::vector& arColors) const + std::wstring CColor::EquateToColor(const std::vector> &arColors) const { if (arColors.empty()) return L"none"; - TRGB oColor; + TRGB oCurrentColor; switch(m_oValue.m_enType) { - case ColorRGB: oColor = *static_cast(m_oValue.m_pColor); break; - case ColorHEX: oColor = ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); break; + case ColorRGB: oCurrentColor = *static_cast(m_oValue.m_pColor); break; + case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); break; default: return L"none"; } - TRGB oTempColor; std::wstring wsSelectedColor; double dMinDistance = DBL_MAX; double dDistance; - for (const std::wstring& wsColor : arColors) + for (const std::pair& oColor : arColors) { - oTempColor = ConvertHEXtoRGB(wsColor); - dDistance = sqrt(pow(oTempColor.uchRed - oColor.uchRed, 2) + pow(oTempColor.uchGreen - oColor.uchGreen, 2) + pow(oTempColor.uchBlue - oColor.uchBlue, 2)); + dDistance = sqrt(pow(oCurrentColor.uchRed - oColor.first.uchRed, 2) + pow(oCurrentColor.uchGreen - oColor.first.uchGreen, 2) + pow(oCurrentColor.uchBlue - oColor.first.uchBlue, 2)); if (dDistance < dMinDistance) { dMinDistance = dDistance; - wsSelectedColor = wsColor; + wsSelectedColor = oColor.second; } } - std::map::const_iterator oIter = - std::find_if(NSConstValues::COLORS.begin(), NSConstValues::COLORS.end(), [&wsSelectedColor](const std::pair& oPair) - { return wsSelectedColor == oPair.second; }); - - if (NSConstValues::COLORS.end() == oIter) - return std::wstring(); - - return oIter->first; + return wsSelectedColor; } TRGB CColor::ToRGB() const @@ -1364,7 +1355,7 @@ namespace NSCSS { if (wsValue.empty()) return false; - + if (L"none" == wsValue) { SetColor(L"#ffffff", unLevel, bHardMode); @@ -1372,8 +1363,8 @@ namespace NSCSS SetWidth(L"0",unLevel,bHardMode); return true; } - - const std::vector arValues = NS_STATIC_FUNCTIONS::GetWordsW(wsValue, false, L" "); + + const std::vector arValues = NS_STATIC_FUNCTIONS::ParseCSSPropertie(wsValue); for (const std::wstring& sValue : arValues) { if (SetColor(sValue, unLevel, bHardMode)) @@ -2236,7 +2227,7 @@ namespace NSCSS void CFont::UpdateSize(double dFontSize) { if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure()) - m_oSize.ConvertTo(NSCSS::Twips, dFontSize); + m_oSize.ConvertTo(NSCSS::Point, dFontSize); } void CFont::UpdateLineHeight(double dFontSize) diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 9e843e874c6..f3e6f91d236 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -237,7 +237,7 @@ namespace NSCSS int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; - std::wstring EquateToColor(const std::vector& arColors) const; + std::wstring EquateToColor(const std::vector>& arColors) const; TRGB ToRGB() const; }; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 9948bb9e724..26295711879 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -11,23 +11,23 @@ namespace NSCSS { - CStyleUsed::CStyleUsed(const CCompiledStyle &oStyle, bool bIsPStyle) - : m_oStyle(oStyle), m_bIsPStyle(bIsPStyle) + CStyleUsed::CStyleUsed(const std::wstring &wsId, bool bIsPStyle) + : m_bIsPStyle(bIsPStyle), m_wsId(wsId) {} bool CStyleUsed::operator==(const CStyleUsed &oUsedStyle) const { - return (m_bIsPStyle == oUsedStyle.m_bIsPStyle) && (m_oStyle == oUsedStyle.m_oStyle); + return (m_bIsPStyle == oUsedStyle.m_bIsPStyle) && (m_wsId == oUsedStyle.m_wsId); } std::wstring CStyleUsed::getId() { - return m_sId; + return m_wsId; } void CStyleUsed::setId(const std::wstring &sId) { - m_sId = sId; + m_wsId = sId; } CDocumentStyle::CDocumentStyle() : m_arStandardStyles({L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"h1-c", @@ -439,8 +439,25 @@ namespace NSCSS if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); - oXmlElement.AddPropertiesInR(RProperties::R_Highlight, oStyle.m_oBackground.GetColor().EquateToColor({L"000000", L"0000FF", L"00FFFF", L"00FF00", L"FF00FF", L"FF0000", L"FFFF00", L"FFFFFF", L"00008B", L"008B8B", L"006400", L"8B008B", L"8B0000", L"8B8000", L"A9A9A9", L"D3D3D3"})); + const std::wstring wsHighlight{oStyle.m_oBackground.GetColor().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"}, + {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, + {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, + {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, + {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, + {{211, 211, 211}, L"lightGray"}})}; + + if (L"none" != wsHighlight) + oXmlElement.AddPropertiesInR(RProperties::R_Highlight, wsHighlight); + oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); + + std::wstring wsFontFamily{oStyle.m_oFont.GetFamily().ToWString()}; + + if (L"sans-serif" == wsFontFamily) + wsFontFamily = L"Arial"; + else if (L"serif" == wsFontFamily) + wsFontFamily = L"Times New Roman"; + oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString()); oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString()); @@ -455,7 +472,7 @@ namespace NSCSS return false; } - CStyleUsed structStyle(oStyle, false); + CStyleUsed structStyle(oStyle.GetId(), false); std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); @@ -464,6 +481,7 @@ namespace NSCSS m_sId = (*oItem).getId(); return false; } + CXmlElement oXmlElement; SetRStyle(oStyle, oXmlElement); @@ -517,7 +535,7 @@ namespace NSCSS return true; } - CStyleUsed structStyle(oStyle, true); + CStyleUsed structStyle(oStyle.GetId(), true); std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); if (oItem != m_arStyleUsed.end()) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 91bb61cd407..47a9acfb3ea 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -10,12 +10,11 @@ namespace NSCSS { class CStyleUsed { - CCompiledStyle m_oStyle; bool m_bIsPStyle; - std::wstring m_sId; + std::wstring m_wsId; public: - CStyleUsed(const CCompiledStyle& oStyle, bool bIsPStyle); + CStyleUsed(const std::wstring& wsId, bool bIsPStyle); bool operator==(const CStyleUsed& oUsedStyle) const; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index ee91b818e4f..cef405e7257 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -121,6 +121,13 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) return L""; } +typedef enum +{ + ParseModeHeader, + ParseModeBody, + ParseModeFoother +} ERowParseMode; + //Необходимые стили таблицы struct TTableStyles { @@ -181,16 +188,16 @@ class CTableCell { public: CTableCell() - : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false) + : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_enMode(ParseModeBody) {} CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged) - : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged) + : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_enMode(ParseModeBody) {} CTableCell(CTableCell& oCell) - : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), - m_oStyles(oCell.m_oStyles) + : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), + m_enMode(oCell.m_enMode), m_oStyles(oCell.m_oStyles) { m_oData.SetText(oCell.m_oData.GetData()); } @@ -212,6 +219,11 @@ class CTableCell return pCell; } + void SetMode(ERowParseMode eMode) + { + m_enMode = eMode; + } + void SetColspan(UINT unColspan, UINT unCurrentIndex) { if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex) @@ -287,6 +299,9 @@ class CTableCell oCell.WriteNodeBegin(L"w:tc"); oCell.WriteNodeBegin(L"w:tcPr"); + if (ParseModeHeader == m_enMode) + oCell += L""; + if (!m_oStyles.m_oWidth.Empty()) { if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) @@ -304,7 +319,7 @@ class CTableCell oCell += L""; } else - oCell += L""; + oCell += L""; } } else @@ -337,20 +352,20 @@ class CTableCell if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding) { const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + m_oStyles .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); const int nLeftPadding = std::max(oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), - m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + m_oStyles .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); const int nBottomPadding = std::max(oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), - m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); + m_oStyles .m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); const int nRightPadding = std::max(oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH), - m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); oCell += L"" - "" - "" - "" - "" - ""; + "" + "" + "" + "" + ""; } oCell += L""; @@ -368,6 +383,7 @@ class CTableCell UINT m_unRowSpan; bool m_bIsMerged; + ERowParseMode m_enMode; TTableCellStyle m_oStyles; NSStringUtils::CStringBuilder m_oData; @@ -446,7 +462,7 @@ class CTableRow if (0 < m_oStyles.m_unMaxHeight) oRow += L""; - + if (0 <= oTableStyles.m_nCellSpacing) oRow += L""; @@ -524,9 +540,9 @@ class CTable m_arRows.push_back(pRow); } - void SetCaption(const NSStringUtils::CStringBuilder& oCaption) + void AddCaption(NSStringUtils::CStringBuilder& oCaption) { - m_oCaption = oCaption; + m_oCaption += oCaption.GetData(); } void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) @@ -634,14 +650,17 @@ class CTable for (CTableRow* pRow : m_arRows) { pRow->RecalculateMaxIndex(); + unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); + } - if (unMaxIndex > pRow->GetIndex()) - { - for (UINT unIndex = 0; unIndex < unMaxIndex - pRow->GetIndex(); ++unIndex) - pRow->AddCell(CTableCell::CreateEmpty()); - } + UINT unMissingCount = 0; + + for (CTableRow* pRow : m_arRows) + { + unMissingCount = unMaxIndex - pRow->GetIndex(); - unMaxIndex = std::max(pRow->GetIndex(), unMaxIndex); + for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex) + pRow->AddCell(CTableCell::CreateEmpty()); } } @@ -1987,7 +2006,7 @@ class CHtmlFile2_Private } // Таблицы else if(sName == L"table") - readTable(oXml, sSelectors, oTS); + ParseTable(oXml, sSelectors, oTS); // Текст с границами else if(sName == L"textarea" || sName == L"fieldset") { @@ -2026,273 +2045,6 @@ class CHtmlFile2_Private return true; } - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const TTableStyles& oTableStyles) - { - const std::wstring wsName = m_oLightReader.GetName(); - - std::vector mTable; - int nDeath = m_oLightReader.GetDepth(); - int i = 1; // Строка - - UINT unMaxColumns = 0; - - bool bTableHasBorderAttribute = false; - - for (std::vector::const_reverse_iterator oIter = sSelectors.crbegin(); oIter < sSelectors.crend(); ++oIter) - { - if (L"table" != oIter->m_wsName) - continue; - - if (oIter->m_mAttributes.end() != oIter->m_mAttributes.find(L"border")) - { - bTableHasBorderAttribute = true; - break; - } - } - - while(m_oLightReader.ReadNextSiblingNode(nDeath) && i < MAXROWSINTABLE) - { - // tr - строки в таблице - if(m_oLightReader.GetName() != L"tr") - continue; - - GetSubClass(oXml, sSelectors); - - int nTrDeath = m_oLightReader.GetDepth(); - if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode(nTrDeath)) - continue; - - int j = 1; // Столбец - oXml->WriteString(L""); - - int nHeight = -1; - - NSStringUtils::CStringBuilder oTrBody; - - do - { - int nColspan = 1; - int nRowspan = 1; - while(m_oLightReader.MoveToNextAttribute()) - { - if(m_oLightReader.GetName() == L"colspan") - nColspan = std::min((MAXCOLUMNSINTABLE - j), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); - else if(m_oLightReader.GetName() == L"rowspan") - nRowspan = std::min((MAXROWSINTABLE - i), NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); - } - - m_oLightReader.MoveToElement(); - - // Вставляем ячейки до - std::vector::iterator it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - std::vector::iterator it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - while(it1 != mTable.end() || it2 != mTable.end()) - { - oTrBody.WriteString(L""); - oTrBody.WriteString(it1->sPr); - oTrBody.WriteString(L"sGridSpan : it2->sGridSpan); - oTrBody.WriteString(sCol); - oTrBody.WriteString(L"\"/>"); - j += stoi(sCol); - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - } - - GetSubClass(&oTrBody, sSelectors); - oTrBody.WriteString(L""); - - std::vector arNewSelectors; - - for (std::vector::const_iterator oIter = sSelectors.cbegin(); oIter < sSelectors.cend(); ++oIter) - { - if (L"table" == oIter->m_wsName) - { - arNewSelectors.insert(arNewSelectors.end(), oIter, sSelectors.cend()); - break; - } - } - - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(arNewSelectors, true); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(arNewSelectors, false); - - NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); - - if (!oStyle.m_oDisplay.GetHeight().Empty() && 1 == nColspan && 1 == nRowspan) - nHeight = std::max(nHeight, oStyle.m_oDisplay.GetHeight().ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT)); - - std::wstring wsTcPr; - - if (!oStyle.m_oDisplay.GetWidth().Empty()) - { - if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) - wsTcPr += L""; - else - wsTcPr += L""; - } - else - wsTcPr += L""; - - if(nColspan > 1) - wsTcPr += L""; - - if (!oStyle.m_oBorder.Zero()) - { - if (!oStyle.m_oBorder.Empty()) - wsTcPr += L"" + CreateBorders(oStyle.m_oBorder) + L""; - else if (bTableHasBorderAttribute) - wsTcPr += L""; - } - - if (!oStyle.m_oBackground.Empty() && !oStyle.m_oBackground.GetColor().Empty()) - { - const std::wstring wsShdFill{oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()}; - wsTcPr += L""; - } - - std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); - - if (!wsVerticalAlign.empty()) - wsTcPr += L""; - -// if (!oStyle.m_oPadding.Empty() && (NULL == oTableStyles.m_pPadding || oStyle.m_oPadding != *oTableStyles.m_pPadding)) -// { -// const int nTopPadding = std::max((NULL != oTableStyles.m_pPadding) ? -// oTableStyles.m_pPadding->GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, -// oStyle .m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); -// const int nLeftPadding = std::max((NULL != oTableStyles.m_pPadding) ? -// oTableStyles.m_pPadding->GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, -// oStyle .m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); -// const int nBottomPadding = std::max((NULL != oTableStyles.m_pPadding) ? -// oTableStyles.m_pPadding->GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT) : 0, -// oStyle .m_oPadding.GetBottom() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); -// const int nRightPadding = std::max((NULL != oTableStyles.m_pPadding) ? -// oTableStyles.m_pPadding->GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ) : 0, -// oStyle .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - -// wsTcPr += L"" -// "" -// "" -// "" -// "" -// ""; -// } - - if(nRowspan > 1 && nColspan >= 1 && j < MAXCOLUMNSINTABLE) - { - oTrBody.WriteString(L""); - std::wstring sColspan = std::to_wstring(nColspan); - if(nRowspan == 0) - mTable.push_back({0, j, sColspan, wsTcPr}); - else - for(int k = i + 1; k < i + nRowspan; k++) - mTable.push_back({k, j, sColspan, wsTcPr}); - } - - if(nColspan > 1) - j += nColspan; - else - ++j; - - oTrBody.WriteString(wsTcPr); - - oTrBody.WriteString(L""); - m_bWasPStyle = false; - - // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным - if(m_oLightReader.GetName() == L"th") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L""; - readStream(&oTrBody, sSelectors, oTSR); - } - // Читаем td. Ячейка таблицы. Выравнивание вправо - else if(m_oLightReader.GetName() == L"td") - { - if (!readStream(&oTrBody, sSelectors, oTS)) - { - wrP(&oTrBody, sSelectors, oTS); - wrR(&oTrBody, sSelectors, oTS); - CloseP(&oTrBody, sSelectors); - m_bInP = false; - } - } - sSelectors.pop_back(); - - if (m_bInP) - wrP(&oTrBody, sSelectors, oTS); - else if (oTrBody.GetSubData(oTrBody.GetCurSize() - 6) != L"") - oTrBody.WriteString(L""); - - if (j - 1 == MAXCOLUMNSINTABLE) - { - CTextSettings oTrTS{oTS}; - oTrTS.bMergeText = true; - oTrTS.bAddSpaces = true; - m_bWasSpace = true; - - while (m_oLightReader.ReadNextSiblingNode(nTrDeath) && L"td" == m_oLightReader.GetName()) - { - GetSubClass(&oTrBody, sSelectors); - - readStream(&oTrBody, sSelectors, oTrTS); - sSelectors.pop_back(); - } - } - CloseP(&oTrBody, sSelectors); - oTrBody.WriteString(L""); - - if (j - 1 == MAXCOLUMNSINTABLE) - break; - - // Вставляем ячейки после - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - while(it1 != mTable.end() || it2 != mTable.end()) - { - oTrBody.WriteString(L""); - oTrBody.WriteString(it1->sPr); - oTrBody.WriteString(L"sGridSpan : it2->sGridSpan); - oTrBody.WriteString(sCol); - oTrBody.WriteString(L"\"/>"); - j += stoi(sCol); - it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - it2 = std::find_if(mTable.begin(), mTable.end(), [j] (const CTc& item){ return item.i == 0 && item.j == j; }); - } - } while(m_oLightReader.ReadNextSiblingNode(nTrDeath) && j <= MAXCOLUMNSINTABLE); - - if (j > unMaxColumns) - unMaxColumns = j; - else - { - for (; j < unMaxColumns; ++j) - oTrBody.WriteString(L""); - } - - std::wstring wsTrPr; - - if (L"thead" == wsName) - wsTrPr += L""; - - if (nHeight > 0) - wsTrPr += L""; - - if (0 <= oTableStyles.m_nCellSpacing) - wsTrPr += L""; -// else if (!bTableHasBorderAttribute && NULL != oTableStyles.m_pCollapse && *oTableStyles.m_pCollapse == NSCSS::NSProperties::BorderCollapse::Separate) -// wsTrPr += L""; - - if (!wsTrPr.empty()) - oXml->WriteString(L"" + wsTrPr + L""); - - oXml->WriteString(oTrBody.GetData()); - oXml->WriteString(L""); - sSelectors.pop_back(); - i++; - } - } - void CalculateCellStyles(CTableCell* pCell, const std::vector& arSelectors) { if (NULL == pCell) @@ -2311,34 +2063,26 @@ class CHtmlFile2_Private pCell->SetBorder(oStyle.m_oBorder); } - struct TTableCaption - { - UINT m_unPrevRows; - NSStringUtils::CStringBuilder m_oData; - - TTableCaption(UINT unPrevRows = 0) : m_unPrevRows(unPrevRows) - {} - }; - - void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, std::vector& arCaptions) + void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) { GetSubClass(NULL, sSelectors); - TTableCaption *pData = new TTableCaption(oTable.GetRowCount()); + NSStringUtils::CStringBuilder oData; CTextSettings oTSCaption{oTS}; oTSCaption.sPStyle += L""; - wrP(&(pData->m_oData), sSelectors, oTSCaption); - readStream(&(pData->m_oData), sSelectors, oTSCaption); - CloseP(&(pData->m_oData), sSelectors); + wrP(&oData, sSelectors, oTSCaption); + readStream(&oData, sSelectors, oTSCaption); + CloseP(&oData, sSelectors); + + oTable.AddCaption(oData); - arCaptions.push_back(pData); sSelectors.pop_back(); return; } - void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) + void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, ERowParseMode eMode) { int nDeath = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nDeath)) @@ -2355,6 +2099,8 @@ class CHtmlFile2_Private { CTableCell *pCell = new CTableCell(); + pCell->SetMode(eMode); + GetSubClass(pCell->GetData(), sSelectors); CalculateCellStyles(pCell, sSelectors); @@ -2375,9 +2121,7 @@ class CHtmlFile2_Private CTextSettings oTSR(oTS); oTSR.sPStyle += L""; oTSR.sRStyle += L""; - wrP(pCell->GetData(), sSelectors, oTS); readStream(pCell->GetData(), sSelectors, oTSR); - CloseP(pCell->GetData(), sSelectors); } // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") @@ -2461,227 +2205,30 @@ class CHtmlFile2_Private oTable.SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); //------ - std::vector arCaptions; - int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) + while(m_oLightReader.ReadNextSiblingNode(nDeath)) { - std::wstring sName = m_oLightReader.GetName(); + const std::wstring sName = m_oLightReader.GetName(); GetSubClass(oXml, sSelectors); - // Заголовок таблицы + if(sName == L"caption") - ParseTableCaption(oTable, sSelectors, oTS, arCaptions); -// if(sName == L"thead") -// readTr(&oHead, sSelectors, oTS, oTableStyles); + ParseTableCaption(oTable, sSelectors, oTS); + if(sName == L"thead") + ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeHeader); if(sName == L"tbody") - ParseTableRows(oTable, sSelectors, oTS); -// else if(sName == L"tfoot") -// readTr(&oFoot, sSelectors, oTS, oTableStyles); - sSelectors.pop_back(); - } - - if (!arCaptions.empty() && !oTable.Empty()) - { - std::vector arUnnecessaryCaptions; - - for (TTableCaption* pCaption : arCaptions) - { - if (0 == pCaption->m_unPrevRows || oTable.GetRowCount() == pCaption->m_unPrevRows) - { - arUnnecessaryCaptions.push_back(&pCaption->m_oData); - continue; - } - - if (arUnnecessaryCaptions.empty() && !oTable.HaveCaption()) - { - oTable.SetCaption(pCaption->m_oData); - continue; - } - - CTableRow* pRow = oTable[pCaption->m_unPrevRows - 1]; - - if (NULL == pRow) - continue; - - CTableCell *pCell = new CTableCell; - - if (NULL == pCell) - continue; - - pCell->GetData()->SetText(pCaption->m_oData.GetData()); - pRow->AddCell(pCell); - } + ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeBody); + else if(sName == L"tfoot") + ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother); - if (!arUnnecessaryCaptions.empty()) - { - oTable.SetCaption(*arUnnecessaryCaptions.back()); - arUnnecessaryCaptions.pop_back(); - } - - if (!oTable.Empty()) - { - CTableRow* pRow = oTable[0]; - if (NULL != pRow) - { - CTableCell *pCell = (*pRow)[0]; - if (NULL != pCell) - { - NSStringUtils::CStringBuilder oData; - - for (NSStringUtils::CStringBuilder* pData : arUnnecessaryCaptions) - oData += pData->GetData(); - - arCaptions.clear(); - - oData += pCell->GetData()->GetData(); - pCell->GetData()->SetText(oData.GetData()); - } - } - } + sSelectors.pop_back(); } - for (TTableCaption* pCaption : arCaptions) - delete pCaption; - oTable.ApplyRowspan(); oTable.Shorten(); oTable.CompleteTable(); oXml->WriteString(oTable.ConvertToOOXML()); } - void readTable (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) - { - ParseTable(oXml, sSelectors, oTS); - - return; - if(m_oLightReader.IsEmptyNode()) - return; - - NSStringUtils::CStringBuilder oHead; - NSStringUtils::CStringBuilder oBody; - NSStringUtils::CStringBuilder oFoot; - - TTableStyles oTableStyles; - - if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) - { - const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); - - if (0 >= nWidth) - sSelectors.back().m_mAttributes[L"border"] = L"none"; - else - sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; - - oTableStyles.m_bHaveBorderAttribute = true; - } - - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - -// oTableStyles.m_pCollapse = &oStyle.m_oBorder.GetCollapse(); - - if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") - WriteEmptyParagraph(oXml, true); - - m_bWasSpace = false; - - // Начало таблицы - std::wstring wsTable = L""; - - if (!oStyle.m_oDisplay.GetWidth().Empty()) - { - if (NSCSS::UnitMeasure::Percent == oStyle.m_oDisplay.GetWidth().GetUnitMeasure()) - wsTable += L""; - else - wsTable += L""; - } - else - wsTable += L""; - - if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) - oTableStyles.m_nCellSpacing = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"]); - else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) - oTableStyles.m_nCellSpacing = 15; - - if (0 < oTableStyles.m_nCellSpacing) - wsTable += L""; - - if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) - oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); - - const std::wstring wsAlign = (oStyle.m_oDisplay.GetHAlign().Empty()) ? L"center" : oStyle.m_oDisplay.GetHAlign().ToWString(); - - // borders - if (!oStyle.m_oBorder.Empty() && !oStyle.m_oBorder.Zero()) - wsTable += L"" + CreateBorders(oStyle.m_oBorder) + L""; - - if (!oStyle.m_oPadding.Empty()) - { - const int nTopPadding = std::max(0, oStyle.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nLeftPadding = std::max(0, oStyle.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - const int nBottomPadding = std::max(0, oStyle.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); - const int nRightPadding = std::max(0, oStyle.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - - wsTable += L"" - "" - "" - "" - "" - ""; - -// oTableStyles.m_pPadding = &oStyle.m_oPadding; - } - else - wsTable += L""; - - wsTable += L""; - wsTable += L""; - wsTable += L""; - - oXml->WriteString(wsTable); - - int nDeath = m_oLightReader.GetDepth(); - while(m_oLightReader.ReadNextSiblingNode(nDeath)) - { - std::wstring sName = m_oLightReader.GetName(); - GetSubClass(oXml, sSelectors); - // Заголовок таблицы - if(sName == L"caption") - { - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - { - if (item.m_wsName == L"a") - oXml->WriteString(L""); - } - m_bInP = true; - m_bWasPStyle = false; - } - // Заголовок таблицы выравнивание посередине - CTextSettings oTSP(oTS); - oTSP.sPStyle += L""; - readStream(oXml, sSelectors, oTSP); - if (m_bInP) - m_bWasPStyle = false; - CloseP(oXml, sSelectors); - } - if(sName == L"thead") - readTr(&oHead, sSelectors, oTS, oTableStyles); - else if(sName == L"tbody") - readTr(&oBody, sSelectors, oTS, oTableStyles); - else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS, oTableStyles); - sSelectors.pop_back(); - } - - // Конец таблицы - oXml->WriteString(oHead.GetData()); - oXml->WriteString(oBody.GetData()); - oXml->WriteString(oFoot.GetData()); - oXml->WriteString(L""); - } - void readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { std::wstring sValue; From 79fa4f26a71eeae9ca66ad5ab7fc06960b6389a9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 12 Apr 2024 13:55:14 +0300 Subject: [PATCH 538/794] Remove GetShapes test --- .../pro/js/wasm/src/drawingfile_test.cpp | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 6c967e95280..b098bb32bca 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1791,35 +1791,6 @@ int main(int argc, char* argv[]) free(pAnnotAP); } - // SHAPES - if (true) - { - BYTE* pShapes = GetShapes(pGrFile, 0); - nLength = READ_INT(pShapes); - int i = 4; - nLength -= 4; - - std::cout << std::endl; - - while (i < nLength) - { - int nShapesLength = READ_INT(pShapes + i); - i += 4; - std::cout << "Shapes" << std::endl; - - for (int j = 0; j < nShapesLength; ++j) - { - int nPathLength = READ_INT(pShapes + i); - i += 4; - std::cout << std::string((char*)(pShapes + i), nPathLength) << std::endl; - i += nPathLength; - } - } - - if (pShapes) - free(pShapes); - } - Close(pGrFile); RELEASEARRAYOBJECTS(pCMapData); From 4f3d495b3aadd609d1dea7950b7160031448f27f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 12 Apr 2024 13:56:05 +0300 Subject: [PATCH 539/794] Rotate page --- PdfFile/PdfReader.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index c5973719808..88ca1bcbd0a 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -429,7 +429,7 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, if (!m_pPDFDocument) return; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); #else @@ -496,8 +496,8 @@ void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* oRendererOut.NewPDF(m_pPDFDocument->getXRef()); oRendererOut.SetBreak(pbBreak); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); +#ifdef BUILDING_WASM_MODULE + nRotate = -m_pPDFDocument->getPageRotate(_nPageIndex + 1); #endif m_pPDFDocument->displayPage(&oRendererOut, _nPageIndex + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); } @@ -744,11 +744,13 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, double dy = 0; double dTop = pLinkDest->getTop(); double dHeight = pdfDoc->getPageCropHeight(pg); + /* if (pdfDoc->getPageRotate(pg) % 180 != 0) { dHeight = pdfDoc->getPageCropWidth(pg); dTop = pLinkDest->getLeft(); } + */ if (dTop > 0 && dTop < dHeight) dy = dHeight - dTop; @@ -891,7 +893,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) RELEASEOBJECT(pLinks); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); #endif From 8b2b4d1bbfb9c4402fdb1255cc28a6cb56d8cb0e Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 12 Apr 2024 17:07:20 +0300 Subject: [PATCH 540/794] Add support shapes from metadata --- DocxRenderer/DocxRenderer.cpp | 49 +++++++++++++++++++++++++++++++++ DocxRenderer/DocxRenderer.h | 3 ++ DocxRenderer/src/logic/Page.cpp | 2 ++ DocxRenderer/src/logic/Page.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index a375bf48207..a3c22eceaae 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -34,6 +34,7 @@ #include "../DesktopEditor/common/Directory.h" #include "../OfficeUtils/src/OfficeUtils.h" #include "src/logic/Document.h" +#include "../DesktopEditor/graphics/commands/DocInfo.h" class CDocxRenderer_Private { @@ -124,6 +125,11 @@ std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz xml_shapes.push_back(writer->GetData()); delete writer; } + + std::vector& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; + if (!arComleteObjects.empty()) + xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end()); + m_pInternal->m_oDocument.Clear(); return xml_shapes; } @@ -147,6 +153,11 @@ std::vector CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, xml_shapes.push_back(writer->GetData()); delete writer; } + + std::vector& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; + if (!arComleteObjects.empty()) + xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end()); + m_pInternal->m_oDocument.Clear(); return xml_shapes; } @@ -180,6 +191,44 @@ HRESULT CDocxRenderer::SetTempFolder(const std::wstring& wsPath) m_pInternal->m_sTempDirectory = wsPath; return S_OK; } + +HRESULT CDocxRenderer::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type) +{ + switch (type) + { + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + return S_OK; + default: + break; + } + + return S_FALSE; +} +HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command) +{ + if (NULL == command) + return S_FALSE; + + switch (command->GetCommandType()) + { + case IAdvancedCommand::AdvancedCommandType::ShapeStart: + { + CShapeStart* pShape = (CShapeStart*)command; + const std::string& sUtf8Shape = pShape->GetShapeXML(); + m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml.push_back(UTF8_TO_U(sUtf8Shape)); + return S_OK; + } + case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + { + return S_OK; + } + default: + break; + } + return S_FALSE; +} + //---------------------------------------------------------------------------------------- // Тип рендерера //---------------------------------------------------------------------------------------- diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index 239b998aa0f..cfe625defda 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -196,6 +196,9 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer std::vector ScanPage(IOfficeDrawingFile* pFile, size_t nPage); std::vector ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage); + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type); + virtual HRESULT AdvancedCommand(IAdvancedCommand* command); + private: CDocxRenderer_Private* m_pInternal; void DrawPage(IOfficeDrawingFile* pFile, size_t nPage); diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 42b93232a21..c16628ef09e 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -58,6 +58,8 @@ namespace NSDocxRenderer m_pCurrentLine = nullptr; m_oVector.Clear(); + + m_arCompleteObjectsXml.clear(); } CPage::~CPage() diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index ffe1894e85c..594bd18bb80 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -43,6 +43,8 @@ namespace NSDocxRenderer std::vector> m_arImages; std::vector> m_arShapes; + std::vector m_arCompleteObjectsXml; + std::vector> m_arOutputObjects; CTextLine* m_pCurrentLine {nullptr}; From 2f916dcd11cb94610ce55f3badef90e91a880a96 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 12 Apr 2024 17:45:31 +0300 Subject: [PATCH 541/794] Fix build --- DocxRenderer/src/logic/Page.cpp | 16 +++------------- PdfFile/PdfReader.cpp | 8 +++----- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index c16628ef09e..5ea2118369c 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1218,19 +1218,9 @@ namespace NSDocxRenderer // совпадает ли left, right, center со строкой ниже struct Position { - Position() { - left = false; - center = false; - right = false; - } - Position(bool bLeft, bool bCenter, bool bRight) { - left = bLeft; - center = bCenter; - right = bRight; - } - bool left = false; - bool center = false; - bool right = false; + bool left{false}; + bool center{false}; + bool right{false}; }; // параграф будет набиваться строчками diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 88ca1bcbd0a..054f7ceb894 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -429,7 +429,7 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, if (!m_pPDFDocument) return; -#ifdef BUILDING_WASM_MODULE +#if 0 //#ifdef BUILDING_WASM_MODULE *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); #else @@ -496,7 +496,7 @@ void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* oRendererOut.NewPDF(m_pPDFDocument->getXRef()); oRendererOut.SetBreak(pbBreak); int nRotate = 0; -#ifdef BUILDING_WASM_MODULE +#if 0 //#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(_nPageIndex + 1); #endif m_pPDFDocument->displayPage(&oRendererOut, _nPageIndex + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); @@ -744,13 +744,11 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, double dy = 0; double dTop = pLinkDest->getTop(); double dHeight = pdfDoc->getPageCropHeight(pg); - /* if (pdfDoc->getPageRotate(pg) % 180 != 0) { dHeight = pdfDoc->getPageCropWidth(pg); dTop = pLinkDest->getLeft(); } - */ if (dTop > 0 && dTop < dHeight) dy = dHeight - dTop; @@ -893,7 +891,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) RELEASEOBJECT(pLinks); int nRotate = 0; -#ifdef BUILDING_WASM_MODULE +#if 0 //#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); #endif From ddb01d9478dd3bc5203ec7e864eb36b739aac978 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 12 Apr 2024 20:19:12 +0300 Subject: [PATCH 542/794] Sets bDateTime true by default --- X2tConverter/src/ASCConverters.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index cf995cd0fa4..051792ee9b2 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -56,7 +56,7 @@ namespace NExtractTools typedef std::function<_UINT32(const std::wstring&, const std::wstring&, InputParams&, ConvertParams&)> CONVERT_FUNC; // zip - _UINT32 dir2zip(const std::wstring& sFrom, const std::wstring& sTo, bool bSorted = false, int method = 8 /*Z_DEFLATED*/, short level = -1, bool bDateTime = false); + _UINT32 dir2zip(const std::wstring& sFrom, const std::wstring& sTo, bool bSorted = false, int method = 8 /*Z_DEFLATED*/, short level = -1, bool bDateTime = true); _UINT32 zip2dir(const std::wstring& sFrom, const std::wstring& sTo); DECLARE_CONVERT_FUNC(dir2zipMscrypt); From 2e74e8fa11829f54bd507d44b163d741aabad677 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Sun, 14 Apr 2024 17:06:40 +0300 Subject: [PATCH 543/794] fix bug #67398 --- MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp index 7ecadb8da0e..f0d2708d5e1 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp @@ -1368,7 +1368,7 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state) { CP_XML_ATTR(L"id", drawing_state->id); if (drawing_state->name.empty()) - drawing_state->name = L"Picture_" + drawing_state->objectId.substr(5); + drawing_state->name = L"Picture_" + (drawing_state->objectId.size() > 5 ? drawing_state->objectId.substr(5) : std::to_wstring(drawing_state->id)); CP_XML_ATTR(L"name", drawing_state->name); if (!drawing_state->description.empty()) From 6431ba524559f0c7f7c7a37284cf551650e1b642 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 15 Apr 2024 14:02:43 +0300 Subject: [PATCH 544/794] Fix clear content --- DesktopEditor/graphics/IRenderer.h | 3 ++- DesktopEditor/graphics/MetafileToRenderer.cpp | 2 ++ DesktopEditor/graphics/MetafileToRenderer.h | 4 +++- DesktopEditor/graphics/MetafileToRendererReader.cpp | 3 ++- DesktopEditor/graphics/commands/DocInfo.cpp | 3 +-- DesktopEditor/graphics/commands/DocInfo.h | 6 ++---- PdfFile/PdfEditor.cpp | 4 +++- PdfFile/PdfFile.cpp | 9 ++++++++- PdfFile/PdfWriter.cpp | 4 ++++ PdfFile/PdfWriter.h | 1 + PdfFile/SrcReader/RendererOutputDev.cpp | 2 +- PdfFile/SrcWriter/Document.cpp | 6 +++++- PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Pages.cpp | 6 ++++++ PdfFile/SrcWriter/Pages.h | 1 + PdfFile/test/test.cpp | 5 ++++- 16 files changed, 46 insertions(+), 14 deletions(-) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 19212ece2bc..2d333cfc161 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -149,7 +149,8 @@ class IAdvancedCommand WidgetsInfo = 6, ShapeStart = 7, ShapeEnd = 8, - PageRotate = 9, + PageClear = 9, + PageRotate = 10, Undefined = 255 }; diff --git a/DesktopEditor/graphics/MetafileToRenderer.cpp b/DesktopEditor/graphics/MetafileToRenderer.cpp index 35683b3f23e..d5258ab8e05 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -927,6 +927,7 @@ namespace NSOnlineOfficeBinToPdf case ctWidgetsInfo: case ctShapeStart: case ctShapeEnd: + case ctPageClear: case ctPageRotate: { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Undefined; @@ -938,6 +939,7 @@ namespace NSOnlineOfficeBinToPdf case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break; case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break; case ctShapeEnd: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; break; + case ctPageClear: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::PageClear; break; case ctPageRotate: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::PageRotate; break; default: break; diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index 825f5f1d439..12e91e57e24 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -191,7 +191,9 @@ namespace NSOnlineOfficeBinToPdf ctPageStart = 202, ctPageEnd = 203, - ctPageRotate = 204, + + ctPageClear = 207, + ctPageRotate = 208, // gradients diff --git a/DesktopEditor/graphics/MetafileToRendererReader.cpp b/DesktopEditor/graphics/MetafileToRendererReader.cpp index 0eeceb1e188..1b66a6b9f5d 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -59,7 +59,8 @@ namespace NSOnlineOfficeBinToPdf case ctAnnotFieldDelete: return Read_Command(this, pCorrector); case ctWidgetsInfo: return Read_Command (this, pCorrector); case ctShapeStart: return Read_Command (this, pCorrector); - case ctShapeEnd: return Read_Command (this, pCorrector); + case ctShapeEnd: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); + case ctPageClear: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::PageClear); case ctPageRotate: return Read_Command (this, pCorrector); default: break; } diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index b1d0faab7d8..6ebbaf74e83 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -138,8 +138,7 @@ bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafile return true; } -CShapeEnd::CShapeEnd() : IAdvancedCommand(AdvancedCommandType::ShapeEnd) {} -bool CShapeEnd::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { return true; } +CEmptyComand::CEmptyComand(AdvancedCommandType nType) : IAdvancedCommand(nType) {} CPageRotate::CPageRotate() : IAdvancedCommand(AdvancedCommandType::PageRotate) {} int CPageRotate::GetPageRotate() { return m_nPageRotate; } diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index 40b8470dc02..9690ffd14fb 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -146,12 +146,10 @@ class GRAPHICS_DECL CShapeStart : public IAdvancedCommand std::string m_sShapeXML; }; -class GRAPHICS_DECL CShapeEnd : public IAdvancedCommand +class GRAPHICS_DECL CEmptyComand : public IAdvancedCommand { public: - CShapeEnd(); - - bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); + CEmptyComand(AdvancedCommandType nType); }; class GRAPHICS_DECL CPageRotate : public IAdvancedCommand diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ed3b805b17a..d41f2879599 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -36,6 +36,8 @@ #include "lib/xpdf/PDFDoc.h" #include "lib/xpdf/AcroForm.h" #include "lib/xpdf/TextString.h" +#include "lib/xpdf/Lexer.h" +#include "lib/xpdf/Parser.h" #include "SrcWriter/Catalog.h" #include "SrcWriter/EncryptDictionary.h" diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 6307e0c8121..54452bbaf5c 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -54,7 +54,7 @@ class CPdfEditor int GetPagesCount() { return 0; } int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} - bool EditPage() { return false; } + bool EditPage(int nPageIndex) { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} }; @@ -1152,6 +1152,7 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma case IAdvancedCommand::AdvancedCommandType::WidgetsInfo: case IAdvancedCommand::AdvancedCommandType::ShapeStart: case IAdvancedCommand::AdvancedCommandType::ShapeEnd: + case IAdvancedCommand::AdvancedCommandType::PageClear: case IAdvancedCommand::AdvancedCommandType::PageRotate: return S_OK; default: @@ -1224,6 +1225,12 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) m_pInternal->pEditor->EndMarkedContent(); return S_OK; } + case IAdvancedCommand::AdvancedCommandType::PageClear: + { + if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + m_pInternal->pWriter->PageClear(); + return S_OK; + } case IAdvancedCommand::AdvancedCommandType::PageRotate: { CPageRotate* pCommand = (CPageRotate*)command; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 9d704922689..efc99604de2 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2637,6 +2637,10 @@ bool CPdfWriter::EditClose() return true; } +void CPdfWriter::PageClear() +{ + m_pDocument->ClearPage(); +} void CPdfWriter::PageRotate(int nRotate) { if (m_pPage) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 50a8d7e33cc..b031adfde00 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -211,6 +211,7 @@ class CPdfWriter bool EditPage(PdfWriter::CPage* pNewPage); bool AddPage(int nPageIndex); bool EditClose(); + void PageClear(); void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 748962afa54..66750662f4b 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -4174,7 +4174,7 @@ namespace PdfReader IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeEnd; if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) { - CShapeEnd* pCommand = new CShapeEnd(); + CEmptyComand* pCommand = new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); m_pRenderer->AdvancedCommand(pCommand); RELEASEOBJECT(pCommand); } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 4a7b7048559..e77325707f7 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1797,7 +1797,7 @@ namespace PdfWriter sID = (CBinaryObject*)pID->Get(1)->Copy(); pMetaOForm->Add("ID", sID); } - CArrayObject* pArrayMeta = (CArrayObject*)pMetaOForm->Get("Medata"); + CArrayObject* pArrayMeta = (CArrayObject*)pMetaOForm->Get("Metadata"); if (!pArrayMeta) { pArrayMeta = new CArrayObject(); @@ -1810,4 +1810,8 @@ namespace PdfWriter m_pCurPage->BeginMarkedContentDict("MetaOForm", pBDC); RELEASEOBJECT(pBDC); } + void CDocument::ClearPage() + { + m_pCurPage->ClearContent(m_pXref); + } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index e4f75738807..287d8676d5f 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -203,6 +203,7 @@ namespace PdfWriter bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); + void ClearPage(); private: char* GetTTFontTag(); diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 08744c5934d..fb5aafb8515 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1578,6 +1578,12 @@ namespace PdfWriter Add("Rotate", nRotate % 360); } } + void CPage::ClearContent(CXref* pXref) + { + m_pContents = new CArrayObject(); + Add("Contents", m_pContents); + AddContents(pXref); + } int CPage::GetRotate() { CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 053056055a0..b4656c5df0c 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -164,6 +164,7 @@ namespace PdfWriter void AddContents(CXref* pXref); void SetRotate(int nRotate); int GetRotate(); + void ClearContent(CXref* pXref); private: diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 6eab94b8e3b..fb83ca3d9ba 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -304,8 +304,11 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) } EXPECT_TRUE(NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)); - pdfFile->AddToPdfFromBinary(pBuffer, nBufferLen, NULL); + CConvertFromBinParams* pParams = new CConvertFromBinParams(); + pParams->m_sMediaDirectory = NSFile::GetProcessDirectory() + L"/media"; + pdfFile->AddToPdfFromBinary(pBuffer, nBufferLen, pParams); + RELEASEOBJECT(pParams); RELEASEARRAYOBJECTS(pBuffer); RELEASEARRAYOBJECTS(pFileContent); From cb53604c1397298ba416b8366d6d7efcfdd31131 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 15 Apr 2024 19:27:19 +0600 Subject: [PATCH 545/794] Add parsing ptg types method --- .../Logic/Biff_structures/PtgFuncVar.cpp | 10 ++++ .../Format/Logic/Biff_structures/PtgFuncVar.h | 4 ++ .../Logic/Biff_structures/StringPtgParser.cpp | 48 ++++++++++++++++--- .../Logic/Biff_structures/StringPtgParser.h | 1 + OOXML/XlsxFormat/Worksheets/SheetData.cpp | 11 ----- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp index f0e1c277d67..7e968497318 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp @@ -144,6 +144,16 @@ void PtgFuncVar::setParamsNum(const unsigned char num) } } +const unsigned char PtgFuncVar::getParamsNum() +{ + return cparams; +} + +const bool PtgFuncVar::getFCeFunc() +{ + return fCeFunc; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h index e1680a9ebd1..268f9046238 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h @@ -58,6 +58,10 @@ class PtgFuncVar : public OperandPtg void setParamsNum(const unsigned char num); + const unsigned char getParamsNum(); + + const bool getFCeFunc(); + static const unsigned short fixed_id = 0x02; private: unsigned char cparams; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 1f3544d4d89..2340f423c60 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -322,11 +322,14 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList, ixti))// Shall be placed strongly before PtgArea and PtgRef { + if((ptgList.rowType == 0x10 || ptgList.rowType == 0x08 || ptgList.rowType == 0x02) + && ptgList.columns == 0x01) + ptgList.type_ = 0x01; rgce.addPtg(found_operand = OperandPtgPtr(new PtgList(ptgList))); } else if (SyntaxPtg::extract_PtgName(it, itEnd, number))// Shall be placed strongly before PtgArea and PtgRef { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgNameX(ixti, number, OperandPtg::ptg_VALUE))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgNameX(ixti, number, OperandPtg::ptg_REFERENCE))); } else { @@ -335,7 +338,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if(SyntaxPtg::extract_PtgName(it, itEnd, number))// Shall be placed strongly before PtgArea and PtgRef { - rgce.addPtg(found_operand = OperandPtgPtr(new PtgName(number, OperandPtg::ptg_VALUE))); + rgce.addPtg(found_operand = OperandPtgPtr(new PtgName(number, OperandPtg::ptg_REFERENCE))); } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList))// Shall be placed strongly before PtgArea and PtgRef { @@ -379,20 +382,20 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R else if(SyntaxPtg::extract_PtgFunc(it, itEnd, operand_str)) { PtgPtr func; - if((func = PtgFunc::create(operand_str, OperandPtg::ptg_VALUE)) || - (func = PtgFuncVar::create(operand_str, OperandPtg::ptg_VALUE))) + if((func = PtgFunc::create(operand_str, OperandPtg::ptg_REFERENCE)) || + (func = PtgFuncVar::create(operand_str, OperandPtg::ptg_REFERENCE))) { ptg_stack.push(func); } else { - func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_VALUE); + func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_REFERENCE); if(!func) { // EXCEPT::LE::WhatIsTheFuck("Ftab_Cetab doesn't contain info about user-defined function (0xFF).", __FUNCTION__); } ptg_stack.push(func); - rgce.addPtg(PtgPtr(new PtgNameX(operand_str, OperandPtg::ptg_VALUE))); + rgce.addPtg(PtgPtr(new PtgNameX(operand_str, OperandPtg::ptg_REFERENCE))); } } else if(SyntaxPtg::extract_UndefinedName(it, itEnd)) // Shall be placed strongly after extract_PtgName @@ -433,9 +436,42 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R return false; } } + //parsePtgTypes(rgce); return true; } +const void StringPtgParser::parsePtgTypes(Rgce& rgce) +{ + PtgVector functionStack; + for(auto i:rgce.sequence) + { + auto ptgId = i->ptg_id; + if(!ptgId.is_initialized()) + continue; + auto untypedId = GETBITS(ptgId.get(), 0, 4); + if(untypedId == 1) + { + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParametersNum(); + for(auto j = 0; j < paramsNum; j++) + { + functionStack.pop_back(); + } + ///check and change fixed num of args + } + else if(untypedId == 2) + { + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParamsNum(); + auto testval = funcPtr->dataType; + for(auto j = 0; j < paramsNum; j++) + { + functionStack.pop_back(); + } + } + functionStack.push_back(i); + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h index f3e744803d7..09adfdbc5eb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h @@ -45,6 +45,7 @@ class StringPtgParser const bool parseToPtgs(const std::wstring& assembled_formula, Rgce& rgce, RgbExtra& rgb, const std::wstring & tag_name); private: + const void parsePtgTypes(Rgce& rgce); PtgStack ptg_stack; }; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 76225939f1f..e24490613aa 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1119,17 +1119,6 @@ namespace OOX { auto formula = dynamic_cast(obj.get()); formula->formula = m_sText; - for(auto i:formula->formula.rgce.sequence) - { - if(i->ptg_id.get() == 37) - { - i->ptg_id = 101; - } - if(i->ptg_id.get() == 36) - { - i->ptg_id = 100; - } - } if(m_oAca.IsInit()) { formula->fAlwaysCalc = m_oAca->GetValue(); From ca179304c3d8b2bd4bc0519b3fd6577aef1ba907 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Mon, 15 Apr 2024 21:46:24 +0300 Subject: [PATCH 546/794] Fix bugs in html to ooxml conversion --- Common/3dParty/html/css/src/ConstValues.cpp | 2 +- .../3dParty/html/css/src/StyleProperties.cpp | 4 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 22 ++-- .../html/css/src/xhtml/CXmlElement.cpp | 4 +- HtmlFile2/htmlfile2.cpp | 101 ++++++++++++------ 5 files changed, 86 insertions(+), 47 deletions(-) diff --git a/Common/3dParty/html/css/src/ConstValues.cpp b/Common/3dParty/html/css/src/ConstValues.cpp index 9cbb9368a71..56f1b28f790 100644 --- a/Common/3dParty/html/css/src/ConstValues.cpp +++ b/Common/3dParty/html/css/src/ConstValues.cpp @@ -70,7 +70,7 @@ namespace NSCSS {L"deepskyblue", L"00BFFF"}, {L"dodgerblue", L"1E90FF"}, {L"cornflowerblue",L"6495ED"}, {L"mediumdlateblue", L"7B68EE"}, {L"royalblue", L"4169E1"}, {L"blue", L"0000FF"}, {L"LightCoral", L"#F08080"}, {L"LightCoral", L"#F08080"}, {L"LightCoral", L"#F08080"}, {L"mediumblue", L"0000CD"}, {L"darkblue", L"00008B"}, {L"navy", L"000080"}, - {L"midnightblue", L"191970"}, + {L"midnightblue", L"191970"}, {L"navyblue", L"A0B0E0"}, /* White tones */ {L"white", L"FFFFFF"}, {L"snow", L"FFFAFA"}, {L"honeydew", L"F0FFF0"}, {L"mintcream", L"F5FFFA"}, {L"azure", L"F0FFFF"}, {L"aliceblue", L"F0F8FF"}, diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index dc4e1eb9c02..459fc3153f9 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -2300,9 +2300,7 @@ namespace NSCSS CFont &CFont::operator+=(const CFont &oFont) { - if (!oFont.m_oSize.Empty()) - m_oSize = oFont.m_oSize; - + m_oSize += oFont.m_oSize; m_oLineHeight += oFont.m_oLineHeight; m_oFamily += oFont.m_oFamily; m_oStretch += oFont.m_oStretch; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 26295711879..a2711269f5a 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -272,8 +272,15 @@ namespace NSCSS if (oStyle.Empty()) return; - - oXmlElement.AddPropertiesInP(PProperties::P_Jc, oStyle.m_oText.GetAlign().ToWString()); + + const bool bInTable{oStyle.HaveThisParent(L"table")}; + + std::wstring wsTextAlign{oStyle.m_oText.GetAlign().ToWString()}; + + if (wsTextAlign.empty() && bInTable) + wsTextAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + + oXmlElement.AddPropertiesInP(PProperties::P_Jc, wsTextAlign); std::wstring sInfValue; sInfValue.reserve(64); @@ -317,10 +324,10 @@ namespace NSCSS oXmlElement.AddPropertiesInP(PProperties::P_ContextualSpacing, L"true"); } - if (!oStyle.m_oBackground.Empty() && !oStyle.HaveThisParent(L"table")) + if (!oStyle.m_oBackground.Empty() && !bInTable) oXmlElement.AddPropertiesInP(PProperties::P_Shd, oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()); - if (!oStyle.m_oBorder.Empty() && !oStyle.HaveThisParent(L"table")) + if (!oStyle.m_oBorder.Empty() && !bInTable) { if (oStyle.m_oBorder.EqualSides()) { @@ -450,7 +457,7 @@ namespace NSCSS oXmlElement.AddPropertiesInR(RProperties::R_Highlight, wsHighlight); oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); - + std::wstring wsFontFamily{oStyle.m_oFont.GetFamily().ToWString()}; if (L"sans-serif" == wsFontFamily) @@ -466,6 +473,8 @@ namespace NSCSS bool CDocumentStyle::WriteRStyle(const NSCSS::CCompiledStyle& oStyle) { + Clear(); + if(oStyle.GetId().empty()) { m_sId = L"normal"; @@ -479,7 +488,7 @@ namespace NSCSS if (oItem != m_arStyleUsed.end()) { m_sId = (*oItem).getId(); - return false; + return true; } CXmlElement oXmlElement; @@ -488,7 +497,6 @@ namespace NSCSS if (oXmlElement.Empty()) return false; - structStyle.setId(oXmlElement.GetStyleId()); m_arStyleUsed.push_back(structStyle); m_sStyle += oXmlElement.GetRStyle(); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index e25590e4344..8341aba31fd 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -597,7 +597,7 @@ std::wstring CXmlElement::GetPStyle(bool bIsLite) const { if (bIsLite) return ConvertPStyle(true); - + return GetStyle(true, true, false); } @@ -605,7 +605,7 @@ std::wstring CXmlElement::GetRStyle(bool bIsLite) const { if (bIsLite) return ConvertRStyle(true); - + return GetStyle(true, false, true); } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index cef405e7257..3179934b39a 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -174,13 +174,14 @@ struct TTableCellStyle NSCSS::NSProperties::CIndent m_oPadding; NSCSS::NSProperties::CColor m_oBackground; - std::wstring m_wsAlign; + std::wstring m_wsHAlign; + std::wstring m_wsVAlign; TTableCellStyle(){} bool Empty() { - return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsAlign.empty(); + return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty(); } }; @@ -282,9 +283,14 @@ class CTableCell m_oStyles.m_oPadding = oPadding; } - void SetAlign(const std::wstring& wsAlign) + void SetHAlign(const std::wstring& wsAlign) { - m_oStyles.m_wsAlign = wsAlign; + m_oStyles.m_wsHAlign = wsAlign; + } + + void SetVAlign(const std::wstring& wsAlign) + { + m_oStyles.m_wsVAlign = wsAlign; } void SetBackground(const NSCSS::NSProperties::CColor& oColor) @@ -344,8 +350,8 @@ class CTableCell oCell += L""; } - if (!m_oStyles.m_wsAlign.empty()) - oCell += L""; + if (!m_oStyles.m_wsVAlign.empty()) + oCell += L""; else oCell += L""; @@ -463,7 +469,7 @@ class CTableRow if (0 < m_oStyles.m_unMaxHeight) oRow += L""; - if (0 <= oTableStyles.m_nCellSpacing) + if (0 < oTableStyles.m_nCellSpacing) oRow += L""; oRow.WriteNodeEnd(L"w:trPr"); @@ -606,7 +612,7 @@ class CTable if (1 != pCell->GetRowspan()) { - for (UINT unIndex = unRowIndex + 1; unIndex < m_arRows.size(); ++unIndex) + for (UINT unIndex = unRowIndex + 1; unIndex < std::min((UINT)m_arRows.size(), unRowIndex + pCell->GetRowspan()); ++unIndex) (*m_arRows[unIndex]).InsertCell(CTableCell::CreateEmpty(pCell->GetColspan(), true, pCell->GetStyles()), unColumnIndex); } } @@ -618,16 +624,38 @@ class CTable UINT unIndex = 0; CTableCell* pCell = NULL; + UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка + + for (const CTableRow* pRow : m_arRows) + { + if (1 < pRow->GetCount()) + unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); + } + while (unIndex < m_arMinColspan.size()) { for (CTableRow* pRow : m_arRows) { + if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex) + { + pCell = (*pRow)[unIndex]; + + if (NULL == pCell) + continue; + + pCell->SetColspan(unMaxIndex , MAXCOLUMNSINTABLE); + continue; + } + + if (1 == m_arMinColspan[unIndex]) + break; + pCell = (*pRow)[unIndex]; if (NULL == pCell) continue; - if (1 != pCell->GetColspan() && unIndex + pCell->GetColspan() > m_arMinColspan[unIndex]) + if (1 < pCell->GetColspan() && unIndex + pCell->GetColspan() > m_arMinColspan[unIndex]) { pCell->SetColspan(m_arMinColspan[unIndex] - unIndex, MAXCOLUMNSINTABLE); continue; @@ -695,7 +723,7 @@ class CTable if (!m_oStyles.m_wsAlign.empty()) oTable += L""; - if (0 <= m_oStyles.m_nCellSpacing) + if (0 < m_oStyles.m_nCellSpacing) oTable += L""; if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) @@ -724,9 +752,6 @@ class CTable if (HaveCaption()) { oTable.WriteNodeBegin(L"w:tr"); - oTable.WriteNodeBegin(L"w:trPr"); - oTable += L""; - oTable.WriteNodeEnd(L"w:trPr"); oTable.WriteNodeBegin(L"w:tc"); oTable.WriteNodeBegin(L"w:tcPr"); oTable += L""; @@ -1597,6 +1622,7 @@ class CHtmlFile2_Private if(sName == L"#text") { std::wstring sText = GetText(); + std::wstring wsTemp{sText}; size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) @@ -1656,6 +1682,9 @@ class CHtmlFile2_Private sText.erase(0, nAfter + 1); nAfter = sText.find_first_of(L"\n\r"); } + + if (sText.empty()) + return; } else ReplaceSpaces(sText); @@ -2007,7 +2036,7 @@ class CHtmlFile2_Private // Таблицы else if(sName == L"table") ParseTable(oXml, sSelectors, oTS); - // Текст с границами + // Текст с границами else if(sName == L"textarea" || sName == L"fieldset") { CTextSettings oTSP(oTS); @@ -2032,12 +2061,20 @@ class CHtmlFile2_Private sSelectors.pop_back(); } - bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, bool bInsertEmptyP = false) { int nDeath = m_oLightReader.GetDepth(); if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath)) + { + if (bInsertEmptyP) + { + wrP(oXml, sSelectors, oTS); + wrR(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + m_bInP = false; + } return false; - + } do { readInside(oXml, sSelectors, oTS, m_oLightReader.GetName()); @@ -2055,7 +2092,8 @@ class CHtmlFile2_Private NSCSS::CCompiledStyle oStyle; m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors); - pCell->SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + pCell->SetVAlign(oStyle.m_oDisplay.GetVAlign().ToWString()); + pCell->SetHAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); pCell->SetBackground(oStyle.m_oBackground.GetColor()); pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); @@ -2119,21 +2157,16 @@ class CHtmlFile2_Private if(m_oLightReader.GetName() == L"th") { CTextSettings oTSR(oTS); - oTSR.sPStyle += L""; - oTSR.sRStyle += L""; - readStream(pCell->GetData(), sSelectors, oTSR); + + if (pCell->GetStyles()->m_wsHAlign.empty()) + oTSR.sPStyle += L""; + + oTSR.sRStyle += L""; + readStream(pCell->GetData(), sSelectors, oTSR, true); } - // Читаем td. Ячейка таблицы. Выравнивание вправо + // Читаем td. Ячейка таблицы else if(m_oLightReader.GetName() == L"td") - { - if (!readStream(pCell->GetData(), sSelectors, oTS)) - { - wrP(pCell->GetData(), sSelectors, oTS); - wrR(pCell->GetData(), sSelectors, oTS); - CloseP(pCell->GetData(), sSelectors); - m_bInP = false; - } - } + readStream(pCell->GetData(), sSelectors, oTS, true); if (pRow->ColumnsOverflowing()) { @@ -2142,10 +2175,10 @@ class CHtmlFile2_Private oTrTS.bAddSpaces = true; m_bWasSpace = true; - while (m_oLightReader.ReadNextSiblingNode(nTrDepth) && L"td" == m_oLightReader.GetName()) + while (m_oLightReader.ReadNextSiblingNode(nTrDepth) && (L"td" == m_oLightReader.GetName() || L"th" == m_oLightReader.GetName())) { GetSubClass(pCell->GetData(), sSelectors); - readStream(pCell->GetData(), sSelectors, oTrTS); + readStream(pCell->GetData(), sSelectors, oTrTS, true); sSelectors.pop_back(); } } @@ -2184,7 +2217,7 @@ class CHtmlFile2_Private oTable.HaveBorderAttribute(); } - + if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") WriteEmptyParagraph(oXml, true); @@ -2198,7 +2231,7 @@ class CHtmlFile2_Private oTable.SetCellSpacing(NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"])); else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) oTable.SetCellSpacing(15); - + oTable.SetWidth(oStyle.m_oDisplay.GetWidth()); oTable.SetBorder(oStyle.m_oBorder); oTable.SetPadding(oStyle.m_oPadding); From 2901f337e7e505a9155f3ae690b0df6187a634aa Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Tue, 16 Apr 2024 15:15:37 +0400 Subject: [PATCH 547/794] Add some functionality to libvlc player --- Common/3dParty/libvlc/vlcplayer.cpp | 11 +++++++++++ Common/3dParty/libvlc/vlcplayer.h | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/Common/3dParty/libvlc/vlcplayer.cpp b/Common/3dParty/libvlc/vlcplayer.cpp index c46a3f2bb8f..d6addf4f9ed 100644 --- a/Common/3dParty/libvlc/vlcplayer.cpp +++ b/Common/3dParty/libvlc/vlcplayer.cpp @@ -97,9 +97,20 @@ void CVlcPlayer::setTime(qint64 nTime) libvlc_media_player_set_time(m_pVlcPlayer, nTime); } +qint64 CVlcPlayer::time() +{ + return libvlc_media_player_get_time(m_pVlcPlayer); +} + void CVlcPlayer::setPosition(float fPos) { libvlc_media_player_set_position(m_pVlcPlayer, fPos); + emit positionChanged(libvlc_media_player_get_position(m_pVlcPlayer)); +} + +float CVlcPlayer::position() +{ + return libvlc_media_player_get_position(m_pVlcPlayer); } bool CVlcPlayer::isAudio() diff --git a/Common/3dParty/libvlc/vlcplayer.h b/Common/3dParty/libvlc/vlcplayer.h index 1158d517876..c0563ce8588 100644 --- a/Common/3dParty/libvlc/vlcplayer.h +++ b/Common/3dParty/libvlc/vlcplayer.h @@ -24,12 +24,19 @@ class CVlcPlayer : public QWidget public: void integrateIntoWidget(QWidget* pWidget); void open(CVlcMedia* pMedia); + // control playback void pause(); void play(); void stop(); + // volume void setVolume(int nVolume); + // time (in ms) void setTime(qint64 nTime); + qint64 time(); + // position (in range 0.0...1.0) void setPosition(float fPos); + float position(); + bool isAudio(); bool isPlaying(); libvlc_state_t getState(); From 6778a4c0da22d6a9ac85ba465ec00c20c7b51ffc Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 16 Apr 2024 18:17:49 +0600 Subject: [PATCH 548/794] Add operators check in pthtypesParsing --- .../Logic/Biff_structures/StringPtgParser.cpp | 71 ++++++++++++++----- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 2340f423c60..77ad8ffd46f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -440,37 +440,72 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R return true; } +void SetPtgType(unsigned short &ptgId, const char type) +{ + if(ptgId > 31) + SETBITS(ptgId,5,6,type); +} const void StringPtgParser::parsePtgTypes(Rgce& rgce) { PtgVector functionStack; for(auto i:rgce.sequence) { - auto ptgId = i->ptg_id; - if(!ptgId.is_initialized()) + if(!i->ptg_id.is_initialized()) continue; - auto untypedId = GETBITS(ptgId.get(), 0, 4); - if(untypedId == 1) + auto ptgId = i->ptg_id.get(); + + auto untypedId = GETBITS(ptgId, 0, 4); + if(ptgId > 21) { - auto funcPtr = dynamic_cast(i.get()); - auto paramsNum = funcPtr->getParametersNum(); - for(auto j = 0; j < paramsNum; j++) + if(untypedId == 1) { - functionStack.pop_back(); + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParametersNum(); + for(auto j = 0; j < paramsNum; j++) + { + functionStack.pop_back(); + } + ///check and change fixed num of args } - ///check and change fixed num of args - } - else if(untypedId == 2) - { - auto funcPtr = dynamic_cast(i.get()); - auto paramsNum = funcPtr->getParamsNum(); - auto testval = funcPtr->dataType; - for(auto j = 0; j < paramsNum; j++) + else if(untypedId == 2) { - functionStack.pop_back(); + auto funcPtr = dynamic_cast(i.get()); + auto paramsNum = funcPtr->getParamsNum(); + for(auto j = 0; j < paramsNum; j++) + { + functionStack.pop_back(); + } } + functionStack.push_back(i); + } + else if(ptgId > 1 && ptgId < 15) + { + SetPtgType(functionStack.back()->ptg_id.get(), 2); + functionStack.pop_back(); + SetPtgType(functionStack.back()->ptg_id.get(), 2); + } + else if(ptgId > 14 && ptgId < 18) + { + SetPtgType(functionStack.back()->ptg_id.get(), 1); + functionStack.pop_back(); + SetPtgType(functionStack.back()->ptg_id.get(), 1); + } + else if(ptgId > 17 && ptgId < 21) + { + SetPtgType(functionStack.back()->ptg_id.get(), 2); + } + else if(ptgId == 21) + { + continue; } - functionStack.push_back(i); + else + { + functionStack.push_back(i); + } + } + auto exit = 1; + exit++; } From bd39d887cf55df35790b59213df5e2b822ab0bd3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 16 Apr 2024 17:35:52 +0300 Subject: [PATCH 549/794] Create DrawTextComment-N and -R --- .../graphics/pro/js/wasm/src/pdfwriter.cpp | 1 + PdfFile/PdfFile.cpp | 2 +- PdfFile/PdfWriter.cpp | 2 + PdfFile/SrcWriter/Annotation.cpp | 45 +++++++++++++- PdfFile/SrcWriter/Field.cpp | 59 ++++++++----------- PdfFile/SrcWriter/Field.h | 3 +- PdfFile/test/test.cpp | 2 +- 7 files changed, 73 insertions(+), 41 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index 87e1c4d213e..76de8ff5f4d 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -143,6 +143,7 @@ HRESULT CPdfWriter::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2 bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) { return false; } bool CPdfWriter::AddPage(int nPageIndex) { return false; } bool CPdfWriter::EditClose() { return false; } +void CPdfWriter::PageClear() {} void CPdfWriter::PageRotate(int nRotate) {} void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) {} HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) { return 0; } diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 54452bbaf5c..0c7e3f9ccbe 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -54,7 +54,7 @@ class CPdfEditor int GetPagesCount() { return 0; } int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} - bool EditPage(int nPageIndex) { return false; } + bool EditPage() { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} }; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index efc99604de2..8b04f0579a1 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1854,6 +1854,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pTextAnnot->SetStateModel(pPr->GetStateModel()); if (nFlags & (1 << 18)) pTextAnnot->SetState(pPr->GetState()); + + pTextAnnot->SetAP(); } else if (oInfo.IsInk()) { diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 05f9378f3d6..d5841ebe6fe 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -466,10 +466,29 @@ namespace PdfWriter { case 3: { - CAnnotAppearanceObject* pAP = new CAnnotAppearanceObject(m_pXref, this); + CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); Add("AP", pAP); + std::string sColor = GetColor(dynamic_cast(Get("C")), false); + CAnnotAppearanceObject* pN = pAP->GetNormal(); + pN->DrawTextCommentN(sColor); + + CArrayObject* pArray = new CArrayObject(); + pN->Add("BBox", pArray); + pArray->Add(0); + pArray->Add(0); + pArray->Add(24); + pArray->Add(24); + + CAnnotAppearanceObject* pR = pAP->GetRollover(); + pR->DrawTextCommentR(sColor); + + pArray = new CArrayObject(); + pR->Add("BBox", pArray); + pArray->Add(0); + pArray->Add(0); + pArray->Add(24); + pArray->Add(24); - pAP->DrawTextComment(); break; } case 10: @@ -789,6 +808,28 @@ namespace PdfWriter CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); CStream* pStream = pNormal->GetStream(); + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + pNormal->Add("BBox", pArray); + + pArray->Add(GetRect().fLeft); + pArray->Add(GetRect().fBottom); + pArray->Add(GetRect().fRight); + pArray->Add(GetRect().fTop); + + pArray = new CArrayObject(); + if (!pArray) + return; + + pNormal->Add("Matrix", pArray); + pArray->Add(1); + pArray->Add(0); + pArray->Add(0); + pArray->Add(1); + pArray->Add(-GetRect().fLeft); + pArray->Add(-GetRect().fBottom); + if (GetBorderType() == EBorderType::Dashed) pStream->WriteStr(GetBorderDash().c_str()); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 38703828e22..d025fa7e141 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1654,36 +1654,17 @@ namespace PdfWriter m_pAnnot = pAnnot; m_pField = NULL; - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - Add("BBox", pArray); - if (pAnnot->GetAnnotationType() == EAnnotType::AnnotWidget) { - pArray->Add(0); - pArray->Add(0); - pArray->Add(fabs(pAnnot->GetRect().fRight - pAnnot->GetRect().fLeft)); - pArray->Add(fabs(pAnnot->GetRect().fBottom - pAnnot->GetRect().fTop)); - } - else - { - pArray->Add(pAnnot->GetRect().fLeft); - pArray->Add(pAnnot->GetRect().fBottom); - pArray->Add(pAnnot->GetRect().fRight); - pArray->Add(pAnnot->GetRect().fTop); - - pArray = new CArrayObject(); + CArrayObject* pArray = new CArrayObject(); if (!pArray) return; + Add("BBox", pArray); - Add("Matrix", pArray); - pArray->Add(1); pArray->Add(0); pArray->Add(0); - pArray->Add(1); - pArray->Add(-pAnnot->GetRect().fLeft); - pArray->Add(-pAnnot->GetRect().fBottom); + pArray->Add(fabs(pAnnot->GetRect().fRight - pAnnot->GetRect().fLeft)); + pArray->Add(fabs(pAnnot->GetRect().fBottom - pAnnot->GetRect().fTop)); } } void CAnnotAppearanceObject::DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize, double dX, double dY, double dR, double dG, double dB, const char* sExtGStateName, double dWidth, double dHeight, CFontCidTrueType** ppFonts, double* pShifts) @@ -2620,18 +2601,24 @@ namespace PdfWriter m_pStream->WriteStr("ET\012"); m_pStream->WriteStr("Q\012EMC\012"); } - void CAnnotAppearanceObject::DrawTextComment() - { - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - - Add("BBox", pArray); - pArray->Add(0); - pArray->Add(0); - pArray->Add(20); - pArray->Add(20); - - m_pStream->WriteStr(""); + void CAnnotAppearanceObject::DrawTextCommentN(const std::string& sColor) + { + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + // GS0 gs + m_pStream->WriteStr("1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c "); + m_pStream->WriteStr("7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c h f Q 0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 1 0 m -2.325 -2.81 l -2.325 0 l -5.72 0 l -5.72 8.94 l 5.51 8.94 l 5.51 0 l 1 0 l -3.50 5.01 m "); + m_pStream->WriteStr("-3.50 5.59 l 3.29 5.59 l 3.29 5.01 l -3.50 5.01 l -3.50 3.34 m -3.50 3.92 l 2.27 3.92 l 2.27 3.34 l -3.50 3.34 l 7.74 12.616 m -7.74 12.616 l "); + m_pStream->WriteStr("-8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c 7.74 -4.798 l "); + m_pStream->WriteStr("8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c b"); + } + void CAnnotAppearanceObject::DrawTextCommentR(const std::string& sColor) + { + m_pStream->WriteStr("0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 4.1 1.71 m -0.54 -2.29 l -0.54 1.71 l -5.5 1.71 l -5.5 14.42 l 10.5 14.42 l 10.5 1.71 l 4.1 1.71 l "); + m_pStream->WriteStr("-2.33 9.66 m 7.34 9.66 l 7.34 8.83 l -2.33 8.83 l -2.33 9.66 l -2.33 7.28 m 5.88 7.28 l 5.88 6.46 l -2.33 6.46 l -2.33 7.28 l 14.9 23.1235 m -14.9 23.1235 l "); + m_pStream->WriteStr("-14.9 -20.345 l 14.9 -20.345 l 14.9 23.1235 l b"); } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 9d199d04f9d..03786678e9d 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -396,7 +396,8 @@ namespace PdfWriter void EndText(); void EndDraw(); - void DrawTextComment(); + void DrawTextCommentN(const std::string& sColor); + void DrawTextCommentR(const std::string& sColor); CStream* GetStream() { return m_pStream; } bool m_bStart; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index fb83ca3d9ba..19b3ce54a4b 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -305,7 +305,7 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) EXPECT_TRUE(NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)); CConvertFromBinParams* pParams = new CConvertFromBinParams(); - pParams->m_sMediaDirectory = NSFile::GetProcessDirectory() + L"/media"; + pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); pdfFile->AddToPdfFromBinary(pBuffer, nBufferLen, pParams); RELEASEOBJECT(pParams); From 6065c8b1f250ff3e183c0dbfee6771e8615a2f8f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 17 Apr 2024 12:47:42 +0300 Subject: [PATCH 550/794] Fix bug 67337 --- PdfFile/PdfEditor.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index d41f2879599..4762d4fc8ff 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -870,6 +870,21 @@ bool CPdfEditor::EditPage(int nPageIndex) char* chKey = pageObj.dictGetKey(nIndex); if (strcmp("Resources", chKey) == 0 || strcmp("Annots", chKey) == 0) pageObj.dictGetVal(nIndex, &oTemp); + else if (strcmp("Contents", chKey) == 0) + { + pageObj.dictGetVal(nIndex, &oTemp); + if (oTemp.isArray()) + { + DictToCDictObject(&oTemp, pPage, true, chKey); + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } else pageObj.dictGetValNF(nIndex, &oTemp); DictToCDictObject(&oTemp, pPage, true, chKey); From c859b5c44000e6414ce683b1ba92b60673204f20 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 17 Apr 2024 12:50:43 +0300 Subject: [PATCH 551/794] Rename IsEditPage --- PdfFile/PdfEditor.cpp | 2 +- PdfFile/PdfEditor.h | 2 +- PdfFile/PdfFile.cpp | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 4762d4fc8ff..ecd6e54ec39 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1246,7 +1246,7 @@ int CPdfEditor::GetRotate(int nPageIndex) return 0; return pPage->GetRotate(); } -bool CPdfEditor::EditPage() +bool CPdfEditor::IsEditPage() { return bEditPage; } diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 5c9c287b972..1f3c6258385 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -53,7 +53,7 @@ class CPdfEditor int GetPagesCount(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); int GetRotate(int nPageIndex); - bool EditPage(); + bool IsEditPage(); void AddShapeXML(const std::string& sXML); void EndMarkedContent(); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 0c7e3f9ccbe..c5501cdf784 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1194,14 +1194,14 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Annotaion: { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetID()); return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand); } case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: { CAnnotFieldDelete* pCommand = (CAnnotFieldDelete*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pEditor->DeleteAnnot(pCommand->GetID()); return S_OK; } @@ -1215,26 +1215,26 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::ShapeStart: { CShapeStart* pCommand = (CShapeStart*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pEditor->AddShapeXML(pCommand->GetShapeXML()); return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pEditor->EndMarkedContent(); return S_OK; } case IAdvancedCommand::AdvancedCommandType::PageClear: { - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pWriter->PageClear(); return S_OK; } case IAdvancedCommand::AdvancedCommandType::PageRotate: { CPageRotate* pCommand = (CPageRotate*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->EditPage()) + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) m_pInternal->pWriter->PageRotate(pCommand->GetPageRotate()); return S_OK; } From a782d26621c9adb028d20f9917408959ae6ed86e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 17 Apr 2024 13:04:55 +0300 Subject: [PATCH 552/794] Fix build --- PdfFile/PdfFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index c5501cdf784..62e04cd7753 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -54,7 +54,7 @@ class CPdfEditor int GetPagesCount() { return 0; } int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} - bool EditPage() { return false; } + bool IsEditPage() { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} }; From 513b39b156e3c46f3de69a812e9106e387b532cc Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Wed, 17 Apr 2024 15:18:49 +0300 Subject: [PATCH 553/794] Fix bugs in html to ooxml conversion --- .../html/css/src/CCssCalculator_Private.cpp | 1 + .../3dParty/html/css/src/StyleProperties.cpp | 16 ++++-- Common/3dParty/html/css/src/StyleProperties.h | 2 + .../html/css/src/xhtml/CDocumentStyle.cpp | 55 +++++++++---------- .../html/css/src/xhtml/CDocumentStyle.h | 3 +- HtmlFile2/htmlfile2.cpp | 50 +++++++---------- 6 files changed, 62 insertions(+), 65 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 77938ba688b..f3e508e3928 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -526,6 +526,7 @@ namespace NSCSS { oStyle.m_oFont.Clear(); oStyle.m_oPadding.Clear(); + oStyle.m_oMargin.Clear(); } oStyle.m_oBorder.Clear(); diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 459fc3153f9..880eade9a3f 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1850,6 +1850,14 @@ namespace NSCSS CDigit::Equation(oFirstMargin.m_oBottom, oSecondMargin.m_oBottom); } + bool CIndent::Equals() const + { + if (Empty()) + return true; + + return m_oLeft == m_oTop && m_oTop == m_oRight && m_oRight == m_oBottom; + } + bool CIndent::SetValues(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { if (!m_bPermission) @@ -1946,10 +1954,10 @@ namespace NSCSS CIndent &CIndent::operator+=(const CIndent &oIndent) { - m_oTop += oIndent.m_oTop; - m_oRight += oIndent.m_oRight; - m_oBottom += oIndent.m_oBottom; - m_oLeft += oIndent.m_oLeft; + m_oTop = oIndent.m_oTop; + m_oRight = oIndent.m_oRight; + m_oBottom = oIndent.m_oBottom; + m_oLeft = oIndent.m_oLeft; return *this; } diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index f3e6f91d236..4f6546861ff 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -592,6 +592,8 @@ namespace NSCSS static void Equation(CIndent &oFirstMargin, CIndent &oSecondMargin); + bool Equals() const; + void SetPermisson(bool bPermission); bool SetValues (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index a2711269f5a..3c94b1b116a 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -285,14 +285,14 @@ namespace NSCSS std::wstring sInfValue; sInfValue.reserve(64); -// if (!oStyle.m_oPadding.GetLeft().Empty() && !oStyle.m_oPadding.GetLeft().Zero()) -// sInfValue += L"w:left=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetLeft().ToDouble(NSCSS::Twips)) + L"\" "; + if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero()) + sInfValue += L"w:left=\"" + std::to_wstring(oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips)) + L"\" "; -// if (!oStyle.m_oPadding.GetRight().Empty() && !oStyle.m_oPadding.GetRight().Zero()) -// sInfValue += L"w:right=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetRight().ToDouble(NSCSS::Twips)) + L"\" "; + if (!oStyle.m_oMargin.GetRight().Empty() && !oStyle.m_oMargin.GetRight().Zero()) + sInfValue += L"w:right=\"" + std::to_wstring(oStyle.m_oMargin.GetRight().ToInt(NSCSS::Twips)) + L"\" "; const int nIndent = oStyle.m_oText.GetIndent().ToInt(NSCSS::Twips); - + if (0 != nIndent) sInfValue += L"w:firstLine=\"" + std::to_wstring(nIndent) + L"\" "; @@ -301,14 +301,11 @@ namespace NSCSS std::wstring sSpacingValue; sSpacingValue.reserve(128); -// if (!oStyle.m_oPadding.GetBottom().Empty() && !oStyle.m_oPadding.GetBottom().Zero()) -// sSpacingValue += L"w:after=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetBottom().ToDouble(NSCSS::Twips)) + L"\" "; - -// if (!oStyle.m_oPadding.GetTop().Empty() && !oStyle.m_oPadding.GetTop().Zero()) -// sSpacingValue += L"w:before=\"" + DOUBLE_TO_INTW(oStyle.m_oPadding.GetTop().ToDouble(NSCSS::Twips)) + L"\" "; + if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero()) + sSpacingValue += L"w:before=\"" + std::to_wstring(oStyle.m_oMargin.GetTop().ToInt(NSCSS::Twips)) + L"\" "; -// else/* if (!oStyle.m_pBorder.Empty() || !oStyle.m_oMargin.GetPermission())*/ -// sSpacingValue += L"w:after=\"0\" w:before=\"0\""; + if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero()) + sSpacingValue += L"w:after=\"" + std::to_wstring(oStyle.m_oMargin.GetBottom().ToInt(NSCSS::Twips)) + L"\" "; if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) { @@ -319,10 +316,7 @@ namespace NSCSS } if (!sSpacingValue.empty()) - { oXmlElement.AddPropertiesInP(PProperties::P_Spacing, sSpacingValue); - oXmlElement.AddPropertiesInP(PProperties::P_ContextualSpacing, L"true"); - } if (!oStyle.m_oBackground.Empty() && !bInTable) oXmlElement.AddPropertiesInP(PProperties::P_Shd, oStyle.m_oBackground.IsNone() ? L"auto" : oStyle.m_oBackground.GetColor().ToWString()); @@ -353,50 +347,45 @@ namespace NSCSS } } - void CDocumentStyle::SetAllBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement) - { - const std::wstring wsBorder = CalculateBorderStyle(oStyle.m_oBorder.GetLeftBorder()); - - oXmlElement.AddPropertiesInP(PProperties::P_TopBorder, wsBorder); - oXmlElement.AddPropertiesInP(PProperties::P_RightBorder, wsBorder); - oXmlElement.AddPropertiesInP(PProperties::P_BottomBorder, wsBorder); - oXmlElement.AddPropertiesInP(PProperties::P_LeftBorder, wsBorder); - } - void CDocumentStyle::SetBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement, const PProperties &enBorderProperty) { const NSCSS::NSProperties::CBorderSide* pBorder = NULL; + const NSCSS::NSProperties::CDigit* pPadding = NULL; switch(enBorderProperty) { case PProperties::P_BottomBorder: { - pBorder = &oStyle.m_oBorder.GetBottomBorder(); + pBorder = &oStyle.m_oBorder.GetBottomBorder(); + pPadding = &oStyle.m_oPadding.GetBottom(); break; } case PProperties::P_LeftBorder: { pBorder = &oStyle.m_oBorder.GetLeftBorder(); + pPadding = &oStyle.m_oPadding.GetLeft(); break; } case PProperties::P_RightBorder: { pBorder = &oStyle.m_oBorder.GetRightBorder(); + pPadding = &oStyle.m_oPadding.GetRight(); break; } case PProperties::P_TopBorder: { pBorder = &oStyle.m_oBorder.GetTopBorder(); + pPadding = &oStyle.m_oPadding.GetTop(); break; } default: return; } - oXmlElement.AddPropertiesInP(enBorderProperty, CalculateBorderStyle(*pBorder)); + oXmlElement.AddPropertiesInP(enBorderProperty, CalculateBorderStyle(*pBorder, pPadding)); } - std::wstring CDocumentStyle::CalculateBorderStyle(const NSProperties::CBorderSide &oBorder) + std::wstring CDocumentStyle::CalculateBorderStyle(const NSProperties::CBorderSide &oBorder, const NSProperties::CDigit *pPadding) { if (oBorder.Empty()) return L""; @@ -406,6 +395,9 @@ namespace NSCSS int nWidth = static_cast(std::round(oBorder.GetWidth().ToDouble(Point) * 8.)); + if (L"double" == wsStyle) + nWidth /= 3; // в ooxml double граница формируется из трёх линий + if (nWidth <= 3) nWidth = 2; else if (nWidth <= 5) @@ -431,7 +423,12 @@ namespace NSCSS if (wsStyle.empty()) wsStyle = L"single"; - return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"0\" w:color=\"" + wsColor + L"\""; + int nSpace{0}; + + if (NULL != pPadding && !pPadding->Empty() && !pPadding->Zero()) + nSpace = pPadding->ToInt(NSCSS::Point); + + return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"" + std::to_wstring(nSpace) + L"\" w:color=\"" + wsColor + L"\""; } void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 47a9acfb3ea..87b132bd9ba 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -42,7 +42,6 @@ namespace NSCSS void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); - void SetAllBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty); public: CDocumentStyle(); @@ -61,7 +60,7 @@ namespace NSCSS void Clear(); - static std::wstring CalculateBorderStyle(const NSCSS::NSProperties::CBorderSide& oBorder); + static std::wstring CalculateBorderStyle(const NSCSS::NSProperties::CBorderSide& oBorder, const NSCSS::NSProperties::CDigit* pPadding = NULL); }; } #endif // CDOCUMENTSTYLE_H diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 3179934b39a..6bb56785b92 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -88,11 +88,11 @@ struct CTextSettings {} }; -std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) +std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL) { - if (oBorder.EqualSides()) + if (oBorder.EqualSides() && (NULL == pPadding || pPadding->Equals())) { - const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder()); + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft())))); return L"" + L"" + @@ -104,16 +104,16 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder) std::wstring wsTable; if (oBorder.GetTopBorder().Valid()) - wsTable += L""; + wsTable += L"GetTop())))) + L"/>"; if (oBorder.GetLeftBorder().Valid()) - wsTable += L""; + wsTable += L"GetLeft())))) + L"/>"; if (oBorder.GetBottomBorder().Valid()) - wsTable += L""; + wsTable += L"GetBottom())))) + L"/>"; if (oBorder.GetRightBorder().Valid()) - wsTable += L""; + wsTable += L"GetRight())))) + L"/>"; return wsTable; } @@ -877,7 +877,7 @@ class CHtmlFile2_Private CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), - m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(false) + m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true) { m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); @@ -1622,7 +1622,6 @@ class CHtmlFile2_Private if(sName == L"#text") { std::wstring sText = GetText(); - std::wstring wsTemp{sText}; size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) @@ -1647,7 +1646,7 @@ class CHtmlFile2_Private if (OpenR(oXml)) { - sRStyle = wrR(oXml, sSelectors, oTS); + sRStyle = wrRPr(oXml, sSelectors, oTS); OpenT(oXml); } @@ -1753,7 +1752,7 @@ class CHtmlFile2_Private // Перенос строки else if(sName == L"br") { - if (L"" == oXml->GetSubData(oXml->GetCurSize() - 6)) + if (m_bInP) { oXml->WriteString(L""); NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); @@ -1862,7 +1861,7 @@ class CHtmlFile2_Private { wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); + std::wstring sRStyle = wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"""); CTextSettings oTSR(oTS); @@ -2069,7 +2068,7 @@ class CHtmlFile2_Private if (bInsertEmptyP) { wrP(oXml, sSelectors, oTS); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); CloseP(oXml, sSelectors); m_bInP = false; } @@ -2099,6 +2098,9 @@ class CHtmlFile2_Private pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); pCell->SetPadding(oStyle.m_oPadding); pCell->SetBorder(oStyle.m_oBorder); + + if (pCell->GetStyles()->m_wsHAlign.empty()) + pCell->SetHAlign(oStyle.m_oText.GetAlign().ToWString()); } void ParseTableCaption(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS) @@ -2286,7 +2288,7 @@ class CHtmlFile2_Private { wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L""); oXml->WriteEncodeXmlString(sValue + L' '); oXml->WriteString(L""); @@ -2319,7 +2321,7 @@ class CHtmlFile2_Private CloseP(oXml, sSelectors); wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L""); oXml->WriteEncodeXmlString(m_oLightReader.GetText()); oXml->WriteString(L""); @@ -2421,15 +2423,6 @@ class CHtmlFile2_Private if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); - if (!m_bInP) - { - oXml->WriteString(L""); - for (size_t i = 0; i < sSelectors.size() - 1; i++) - if (sSelectors[i].m_wsName == L"a") - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } wrP(oXml, sSelectors, oTS); // Перекрестная ссылка внутри файла if(bCross) @@ -2465,7 +2458,7 @@ class CHtmlFile2_Private if(!readStream(oXml, sSelectors, oTS)) { oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L""); oXml->WriteEncodeXmlString(sAlt); oXml->WriteString(L""); @@ -2582,7 +2575,7 @@ class CHtmlFile2_Private wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L""); oXml->WriteEncodeXmlString(wsAlt); oXml->WriteString(L""); @@ -2692,9 +2685,6 @@ class CHtmlFile2_Private if (!m_bInP) { oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); m_bInP = true; m_bWasPStyle = false; } @@ -2762,7 +2752,7 @@ class CHtmlFile2_Private return sPStyle; } - std::wstring wrR(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) + std::wstring wrRPr(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { if (!m_bInP) return L""; From b6c81a1f0581e97065f340632021a54787fb5cd1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 17 Apr 2024 17:52:20 +0300 Subject: [PATCH 554/794] Draw AP for 0-10 types text annot --- PdfFile/SrcReader/PdfAnnot.cpp | 4 +- PdfFile/SrcWriter/Annotation.cpp | 106 ++++++++++++++++++----- PdfFile/SrcWriter/Field.cpp | 139 ++++++++++++++++++++++++++++++- PdfFile/SrcWriter/Field.h | 12 +++ 4 files changed, 237 insertions(+), 24 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 15cafb8f9fb..4823d4254cd 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1269,12 +1269,12 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnn oObj.free(); // 16 - Иконка - Name + m_unFlags |= (1 << 16); + m_nName = 10; // Default: Note if (oAnnot.dictLookup("Name", &oObj)->isName()) { - m_unFlags |= (1 << 16); std::string sName(oObj.getName()); std::vector arrName = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; - m_nName = 10; // Default: Note std::vector::iterator p = std::find(arrName.begin(), arrName.end(), sName); if (p != arrName.end()) m_nName = p - arrName.begin(); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index d5841ebe6fe..253c7da24aa 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -462,38 +462,102 @@ namespace PdfWriter } void CTextAnnotation::SetAP() { + std::string sColor = GetColor(dynamic_cast(Get("C")), false); + + CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); + Add("AP", pAP); + CAnnotAppearanceObject* pN = pAP->GetNormal(); + CAnnotAppearanceObject* pR = pAP->GetRollover(); + switch (m_nName) { + case 0: + { + pN->AddBBox(0, 0, 19, 19); + pN->DrawTextCheck(sColor); + pR->AddBBox(0, 0, 19, 19); + pR->DrawTextCheck(sColor); + break; + } + case 1: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCheckmark(); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCheckmark(); + break; + } + case 2: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCircle(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCircle(sColor); + break; + } case 3: { - CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); - Add("AP", pAP); - std::string sColor = GetColor(dynamic_cast(Get("C")), false); - CAnnotAppearanceObject* pN = pAP->GetNormal(); + pN->AddBBox(0, 0, 24, 24); pN->DrawTextCommentN(sColor); - - CArrayObject* pArray = new CArrayObject(); - pN->Add("BBox", pArray); - pArray->Add(0); - pArray->Add(0); - pArray->Add(24); - pArray->Add(24); - - CAnnotAppearanceObject* pR = pAP->GetRollover(); + pR->AddBBox(0, 0, 24, 24); pR->DrawTextCommentR(sColor); - - pArray = new CArrayObject(); - pR->Add("BBox", pArray); - pArray->Add(0); - pArray->Add(0); - pArray->Add(24); - pArray->Add(24); - + break; + } + case 4: + { + pN->AddBBox(0, 0, 19, 19); + pN->DrawTextCross(sColor); + pR->AddBBox(0, 0, 19, 19); + pR->DrawTextCross(sColor); + break; + } + case 5: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextCrossHairs(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextCrossHairs(sColor); + break; + } + case 6: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextHelp(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextHelp(sColor); + break; + } + case 7: + { + pN->AddBBox(0, 0, 17, 20); + pN->DrawTextInsert(sColor); + pR->AddBBox(0, 0, 17, 20); + pR->DrawTextInsert(sColor); + break; + } + case 8: + { + pN->AddBBox(0, 0, 13, 18); + pN->DrawTextKey(sColor); + pR->AddBBox(0, 0, 13, 18); + pR->DrawTextKey(sColor); + break; + } + case 9: + { + pN->AddBBox(0, 0, 13, 20); + pN->DrawTextNewParagraph(sColor); + pR->AddBBox(0, 0, 13, 20); + pR->DrawTextNewParagraph(sColor); break; } case 10: default: { + pN->AddBBox(0, 0, 18, 20); + pN->DrawTextNote(sColor); + pR->AddBBox(0, 0, 18, 20); + pR->DrawTextNote(sColor); break; } } diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index d025fa7e141..45c037f750d 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -2601,10 +2601,26 @@ namespace PdfWriter m_pStream->WriteStr("ET\012"); m_pStream->WriteStr("Q\012EMC\012"); } + void CAnnotAppearanceObject::AddBBox(double dX, double dY, double dW, double dH) + { + CArrayObject* pArray = new CArrayObject(); + Add("BBox", pArray); + pArray->Add(dX); + pArray->Add(dY); + pArray->Add(dW); + pArray->Add(dH); + } void CAnnotAppearanceObject::DrawTextCommentN(const std::string& sColor) { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); - // GS0 gs + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } m_pStream->WriteStr("1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c "); m_pStream->WriteStr("7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c h f Q 0 G "); m_pStream->WriteStr(sColor.c_str()); @@ -2621,4 +2637,125 @@ namespace PdfWriter m_pStream->WriteStr("-2.33 9.66 m 7.34 9.66 l 7.34 8.83 l -2.33 8.83 l -2.33 9.66 l -2.33 7.28 m 5.88 7.28 l 5.88 6.46 l -2.33 6.46 l -2.33 7.28 l 14.9 23.1235 m -14.9 23.1235 l "); m_pStream->WriteStr("-14.9 -20.345 l 14.9 -20.345 l 14.9 23.1235 l b"); } + void CAnnotAppearanceObject::DrawTextCheck(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 7.1836 1.2061 cm 0 0 m 6.691 11.152 11.31 14.196 v 10.773 15.201 9.626 16.892 8.155 17.587 c "); + m_pStream->WriteStr("2.293 10.706 -0.255 4.205 y -4.525 9.177 l -6.883 5.608 l h b"); + } + void CAnnotAppearanceObject::DrawTextCheckmark() + { + m_pStream->WriteStr("q 0.396 0.396 0.396 rg 1 0 0 1 13.5151 16.5 cm 0 0 m -6.7 -10.23 l -8.81 -7 l -13.22 -7 l -6.29 -15 l 4.19 0 l h f Q"); + } + void CAnnotAppearanceObject::DrawTextCircle(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c 3.514 12.724 6.363 9.875 6.363 6.363 c "); + m_pStream->WriteStr("6.363 2.85 3.514 0 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c "); + m_pStream->WriteStr("3.514 12.724 6.363 9.875 6.363 6.363 c 6.363 2.85 3.514 0 0 0 c 0 16.119 m -5.388 16.119 -9.756 11.751 -9.756 6.363 c -9.756 0.973 -5.388 -3.395 0 -3.395 c "); + m_pStream->WriteStr("5.391 -3.395 9.757 0.973 9.757 6.363 c 9.757 11.751 5.391 16.119 0 16.119 c b"); + } + void CAnnotAppearanceObject::DrawTextCross(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 18.6924 3.1357 cm 0 0 m -6.363 6.364 l 0 12.728 l -2.828 15.556 l -9.192 9.192 l -15.556 15.556 l "); + m_pStream->WriteStr("-18.384 12.728 l -12.02 6.364 l -18.384 0 l -15.556 -2.828 l -9.192 3.535 l -2.828 -2.828 l h b"); + } + void CAnnotAppearanceObject::DrawTextCrossHairs(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c 4.447 16.106 8.054 12.5 8.054 8.053 c "); + m_pStream->WriteStr("8.054 3.604 4.447 0 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c "); + m_pStream->WriteStr("4.447 16.106 8.054 12.5 8.054 8.053 c 8.054 3.604 4.447 0 0 0 c 0 17.716 m -5.336 17.716 -9.663 13.39 -9.663 8.053 c -9.663 2.716 -5.336 -1.61 0 -1.61 c "); + m_pStream->WriteStr("5.337 -1.61 9.664 2.716 9.664 8.053 c 9.664 13.39 5.337 17.716 0 17.716 c b Q q 1 0 0 1 10.7861 14.8325 cm 0 0 m -1.611 0 l -1.611 -4.027 l -5.638 -4.027 l "); + m_pStream->WriteStr("-5.638 -5.638 l -1.611 -5.638 l -1.611 -9.665 l 0 -9.665 l 0 -5.638 l 4.026 -5.638 l 4.026 -4.027 l 0 -4.027 l h b Q"); + } + void CAnnotAppearanceObject::DrawTextHelp(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 12.1465 10.5137 cm -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c "); + m_pStream->WriteStr("3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 12.1465 10.5137 cm 0 0 m -0.682 -0.756 -0.958 -1.472 -0.938 -2.302 c -0.938 -2.632 l -3.385 -2.632 l "); + m_pStream->WriteStr("-3.403 -2.154 l -3.459 -1.216 -3.147 -0.259 -2.316 0.716 c -1.729 1.433 -1.251 2.022 -1.251 2.647 c -1.251 3.291 -1.674 3.715 -2.594 3.751 c "); + m_pStream->WriteStr("-3.202 3.751 -3.937 3.531 -4.417 3.2 c -5.041 5.205 l -4.361 5.591 -3.274 5.959 -1.968 5.959 c 0.46 5.959 1.563 4.616 1.563 3.089 c "); + m_pStream->WriteStr("1.563 1.691 0.699 0.771 0 0 c -2.227 -6.863 m -2.245 -6.863 l -3.202 -6.863 -3.864 -6.146 -3.864 -5.189 c -3.864 -4.196 -3.182 -3.516 -2.227 -3.516 c "); + m_pStream->WriteStr("-1.233 -3.516 -0.589 -4.196 -0.57 -5.189 c -0.57 -6.146 -1.233 -6.863 -2.227 -6.863 c -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c "); + m_pStream->WriteStr("-12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c b"); + } + void CAnnotAppearanceObject::DrawTextInsert(const std::string& sColor) + { + m_pStream->WriteStr("0 G "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 8.5386 19.8545 cm 0 0 m -8.39 -19.719 l 8.388 -19.719 l h B"); + } + void CAnnotAppearanceObject::DrawTextKey(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 6.5 12.6729 cm 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); + m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l "); + m_pStream->WriteStr("1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 6.5 12.6729 cm 0 0 m -1.076 0 -1.95 0.874 -1.95 1.95 c -1.95 3.028 -1.076 3.306 0 3.306 c "); + m_pStream->WriteStr("1.077 3.306 1.95 3.028 1.95 1.95 c 1.95 0.874 1.077 0 0 0 c 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); + m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l "); + m_pStream->WriteStr("1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c b"); + } + void CAnnotAppearanceObject::DrawTextNewParagraph(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 6.4995 20 cm 0 0 m -6.205 -12.713 l 6.205 -12.713 l h b Q q 1 0 0 1 1.1909 6.2949 cm 0 0 m 1.278 0 l "); + m_pStream->WriteStr("1.353 0 1.362 -0.02 1.391 -0.066 c 2.128 -1.363 3.78 -4.275 3.966 -4.713 c 3.985 -4.713 l 3.976 -4.453 3.957 -3.91 3.957 -3.137 c 3.957 -0.076 l "); + m_pStream->WriteStr("3.957 -0.02 3.976 0 4.041 0 c 4.956 0 l 5.021 0 5.04 -0.029 5.04 -0.084 c 5.04 -6.049 l 5.04 -6.113 5.021 -6.133 4.947 -6.133 c 3.695 -6.133 l "); + m_pStream->WriteStr("3.621 -6.133 3.611 -6.113 3.574 -6.066 c 3.052 -4.955 1.353 -2.063 0.971 -1.186 c 0.961 -1.186 l 0.999 -1.68 0.999 -2.146 1.008 -3.025 c 1.008 -6.049 l "); + m_pStream->WriteStr("1.008 -6.104 0.989 -6.133 0.933 -6.133 c 0.009 -6.133 l -0.046 -6.133 -0.075 -6.123 -0.075 -6.049 c -0.075 -0.066 l -0.075 -0.02 -0.056 0 0 0 c f Q q "); + m_pStream->WriteStr("1 0 0 1 9.1367 3.0273 cm 0 0 m 0.075 0 0.215 -0.008 0.645 -0.008 c 1.4 -0.008 2.119 0.281 2.119 1.213 c 2.119 1.969 1.633 2.381 0.737 2.381 c "); + m_pStream->WriteStr("0.354 2.381 0.075 2.371 0 2.361 c h -1.146 3.201 m -1.146 3.238 -1.129 3.268 -1.082 3.268 c -0.709 3.275 0.02 3.285 0.729 3.285 c "); + m_pStream->WriteStr("2.613 3.285 3.248 2.314 3.258 1.232 c 3.258 -0.27 2.007 -0.914 0.607 -0.914 c 0.327 -0.914 0.057 -0.914 0 -0.904 c 0 -2.789 l "); + m_pStream->WriteStr("0 -2.836 -0.019 -2.865 -0.074 -2.865 c -1.082 -2.865 l -1.119 -2.865 -1.146 -2.846 -1.146 -2.799 c h f Q"); + } + void CAnnotAppearanceObject::DrawTextNote(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr("0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 16.959 1.3672 cm 0 0 m 0 -0.434 -0.352 -0.785 -0.784 -0.785 c -14.911 -0.785 l"); + m_pStream->WriteStr("-15.345 -0.785 -15.696 -0.434 -15.696 0 c -15.696 17.266 l -15.696 17.699 -15.345 18.051 -14.911 18.051 c -0.784 18.051 l -0.352 18.051 0 17.699 0 17.266 c "); + m_pStream->WriteStr("h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q "); + m_pStream->WriteStr("1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q"); + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 03786678e9d..632153b1c3c 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -389,6 +389,7 @@ namespace PdfWriter void DrawTextLine(const double& dX, const double& dY, const unsigned short* pCodes, const unsigned int& unCount, CFontCidTrueType** ppFonts, const double* pShifts); void DrawTextLine(const double &dX, const double &dY, const std::wstring& wsText); void EndDrawText(); + void AddBBox(double dX, double dY, double dW, double dH); void StartDraw(const double& dWidth, const double& dHeight); void StartText(CFontDict* pFont, const double& dFontSize); @@ -398,6 +399,17 @@ namespace PdfWriter void DrawTextCommentN(const std::string& sColor); void DrawTextCommentR(const std::string& sColor); + void DrawTextCheck(const std::string& sColor); + void DrawTextCheckmark(); + void DrawTextCircle(const std::string& sColor); + void DrawTextCross(const std::string& sColor); + void DrawTextCrossHairs(const std::string& sColor); + void DrawTextHelp(const std::string& sColor); + void DrawTextInsert(const std::string& sColor); + void DrawTextKey(const std::string& sColor); + void DrawTextNewParagraph(const std::string& sColor); + void DrawTextNote(const std::string& sColor); + CStream* GetStream() { return m_pStream; } bool m_bStart; From 05ad1362310015f7f50cc174de8a6e2d1a757e0a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 18 Apr 2024 12:18:57 +0300 Subject: [PATCH 555/794] Draw AP for 11-16 types text annot --- PdfFile/SrcWriter/Annotation.cpp | 42 +++++++++++++++++++++++ PdfFile/SrcWriter/Field.cpp | 59 ++++++++++++++++++++++++++++++++ PdfFile/SrcWriter/Field.h | 6 ++++ 3 files changed, 107 insertions(+) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 253c7da24aa..ba06c725952 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -551,6 +551,48 @@ namespace PdfWriter pR->DrawTextNewParagraph(sColor); break; } + case 11: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextParagraph(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextParagraph(sColor); + } + case 12: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextRightArrow(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextRightArrow(sColor); + } + case 13: + { + pN->AddBBox(0, 0, 20, 17); + pN->DrawTextRightPointer(sColor); + pR->AddBBox(0, 0, 20, 17); + pR->DrawTextRightPointer(sColor); + } + case 14: + { + pN->AddBBox(0, 0, 20, 19); + pN->DrawTextStar(sColor); + pR->AddBBox(0, 0, 20, 19); + pR->DrawTextStar(sColor); + } + case 15: + { + pN->AddBBox(0, 0, 17, 20); + pN->DrawTextUpArrow(sColor); + pR->AddBBox(0, 0, 17, 20); + pR->DrawTextUpArrow(sColor); + } + case 16: + { + pN->AddBBox(0, 0, 17, 17); + pN->DrawTextUpLeftArrow(sColor); + pR->AddBBox(0, 0, 17, 17); + pR->DrawTextUpLeftArrow(sColor); + } case 10: default: { diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 45c037f750d..460a2c2d8ff 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -2758,4 +2758,63 @@ namespace PdfWriter m_pStream->WriteStr("h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q "); m_pStream->WriteStr("1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q"); } + void CAnnotAppearanceObject::DrawTextParagraph(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c "); + m_pStream->WriteStr("-4.326 9.662 0 5.335 0 0 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c "); + m_pStream->WriteStr("-19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h S Q q 1 0 0 1 11.6787 2.6582 cm 0 0 m -1.141 0 l -1.227 0 -1.244 0.052 -1.227 0.139 c "); + m_pStream->WriteStr("-0.656 1.157 -0.52 2.505 -0.52 3.317 c -0.52 3.594 l -2.833 3.783 -5.441 4.838 -5.441 8.309 c -5.441 10.778 -3.714 12.626 -0.57 13.024 c "); + m_pStream->WriteStr("-0.535 13.508 -0.381 14.129 -0.242 14.389 c -0.207 14.44 -0.174 14.475 -0.104 14.475 c 1.088 14.475 l 1.156 14.475 1.191 14.458 1.175 14.372 c "); + m_pStream->WriteStr("1.105 14.095 0.881 13.127 0.881 12.402 c 0.881 9.431 0.932 7.324 0.95 4.06 c 0.95 2.298 0.708 0.813 0.189 0.07 c 0.155 0.034 0.103 0 0 0 c b Q"); + } + void CAnnotAppearanceObject::DrawTextRightArrow(const std::string& sColor) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + + m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs "); + } + m_pStream->WriteStr("1 0 0 1 3.7856 11.1963 cm 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); + m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c h f Q "); + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 3.7856 11.1963 cm 0 0 m 8.554 0 l 6.045 2.51 l 7.236 3.702 l 12.135 -1.197 l 7.236 -6.096 l 6.088 -4.949 l"); + m_pStream->WriteStr("8.644 -2.394 l 0 -2.394 l h 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); + m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c b"); + } + void CAnnotAppearanceObject::DrawTextRightPointer(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 1.1871 17.0000 cm 0 0 m 4.703 -8.703 l 0 -17 l 18.813 -8.703 l b"); + } + void CAnnotAppearanceObject::DrawTextStar(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 18.8838 cm 0 0 m 3.051 -6.178 l 9.867 -7.168 l 4.934 -11.978 l 6.099 -18.768 l 0 -15.562 l -6.097 -18.768 l "); + m_pStream->WriteStr("-4.933 -11.978 l -9.866 -7.168 l -3.048 -6.178 l b"); + } + void CAnnotAppearanceObject::DrawTextUpArrow(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 1.1007 6.7185 cm 0 0 m 4.009 0 l 4.009 -6.719 l 11.086 -6.719 l 11.086 0 l 14.963 0 l 7.499 13.081 l b"); + } + void CAnnotAppearanceObject::DrawTextUpLeftArrow(const std::string& sColor) + { + m_pStream->WriteStr(sColor.c_str()); + m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 632153b1c3c..6280a8d038f 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -409,6 +409,12 @@ namespace PdfWriter void DrawTextKey(const std::string& sColor); void DrawTextNewParagraph(const std::string& sColor); void DrawTextNote(const std::string& sColor); + void DrawTextParagraph(const std::string& sColor); + void DrawTextRightArrow(const std::string& sColor); + void DrawTextRightPointer(const std::string& sColor); + void DrawTextStar(const std::string& sColor); + void DrawTextUpArrow(const std::string& sColor); + void DrawTextUpLeftArrow(const std::string& sColor); CStream* GetStream() { return m_pStream; } From a94a0682022d722558c72993def2d021f235b4ff Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 18 Apr 2024 17:58:50 +0600 Subject: [PATCH 556/794] Fix cell error conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index e24490613aa..66e1742fb78 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2078,6 +2078,40 @@ namespace OOX pSource = error; } } + else if (m_oValue->m_sText == L"#VALUE!") + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + } + else + { + if(m_oFormula.IsInit()) + { + auto error = new XLSB::FmlaError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + else + { + auto error = new XLSB::CellError; + error->value = 0x0F; + oCell = &error->cell; + pSource = error; + } + } } break; case SimpleTypes::Spreadsheet::celltypeBool: From 040ead411f1c6904ed479b2efff2dde1f25a4ef1 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 18 Apr 2024 15:04:50 +0300 Subject: [PATCH 557/794] Fixed a bug with encoding detection --- Common/3dParty/html/htmltoxhtml.h | 31 ++++++++--- HtmlFile2/htmlfile2.cpp | 85 ++++++++++++------------------- HtmlFile2/src/StringFinder.h | 66 ++++++++++++++++++------ 3 files changed, 107 insertions(+), 75 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index f3cfabda279..0e3e3c7621b 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -11,6 +11,7 @@ #include "../../../DesktopEditor/common/File.h" #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/common/StringBuilder.h" +#include "../../../DesktopEditor/xml/include/xmlutils.h" #include "../../../UnicodeConverter/UnicodeConverter.h" #include "../../../HtmlFile2/src/StringFinder.h" @@ -35,8 +36,22 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } -static std::wstring htmlToXhtml(std::string& sFileContent) +static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) { + if (bNeedConvert) + { // Определение кодировки + std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\""}); + + if (sEncoding.empty()) + sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}); + + if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding)) + { + NSUnicodeConverter::CUnicodeConverter oConverter; + sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str())); + } + } + // Избавляемся от лишних символов до <... boost::regex oRegex("<[a-zA-Z]"); boost::match_results oResult; @@ -213,7 +228,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun nContentTag += 2; // Content-Type - std::string sContentType = NSStringFinder::FindPropety(sFileContent, "content-type", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentType = NSStringFinder::FindPropety(sFileContent, "content-type", {":"}, {";", "\\n", "\\r"}, nFound); if (sContentType.empty()) { @@ -227,19 +242,19 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun size_t nTag = 0, nTagEnd = 0; // name - std::string sName = NSStringFinder::FindPropety(sFileContent, "name", {"="}, {";", "\\n", "\\r"}, nFound); + std::string sName = NSStringFinder::FindPropety(sFileContent, "name", {"="}, {";", "\\n", "\\r"}, nFound); // charset - std::string sCharset = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r"}, nFound); + std::string sCharset = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r"}, nFound); NSStringFinder::CutInside(sCharset, "\""); // Content-Location - std::string sContentLocation = NSStringFinder::FindPropety(sFileContent, "content-location", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentLocation = NSStringFinder::FindPropety(sFileContent, "content-location", {":"}, {";", "\\n", "\\r"}, nFound); if (sContentLocation.empty()) { // Content-ID - std::string sContentID = NSStringFinder::FindPropety(sFileContent, "content-id", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentID = NSStringFinder::FindPropety(sFileContent, "content-id", {":"}, {";", "\\n", "\\r"}, nFound); NSStringFinder::CutInside(sCharset, "<", ">"); if (!sContentID.empty()) @@ -247,7 +262,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun } // Content-Transfer-Encoding - std::string sContentEncoding = NSStringFinder::FindPropety(sFileContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, nFound);; + std::string sContentEncoding = NSStringFinder::FindPropety(sFileContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, nFound);; // nTag = sFileContent.find("Content-Transfer-Encoding: ", nFound); // if(nTag != std::string::npos && nTag < nContentTag) @@ -330,7 +345,7 @@ static std::string mhtTohtml(std::string& sFileContent) size_t nFound = 0; // Поиск boundary - std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""}, 0, nFound); + std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""}, 0, nFound); if (sBoundary.empty()) { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 6bb56785b92..9b39be7f93a 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -459,7 +459,7 @@ class CTableRow NSStringUtils::CStringBuilder oRow; oRow.WriteNodeBegin(L"w:tr"); - if (!m_oStyles.Empty() || 0 <= oTableStyles.m_nCellSpacing) + if (!m_oStyles.Empty() || 0 < oTableStyles.m_nCellSpacing) { oRow.WriteNodeBegin(L"w:trPr"); @@ -848,8 +848,6 @@ class CHtmlFile2_Private std::wstring m_sDst; // Директория назначения std::wstring m_sBase; // Полный базовый адрес - std::wstring m_sEncoding; - NSCSS::CTree m_oTree; // Дерево body html-файла private: @@ -1185,19 +1183,21 @@ class CHtmlFile2_Private return false; std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); -// bool bNeedConvert = true; -// if (nLength > 4) -// { -// if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) -// bNeedConvert = false; -// if (pData[0] == 0xFE && pData[1] == 0xFF) -// bNeedConvert = false; - -// if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) -// bNeedConvert = false; -// if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) -// bNeedConvert = false; -// } + + bool bNeedConvert = true; + if (nLength > 4) + { + if (pData[0] == 0xFF && pData[1] == 0xFE && !(pData[2] == 0x00 && pData[3] == 0x00)) + bNeedConvert = false; + if (pData[0] == 0xFE && pData[1] == 0xFF) + bNeedConvert = false; + + if (pData[0] == 0xFF && pData[1] == 0xFE && pData[2] == 0x00 && pData[3] == 0x00) + bNeedConvert = false; + if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) + bNeedConvert = false; + } + RELEASEARRAYOBJECTS(pData); size_t nFind = sFileContent.find("version=\""); @@ -1209,8 +1209,8 @@ class CHtmlFile2_Private sFileContent.replace(nFind, nFindEnd - nFind, "1.0"); } - std::wstring sRes = htmlToXhtml(sFileContent); - + std::wstring sRes = htmlToXhtml(sFileContent, bNeedConvert); + #ifdef SAVE_NORMALIZED_HTML #if 1 == SAVE_NORMALIZED_HTML NSFile::CFileBinary oWriter; @@ -1221,6 +1221,7 @@ class CHtmlFile2_Private } #endif #endif + return m_oLightReader.FromString(sRes); } @@ -1243,7 +1244,7 @@ class CHtmlFile2_Private file.CloseFile(); std::string xml_string = XmlUtils::GetUtf8FromFileContent(buffer, dwReadBytes); - const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); + const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); bool bRes = false; if(NSStringFinder::Equals(sContentType, "multipart/related")) @@ -1426,17 +1427,6 @@ class CHtmlFile2_Private return wsValue; } - std::wstring ToUnicode(const std::string& sText) const - { - if (!m_sEncoding.empty() && !NSStringFinder::Equals("utf-8", m_sEncoding)) - { - NSUnicodeConverter::CUnicodeConverter oConverter; - return oConverter.toUnicode(sText, *m_sEncoding.c_str()); - } - - return UTF8_TO_U(sText); - } - // Так как CSS калькулятор не знает для какой ноды производится расчет стиля // и не знает, что некоторые стили предназначены только определенной ноде, // то проще пока обрабатывать это заранее @@ -1518,11 +1508,6 @@ class CHtmlFile2_Private m_bInP = false; } - std::wstring GetText() - { - return ToUnicode(m_oLightReader.GetTextA()); - } - std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors) { NSCSS::CNode oNode; @@ -1582,18 +1567,9 @@ class CHtmlFile2_Private // Базовый адрес if (L"base" == wsName) m_sBase = GetArgumentValue(L"href"); - else if (L"meta" == wsName) - { - m_sEncoding = GetArgumentValue(L"charset"); - if (m_sEncoding.empty()) - { - const std::wstring sContent = GetArgumentValue(L"content"); - - if (!sContent.empty()) - m_sEncoding = NSStringFinder::FindPropety(sContent, L"charset", {L"="}, {L";", L" ", L"\\n", L"\\t", L"\\f"}); - } - } } + + m_oLightReader.MoveToElement(); } void readBody() @@ -1621,7 +1597,7 @@ class CHtmlFile2_Private { if(sName == L"#text") { - std::wstring sText = GetText(); + std::wstring sText = m_oLightReader.GetText(); size_t find = sText.find_first_not_of(L" \n\t\r"); if (find == std::wstring::npos) @@ -2212,12 +2188,13 @@ class CHtmlFile2_Private { const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); - if (0 >= nWidth) - sSelectors.back().m_mAttributes[L"border"] = L"none"; - else + if (0 < nWidth) + { sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; - - oTable.HaveBorderAttribute(); + oTable.HaveBorderAttribute(); + } + else + sSelectors.back().m_mAttributes[L"border"] = L"none"; } if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") @@ -2571,7 +2548,11 @@ class CHtmlFile2_Private void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt) { if (wsAlt.empty()) + { + //TODO:: реализовать отображение того, что картинку не удалось получить + WriteEmptyParagraph(oXml); return; + } wrP(oXml, sSelectors, oTS); oXml->WriteString(L""); diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index f41830abc8c..e66b1b00456 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -5,17 +5,16 @@ #include #include +#if defined(_WIN32) || defined (_WIN64) +#include +#elif __linux__ || MAC +#include +#endif + namespace NSStringFinder { - template - StringType FindPropety(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding) - { - size_t unEndPosition = 0; - return FindPropety(sString, sProperty, sDelimiter, sEnding, 0, unEndPosition); - } - - template - StringType FindPropety(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) + template, std::allocator>> + StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) { if (sString.length() < unStarting) return StringType(); @@ -44,8 +43,30 @@ namespace NSStringFinder return sValue; } - template - StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition) + { + return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition) + { + return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); + } + + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); + } + + template, std::allocator>> + StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) { if (sString.length() < unStarting) return StringType(); @@ -89,11 +110,26 @@ namespace NSStringFinder return sValue; } - template - StringType FindPropety(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) { - size_t unTempEnding = 0; - return FindPropety(sString, sProperty, arDelimiters, arEndings, unStarting, unTempEnding); + return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) + { + return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting, unEndPosition); + } + + std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting, unEndPosition); + } + + std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + { + size_t unEndPosition = 0; + return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting, unEndPosition); } template From c3767cf68eb5c45b51c1db93f56b06455ae66399 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 18 Apr 2024 18:01:23 +0300 Subject: [PATCH 558/794] Fix bug 67439 --- PdfFile/SrcReader/RendererOutputDev.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 66750662f4b..130ac7659b5 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3060,6 +3060,12 @@ namespace PdfReader if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) return; + if (nX1 - nX0 == 1 && nY1 - nY0 == 1) // Одно изображение, tilingPattern не требуется + { + gfx->drawForm(pStream, pResourcesDict, matrix, pBBox); + return; + } + if (abs(pBBox[2] - pBBox[0] - dXStep) > 0.001 || abs(pBBox[3] - pBBox[1] - dYStep) > 0.001) return; @@ -3111,12 +3117,14 @@ namespace PdfReader oImage->Create(pBgraData, nWidth, nHeight, 4 * nWidth); double xMin, yMin, xMax, yMax; - pGState->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); - - pGState->moveTo(xMin + pBBox[0], yMin + pBBox[1]); - pGState->lineTo(xMax + pBBox[2], yMin + pBBox[1]); - pGState->lineTo(xMax + pBBox[2], yMax + pBBox[3]); - pGState->lineTo(xMin + pBBox[0], yMax + pBBox[3]); + Transform(matrix, pBBox[0], pBBox[1], &xMin, &yMin); + Transform(matrix, pBBox[2], pBBox[3], &xMax, &yMax); + xMax *= (nX1 - nX0); + yMax *= (nY1 - nY0); + pGState->moveTo(xMin, yMin); + pGState->lineTo(xMax, yMin); + pGState->lineTo(xMax, yMax); + pGState->lineTo(xMin, yMax); pGState->closePath(); DoPath(pGState, pGState->getPath(), pGState->getPageHeight(), pGState->getCTM()); From 0a088eb949a1f0f6dba38cc7b0c10e026873022f Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Thu, 18 Apr 2024 21:32:51 +0300 Subject: [PATCH 559/794] fix bug 67231 --- .../StarMath2OOXML/StarMath2OOXML.pri | 3 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 328 +++++++++++------- .../StarMath2OOXML/cconversionsmtoooxml.h | 20 +- .../StarMath2OOXML/cstarmathpars.cpp | 188 +++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 40 ++- .../Converter/StarMath2OOXML/typeConversion.h | 13 + .../Converter/oox_conversion_context.cpp | 15 - OdfFile/Reader/Format/chart_build_oox.cpp | 4 +- OdfFile/Reader/Format/draw_frame_docx.cpp | 5 +- OdfFile/Reader/Format/math_elements.cpp | 10 +- OdfFile/Reader/Format/math_elements.h | 4 +- 11 files changed, 352 insertions(+), 278 deletions(-) create mode 100644 OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri index fe88c40eb88..625d8c8076c 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri @@ -3,7 +3,7 @@ CORE_ROOT_DIR = $$PWD/../../../.. PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) - +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) ADD_DEPENDENCY(UnicodeConverter, kernel) SOURCES += $$PWD/cconversionsmtoooxml.cpp \ @@ -12,5 +12,6 @@ SOURCES += $$PWD/cconversionsmtoooxml.cpp \ HEADERS += \ $$PWD/cconversionsmtoooxml.h \ $$PWD/cstarmathpars.h \ + $$PWD/typeConversion.h \ $$PWD/typeselements.h diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 1ce1665b91d..bedfc7c8c40 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -40,32 +40,38 @@ namespace StarMath { void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; -// m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); -// if(iAlignment>= 0 && iAlignment <= 2) -// { -// std::wstring wsAlignment; -// switch(iAlignment) -// { -// case 0: -// wsAlignment = L"center"; -// break; -// case 1: -// wsAlignment = L"left"; -// break; -// case 2: -// wsAlignment = L"right"; -// break; -// default: -// wsAlignment = L"center"; -// break; -// } -// m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); -// m_pXmlWrite->WriteNodeBegin(L"m:jc",true); -// m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); -// m_pXmlWrite->WriteNodeEnd(L"",true,true); -// m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); -// } -// m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; + switch(iAlignment) + { + case 0: + wsAlignment = L"center"; + break; + case 1: + wsAlignment = L"left"; + break; + case 2: + wsAlignment = L"right"; + break; + default: + wsAlignment = L"center"; + break; + } + if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) + { + wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsAlignment += L"Group"; + } + m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); + if(iAlignment>= 0 && iAlignment <= 2) + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); + m_pXmlWrite->WriteNodeBegin(L"m:jc",true); + m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); + } + m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); for(CElement* oTempElement:arPars) { if(oTempElement != nullptr) @@ -73,106 +79,158 @@ namespace StarMath { if(CParserStarMathString::CheckNewline(oTempElement)) { m_pXmlWrite->WriteNodeBegin(L"m:r",false); - m_pXmlWrite->WriteNodeBegin(L"a:br",true); + m_pXmlWrite->WriteNodeBegin(L"w:br",true); m_pXmlWrite->WriteNodeEnd(L"",true,true); m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); } else oTempElement->ConversionToOOXML(m_pXmlWrite); } } -// EndConversion(); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } - void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { - if(pAttribute == nullptr) - { - //тут должны быть базовые свойства шрифта, задаваемые выше - - pXmlWrite->WriteNodeBegin(L"a:rPr",false); - pXmlWrite->WriteNodeBegin(L"a:rFonts",true); - pXmlWrite->WriteAttribute(L"a:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"a:ascii",L"Cambria Math"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:sz",true); - pXmlWrite->WriteAttribute(L"a:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:szCs",true); - pXmlWrite->WriteAttribute(L"a:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"a:rPr",false,false); - } - else - { - std::wstring wsNameFont = pAttribute->GetFontName(); - pXmlWrite->WriteNodeBegin(L"a:rPr",false); - pXmlWrite->WriteNodeBegin(L"a:rFonts",true); - if(!wsNameFont.empty()) - { - pXmlWrite->WriteAttribute(L"a:hAnsi",wsNameFont); - pXmlWrite->WriteAttribute(L"a:ascii",wsNameFont); - } - else - { - pXmlWrite->WriteAttribute(L"a:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"a:ascii",L"Cambria Math"); - } - pXmlWrite->WriteNodeEnd(L"w",true,true); - if(pAttribute->GetSize() == 0) - { - //тут должны быть базовые свойства шрифта, задаваемые выше - далее везде где не задано - аналогично - pXmlWrite->WriteNodeBegin(L"a:sz",true); - pXmlWrite->WriteAttribute(L"a:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:szCs",true); - pXmlWrite->WriteAttribute(L"a:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - else if(pAttribute->GetSize() != 0) - { - pXmlWrite->WriteNodeBegin(L"a:sz",true); - pXmlWrite->WriteAttribute(L"a:val",std::to_wstring(pAttribute->GetSize())); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:szCs",true); - pXmlWrite->WriteAttribute(L"a:val",std::to_wstring(pAttribute->GetSize())); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(!pAttribute->EmptyColor()) - { - pXmlWrite->WriteNodeBegin(L"a:color",true); - pXmlWrite->WriteAttribute(L"a:val",pAttribute->GetColor()); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(pAttribute->GetBold() && pAttribute->GetItal()) - { - WriteStyNode(pXmlWrite,L"bi"); - } - else if(pAttribute->GetBold()) - { - pXmlWrite->WriteNodeBegin(L"m:sty", true); - pXmlWrite->WriteAttribute(L"m:val",L"b"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:b",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"a:bCs",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - else if(pAttribute->GetItal()) - { - pXmlWrite->WriteNodeBegin(L"a:i",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(pAttribute->GetStrike()) - { - pXmlWrite->WriteNodeBegin(L"a:strike",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - pXmlWrite->WriteNodeEnd(L"a:rPr",false,false); - } + if(TypeConversion::docx == enTypeConversion || TypeConversion::undefine == enTypeConversion) + { + if(pAttribute == nullptr) + { + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + else + { + std::wstring wsNameFont = pAttribute->GetFontName(); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + if(!wsNameFont.empty()) + { + pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); + pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); + } + else + { + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + } + pXmlWrite->WriteNodeEnd(L"w",true,true); + if(pAttribute->GetSize() == 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetSize() != 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!pAttribute->EmptyColor()) + { + pXmlWrite->WriteNodeBegin(L"w:color",true); + pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetBold() && pAttribute->GetItal()) + { + WriteStyNode(pXmlWrite,L"bi"); + } + else if(pAttribute->GetBold()) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",L"b"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:b",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:bCs",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetItal()) + { + pXmlWrite->WriteNodeBegin(L"w:i",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetStrike()) + { + pXmlWrite->WriteNodeBegin(L"w:strike",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + } + else if(TypeConversion::pptx == enTypeConversion) + { + if(pAttribute !=nullptr) + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + if(pAttribute->GetSize()!=0) + { + int iSize = pAttribute->GetSize(); + iSize = iSize*50; + pXmlWrite->WriteAttribute(L"sz",iSize); + } + else + pXmlWrite->WriteAttribute(L"sz",L"1500"); + if(pAttribute->GetBold()) + pXmlWrite->WriteAttribute(L"b",L"1"); + if(pAttribute->GetItal()) + pXmlWrite->WriteAttribute(L"i",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + if(!pAttribute->GetColor().empty()) + { + pXmlWrite->WriteNodeBegin(L"a:solidFill",false); + pXmlWrite->WriteNodeBegin(L"a:srgbClr",true); + pXmlWrite->WriteAttribute(L"val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:solidFill",false,false); + } + pXmlWrite->WriteNodeBegin(L"a:latin",true); + if(!pAttribute->GetFontName().empty()) + pXmlWrite->WriteAttribute(L"typeface",pAttribute->GetFontName()); + else + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); + // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); + // pXmlWrite->WriteAttribute(L"charset",L"0"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + else + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + pXmlWrite->WriteAttribute(L"sz",L"1500"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteNodeBegin(L"a:latin",true); + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); + // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); + // pXmlWrite->WriteAttribute(L"charset",L"0"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + } } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) @@ -181,10 +239,10 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"lin"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - WriteCtrlPrNode(pXmlWrite,pAttribute); + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } - void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:naryPr",false); switch(enTypeOp) @@ -231,7 +289,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"1"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - WriteCtrlPrNode(pXmlWrite,pAttribute); + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } void CConversionSMtoOOXML::WriteNodeConversion(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) @@ -257,16 +315,16 @@ namespace StarMath { m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } - void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:funcPr", false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr", false); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } - void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:dPr",false); switch(enTypeBracket) @@ -297,7 +355,7 @@ namespace StarMath { break; } pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); } @@ -310,7 +368,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute) + void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:mPr",false); pXmlWrite->WriteNodeBegin(L"m:mcs",false); @@ -334,11 +392,11 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:mc",false,false); pXmlWrite->WriteNodeEnd(L"m:mcs",false,false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:mPr",false,false); } - void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) + void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:d",false); pXmlWrite->WriteNodeBegin(L"m:dPr",false); @@ -349,7 +407,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"\u23AA"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,pValueGrade->GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); @@ -357,10 +415,10 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:d",false,false); } - void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute) + void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); } void CConversionSMtoOOXML::WriteChrNode(const std::wstring &wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite) @@ -375,7 +433,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp) + void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -383,7 +441,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"p"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(enTypeOp) { @@ -411,10 +469,10 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsAttributeNode); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute) + void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:r",false); - StandartProperties(pXmlWrite,pAttribute); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeBegin(L"m:t",true); pXmlWrite->WriteAttribute(L"xml:space",L"preserve"); pXmlWrite->WriteNodeEnd(L"w",true,false); @@ -425,10 +483,10 @@ namespace StarMath { { pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,pValue->GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName); + CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,pValue->GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(pValue!= nullptr && pIndex != nullptr) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 05d61d0b83d..64f3ce080ed 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -42,20 +42,20 @@ namespace StarMath { public: CConversionSMtoOOXML(); void StartConversion(std::vector arPars, const unsigned int& iAlignment = -1); - static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); - static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); + static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute); - static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute); - static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); - static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); + static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); - static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp); + static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); - static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute); + static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion); static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); void EndConversion(); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index ec5dfd6b98f..17ba21b2544 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -35,10 +35,11 @@ namespace StarMath { //class methods CParsStarMath - std::vector CParserStarMathString::Parse(std::wstring& wsParseString,const TBaseAttribute* pBaseAttribute) + std::vector CParserStarMathString::Parse(std::wstring& wsParseString,int iTypeConversion,const TBaseAttribute* pBaseAttribute) { + TypeConversion enTypeConvers = (TypeConversion)iTypeConversion; std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); - CStarMathReader* pReader = new CStarMathReader(itStart,itEnd); + CStarMathReader* pReader = new CStarMathReader(itStart,itEnd,enTypeConvers); pReader->SetBaseAttribute(pBaseAttribute); if(pBaseAttribute != nullptr && (pBaseAttribute->base_alignment >= 0 && pBaseAttribute->base_alignment <= 2)) SetAlignment(pBaseAttribute->base_alignment); @@ -53,7 +54,7 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::newline) { - m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); pReader->ClearReader(); } CElement* pTempElement = ParseElement(pReader); @@ -208,7 +209,7 @@ namespace StarMath pReader->ReadingTheNextToken(); if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { - CElement* pIndex = new CElementIndex(pReader->GetLocalType()); + CElement* pIndex = new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); pReader->ClearReader(); pIndex->Parse(pReader); AddLeftArgument(pElement,pIndex); @@ -630,60 +631,60 @@ namespace StarMath } CElement::CElement(): m_pAttribute(nullptr) {} - CElement::CElement(const TypeElement &enTypeBase): m_pAttribute(nullptr),m_enBaseType(enTypeBase) + CElement::CElement(const TypeElement &enTypeBase,const TypeConversion &enTypeConversion): m_pAttribute(nullptr),m_enBaseType(enTypeBase),m_enTypeConversion(enTypeConversion) { } CElement* CElement::CreateElement(CStarMathReader* pReader) { switch (pReader->GetGlobalType()) { case TypeElement::String: - return new CElementString(pReader->GetString()); + return new CElementString(pReader->GetString(),pReader->GetTypeConversion()); case TypeElement::BinOperator: - return new CElementBinOperator(pReader->GetLocalType()); + return new CElementBinOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::SetOperations: - return new CElementSetOperations(pReader->GetLocalType()); + return new CElementSetOperations(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Connection: - return new CElementConnection(pReader->GetLocalType()); + return new CElementConnection(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Function: { if(pReader->GetLocalType() == TypeElement::func) { if (pReader->GetToken()) - return new CElementFunction(pReader->GetLocalType(),pReader->GetString()); + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); else return nullptr; } else - return new CElementFunction(pReader->GetLocalType()); + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion()); } case TypeElement::Bracket: - return new CElementBracket(pReader->GetLocalType()); + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Operation: { if(pReader->GetLocalType() == TypeElement::oper) { if (pReader->GetToken()) { - return new CElementOperator(pReader->GetLocalType(),pReader->GetString()); + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); } else return nullptr; } else - return new CElementOperator(pReader->GetLocalType()); + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); } case TypeElement::BracketWithIndex: - return new CElementBracketWithIndex(pReader->GetLocalType()); + return new CElementBracketWithIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Grade: - return new CElementGrade(); + return new CElementGrade(pReader->GetTypeConversion()); case TypeElement::Matrix: - return new CElementMatrix(pReader->GetLocalType()); + return new CElementMatrix(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::SpecialSymbol: - return new CElementSpecialSymbol(pReader->GetLocalType()); + return new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Index: - return new CElementIndex(pReader->GetLocalType()); + return new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Mark: - return new CElementDiacriticalMark(pReader->GetLocalType()); + return new CElementDiacriticalMark(pReader->GetLocalType(),pReader->GetTypeConversion()); default: return nullptr; } @@ -720,9 +721,13 @@ namespace StarMath { return m_pAttribute; } + const TypeConversion& CElement::GetTypeConversion() + { + return m_enTypeConversion; + } //class methods CElementString - CElementString::CElementString(const std::wstring& wsTokenString) - :CElement(TypeElement::String),m_wsString(wsTokenString) + CElementString::CElementString(const std::wstring& wsTokenString,const TypeConversion &enTypeConversion) + :CElement(TypeElement::String,enTypeConversion),m_wsString(wsTokenString) { } CElementString::~CElementString() @@ -738,7 +743,7 @@ namespace StarMath void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(m_wsString); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -773,8 +778,8 @@ namespace StarMath SetBaseAttribute(pAttribute); } //class methods CElementBinOperator - CElementBinOperator::CElementBinOperator(const TypeElement& enType) - :CElement(TypeElement::BinOperator),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) + CElementBinOperator::CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BinOperator,enTypeConversion),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) { } CElementBinOperator::~CElementBinOperator() @@ -821,9 +826,9 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:f",false); if(m_enTypeBinOp == TypeElement::division) - CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute(),GetTypeConversion()); else - CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute(),GetTypeConversion()); CConversionSMtoOOXML::WriteNodeConversion(L"m:num",m_pLeftArgument,pXmlWrite); CConversionSMtoOOXML::WriteNodeConversion(L"m:den",m_pRightArgument,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -832,7 +837,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeBinOp) { @@ -991,8 +996,8 @@ namespace StarMath return m_enTypeBinOp; } //class methods CElementBracket - CElementBracket::CElementBracket(const TypeElement& enType) - :CElement(TypeElement::Bracket),m_enTypeBracket(enType) + CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType) { } CElementBracket::~CElementBracket() @@ -1050,7 +1055,7 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::newline) { - m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType())); + m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); pReader->ClearReader(); } CElement* pTempElement =CParserStarMathString::ParseElement(pReader); @@ -1064,7 +1069,7 @@ namespace StarMath if(m_enTypeBracket != TypeElement::brace) { pXmlWrite->WriteNodeBegin(L"m:d",false); - CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute()); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* pTemp:m_arBrecketValue) { @@ -1073,7 +1078,7 @@ namespace StarMath if(CheckMline(pTemp)) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(L"\u007C"); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1118,8 +1123,8 @@ namespace StarMath } } //class methods CElementSpecialSymbol - CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType) - :CElement(TypeElement::SpecialSymbol),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SpecialSymbol,enTypeConversion),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") { } CElementSpecialSymbol::~CElementSpecialSymbol() @@ -1271,7 +1276,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(L"\u0021"); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1280,25 +1285,19 @@ namespace StarMath } case TypeElement::interval: { - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); break; } case TypeElement::emptiness: { - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); break; } case TypeElement::newline: { -// pXmlWrite->WriteNodeBegin(L"m:r",false); -// pXmlWrite->WriteNodeBegin(L"w:br",true); -// pXmlWrite->WriteNodeEnd(L"",true,true); -// pXmlWrite->WriteNodeEnd(L"m:r",false,false); -// pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); -// pXmlWrite->WriteNodeBegin(L"m:oMath",false); break; } default: @@ -1306,7 +1305,7 @@ namespace StarMath if(!m_wsType.empty()) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(m_wsType); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1590,8 +1589,8 @@ namespace StarMath } } //class methods CElementSetOperations - CElementSetOperations::CElementSetOperations(const TypeElement &enType) - :CElement(TypeElement::SetOperations),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) + CElementSetOperations::CElementSetOperations(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SetOperations,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) { } CElementSetOperations::~CElementSetOperations() @@ -1629,7 +1628,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r", false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeSet) { @@ -1717,8 +1716,8 @@ namespace StarMath return m_enTypeSet; } //class methods CElementConnection - CElementConnection::CElementConnection(const TypeElement& enType) - :CElement(TypeElement::Connection),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) + CElementConnection::CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Connection,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) { } CElementConnection::~CElementConnection() @@ -1757,7 +1756,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeCon) { @@ -1915,8 +1914,8 @@ namespace StarMath return m_enTypeCon; } //class methods CIndex - CElementIndex::CElementIndex(const TypeElement& enType) - : CElement(TypeElement::Index),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) + CElementIndex::CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion) + : CElement(TypeElement::Index,enTypeConversion),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) { } CElementIndex::~CElementIndex() @@ -2059,7 +2058,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",1); pXmlWrite->WriteNodeEnd(L"",true,true); } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) { @@ -2081,12 +2080,12 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:limLow",false); pXmlWrite->WriteNodeBegin(L"m:limLowPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limLowPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); pXmlWrite->WriteNodeBegin(L"m:limUpp",false); pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); ConversionOfIndicesToValue(pXmlWrite); @@ -2106,7 +2105,7 @@ namespace StarMath wsNameLim = L"m:limUpp"; pXmlWrite->WriteNodeBegin(wsNameLim,false); pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); ConversionOfIndicesToValue(pXmlWrite); @@ -2151,7 +2150,7 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:sPre",false); pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLsubIndex,pXmlWrite); CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pLsupIndex,pXmlWrite); @@ -2176,7 +2175,7 @@ namespace StarMath wsNameNodeIndex = L"m:sSup"; pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); if(m_pUpperIndex!=nullptr && m_pLowerIndex != nullptr) @@ -2198,8 +2197,8 @@ namespace StarMath return m_enTypeIndex; } //class methods CElementFunction - CElementFunction::CElementFunction(const TypeElement &enType, const std::wstring &wsNameFunc) - :CElement(TypeElement::Function), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) + CElementFunction::CElementFunction(const TypeElement &enType, const TypeConversion &enTypeConversion ,const std::wstring &wsNameFunc) + :CElement(TypeElement::Function,enTypeConversion), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) { switch (m_enTypeFunction) { case TypeElement::cos: @@ -2295,7 +2294,7 @@ namespace StarMath if(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) { m_pIndex = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc),m_pIndex); + CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc,pReader->GetTypeConversion()),m_pIndex); return ; } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -2313,7 +2312,7 @@ namespace StarMath else { pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:fName",false); pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -2321,7 +2320,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",L"p"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); if(!m_wsNameFunc.empty()) pXmlWrite->WriteString(m_wsNameFunc); @@ -2371,8 +2370,8 @@ namespace StarMath m_pValue->SetAttribute(pAttribute); } //class methods CElementOperation - CElementOperator::CElementOperator(const TypeElement &enType, const std::wstring& wsNameOp) - :CElement(TypeElement::Operator), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) + CElementOperator::CElementOperator(const TypeElement &enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameOp) + :CElement(TypeElement::Operator,enTypeConversion), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) { } CElementOperator::~CElementOperator() @@ -2477,7 +2476,7 @@ namespace StarMath if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator || TypeElement::oper == m_enTypeOperator) { pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:fName",false); if((m_pValueFrom != nullptr || m_pLowerIndex != nullptr) && (m_pValueTo == nullptr && m_pUpperIndex == nullptr)) CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); @@ -2487,7 +2486,7 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:limUpp",false); pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); @@ -2501,7 +2500,7 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); } else if(m_pValueFrom == nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:fName",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:func",false,false); @@ -2509,7 +2508,7 @@ namespace StarMath else { pXmlWrite->WriteNodeBegin(L"m:nary",false); - CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute(),GetTypeConversion()); if(m_pValueFrom != nullptr && m_pLowerIndex != nullptr) { pXmlWrite->WriteNodeBegin(L"m:sub",false); @@ -2551,8 +2550,8 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } // class methods CStarMathReader - CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd) - : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true) + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true),m_enTypeCon(enTypeConversion) { m_itStart = itStart; m_itEnd = itEnd; @@ -2920,9 +2919,17 @@ namespace StarMath { return m_bMarkForUnar; } + void CStarMathReader::SetTypeConversion(const TypeConversion &enTypeCon) + { + m_enTypeCon = enTypeCon; + } + TypeConversion CStarMathReader::GetTypeConversion() + { + return m_enTypeCon; + } //class methods CElementBracketWithIndex - CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType) - :CElement(TypeElement::BracketWithIndex),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) + CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BracketWithIndex,enTypeConversion),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) { } CElementBracketWithIndex::~CElementBracketWithIndex() @@ -2966,7 +2973,7 @@ namespace StarMath } pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); pXmlWrite->WriteNodeBegin(L"m:groupChr",false); @@ -2983,7 +2990,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",L"bot"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); switch(m_enTypeBracketWithIndex) @@ -3034,8 +3041,8 @@ namespace StarMath return m_enTypeBracketWithIndex; } //class methods CElementGrade - CElementGrade::CElementGrade() - :CElement(TypeElement::Grade),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) + CElementGrade::CElementGrade(const TypeConversion &enTypeConversion) + :CElement(TypeElement::Grade,enTypeConversion),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) { } CElementGrade::~CElementGrade() @@ -3078,7 +3085,7 @@ namespace StarMath { if(m_pValueFrom == nullptr && m_pValueTo == nullptr) { - CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); } else { @@ -3098,11 +3105,11 @@ namespace StarMath pXmlWrite->WriteNodeBegin(wsNodeGrade,false); pXmlWrite->WriteNodeBegin(wsNodeGrade + L"Pr",false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(wsNodeGrade + L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(m_pValueFrom != nullptr) { @@ -3131,8 +3138,8 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } //class methods CElementMatrix - CElementMatrix::CElementMatrix(const TypeElement &enType) - :CElement(TypeElement::Matrix), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) + CElementMatrix::CElementMatrix(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Matrix,enTypeConversion), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) { } CElementMatrix::~CElementMatrix() @@ -3172,7 +3179,7 @@ namespace StarMath void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:m",false); - CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute()); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:mr",false); switch(m_enTypeMatrix) { @@ -3236,8 +3243,8 @@ namespace StarMath m_pSecondArgument->SetAttribute(pAttribute); } //class CElementDiacriticalMark - CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType) - :CElement(TypeElement::Mark),m_pValueMark(nullptr),m_enTypeMark(enType) + CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Mark,enTypeConversion),m_pValueMark(nullptr),m_enTypeMark(enType) { } CElementDiacriticalMark::~CElementDiacriticalMark() @@ -3270,6 +3277,7 @@ namespace StarMath else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; else if(L"widehat" == wsToken) return TypeElement::widehat; else if(L"underline" == wsToken) return TypeElement::underline; + else return TypeElement::undefine; } void CElementDiacriticalMark::Parse(CStarMathReader *pReader) { @@ -3351,7 +3359,7 @@ namespace StarMath break; } } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueMark,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:acc",false,false); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 35a26cf6f12..2a67a439dc5 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -33,6 +33,7 @@ #ifndef CSTARMATHPARS_H #define CSTARMATHPARS_H #include "typeselements.h" +#include "typeConversion.h" #include #include #include @@ -70,7 +71,7 @@ namespace StarMath const std::wstring& GetFontName(); bool EmptyColor(); bool ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); - bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); + bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); void SetSize(const unsigned int& iSize); void SetAlignment(const unsigned int& iAlignment); void SetBold(); @@ -94,7 +95,7 @@ namespace StarMath class CStarMathReader { public: - CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd); + CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion); ~CStarMathReader(); bool GetToken(); //getting a subtype and setting the global type of a token to variables m_enUnderType and m_enGlobalType @@ -123,6 +124,8 @@ namespace StarMath void ReadingTheNextToken(); void SetMarkForUnar(const bool& bMark); bool GetMarkForUnar(); + void SetTypeConversion(const TypeConversion &enTypeCon); + TypeConversion GetTypeConversion(); private: bool CheckTokenForGetElement(const wchar_t& cToken); bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); @@ -132,6 +135,7 @@ namespace StarMath std::wstring m_wsToken; CAttribute* m_pAttribute; CAttribute* m_pBaseAttribute; + TypeConversion m_enTypeCon; std::stack m_stBracket; }; @@ -139,7 +143,7 @@ namespace StarMath { public: CElement(); - CElement(const TypeElement& enTypeBase); + CElement(const TypeElement& enTypeBase, const TypeConversion& enTypeConversion); virtual ~CElement(); virtual void Parse(CStarMathReader* pReader) = 0; //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) @@ -150,15 +154,17 @@ namespace StarMath void SetBaseType(const TypeElement& enType); CAttribute* GetAttribute(); const TypeElement& GetBaseType(); + const TypeConversion& GetTypeConversion(); private: CAttribute* m_pAttribute; TypeElement m_enBaseType; + TypeConversion m_enTypeConversion; }; class CElementIndex: public CElement { public: - CElementIndex(const TypeElement& enType); + CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementIndex(); void SetValueIndex(CElement* pElement); void SetLeftArg(CElement* pElement); @@ -188,7 +194,7 @@ namespace StarMath class CElementString: public CElement { public: - CElementString(const std::wstring& wsTokenString); + CElementString(const std::wstring& wsTokenString, const TypeConversion &enTypeConversion); virtual ~CElementString(); void SetString(const std::wstring& wsTokenString); std::wstring GetString(); @@ -204,7 +210,7 @@ namespace StarMath class CElementBinOperator: public CElement { public: - CElementBinOperator(const TypeElement& enType); + CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBinOperator(); void SetLeftArg(CElement* pElement); void SetRightArg(CElement* pElement); @@ -229,7 +235,7 @@ namespace StarMath class CElementOperator: public CElement { public: - CElementOperator(const TypeElement& enType,const std::wstring& wsNameOp = L""); + CElementOperator(const TypeElement& enType, const TypeConversion &enTypeConversion ,const std::wstring& wsNameOp = L""); virtual ~CElementOperator(); void SetValueOperator(CElement* pElement); CElement* GetValueOperator(); @@ -257,7 +263,7 @@ namespace StarMath class CElementGrade: public CElement { public: - CElementGrade(); + CElementGrade(const TypeConversion &enTypeConversion); virtual ~CElementGrade(); void SetValueGrade(CElement* pElement); void SetValueFrom(CElement* pElement); @@ -275,7 +281,7 @@ namespace StarMath class CElementBracket: public CElement { public: - CElementBracket(const TypeElement& enType); + CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); static TypeElement GetBracketOpen(const std::wstring& wsToken); @@ -293,7 +299,7 @@ namespace StarMath class CElementBracketWithIndex: public CElement { public: - CElementBracketWithIndex(const TypeElement& enType); + CElementBracketWithIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBracketWithIndex(); void SetLeftArg(CElement* pElement); void SetBracketValue(CElement* pElement); @@ -312,7 +318,7 @@ namespace StarMath class CElementSetOperations: public CElement { public: - CElementSetOperations(const TypeElement& enType); + CElementSetOperations(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementSetOperations(); void SetLeftArg(CElement* pElement); CElement* GetLeftArg(); @@ -332,7 +338,7 @@ namespace StarMath class CElementConnection: public CElement { public: - CElementConnection(const TypeElement& enType); + CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementConnection(); void SetRightArg(CElement* pElement); CElement* GetRightArg(); @@ -352,7 +358,7 @@ namespace StarMath class CElementFunction: public CElement { public: - CElementFunction(const TypeElement& enType, const std::wstring& wsNameFunc = L""); + CElementFunction(const TypeElement& enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameFunc = L""); virtual ~CElementFunction(); void SetValueFunction(CElement* pElement); CElement* GetValueFunction(); @@ -372,7 +378,7 @@ namespace StarMath class CElementSpecialSymbol: public CElement { public: - CElementSpecialSymbol(const TypeElement& enType); + CElementSpecialSymbol(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementSpecialSymbol(); static TypeElement GetSpecialSymbol(std::wstring& wsToken); void SetValue(CElement* pValue); @@ -390,7 +396,7 @@ namespace StarMath class CElementMatrix: public CElement { public: - CElementMatrix(const TypeElement& enType); + CElementMatrix(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementMatrix(); void SetFirstArgument(CElement* pElement); void SetSecondArgument(CElement* pElement); @@ -407,7 +413,7 @@ namespace StarMath class CElementDiacriticalMark: public CElement { public: - CElementDiacriticalMark(const TypeElement& enType); + CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementDiacriticalMark(); void SetValueMark(CElement* pValue); static TypeElement GetMark(const std::wstring& wsToken); @@ -422,7 +428,7 @@ namespace StarMath class CParserStarMathString { public: - std::vector Parse(std::wstring& wsParseString, const TBaseAttribute* pBaseAttribute = nullptr); + std::vector Parse(std::wstring& wsParseString,int iTypeConversion,const TBaseAttribute* pBaseAttribute = nullptr); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h new file mode 100644 index 00000000000..f13733e5c5d --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h @@ -0,0 +1,13 @@ +#ifndef TYPECONVERSION_H +#define TYPECONVERSION_H +namespace StarMath +{ +enum class TypeConversion +{ + undefine, + pptx, + docx, +}; +} + +#endif // TYPECONVERSION_H diff --git a/OdfFile/Reader/Converter/oox_conversion_context.cpp b/OdfFile/Reader/Converter/oox_conversion_context.cpp index 15e36a90b78..d42d47ae417 100644 --- a/OdfFile/Reader/Converter/oox_conversion_context.cpp +++ b/OdfFile/Reader/Converter/oox_conversion_context.cpp @@ -265,20 +265,6 @@ void math_context::start() text_properties_->content_.fo_font_family_ = base_font_name_.empty() ? L"Cambria Math" : base_font_name_; text_properties_->content_.fo_font_size_ = odf_types::length(base_font_size_, odf_types::length::pt); - - math_stream_ << L""; - - math_stream_ << L""; - //math_stream_ << L""; start_level(); } @@ -286,7 +272,6 @@ std::wstring math_context::end() { end_level(); - math_stream_ << L""; std::wstring math = math_stream_.str(); math_stream_.str( std::wstring() ); diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index 2fa5f2097fc..0b72a70e1b1 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -261,7 +261,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.start_math_formula(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(),2); Context.end_math_formula(); Context.get_drawing_context().get_text_stream_frame() = temp_stream.str(); @@ -307,7 +307,7 @@ void object_odf_context::pptx_convert(oox::pptx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(),1); } else if(object_type_ == 4 && office_spreadsheet_) { diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 567d4eca62b..0fbd1ed881f 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -1756,8 +1756,7 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) drawing->type = oox::typeShape; drawing->additional.push_back(_property(L"fit-to-size", true)); - drawing->additional.push_back(_property(L"text-content", std::wstring(L"") + - content + std::wstring(L""))); + drawing->additional.push_back(_property(L"text-content", std::wstring(L"") + content + std::wstring(L""))); } else {//in text @@ -1765,9 +1764,7 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) if (runState) Context.finish_run(); - Context.output_stream() << L""; Context.output_stream() << content; - Context.output_stream() << L""; if (runState) Context.add_new_run(_T("")); } diff --git a/OdfFile/Reader/Format/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index aa46882f156..d2c040eab2d 100644 --- a/OdfFile/Reader/Format/math_elements.cpp +++ b/OdfFile/Reader/Format/math_elements.cpp @@ -62,12 +62,12 @@ void office_math::add_child_element( xml::sax * Reader, const std::wstring & Ns, } -void office_math::oox_convert(oox::math_context & Context) +void office_math::oox_convert(oox::math_context & Context, int iTypeConversion) { if (semantics_) { office_math_element* math_element = dynamic_cast(semantics_.get()); - math_element->oox_convert(Context); + math_element->oox_convert(Context,iTypeConversion); } } @@ -93,6 +93,10 @@ void math_semantics::add_child_element( xml::sax * Reader, const std::wstring & void math_semantics::oox_convert(oox::math_context & Context) +{ + this->oox_convert(Context,0); +} +void math_semantics::oox_convert(oox::math_context &Context, int iTypeConversion) { math_annotation* annotation = dynamic_cast(annotation_.get()); math_annotation_xml* annotation_xml = dynamic_cast(annotation_.get()); @@ -115,7 +119,7 @@ void math_semantics::oox_convert(oox::math_context & Context) /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_italic_; /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_bold_; - /*result = */converter.StartConversion(parser.Parse(annotation_text)); + /*result = */converter.StartConversion(parser.Parse(annotation_text,iTypeConversion)); Context.output_stream() << converter.GetOOXML(); } diff --git a/OdfFile/Reader/Format/math_elements.h b/OdfFile/Reader/Format/math_elements.h index 0c8e49dbec3..077f6240414 100644 --- a/OdfFile/Reader/Format/math_elements.h +++ b/OdfFile/Reader/Format/math_elements.h @@ -55,6 +55,7 @@ class office_math_element : public office_element_impl virtual void pptx_convert (oox::pptx_conversion_context & Context) {} virtual void oox_convert (oox::math_context & Context) = 0; + virtual void oox_convert (oox::math_context &Context, int iTypeConversion) {oox_convert(Context);} CPDOCCORE_DEFINE_VISITABLE(); friend class odf_document; @@ -73,7 +74,7 @@ class office_math : public office_element_impl virtual void xlsx_convert (oox::xlsx_conversion_context & Context){} virtual void pptx_convert (oox::pptx_conversion_context & Context){} - void oox_convert (oox::math_context & Context); + void oox_convert (oox::math_context & Context,int iTypeConversion = 0); CPDOCCORE_DEFINE_VISITABLE(); friend class odf_document; @@ -98,6 +99,7 @@ class math_semantics : public office_math_element static const ElementType type = typeMathSemantics; virtual void oox_convert(oox::math_context & Context); + virtual void oox_convert(oox::math_context & Context, int iTypeConversion); private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); From c18224ea0769f963eacbcc4d97b1e46888d4739f Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 19 Apr 2024 17:17:14 +0600 Subject: [PATCH 560/794] Fix csv date conversion --- .../Reader/CellFormatController/DateReader.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp index e7c1eba05ea..8282dc05edc 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp @@ -83,11 +83,17 @@ bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) _INT32 DateReader::getStandartDate(tm &date) { // Преобразование даты в формат excel - auto timeT = mktime(&date); - auto tp = std::chrono::system_clock::from_time_t(timeT); - auto excelTime = (tp.time_since_epoch().count() / 10000000) + 2209161600; - _INT32 tempTime = round(excelTime / 86400.0); - return tempTime; + auto timeT = mktime(&date); + auto tp = std::chrono::system_clock::from_time_t(timeT); + auto excelTime = tp.time_since_epoch().count(); + #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + excelTime = excelTime / 10000000; + #else + excelTime = excelTime / 1000000000; + #endif + excelTime += 2209161600; + _INT32 tempTime = round(excelTime / 86400.0); + return tempTime; } // Функция для определения високосного года From 6de60d254339c5023216d5d3b12ef5d3202299dc Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 19 Apr 2024 19:20:45 +0300 Subject: [PATCH 561/794] Fix bugs in html to ooxml conversion --- .../html/css/src/CCssCalculator_Private.cpp | 2 +- .../html/css/src/CUnitMeasureConverter.cpp | 3 + .../3dParty/html/css/src/StyleProperties.cpp | 74 +++++++++----- Common/3dParty/html/css/src/StyleProperties.h | 3 + .../html/css/src/xhtml/CDocumentStyle.cpp | 5 +- .../raster/Metafile/svg/CSvgFile.cpp | 14 +-- HtmlFile2/htmlfile2.cpp | 98 +++++++++++-------- 7 files changed, 126 insertions(+), 73 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index f3e508e3928..9bc3f2671b0 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -524,7 +524,7 @@ namespace NSCSS // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются if (L"table" == arSelectors[i].m_wsName) { - oStyle.m_oFont.Clear(); + oStyle.m_oFont.GetLineHeight().Clear(); oStyle.m_oPadding.Clear(); oStyle.m_oMargin.Clear(); } diff --git a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp index d0dc327cd4f..3f80a95ed5a 100644 --- a/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp +++ b/Common/3dParty/html/css/src/CUnitMeasureConverter.cpp @@ -159,6 +159,9 @@ namespace NSCSS bool CUnitMeasureConverter::GetValue(const std::wstring &wsValue, double &dValue, UnitMeasure &enUnitMeasure) { + if (wsValue.empty() || wsValue.end() == std::find_if(wsValue.begin(), wsValue.end(), [](wchar_t wChar) { return iswdigit(wChar);})) + return false; + std::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?)\s*(px|pt|cm|mm|in|pc|%|em|rem|tw)?)"); std::wsmatch oMatches; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 880eade9a3f..9dfb2e1c6b6 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -323,12 +323,10 @@ namespace NSCSS CDigit &CDigit::operator+=(const CDigit &oDigit) { - if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || DBL_MAX == oDigit.m_oValue) + if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || oDigit.Empty()) return *this; - if (oDigit.Empty()) - return *this; - else if (Empty()) + if (Empty()) { *this = oDigit; return *this; @@ -394,6 +392,27 @@ namespace NSCSS return true; } + + bool CDigit::SetValue(const CDigit &oValue) + { + if (oValue.Empty() || m_unLevel > oValue.m_unLevel || (m_bImportant && !oValue.m_bImportant)) + return false; + + if (Empty()) + { + m_oValue = oValue.m_oValue; + m_enUnitMeasure = oValue.m_enUnitMeasure; + } + else if (NSCSS::Percent == oValue.m_enUnitMeasure) + m_oValue *= oValue.m_oValue / 100.; + else + m_oValue = oValue.ToDouble(m_enUnitMeasure); + + m_unLevel = oValue.m_unLevel; + m_bImportant = oValue.m_bImportant; + + return true; + } bool TRGB::Empty() const { @@ -1699,6 +1718,8 @@ namespace NSCSS CBorder &CBorder::operator+=(const CBorder &oBorder) { + m_enCollapse = oBorder.m_enCollapse; + if (oBorder.Empty()) return *this; @@ -1707,8 +1728,6 @@ namespace NSCSS m_oRight = oBorder.m_oRight; m_oBottom = oBorder.m_oBottom; - m_enCollapse = oBorder.m_enCollapse; - return *this; } @@ -1946,12 +1965,17 @@ namespace NSCSS { return m_oLeft; } - + bool CIndent::Empty() const { return m_oTop.Empty() && m_oRight.Empty() && m_oBottom.Empty() && m_oLeft.Empty(); } - + + bool CIndent::Zero() const + { + return m_oTop.Zero() && m_oRight.Zero() && m_oBottom.Zero() && m_oLeft.Zero(); + } + CIndent &CIndent::operator+=(const CIndent &oIndent) { m_oTop = oIndent.m_oTop; @@ -2163,10 +2187,10 @@ namespace NSCSS bool CFont::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { const std::map arAbsoluteFontValues = - {{L"xx-small", L"0.6em"}, {L"x-small", L"0.75em"}, - {L"small", L"0.875em"}, {L"medium", L"1em"}, - {L"large", L"1.125em"}, {L"x-large", L"1.25em"}, - {L"xx-large", L"1.5em"}}; + {{L"xx-small", L"7.5pt"}, {L"x-small", L"10pt" }, + {L"small", L"12pt" }, {L"medium", L"13.5pt"}, + {L"large", L"18pt" }, {L"x-large", L"24pt" }, + {L"xx-large", L"36pt" }}; size_t unFoundPos = std::wstring::npos; std::wstring wsNewValue(wsValue); @@ -2275,6 +2299,11 @@ namespace NSCSS return m_oLineHeight; } + CDigit &CFont::GetLineHeight() + { + return m_oLineHeight; + } + const CString &CFont::GetFamily() const { return m_oFamily; @@ -2308,7 +2337,7 @@ namespace NSCSS CFont &CFont::operator+=(const CFont &oFont) { - m_oSize += oFont.m_oSize; + m_oSize.SetValue(oFont.m_oSize); m_oLineHeight += oFont.m_oLineHeight; m_oFamily += oFont.m_oFamily; m_oStretch += oFont.m_oStretch; @@ -2514,15 +2543,13 @@ namespace NSCSS std::map::const_iterator oFound = m_mMap.find(wsNewValue); - if (m_mMap.end() != oFound) - { - m_oValue = oFound->second; - m_unLevel = unLevel; - m_bImportant = bImportant; - } - else + if (m_mMap.end() == oFound) return false; + m_oValue = oFound->second; + m_unLevel = unLevel; + m_bImportant = bImportant; + return true; } @@ -2569,12 +2596,15 @@ namespace NSCSS double CEnum::ToDouble() const { - return 0.; + return (double)m_oValue; } std::wstring CEnum::ToWString() const { - return std::wstring(); + if (m_mMap.empty()) + return std::wstring(); + + return std::find_if(m_mMap.begin(), m_mMap.end(), [this](const std::pair& oValue){ return m_oValue == oValue.second; })->first; } CPage::CPage() diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 4f6546861ff..1d3e2c762fc 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -129,6 +129,7 @@ namespace NSCSS CDigit(double dValue, unsigned int unLevel, bool bImportant = false); bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override; + bool SetValue(const CDigit& oValue); bool Empty() const override; bool Zero() const; @@ -614,6 +615,7 @@ namespace NSCSS const CDigit& GetLeft () const; bool Empty() const; + bool Zero() const; CIndent& operator+=(const CIndent& oIndent); bool operator==(const CIndent& oIndent) const; @@ -656,6 +658,7 @@ namespace NSCSS const CDigit& GetSize() const; const CDigit& GetLineHeight() const; + CDigit& GetLineHeight(); const CString& GetFamily() const; const CString& GetStretch() const; const CString& GetStyle() const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 3c94b1b116a..dd5f78d7e6f 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -22,7 +22,10 @@ namespace NSCSS std::wstring CStyleUsed::getId() { - return m_wsId; + if (m_bIsPStyle) + return m_wsId; + + return m_wsId + L"-c"; } void CStyleUsed::setId(const std::wstring &sId) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index cea56425506..3d920e91f0e 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -178,21 +178,15 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d pRenderer->GetTransform(&oldTransform[0], &oldTransform[1], &oldTransform[2], &oldTransform[3], &oldTransform[4], &oldTransform[5]); pRenderer->ResetTransform(); - double dM11 = 1; - double dM22 = 1; - - if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero()) - dM11 = dWidth / dWindowWidth; - - if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero()) - dM22 = dHeight / dWindowHeight; + double dM11 = dWidth / dWindowWidth; + double dM22 = dHeight / dWindowHeight; double dScaleX = 1, dScaleY = 1; - if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero() && !oViewBox.m_oWidth.Empty() && !oViewBox.m_oWidth.Zero()) + if (!SVG::Equals(0., dViewBoxWidth)) dScaleX = dWindowWidth / dViewBoxWidth; - if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero() && !oViewBox.m_oHeight.Empty() && !oViewBox.m_oHeight.Zero()) + if (!SVG::Equals(0., dViewBoxHeight)) dScaleY = dWindowHeight / dViewBoxHeight; double dMinScale = std::min(dScaleX, dScaleY); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 9b39be7f93a..298c4d7eb53 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -121,6 +121,19 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NS return L""; } +void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false) +{ + if (NULL == pXml) + return; + + pXml->WriteString(L""); + + if (bVahish) + pXml->WriteString(L""); + + pXml->WriteString(L""); +} + typedef enum { ParseModeHeader, @@ -377,7 +390,10 @@ class CTableCell oCell += L""; oCell.WriteNodeEnd(L"w:tcPr"); - oCell += m_oData.GetData(); + if (0 != m_oData.GetCurSize()) + oCell += m_oData.GetData(); + else + WriteEmptyParagraph(&oCell); oCell.WriteNodeEnd(L"w:tc"); @@ -419,6 +435,8 @@ class CTableRow if (nPosition < 0) m_arCells.push_back(pCell); + else if (nPosition > m_arCells.size()) + m_arCells.push_back(pCell); else m_arCells.insert(m_arCells.begin() + nPosition, pCell); @@ -723,25 +741,34 @@ class CTable if (!m_oStyles.m_wsAlign.empty()) oTable += L""; - if (0 < m_oStyles.m_nCellSpacing) + if (0 < m_oStyles.m_nCellSpacing && m_oStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse) oTable += L""; if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) oTable += L"" + CreateBorders(m_oStyles.m_oBorder) + L""; - if (!m_oStyles.m_oPadding.Empty()) + if (!m_oStyles.m_oPadding.Empty() && !m_oStyles.m_oPadding.Zero()) { const int nTopPadding = std::max(0, m_oStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); const int nLeftPadding = std::max(0, m_oStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); const int nBottomPadding = std::max(0, m_oStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); const int nRightPadding = std::max(0, m_oStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - oTable += L"" - "" - "" - "" - "" - ""; + oTable.WriteNodeBegin(L"w:tblCellMar"); + + if (0 != nTopPadding) + oTable += L""; + + if (0 != nLeftPadding) + oTable += L""; + + if (0 != nBottomPadding) + oTable += L""; + + if (0 != nRightPadding) + oTable += L""; + + oTable.WriteNodeEnd(L"w:tblCellMar"); } else oTable += L""; @@ -1439,19 +1466,6 @@ class CHtmlFile2_Private return true; } - void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false) const - { - if (NULL == pXml) - return; - - pXml->WriteString(L""); - - if (bVahish) - pXml->WriteString(L""); - - pXml->WriteString(L""); - } - bool OpenR(NSStringUtils::CStringBuilder* pXml) { if (m_bInR) @@ -1636,22 +1650,28 @@ class CHtmlFile2_Private { oXml->WriteEncodeXmlString(sText.c_str(), nAfter); oXml->WriteString(L""); - if(!sPStyle.empty()) + if(!sPStyle.empty() || !oTS.sPStyle.empty()) { - oXml->WriteString(L"WriteString(sPStyle); - oXml->WriteString(L"\"/>"); + oXml->WriteNodeBegin(L"w:pPr"); + + if (!sPStyle.empty()) + oXml->WriteString(L""); + oXml->WriteString(oTS.sPStyle); - oXml->WriteString(L""); + + oXml->WriteNodeEnd(L"w:pPr"); } - oXml->WriteString(L""); - if (!sRStyle.empty()) + oXml->WriteNodeBegin(L"w:r"); + if (!sRStyle.empty() || !oTS.sRStyle.empty()) { - oXml->WriteString(L"WriteString(sRStyle); - oXml->WriteString(L"\"/>"); + oXml->WriteNodeBegin(L"w:rPr"); + + if (!sRStyle.empty()) + oXml->WriteString(L""); + oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L""); + + oXml->WriteNodeEnd(L"w:rPr"); } oXml->WriteString(L""); sText.erase(0, nAfter + 1); @@ -2197,16 +2217,15 @@ class CHtmlFile2_Private sSelectors.back().m_mAttributes[L"border"] = L"none"; } - if (oXml->GetSubData(oXml->GetCurSize() - 8) == L"") - WriteEmptyParagraph(oXml, true); - NSCSS::CCompiledStyle oStyle; m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); - if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) + if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Collapse) + oTable.SetCellSpacing(0); + else if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing")) oTable.SetCellSpacing(NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"])); else if (oStyle.m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate) oTable.SetCellSpacing(15); @@ -2239,6 +2258,7 @@ class CHtmlFile2_Private oTable.Shorten(); oTable.CompleteTable(); oXml->WriteString(oTable.ConvertToOOXML()); + WriteEmptyParagraph(oXml, true); } void readInput (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) @@ -2889,12 +2909,12 @@ class CHtmlFile2_Private double dOneMaxSize = (double)1000.; - if (dW > dH) + if (dW > dH && dW > dOneMaxSize) { dH *= (dOneMaxSize / dW); dW = dOneMaxSize; } - else + else if (dH > dW && dH > dOneMaxSize) { dW *= (dOneMaxSize / dH); dH = dOneMaxSize; From 82b634878f7608d4e51966570177a70f3bd89f31 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 20 Apr 2024 12:40:01 +0300 Subject: [PATCH 562/794] Fix build --- Fb2File/Fb2File.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Fb2File/Fb2File.pro b/Fb2File/Fb2File.pro index f9a3359fcbe..e04f6d44195 100644 --- a/Fb2File/Fb2File.pro +++ b/Fb2File/Fb2File.pro @@ -18,6 +18,9 @@ include($$CORE_ROOT_DIR/Common/3dParty/html/gumbo.pri) ADD_DEPENDENCY(kernel, UnicodeConverter, graphics) +CONFIG += core_boost_regex +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) + SOURCES += Fb2File.cpp HEADERS += Fb2File.h From 9daa8a1239526aed09fa0ef689ff4abdc6969f41 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Sat, 20 Apr 2024 13:21:45 +0300 Subject: [PATCH 563/794] Fix build --- DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h | 2 +- DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h index a67bd9be416..4d57d48c2ea 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h @@ -3,7 +3,7 @@ #include "CObjectBase.h" -#include "../../../graphics/pro/Fonts.h" +#include "../../../../graphics/pro/Fonts.h" class CSvgFile; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h index 505a6d61c73..66f3b5ed9d1 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h @@ -5,7 +5,7 @@ #include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h" #include "../../../../xml/include/xmlutils.h" #include "../../../../graphics/IRenderer.h" -#include "../../../common/IGrObject.h" +#include "../../../../common/IGrObject.h" #include "../SvgTypes.h" class CSvgFile; From 73624f28acc672b2a20c35a575f3bad373d064a4 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 20 Apr 2024 14:02:19 +0300 Subject: [PATCH 564/794] Fix android build --- Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index dd5f78d7e6f..a7cead51aea 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include From 31090af4406528128da8e98b226063b1710b5416 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 22 Apr 2024 16:32:40 +0600 Subject: [PATCH 565/794] Fix array formula conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 198e6e94437..08be4c93059 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1859,7 +1859,7 @@ namespace OOX { if(checkArrayCell(sourceCellRef, sharedFormulas)) { - if(!m_oFormula.IsInit()) + if(!m_oFormula.IsInit() || m_oFormula->m_sText.empty()) { m_oFormula.Init(); m_oFormula->m_oT = SimpleTypes::Spreadsheet::cellformulatypeArray; From ed9a5f1a242e7423048df8377f702057d3e5d919 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Tue, 23 Apr 2024 15:55:32 +0300 Subject: [PATCH 566/794] editing tabs --- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 384 +++++++++--------- .../StarMath2OOXML/cconversionsmtoooxml.h | 20 +- .../StarMath2OOXML/cstarmathpars.cpp | 237 ++++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 2 +- 4 files changed, 321 insertions(+), 322 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index bedfc7c8c40..011bb3df15b 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -40,38 +40,38 @@ namespace StarMath { void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; - std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; - switch(iAlignment) - { - case 0: - wsAlignment = L"center"; - break; - case 1: - wsAlignment = L"left"; - break; - case 2: - wsAlignment = L"right"; - break; - default: - wsAlignment = L"center"; - break; - } - if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) - { - wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; - wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; - wsAlignment += L"Group"; - } - m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); - if(iAlignment>= 0 && iAlignment <= 2) - { - m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); - m_pXmlWrite->WriteNodeBegin(L"m:jc",true); - m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); - m_pXmlWrite->WriteNodeEnd(L"",true,true); - m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); - } - m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); + std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; + switch(iAlignment) + { + case 0: + wsAlignment = L"center"; + break; + case 1: + wsAlignment = L"left"; + break; + case 2: + wsAlignment = L"right"; + break; + default: + wsAlignment = L"center"; + break; + } + if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) + { + wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsAlignment += L"Group"; + } + m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); + if(iAlignment>= 0 && iAlignment <= 2) + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); + m_pXmlWrite->WriteNodeBegin(L"m:jc",true); + m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); + } + m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); for(CElement* oTempElement:arPars) { if(oTempElement != nullptr) @@ -79,158 +79,158 @@ namespace StarMath { if(CParserStarMathString::CheckNewline(oTempElement)) { m_pXmlWrite->WriteNodeBegin(L"m:r",false); - m_pXmlWrite->WriteNodeBegin(L"w:br",true); + m_pXmlWrite->WriteNodeBegin(L"w:br",true); m_pXmlWrite->WriteNodeEnd(L"",true,true); m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); } else oTempElement->ConversionToOOXML(m_pXmlWrite); } } - m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { - if(TypeConversion::docx == enTypeConversion || TypeConversion::undefine == enTypeConversion) - { - if(pAttribute == nullptr) - { - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - } - else - { - std::wstring wsNameFont = pAttribute->GetFontName(); - pXmlWrite->WriteNodeBegin(L"w:rPr",false); - pXmlWrite->WriteNodeBegin(L"w:rFonts",true); - if(!wsNameFont.empty()) - { - pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); - pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); - } - else - { - pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); - pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); - } - pXmlWrite->WriteNodeEnd(L"w",true,true); - if(pAttribute->GetSize() == 0) - { - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - else if(pAttribute->GetSize() != 0) - { - pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(!pAttribute->EmptyColor()) - { - pXmlWrite->WriteNodeBegin(L"w:color",true); - pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(pAttribute->GetBold() && pAttribute->GetItal()) - { - WriteStyNode(pXmlWrite,L"bi"); - } - else if(pAttribute->GetBold()) - { - pXmlWrite->WriteNodeBegin(L"m:sty", true); - pXmlWrite->WriteAttribute(L"m:val",L"b"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:b",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"w:bCs",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - else if(pAttribute->GetItal()) - { - pXmlWrite->WriteNodeBegin(L"w:i",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - if(pAttribute->GetStrike()) - { - pXmlWrite->WriteNodeBegin(L"w:strike",true); - pXmlWrite->WriteNodeEnd(L"w",true,true); - } - pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); - } - } - else if(TypeConversion::pptx == enTypeConversion) - { - if(pAttribute !=nullptr) - { - pXmlWrite->WriteNodeBegin(L"a:rPr",true); - if(pAttribute->GetSize()!=0) - { - int iSize = pAttribute->GetSize(); - iSize = iSize*50; - pXmlWrite->WriteAttribute(L"sz",iSize); - } - else - pXmlWrite->WriteAttribute(L"sz",L"1500"); - if(pAttribute->GetBold()) - pXmlWrite->WriteAttribute(L"b",L"1"); - if(pAttribute->GetItal()) - pXmlWrite->WriteAttribute(L"i",L"1"); - pXmlWrite->WriteNodeEnd(L"w",true,false); - if(!pAttribute->GetColor().empty()) - { - pXmlWrite->WriteNodeBegin(L"a:solidFill",false); - pXmlWrite->WriteNodeBegin(L"a:srgbClr",true); - pXmlWrite->WriteAttribute(L"val",pAttribute->GetColor()); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"a:solidFill",false,false); - } - pXmlWrite->WriteNodeBegin(L"a:latin",true); - if(!pAttribute->GetFontName().empty()) - pXmlWrite->WriteAttribute(L"typeface",pAttribute->GetFontName()); - else - pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); - // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); - // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); - // pXmlWrite->WriteAttribute(L"charset",L"0"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"a:rPr",false); - } - else - { - pXmlWrite->WriteNodeBegin(L"a:rPr",true); - pXmlWrite->WriteAttribute(L"sz",L"1500"); - pXmlWrite->WriteNodeEnd(L"w",true,false); - pXmlWrite->WriteNodeBegin(L"a:latin",true); - pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); - // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); - // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); - // pXmlWrite->WriteAttribute(L"charset",L"0"); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeEnd(L"a:rPr",false); - } - } + if(TypeConversion::docx == enTypeConversion || TypeConversion::undefine == enTypeConversion) + { + if(pAttribute == nullptr) + { + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + else + { + std::wstring wsNameFont = pAttribute->GetFontName(); + pXmlWrite->WriteNodeBegin(L"w:rPr",false); + pXmlWrite->WriteNodeBegin(L"w:rFonts",true); + if(!wsNameFont.empty()) + { + pXmlWrite->WriteAttribute(L"w:hAnsi",wsNameFont); + pXmlWrite->WriteAttribute(L"w:ascii",wsNameFont); + } + else + { + pXmlWrite->WriteAttribute(L"w:hAnsi",L"Cambria Math"); + pXmlWrite->WriteAttribute(L"w:ascii",L"Cambria Math"); + } + pXmlWrite->WriteNodeEnd(L"w",true,true); + if(pAttribute->GetSize() == 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetSize() != 0) + { + pXmlWrite->WriteNodeBegin(L"w:sz",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:szCs",true); + pXmlWrite->WriteAttribute(L"w:val",std::to_wstring(pAttribute->GetSize())); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!pAttribute->EmptyColor()) + { + pXmlWrite->WriteNodeBegin(L"w:color",true); + pXmlWrite->WriteAttribute(L"w:val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetBold() && pAttribute->GetItal()) + { + WriteStyNode(pXmlWrite,L"bi"); + } + else if(pAttribute->GetBold()) + { + pXmlWrite->WriteNodeBegin(L"m:sty", true); + pXmlWrite->WriteAttribute(L"m:val",L"b"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:b",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeBegin(L"w:bCs",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + else if(pAttribute->GetItal()) + { + pXmlWrite->WriteNodeBegin(L"w:i",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(pAttribute->GetStrike()) + { + pXmlWrite->WriteNodeBegin(L"w:strike",true); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); + } + } + else if(TypeConversion::pptx == enTypeConversion) + { + if(pAttribute !=nullptr) + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + if(pAttribute->GetSize()!=0) + { + int iSize = pAttribute->GetSize(); + iSize = iSize*50; + pXmlWrite->WriteAttribute(L"sz",iSize); + } + else + pXmlWrite->WriteAttribute(L"sz",L"1500"); + if(pAttribute->GetBold()) + pXmlWrite->WriteAttribute(L"b",L"1"); + if(pAttribute->GetItal()) + pXmlWrite->WriteAttribute(L"i",L"1"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + if(!pAttribute->GetColor().empty()) + { + pXmlWrite->WriteNodeBegin(L"a:solidFill",false); + pXmlWrite->WriteNodeBegin(L"a:srgbClr",true); + pXmlWrite->WriteAttribute(L"val",pAttribute->GetColor()); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:solidFill",false,false); + } + pXmlWrite->WriteNodeBegin(L"a:latin",true); + if(!pAttribute->GetFontName().empty()) + pXmlWrite->WriteAttribute(L"typeface",pAttribute->GetFontName()); + else + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); + // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); + // pXmlWrite->WriteAttribute(L"charset",L"0"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + else + { + pXmlWrite->WriteNodeBegin(L"a:rPr",true); + pXmlWrite->WriteAttribute(L"sz",L"1500"); + pXmlWrite->WriteNodeEnd(L"w",true,false); + pXmlWrite->WriteNodeBegin(L"a:latin",true); + pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); + // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); + // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); + // pXmlWrite->WriteAttribute(L"charset",L"0"); + pXmlWrite->WriteNodeEnd(L"w",true,true); + pXmlWrite->WriteNodeEnd(L"a:rPr",false); + } + } } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:fPr",false); if(bType) @@ -239,10 +239,10 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"lin"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:fPr",false,false); } - void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:naryPr",false); switch(enTypeOp) @@ -289,7 +289,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"1"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); + WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:naryPr",false,false); } void CConversionSMtoOOXML::WriteNodeConversion(const std::wstring &wsNameBlock, CElement *pValueBlock,XmlUtils::CXmlWriter* pXmlWrite) @@ -315,16 +315,16 @@ namespace StarMath { m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } - void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:funcPr", false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr", false); - StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr", false,false); pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } - void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:dPr",false); switch(enTypeBracket) @@ -355,7 +355,7 @@ namespace StarMath { break; } pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); - StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); } @@ -368,7 +368,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:mPr",false); pXmlWrite->WriteNodeBegin(L"m:mcs",false); @@ -392,11 +392,11 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:mc",false,false); pXmlWrite->WriteNodeEnd(L"m:mcs",false,false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(L"m:mPr",false,false); } - void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) + void CConversionSMtoOOXML::NodeGrade(XmlUtils::CXmlWriter *pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute) { pXmlWrite->WriteNodeBegin(L"m:d",false); pXmlWrite->WriteNodeBegin(L"m:dPr",false); @@ -407,7 +407,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"\u23AA"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute,pValueGrade->GetTypeConversion()); + StandartProperties(pXmlWrite,pAttribute,pValueGrade->GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); @@ -415,10 +415,10 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:d",false,false); } - void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); } void CConversionSMtoOOXML::WriteChrNode(const std::wstring &wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite) @@ -433,7 +433,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsTypeLimLock); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::WriteRPrFName(const TypeElement &enTypeOp, XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -441,7 +441,7 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",L"p"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(enTypeOp) { @@ -469,10 +469,10 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"m:val",wsAttributeNode); pXmlWrite->WriteNodeEnd(L"w",true,true); } - void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::WritePreserveBlock(XmlUtils::CXmlWriter *pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:r",false); - StandartProperties(pXmlWrite,pAttribute,enTypeConversion); + StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeBegin(L"m:t",true); pXmlWrite->WriteAttribute(L"xml:space",L"preserve"); pXmlWrite->WriteNodeEnd(L"w",true,false); @@ -483,10 +483,10 @@ namespace StarMath { { pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,pValue->GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,pValue->GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,pValue->GetTypeConversion()); + CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,pValue->GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(pValue!= nullptr && pIndex != nullptr) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 64f3ce080ed..3d97900cc11 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -42,20 +42,20 @@ namespace StarMath { public: CConversionSMtoOOXML(); void StartConversion(std::vector arPars, const unsigned int& iAlignment = -1); - static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); - static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); - static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); - static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); + static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion); - static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion); - static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); - static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); + static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteChrNode(const std::wstring& wsTypeOp,XmlUtils::CXmlWriter* pXmlWrite); static void WriteLimLocNode(const std::wstring& wsTypeLimLock,XmlUtils::CXmlWriter* pXmlWrite); - static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion); + static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); - static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion); + static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion); static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); void EndConversion(); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 17ba21b2544..1244463c84d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -209,7 +209,7 @@ namespace StarMath pReader->ReadingTheNextToken(); if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { - CElement* pIndex = new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + CElement* pIndex = new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); pReader->ClearReader(); pIndex->Parse(pReader); AddLeftArgument(pElement,pIndex); @@ -631,60 +631,60 @@ namespace StarMath } CElement::CElement(): m_pAttribute(nullptr) {} - CElement::CElement(const TypeElement &enTypeBase,const TypeConversion &enTypeConversion): m_pAttribute(nullptr),m_enBaseType(enTypeBase),m_enTypeConversion(enTypeConversion) + CElement::CElement(const TypeElement &enTypeBase,const TypeConversion &enTypeConversion): m_pAttribute(nullptr),m_enBaseType(enTypeBase),m_enTypeConversion(enTypeConversion) { } CElement* CElement::CreateElement(CStarMathReader* pReader) { switch (pReader->GetGlobalType()) { case TypeElement::String: - return new CElementString(pReader->GetString(),pReader->GetTypeConversion()); + return new CElementString(pReader->GetString(),pReader->GetTypeConversion()); case TypeElement::BinOperator: - return new CElementBinOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementBinOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::SetOperations: - return new CElementSetOperations(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementSetOperations(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Connection: - return new CElementConnection(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementConnection(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Function: { if(pReader->GetLocalType() == TypeElement::func) { - if (pReader->GetToken()) - return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); - else - return nullptr; + if (pReader->GetToken()) + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); + else + return nullptr; } else - return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion()); } case TypeElement::Bracket: - return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Operation: { if(pReader->GetLocalType() == TypeElement::oper) { - if (pReader->GetToken()) - { - return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); - } - else - return nullptr; + if (pReader->GetToken()) + { + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion(),pReader->GetString()); + } + else + return nullptr; } else - return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementOperator(pReader->GetLocalType(),pReader->GetTypeConversion()); } case TypeElement::BracketWithIndex: - return new CElementBracketWithIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementBracketWithIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Grade: - return new CElementGrade(pReader->GetTypeConversion()); + return new CElementGrade(pReader->GetTypeConversion()); case TypeElement::Matrix: - return new CElementMatrix(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementMatrix(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::SpecialSymbol: - return new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Index: - return new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); case TypeElement::Mark: - return new CElementDiacriticalMark(pReader->GetLocalType(),pReader->GetTypeConversion()); + return new CElementDiacriticalMark(pReader->GetLocalType(),pReader->GetTypeConversion()); default: return nullptr; } @@ -721,13 +721,13 @@ namespace StarMath { return m_pAttribute; } - const TypeConversion& CElement::GetTypeConversion() - { - return m_enTypeConversion; - } + const TypeConversion& CElement::GetTypeConversion() + { + return m_enTypeConversion; + } //class methods CElementString - CElementString::CElementString(const std::wstring& wsTokenString,const TypeConversion &enTypeConversion) - :CElement(TypeElement::String,enTypeConversion),m_wsString(wsTokenString) + CElementString::CElementString(const std::wstring& wsTokenString,const TypeConversion &enTypeConversion) + :CElement(TypeElement::String,enTypeConversion),m_wsString(wsTokenString) { } CElementString::~CElementString() @@ -743,7 +743,7 @@ namespace StarMath void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(m_wsString); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -778,8 +778,8 @@ namespace StarMath SetBaseAttribute(pAttribute); } //class methods CElementBinOperator - CElementBinOperator::CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::BinOperator,enTypeConversion),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) + CElementBinOperator::CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BinOperator,enTypeConversion),m_pLeftArgument(nullptr) , m_pRightArgument(nullptr),m_enTypeBinOp(enType) { } CElementBinOperator::~CElementBinOperator() @@ -826,9 +826,9 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:f",false); if(m_enTypeBinOp == TypeElement::division) - CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute(),GetTypeConversion()); else - CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute(),GetTypeConversion()); CConversionSMtoOOXML::WriteNodeConversion(L"m:num",m_pLeftArgument,pXmlWrite); CConversionSMtoOOXML::WriteNodeConversion(L"m:den",m_pRightArgument,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -837,7 +837,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch (m_enTypeBinOp) { @@ -996,8 +996,8 @@ namespace StarMath return m_enTypeBinOp; } //class methods CElementBracket - CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType) + CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType) { } CElementBracket::~CElementBracket() @@ -1055,7 +1055,7 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::newline) { - m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); + m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); pReader->ClearReader(); } CElement* pTempElement =CParserStarMathString::ParseElement(pReader); @@ -1069,7 +1069,7 @@ namespace StarMath if(m_enTypeBracket != TypeElement::brace) { pXmlWrite->WriteNodeBegin(L"m:d",false); - CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* pTemp:m_arBrecketValue) { @@ -1078,7 +1078,7 @@ namespace StarMath if(CheckMline(pTemp)) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(L"\u007C"); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1123,8 +1123,8 @@ namespace StarMath } } //class methods CElementSpecialSymbol - CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::SpecialSymbol,enTypeConversion),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") + CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SpecialSymbol,enTypeConversion),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") { } CElementSpecialSymbol::~CElementSpecialSymbol() @@ -1276,7 +1276,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(L"\u0021"); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1285,15 +1285,15 @@ namespace StarMath } case TypeElement::interval: { - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); break; } case TypeElement::emptiness: { - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); - CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WritePreserveBlock(pXmlWrite,GetAttribute(),GetTypeConversion()); break; } case TypeElement::newline: @@ -1305,7 +1305,7 @@ namespace StarMath if(!m_wsType.empty()) { pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(m_wsType); pXmlWrite->WriteNodeEnd(L"m:t",false,false); @@ -1589,8 +1589,8 @@ namespace StarMath } } //class methods CElementSetOperations - CElementSetOperations::CElementSetOperations(const TypeElement &enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::SetOperations,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) + CElementSetOperations::CElementSetOperations(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::SetOperations,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeSet(enType) { } CElementSetOperations::~CElementSetOperations() @@ -1628,7 +1628,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r", false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeSet) { @@ -1716,8 +1716,8 @@ namespace StarMath return m_enTypeSet; } //class methods CElementConnection - CElementConnection::CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::Connection,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) + CElementConnection::CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Connection,enTypeConversion),m_pLeftArgument(nullptr), m_pRightArgument(nullptr),m_enTypeCon(enType) { } CElementConnection::~CElementConnection() @@ -1756,7 +1756,7 @@ namespace StarMath { CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArgument); pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); switch(m_enTypeCon) { @@ -1914,8 +1914,8 @@ namespace StarMath return m_enTypeCon; } //class methods CIndex - CElementIndex::CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion) - : CElement(TypeElement::Index,enTypeConversion),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) + CElementIndex::CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion) + : CElement(TypeElement::Index,enTypeConversion),m_pValueIndex(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_pLsubIndex(nullptr),m_pLsupIndex(nullptr),m_pCsubIndex(nullptr),m_pCsupIndex(nullptr),m_pLeftArg(nullptr),m_enTypeIndex(enType) { } CElementIndex::~CElementIndex() @@ -2058,7 +2058,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",1); pXmlWrite->WriteNodeEnd(L"",true,true); } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:radPr",false,false); if(m_pLeftArg != nullptr && m_enTypeIndex == TypeElement::nroot) { @@ -2080,12 +2080,12 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:limLow",false); pXmlWrite->WriteNodeBegin(L"m:limLowPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsubIndex->GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limLowPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); pXmlWrite->WriteNodeBegin(L"m:limUpp",false); pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,m_pCsupIndex->GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); ConversionOfIndicesToValue(pXmlWrite); @@ -2105,7 +2105,7 @@ namespace StarMath wsNameLim = L"m:limUpp"; pXmlWrite->WriteNodeBegin(wsNameLim,false); pXmlWrite->WriteNodeBegin(wsNameLim+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameLim+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); ConversionOfIndicesToValue(pXmlWrite); @@ -2150,7 +2150,7 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:sPre",false); pXmlWrite->WriteNodeBegin(L"m:sPrePr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:sPrePr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:sub",m_pLsubIndex,pXmlWrite); CConversionSMtoOOXML::WriteNodeConversion(L"m:sup",m_pLsupIndex,pXmlWrite); @@ -2175,7 +2175,7 @@ namespace StarMath wsNameNodeIndex = L"m:sSup"; pXmlWrite->WriteNodeBegin(wsNameNodeIndex,false); pXmlWrite->WriteNodeBegin(wsNameNodeIndex+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNodeIndex+L"Pr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); if(m_pUpperIndex!=nullptr && m_pLowerIndex != nullptr) @@ -2197,8 +2197,8 @@ namespace StarMath return m_enTypeIndex; } //class methods CElementFunction - CElementFunction::CElementFunction(const TypeElement &enType, const TypeConversion &enTypeConversion ,const std::wstring &wsNameFunc) - :CElement(TypeElement::Function,enTypeConversion), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) + CElementFunction::CElementFunction(const TypeElement &enType, const TypeConversion &enTypeConversion ,const std::wstring &wsNameFunc) + :CElement(TypeElement::Function,enTypeConversion), m_pValue(nullptr),m_pIndex(nullptr),m_enTypeFunction(enType) { switch (m_enTypeFunction) { case TypeElement::cos: @@ -2294,7 +2294,7 @@ namespace StarMath if(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) { m_pIndex = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc,pReader->GetTypeConversion()),m_pIndex); + CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc,pReader->GetTypeConversion()),m_pIndex); return ; } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -2312,7 +2312,7 @@ namespace StarMath else { pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:fName",false); pXmlWrite->WriteNodeBegin(L"m:r",false); pXmlWrite->WriteNodeBegin(L"m:rPr",false); @@ -2320,7 +2320,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",L"p"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"m:rPr",false,false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:t",false); if(!m_wsNameFunc.empty()) pXmlWrite->WriteString(m_wsNameFunc); @@ -2370,8 +2370,8 @@ namespace StarMath m_pValue->SetAttribute(pAttribute); } //class methods CElementOperation - CElementOperator::CElementOperator(const TypeElement &enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameOp) - :CElement(TypeElement::Operator,enTypeConversion), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) + CElementOperator::CElementOperator(const TypeElement &enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameOp) + :CElement(TypeElement::Operator,enTypeConversion), m_pValueFrom(nullptr), m_pValueTo(nullptr), m_pValueOperator(nullptr),m_pUpperIndex(nullptr),m_pLowerIndex(nullptr),m_enTypeOperator(enType),m_wsName(wsNameOp) { } CElementOperator::~CElementOperator() @@ -2476,7 +2476,7 @@ namespace StarMath if(m_enTypeOperator == TypeElement::lim || TypeElement::liminf == m_enTypeOperator || TypeElement::limsup == m_enTypeOperator || TypeElement::oper == m_enTypeOperator) { pXmlWrite->WriteNodeBegin(L"m:func",false); - CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:fName",false); if((m_pValueFrom != nullptr || m_pLowerIndex != nullptr) && (m_pValueTo == nullptr && m_pUpperIndex == nullptr)) CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); @@ -2486,7 +2486,7 @@ namespace StarMath { pXmlWrite->WriteNodeBegin(L"m:limUpp",false); pXmlWrite->WriteNodeBegin(L"m:limUppPr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); @@ -2500,7 +2500,7 @@ namespace StarMath pXmlWrite->WriteNodeEnd(L"m:limUpp",false,false); } else if(m_pValueFrom == nullptr && m_pValueTo == nullptr) - CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName(),GetTypeConversion()); + CConversionSMtoOOXML::WriteRPrFName(m_enTypeOperator,pXmlWrite,GetAttribute(),GetName(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:fName",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueOperator,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:func",false,false); @@ -2508,7 +2508,7 @@ namespace StarMath else { pXmlWrite->WriteNodeBegin(L"m:nary",false); - CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesNaryPr(m_enTypeOperator,(nullptr == m_pValueFrom && nullptr == m_pLowerIndex),(nullptr == m_pValueTo && nullptr == m_pUpperIndex),pXmlWrite,GetAttribute(),GetTypeConversion()); if(m_pValueFrom != nullptr && m_pLowerIndex != nullptr) { pXmlWrite->WriteNodeBegin(L"m:sub",false); @@ -2550,8 +2550,8 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } // class methods CStarMathReader - CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion) - : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true),m_enTypeCon(enTypeConversion) + CStarMathReader::CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion) + : m_enGlobalType(TypeElement::Empty),m_enUnderType(TypeElement::Empty),m_pAttribute(nullptr),m_bMarkForUnar(true),m_enTypeCon(enTypeConversion) { m_itStart = itStart; m_itEnd = itEnd; @@ -2561,7 +2561,7 @@ namespace StarMath delete m_pAttribute; } //TODO :: ParseColor and ParseFont - bool CStarMathReader::GetToken() + bool CStarMathReader::GetToken() { if(CheckIteratorPosition()) { @@ -2592,10 +2592,9 @@ namespace StarMath m_pAttribute = nullptr; if(m_wsToken == L"left") m_wsToken = GetElement(); else if(L"right" == m_wsToken ) m_wsToken = GetElement(); - - return true; + return true; } - return false; + return false; } void CStarMathReader::SetTypesToken() { @@ -2830,11 +2829,11 @@ namespace StarMath while(CheckIteratorPosition()) { itStartBracketClose = m_itStart; - bool res = GetToken(); - if (false == res) - { - break; - } + bool res = GetToken(); + if (false == res) + { + break; + } if(CElementBracket::GetBracketOpen(m_wsToken) != TypeElement::undefine) { inBracketInside +=1; @@ -2862,8 +2861,8 @@ namespace StarMath } while(TypeElement::undefine == CElementBracket::GetBracketClose(GetString()) && CheckIteratorPosition()) { - if (false == GetToken()) - break; + if (false == GetToken()) + break; } ClearReader(); } @@ -2871,12 +2870,12 @@ namespace StarMath { if(m_wsToken.empty()) { - if (GetToken()) - SetTypesToken(); - else - { - ClearReader(); - } + if (GetToken()) + SetTypesToken(); + else + { + ClearReader(); + } } } bool CStarMathReader::CheckTokenForGetElement(const wchar_t &cToken) @@ -2919,17 +2918,17 @@ namespace StarMath { return m_bMarkForUnar; } - void CStarMathReader::SetTypeConversion(const TypeConversion &enTypeCon) - { - m_enTypeCon = enTypeCon; - } - TypeConversion CStarMathReader::GetTypeConversion() - { - return m_enTypeCon; - } + void CStarMathReader::SetTypeConversion(const TypeConversion &enTypeCon) + { + m_enTypeCon = enTypeCon; + } + TypeConversion CStarMathReader::GetTypeConversion() + { + return m_enTypeCon; + } //class methods CElementBracketWithIndex - CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::BracketWithIndex,enTypeConversion),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) + CElementBracketWithIndex::CElementBracketWithIndex(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::BracketWithIndex,enTypeConversion),m_pLeftArg(nullptr), m_pValue(nullptr),m_enTypeBracketWithIndex(enType) { } CElementBracketWithIndex::~CElementBracketWithIndex() @@ -2973,7 +2972,7 @@ namespace StarMath } pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); pXmlWrite->WriteNodeBegin(L"m:groupChr",false); @@ -2990,7 +2989,7 @@ namespace StarMath pXmlWrite->WriteAttribute(L"m:val",L"bot"); pXmlWrite->WriteNodeEnd(L"w",true,true); } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); switch(m_enTypeBracketWithIndex) @@ -3041,8 +3040,8 @@ namespace StarMath return m_enTypeBracketWithIndex; } //class methods CElementGrade - CElementGrade::CElementGrade(const TypeConversion &enTypeConversion) - :CElement(TypeElement::Grade,enTypeConversion),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) + CElementGrade::CElementGrade(const TypeConversion &enTypeConversion) + :CElement(TypeElement::Grade,enTypeConversion),m_pValueGrade(nullptr), m_pValueFrom(nullptr), m_pValueTo(nullptr) { } CElementGrade::~CElementGrade() @@ -3085,7 +3084,7 @@ namespace StarMath { if(m_pValueFrom == nullptr && m_pValueTo == nullptr) { - CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); } else { @@ -3105,11 +3104,11 @@ namespace StarMath pXmlWrite->WriteNodeBegin(wsNodeGrade,false); pXmlWrite->WriteNodeBegin(wsNodeGrade + L"Pr",false); pXmlWrite->WriteNodeBegin(L"m:ctrlPr",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); pXmlWrite->WriteNodeEnd(wsNodeGrade + L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); + CConversionSMtoOOXML::NodeGrade(pXmlWrite,m_pValueGrade,GetAttribute()); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(m_pValueFrom != nullptr) { @@ -3138,8 +3137,8 @@ namespace StarMath m_pValueTo->SetAttribute(pAttribute); } //class methods CElementMatrix - CElementMatrix::CElementMatrix(const TypeElement &enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::Matrix,enTypeConversion), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) + CElementMatrix::CElementMatrix(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Matrix,enTypeConversion), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) { } CElementMatrix::~CElementMatrix() @@ -3179,7 +3178,7 @@ namespace StarMath void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { pXmlWrite->WriteNodeBegin(L"m:m",false); - CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:mr",false); switch(m_enTypeMatrix) { @@ -3243,8 +3242,8 @@ namespace StarMath m_pSecondArgument->SetAttribute(pAttribute); } //class CElementDiacriticalMark - CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::Mark,enTypeConversion),m_pValueMark(nullptr),m_enTypeMark(enType) + CElementDiacriticalMark::CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Mark,enTypeConversion),m_pValueMark(nullptr),m_enTypeMark(enType) { } CElementDiacriticalMark::~CElementDiacriticalMark() @@ -3277,7 +3276,7 @@ namespace StarMath else if(L"wideharpoon" == wsToken) return TypeElement::wideharpoon; else if(L"widehat" == wsToken) return TypeElement::widehat; else if(L"underline" == wsToken) return TypeElement::underline; - else return TypeElement::undefine; + else return TypeElement::undefine; } void CElementDiacriticalMark::Parse(CStarMathReader *pReader) { @@ -3359,7 +3358,7 @@ namespace StarMath break; } } - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:accPr",false,false); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValueMark,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:acc",false,false); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 2a67a439dc5..0d32026c907 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -71,7 +71,7 @@ namespace StarMath const std::wstring& GetFontName(); bool EmptyColor(); bool ParseFontAttribute(const TypeElement& enTypeFont,CStarMathReader* pReader); - bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); + bool ParseColorAttribute(const std::wstring& wsToken,CStarMathReader* pReader); void SetSize(const unsigned int& iSize); void SetAlignment(const unsigned int& iAlignment); void SetBold(); From eb1bc2779bea991336f5cd2c05075983a20b978d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 24 Apr 2024 18:35:38 +0600 Subject: [PATCH 567/794] Fix formula types conversion --- .../Logic/Biff_structures/CFParsedFormula.cpp | 5 + .../Format/Logic/Biff_structures/PtgFunc.cpp | 4 + .../Format/Logic/Biff_structures/PtgFunc.h | 2 + .../Logic/Biff_structures/PtgFuncVar.cpp | 5 + .../Format/Logic/Biff_structures/PtgFuncVar.h | 2 + .../Logic/Biff_structures/StringPtgParser.cpp | 111 ++++++++++++++++-- .../Logic/Biff_structures/StringPtgParser.h | 1 + OOXML/XlsxFormat/Worksheets/SheetData.cpp | 15 ++- 8 files changed, 131 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp index c64c045e87d..b9074b5586e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormula.cpp @@ -43,6 +43,11 @@ CFParsedFormula::CFParsedFormula(const CellRef& cell_base_ref) : ParsedFormula(c CFParsedFormula& CFParsedFormula::operator=(const std::wstring& value) { parseStringFormula(value, L"CFParsedFormulaNoCCE"); + auto ptgType = GETBITS(rgce.sequence.back()->getPtgId(),5,6); + if(ptgType == 1) + { + SETBITS(rgce.sequence.back()->ptg_id.get(),5,6,2); + } return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp index ae940a2ec07..336b550962b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.cpp @@ -103,6 +103,10 @@ const int PtgFunc::getParametersNum() const return iftab.getParamsNum(); } +const unsigned short PtgFunc::getFuncIndex() const +{ + return iftab.getIndex(); +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h index 88762941bba..5bf52a2e646 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFunc.h @@ -57,6 +57,8 @@ class PtgFunc : public OperandPtg const int getParametersNum() const; + const unsigned short getFuncIndex() const; + static const unsigned short fixed_id = 0x01; private: Ftab_Cetab iftab; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp index 7e968497318..06211778517 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp @@ -154,6 +154,11 @@ const bool PtgFuncVar::getFCeFunc() return fCeFunc; } +const unsigned short PtgFuncVar::getFuncIndex() const +{ + return tab.getIndex(); +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h index 268f9046238..b349e8d251d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h @@ -62,6 +62,8 @@ class PtgFuncVar : public OperandPtg const bool getFCeFunc(); + const unsigned short getFuncIndex() const; + static const unsigned short fixed_id = 0x02; private: unsigned char cparams; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 77ad8ffd46f..0776da1e2a3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -363,11 +363,11 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { if(L"SharedParsedFormula" == tag_name || L"CFParsedFormulaNoCCE" == tag_name) { - found_operand = OperandPtgPtr(new PtgRefN(operand_str, OperandPtg::ptg_VALUE, rgce.getLocation())); + found_operand = OperandPtgPtr(new PtgRefN(operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation())); } else { - found_operand = OperandPtgPtr(new PtgRef(operand_str, OperandPtg::ptg_VALUE)); + found_operand = OperandPtgPtr(new PtgRef(operand_str, OperandPtg::ptg_REFERENCE)); } rgce.addPtg(found_operand); } @@ -436,7 +436,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R return false; } } - //parsePtgTypes(rgce); + parsePtgTypes(rgce); return true; } @@ -461,8 +461,10 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) { auto funcPtr = dynamic_cast(i.get()); auto paramsNum = funcPtr->getParametersNum(); - for(auto j = 0; j < paramsNum; j++) - { + auto refArgs = PosValArgs(funcPtr->getFuncIndex()); + for(auto j = paramsNum-1; j >= 0; j--) + { if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back()->ptg_id.get(), 3); functionStack.pop_back(); } ///check and change fixed num of args @@ -471,8 +473,11 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) { auto funcPtr = dynamic_cast(i.get()); auto paramsNum = funcPtr->getParamsNum(); - for(auto j = 0; j < paramsNum; j++) + auto refArgs = PosValArgs(funcPtr->getFuncIndex()); + for(auto j = paramsNum-1; j >= 0; j--) { + if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back()->ptg_id.get(), 3); functionStack.pop_back(); } } @@ -480,9 +485,9 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) } else if(ptgId > 1 && ptgId < 15) { - SetPtgType(functionStack.back()->ptg_id.get(), 2); + SetPtgType(functionStack.back()->ptg_id.get(), 3); functionStack.pop_back(); - SetPtgType(functionStack.back()->ptg_id.get(), 2); + SetPtgType(functionStack.back()->ptg_id.get(), 3); } else if(ptgId > 14 && ptgId < 18) { @@ -492,7 +497,7 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) } else if(ptgId > 17 && ptgId < 21) { - SetPtgType(functionStack.back()->ptg_id.get(), 2); + SetPtgType(functionStack.back()->ptg_id.get(), 3); } else if(ptgId == 21) { @@ -504,10 +509,94 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) } } - auto exit = 1; - exit++; } +std::vector StringPtgParser::PosValArgs(const unsigned int &index) const +{ + std::vector argVector; + switch(index) + { + case 0x0001: case 0x0002: case 0x0003: case 0x000F: case 0x000B: + case 0x0010: case 0x0011: case 0x0012: case 0x0014: case 0x0015: case 0x0016: case 0x0017: case 0x0018: case 0x001A: case 0x001C: + case 0x0020: case 0x0021: case 0x0026: case 0x0036: + case 0x0040: case 0x0043: case 0x0044: case 0x0045: case 0x0047: case 0x0048: case 0x0049: case 0x004F: + case 0x0051: case 0x0053: case 0x0054: case 0x0056: case 0x0057: case 0x0058: + case 0x0060: case 0x0062: case 0x0063: case 0x0064: case 0x006F: + case 0x0070: case 0x0071: case 0x0072: case 0x0076: case 0x0079: case 0x007B:case 0x007D: case 0x007E:case 0x007F: + case 0x0080: case 0x0081: case 0x0085: case 0x0086: case 0x0087: case 0x008C: case 0x008D: + case 0x0096: case 0x0097: case 0x009D: + case 0x00A2: case 0x00A3: case 0x00A4: case 0x00AC: + case 0x00B1: case 0x00B3: case 0x00B4: case 0x00B5: case 0x00B8: case 0x00B9: case 0x00BA: case 0x00BE: + case 0x00C0: case 0x00C6: case 0x00C8: case 0x00C9: + case 0x00D6: case 0x00D7: + case 0x00E0: case 0x00E2: case 0x00E5: case 0x00E6: case 0x00E7: case 0x00E8: case 0x00E9: case 0x00EA: case 0x00ED: + case 0x00F4: case 0x00F8: case 0x00FB: case 0x00FE: + case 0x0100: case 0x0101: case 0x0105: case 0x0106: case 0x0107: case 0x010F: + case 0x0117: case 0x011B: case 0x011C: + case 0x0126: case 0x0128: case 0x012A: + case 0x0156: case 0x0157: case 0x0158: + case 0x0160: + case 0x0170: case 0x0171: case 0x0172: case 0x0173: case 0x0174: case 0x0175: case 0x0176: case 0x0177: case 0x0178: case 0x0179: case 0x017A: case 0x017C: + case 0x01DF: + case 0x01E0: + argVector.push_back(true); + break; + case 0x000D: case 0x001B: case 0x001E: case 0x0027: case 0x0030: case 0x0046: case 0x005B: case 0x005D: + case 0x0061: case 0x0067: case 0x006B: case 0x006D: case 0x0073: case 0x0074: case 0x0075: + case 0x0084: case 0x0088: case 0x0089: case 0x008A: case 0x008B: case 0x0093: case 0x0094: case 0x00A5: case 0x00AF: + case 0x00B0: case 0x00B2: case 0x00BB: case 0x00BC: case 0x00C5: case 0x00CC: + case 0x00D0: case 0x00D1: case 0x00D4: case 0x00D5: case 0x00EF: case 0x00FD: case 0x0102: case 0x0108: case 0x010C: + case 0x0112: case 0x0113: case 0x0114: case 0x011D: case 0x0120: case 0x012B: case 0x012F: + case 0x0130: case 0x0131: case 0x0132: case 0x0133: case 0x0134: case 0x0136: case 0x0137: case 0x013A: case 0x013B: + case 0x014C: case 0x0151: case 0x0153: case 0x015C: case 0x0161: case 0x0162: case 0x0165: case 0x0167: + argVector.push_back(true); + argVector.push_back(true); + break; + case 0x000E: case 0x001F: case 0x0041: case 0x0042: case 0x0052: case 0x007A: case 0x007C: case 0x008E: case 0x0091: + case 0x009E: case 0x00A0: case 0x00CD: case 0x00CE: case 0x00D2: case 0x00D3: case 0x00DC: case 0x0103: case 0x0104: + case 0x0109: case 0x010A: case 0x010B: case 0x0115: case 0x0116: case 0x0118: case 0x0119: case 0x011A: case 0x011F: + case 0x0122: case 0x0123: case 0x0124: case 0x0127: case 0x0129: case 0x012C: case 0x012D: + case 0x0135: case 0x014F: case 0x0154: case 0x015F: case 0x017E: + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + break; + case 0x006E: case 0x0077: case 0x0078: case 0x008F: case 0x009F: case 0x00AB: case 0x00B6: case 0x00CF: case 0x00F2: case 0x00F3: + case 0x0111: case 0x011E: case 0x0121: case 0x0125: case 0x012E: case 0x013C: case 0x013D: case 0x014E: case 0x0155: case 0x015E: + case 0x0163: case 0x017F: case 0x01DD: + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + break; + case 0x0038: case 0x0039: case 0x003A: case 0x003B: case 0x0090: case 0x009A: case 0x009B: case 0x009C: case 0x00DB: + case 0x00F6: case 0x00F7: case 0x010E: case 0x0110: case 0x0164: + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + break; + case 0x001D: + argVector.push_back(false); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + case 0x0159: case 0x0145: case 0x0146: case 0x0147: case 0x0148: + argVector.push_back(false); + argVector.push_back(true); + break; + case 0x0066: case 0x0065: + argVector.push_back(true); + argVector.push_back(false); + argVector.push_back(false); + argVector.push_back(true); + break; + default: + break; + } + return argVector; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h index 09adfdbc5eb..190d78c5763 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.h @@ -46,6 +46,7 @@ class StringPtgParser private: const void parsePtgTypes(Rgce& rgce); + std::vector PosValArgs(const unsigned int &index)const; PtgStack ptg_stack; }; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 08be4c93059..9eed8a6d500 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1121,7 +1121,12 @@ namespace OOX { auto formula = dynamic_cast(obj.get()); formula->formula = m_sText; - + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1) + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared: @@ -1143,8 +1148,12 @@ namespace OOX } if(m_oRef.IsInit()) formula->rfx = m_oRef.get(); - - + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1) + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: From 0f9b8f14e6581673937d1f0593521cb7ef678db0 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 24 Apr 2024 22:19:35 +0500 Subject: [PATCH 568/794] Fix bug #61378 --- .../Reader/Converter/pptx_text_context.cpp | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index 7d32a3fc8b8..645683a59c0 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -134,6 +134,7 @@ class pptx_text_context::Impl: boost::noncopyable std::wstring last_paragraph_style_name_; std::wstring paragraph_style_name_; std::wstring span_style_name_; + std::wstring base_style_name_; odf_types::style_family::type base_style_family_;//Presentation Or SpreadSheet @@ -220,14 +221,13 @@ void pptx_text_context::Impl::start_span(const std::wstring & styleName)//кус { int text_size = text_.str().length(); - if ((span_style_name_ !=styleName && text_size > 0) || in_span) + if ((span_style_name_ != styleName && text_size > 0) || in_span) { dump_run(); } span_style_name_ = styleName; - - in_span=true; + in_span = true; } void pptx_text_context::Impl::end_span() @@ -451,12 +451,10 @@ void pptx_text_context::Impl::write_rPr(std::wostream & strm) text_properties_.pptx_convert(pptx_context_); - strm << get_styles_context().text_style().str(); - - if (text_properties_.fo_font_size_) + if (text_properties_.fo_font_size_ && text_properties_.fo_font_size_->get_type() == odf_types::font_size::Length) last_run_font_size_ = text_properties_.fo_font_size_->get_length(); - else - last_run_font_size_ = boost::none; + + strm << get_styles_context().text_style().str(); } std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { @@ -481,10 +479,18 @@ std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) CP_XML_NODE(L"a:endParaRPr") { - if(last_run_font_size_ && false) + odf_reader::paragraph_format_properties parap_props; + ApplyParagraphProperties(paragraph_style_name_, parap_props, false); + + if (last_run_font_size_ && !parap_props.fo_margin_top_) { - CP_XML_ATTR(L"sz", last_run_font_size_->get_value_unit(odf_types::length::pt) * 100); + int sz = last_run_font_size_->get_value_unit(odf_types::length::pt) * 100; + + CP_XML_ATTR(L"sz", sz); + } + + last_run_font_size_ = boost::none; } } } @@ -587,7 +593,7 @@ void pptx_text_context::Impl::dump_run() const std::wstring content = XmlUtils::EncodeXmlString(text_.str()); //if (content.length() <1 && span_style_name_.length()<1) return ; ... провеить с пустыми строками нужны ли ... - if (content .length() > 0) + if (content.length() > 0) { CP_XML_WRITER(run_) { @@ -604,6 +610,15 @@ void pptx_text_context::Impl::dump_run() text_.str(std::wstring()); } } + else + { + odf_reader::text_format_properties text_properties_; + ApplyTextProperties(span_style_name_, paragraph_style_name_, text_properties_); + + if (text_properties_.fo_font_size_ && text_properties_.fo_font_size_->get_type() == odf_types::font_size::Length) + last_run_font_size_ = text_properties_.fo_font_size_->get_length(); + } + hyperlink_hId =L""; } From 66d8690dc3d1b845b37f022f8cc2565530e2553b Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 25 Apr 2024 12:08:44 +0300 Subject: [PATCH 569/794] Fix bug 66872 --- DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp | 6 +++++- DesktopEditor/fontengine/TextShaper.cpp | 6 ++++++ DesktopEditor/fontengine/TextShaper.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp index 269a6b9e3b2..76ceb51259a 100644 --- a/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/TextMeasurerEmbed.cpp @@ -134,7 +134,11 @@ JSSmart CTextMeasurerEmbed::FT_Get_Glyph_Render_Params(JSSmart CTextMeasurerEmbed::FT_Get_Glyph_Render_Buffer(JSSmart face, JSSmart size) { void* Data = NSShaper::FT_Get_Glyph_Render_Buffer(RAW_POINTER(face)); - return CJSContext::createUint8Array((unsigned char*)Data, size->toInt32(), true); + int nSize = size->toInt32(); + int nSizeMax = NSShaper::FT_Get_Glyph_Render_BufferSize(RAW_POINTER(face)); + if (nSize > nSizeMax) + nSize = nSizeMax; + return CJSContext::createUint8Array((unsigned char*)Data, nSize, true); } JSSmart CTextMeasurerEmbed::FT_Set_Transform(JSSmart face, JSSmart xx, JSSmart yx, JSSmart xy, JSSmart yy) diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 8b88c0ca4ea..4e509d5cc81 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -356,6 +356,12 @@ namespace NSShaper return ((FT_Face)face)->glyph->bitmap.buffer; } + int FT_Get_Glyph_Render_BufferSize(void* face) + { + FT_GlyphSlot slot = ((FT_Face)face)->glyph; + return slot->bitmap.pitch * slot->bitmap.rows; + } + bool FT_Get_Glyph_Render_Params(void* face, int render_mode, CExternalPointer* result) { FT_GlyphSlot slot = ((FT_Face)face)->glyph; diff --git a/DesktopEditor/fontengine/TextShaper.h b/DesktopEditor/fontengine/TextShaper.h index 7a862f283ba..286505700bf 100644 --- a/DesktopEditor/fontengine/TextShaper.h +++ b/DesktopEditor/fontengine/TextShaper.h @@ -70,6 +70,7 @@ namespace NSShaper GRAPHICS_DECL bool FT_Get_Glyph_Render_Params(void* face, int render_mode, CExternalPointer* result); GRAPHICS_DECL unsigned char* FT_Get_Glyph_Render_Buffer(void* face); + GRAPHICS_DECL int FT_Get_Glyph_Render_BufferSize(void* face); GRAPHICS_DECL void FT_Glyph_Get_CBox(void* glyph, unsigned int bbox_mode, CExternalPointer* result); From 3c2f4874fc0ad23312454db1924675545da2201b Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 25 Apr 2024 16:15:48 +0300 Subject: [PATCH 570/794] Fix bug #63701 --- HtmlFile2/htmlfile2.cpp | 149 +++++++++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 48 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 298c4d7eb53..f4116346bb5 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -35,7 +35,7 @@ #define VALUE2STR(x) VALUE_TO_STRING(x) #endif -#define MAXCOLUMNSINTABLE 64 +#define MAXCOLUMNSINTABLE 63 #define MAXROWSINTABLE 32767 #define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips @@ -216,6 +216,11 @@ class CTableCell m_oData.SetText(oCell.m_oData.GetData()); } + bool Empty() + { + return 0 == m_oData.GetCurSize(); + } + CTableCell* Copy() { return new CTableCell(*this); @@ -228,8 +233,6 @@ class CTableCell if (NULL != pStyle) pCell->m_oStyles = *pStyle; - pCell->m_oData.SetText(L""); - return pCell; } @@ -434,9 +437,66 @@ class CTableRow return; if (nPosition < 0) + { + std::vector::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty(); }); + + if (m_arCells.end() != itFoundEmpty) + { + --m_oStyles.m_unMaxIndex; + delete *itFoundEmpty; + *itFoundEmpty = pCell; + + if (1 != pCell->GetColspan()) + { + UINT unColspan = pCell->GetColspan() - 1; + + while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0) + { + --m_oStyles.m_unMaxIndex; + --unColspan; + delete (*itFoundEmpty); + itFoundEmpty = m_arCells.erase(itFoundEmpty); + } + + if (unColspan != 0) + pCell->SetColspan(pCell->GetColspan() - unColspan, MAXCOLUMNSINTABLE); + } + } + else + m_arCells.push_back(pCell); + } + else if (nPosition >= m_arCells.size()) + { + const UINT unMissingCount = nPosition - m_arCells.size(); + + for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex) + m_arCells.push_back(CTableCell::CreateEmpty()); + + m_oStyles.m_unMaxIndex += unMissingCount; + m_arCells.push_back(pCell); - else if (nPosition > m_arCells.size()) - m_arCells.push_back(pCell); + } + else if (m_arCells[nPosition]->Empty()) + { + delete m_arCells[nPosition]; + --m_oStyles.m_unMaxIndex; + m_arCells[nPosition++] = pCell; + + if (1 != pCell->GetColspan()) + { + UINT unDeleteCount = pCell->GetColspan() - 1; + while (m_arCells[nPosition]->Empty() && nPosition < m_arCells.size() && unDeleteCount > 0) + { + delete m_arCells[nPosition]; + --m_oStyles.m_unMaxIndex; + m_arCells.erase(m_arCells.begin() + nPosition); + --unDeleteCount; + } + + if (0 != unDeleteCount) + pCell->SetColspan(pCell->GetColspan() - unDeleteCount, MAXCOLUMNSINTABLE); + } + } else m_arCells.insert(m_arCells.begin() + nPosition, pCell); @@ -456,19 +516,6 @@ class CTableRow return m_arCells.size(); } - bool ColumnsOverflowing() const - { - return MAXCOLUMNSINTABLE == m_oStyles.m_unMaxIndex; - } - - void RecalculateMaxIndex() - { - m_oStyles.m_unMaxIndex = 0; - - for (const CTableCell* pCell : m_arCells) - m_oStyles.m_unMaxIndex += pCell->GetColspan(); - } - std::wstring ConvertToOOXML(const TTableStyles& oTableStyles) { if (m_arCells.empty()) @@ -619,24 +666,6 @@ class CTable return unMaxColumns; } - void ApplyRowspan() - { - CTableCell* pCell = NULL; - for (UINT unRowIndex = 0; unRowIndex < m_arRows.size(); ++unRowIndex) - { - for (UINT unColumnIndex = 0; unColumnIndex < m_arRows[unRowIndex]->GetCount(); ++unColumnIndex) - { - pCell = (*m_arRows[unRowIndex])[unColumnIndex]; - - if (1 != pCell->GetRowspan()) - { - for (UINT unIndex = unRowIndex + 1; unIndex < std::min((UINT)m_arRows.size(), unRowIndex + pCell->GetRowspan()); ++unIndex) - (*m_arRows[unIndex]).InsertCell(CTableCell::CreateEmpty(pCell->GetColspan(), true, pCell->GetStyles()), unColumnIndex); - } - } - } - } - void Shorten() { UINT unIndex = 0; @@ -694,19 +723,12 @@ class CTable UINT unMaxIndex = 0; for (CTableRow* pRow : m_arRows) - { - pRow->RecalculateMaxIndex(); unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); - } - UINT unMissingCount = 0; - for (CTableRow* pRow : m_arRows) { - unMissingCount = unMaxIndex - pRow->GetIndex(); - - for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex) - pRow->AddCell(CTableCell::CreateEmpty()); + for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex) + pRow->InsertCell(CTableCell::CreateEmpty(), unIndex); } } @@ -2117,9 +2139,22 @@ class CHtmlFile2_Private sSelectors.pop_back(); return; } + + struct TRowspanElement + { + UINT m_unRowSpan; + UINT m_unColumnIndex; + const CTableCell* m_pCell; + + TRowspanElement(UINT unRowSpan, UINT unColumnIndex, const CTableCell* pCell) + : m_unRowSpan(unRowSpan), m_unColumnIndex(unColumnIndex), m_pCell(pCell) + {} + }; void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, ERowParseMode eMode) { + std::vector arRowspanElements; + int nDeath = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nDeath)) { @@ -2130,6 +2165,18 @@ class CHtmlFile2_Private CTableRow *pRow = new CTableRow(); + for (std::vector::iterator itElement = arRowspanElements.begin(); itElement < arRowspanElements.end();) + { + pRow->InsertCell(CTableCell::CreateEmpty(itElement->m_pCell->GetColspan(), true, itElement->m_pCell->GetStyles()), itElement->m_unColumnIndex); + + itElement->m_unRowSpan--; + if (1 == itElement->m_unRowSpan) + itElement = arRowspanElements.erase(itElement); + else + ++itElement; + } + + UINT unColumnIndex = 0; int nTrDepth = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nTrDepth)) { @@ -2145,7 +2192,12 @@ class CHtmlFile2_Private if(m_oLightReader.GetName() == L"colspan") pCell->SetColspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1), pRow->GetIndex()); else if(m_oLightReader.GetName() == L"rowspan") + { pCell->SetRowspan(NSStringFinder::ToInt(m_oLightReader.GetText(), 1)); + + if (1 != pCell->GetRowspan()) + arRowspanElements.push_back({pCell->GetRowspan(), unColumnIndex, pCell}); + } } m_oLightReader.MoveToElement(); @@ -2166,7 +2218,7 @@ class CHtmlFile2_Private else if(m_oLightReader.GetName() == L"td") readStream(pCell->GetData(), sSelectors, oTS, true); - if (pRow->ColumnsOverflowing()) + if (pRow->GetIndex() == MAXCOLUMNSINTABLE - 1) { CTextSettings oTrTS{oTS}; oTrTS.bMergeText = true; @@ -2186,7 +2238,9 @@ class CHtmlFile2_Private sSelectors.pop_back(); - if (pRow->ColumnsOverflowing()) + ++unColumnIndex; + + if (pRow->GetIndex() == MAXCOLUMNSINTABLE) break; } @@ -2254,7 +2308,6 @@ class CHtmlFile2_Private sSelectors.pop_back(); } - oTable.ApplyRowspan(); oTable.Shorten(); oTable.CompleteTable(); oXml->WriteString(oTable.ConvertToOOXML()); From 2fa4cdebb9266a1626fd8f07f3bf2b97ab450a47 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 25 Apr 2024 21:35:11 +0600 Subject: [PATCH 571/794] Fix table conversion --- .../Logic/Biff_structures/StringPtgParser.cpp | 31 +++++++++++-------- .../Logic/Biff_structures/SyntaxPtg.cpp | 2 ++ OOXML/XlsxFormat/Worksheets/SheetData.cpp | 18 ++++++++++- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 0776da1e2a3..980924d3fc1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -342,9 +342,6 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } else if (SyntaxPtg::extract_PtgList(it, itEnd, ptgList))// Shall be placed strongly before PtgArea and PtgRef { - if((ptgList.rowType == 0x10 || ptgList.rowType == 0x08 || ptgList.rowType == 0x02) - && ptgList.columns == 0x01) - ptgList.type_ = 0x01; rgce.addPtg(found_operand = OperandPtgPtr(new PtgList(ptgList))); } else if(SyntaxPtg::extract_PtgArea(it, itEnd, operand_str)) // Sequence is important (in pair with PtgRef) @@ -440,11 +437,19 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R return true; } -void SetPtgType(unsigned short &ptgId, const char type) +void SetPtgType(PtgPtr ptg, const char type) { - if(ptgId > 31) - SETBITS(ptgId,5,6,type); + if(ptg->ptg_id.get() > 0x1F && ptg->ptg_id.get() <= 0x7D ) + { + SETBITS(ptg->ptg_id.get(),5,6,type); + } + else if(ptg->ptg_id.get() == 0x1918) + { + auto list = static_cast(ptg.get()); + list->type_ = type - 1; + } } + const void StringPtgParser::parsePtgTypes(Rgce& rgce) { PtgVector functionStack; @@ -464,7 +469,7 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) auto refArgs = PosValArgs(funcPtr->getFuncIndex()); for(auto j = paramsNum-1; j >= 0; j--) { if(refArgs.size() > j && refArgs.at(j)) - SetPtgType(functionStack.back()->ptg_id.get(), 3); + SetPtgType(functionStack.back(), 3); functionStack.pop_back(); } ///check and change fixed num of args @@ -477,7 +482,7 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) for(auto j = paramsNum-1; j >= 0; j--) { if(refArgs.size() > j && refArgs.at(j)) - SetPtgType(functionStack.back()->ptg_id.get(), 3); + SetPtgType(functionStack.back(), 3); functionStack.pop_back(); } } @@ -485,19 +490,19 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) } else if(ptgId > 1 && ptgId < 15) { - SetPtgType(functionStack.back()->ptg_id.get(), 3); + SetPtgType(functionStack.back(), 3); functionStack.pop_back(); - SetPtgType(functionStack.back()->ptg_id.get(), 3); + SetPtgType(functionStack.back(), 3); } else if(ptgId > 14 && ptgId < 18) { - SetPtgType(functionStack.back()->ptg_id.get(), 1); + SetPtgType(functionStack.back(), 1); functionStack.pop_back(); - SetPtgType(functionStack.back()->ptg_id.get(), 1); + SetPtgType(functionStack.back(), 1); } else if(ptgId > 17 && ptgId < 21) { - SetPtgType(functionStack.back()->ptg_id.get(), 3); + SetPtgType(functionStack.back(), 3); } else if(ptgId == 21) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index f24f5e7ad22..fe99f26850d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -629,12 +629,14 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: else if(boost::regex_search(first, last, results_1, reg_inside_table4)) { _UINT16 indexColumn = -1; + ptgList.rowType = 0x00; auto insider = boost::algorithm::erase_all_copy(results_1.str(0), L"\n"); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { ptgList.columns = 0x01; ptgList.colFirst = indexColumn; + ptgList.colLast = ptgList.colFirst; first = results_1[0].second; return true; } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 9eed8a6d500..d0da1cf9dd9 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -66,6 +66,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraCol.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.h" #include #include @@ -1124,8 +1125,15 @@ namespace OOX if(!formula->formula.rgce.sequence.empty()) { auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); - if(lastValType == 1) + if(lastValType == 1 || lastValType == 3) + { SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } } } break; @@ -1152,7 +1160,15 @@ namespace OOX { auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); if(lastValType == 1) + { SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } } break; From 051a1fa7ef6492e2716e5ebc80e3a3f330fbc9b8 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 26 Apr 2024 12:47:51 +0300 Subject: [PATCH 572/794] Fix bug 67444 --- DesktopEditor/graphics/IRenderer.h | 1 + DocxRenderer/DocxRenderer.cpp | 17 +++++++++++++ DocxRenderer/src/logic/Page.cpp | 7 +++++- PdfFile/SrcReader/RendererOutputDev.cpp | 33 ++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 2d333cfc161..d4493f997e2 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -113,6 +113,7 @@ const long c_nFlipNextRotate = 0x0004; const long c_nDarkMode = 0x0008; const long c_nUseDictionaryFonts = 0x0010; const long c_nPenWidth0As1px = 0x0020; +const long c_nSupportPathTextAsText = 0x0040; // типы рендерера const long c_nUnknownRenderer = 0x0000; diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index a3c22eceaae..65457fb0fbf 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -35,6 +35,7 @@ #include "../OfficeUtils/src/OfficeUtils.h" #include "src/logic/Document.h" #include "../DesktopEditor/graphics/commands/DocInfo.h" +#include class CDocxRenderer_Private { @@ -644,6 +645,22 @@ HRESULT CDocxRenderer::put_ClipMode(const LONG& lMode) //---------------------------------------------------------------------------------------- HRESULT CDocxRenderer::CommandLong(const LONG& lType, const LONG& lCommand) { + if (c_nSupportPathTextAsText == lType) + { + NSStructures::CBrush* pBrush = &m_pInternal->m_oDocument.m_oBrush; + if (c_BrushTypeSolid != pBrush->Type) + return S_FALSE; + + NSStructures::CPen* pPen = &m_pInternal->m_oDocument.m_oPen; + if (pBrush->Color1 != pPen->Color || pBrush->Alpha1 != pPen->Alpha) + return S_FALSE; + + Aggplus::CMatrix* pTransform = &m_pInternal->m_oDocument.m_oTransform; + if (std::abs(pTransform->z_Rotation()) > 1.0 || pTransform->sx() < 0 || pTransform->sy() < 0) + return S_FALSE; + + return S_OK; + } return S_OK; } HRESULT CDocxRenderer::CommandDouble(const LONG& lType, const double& dCommand) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 5ea2118369c..39ebf05f04f 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -342,6 +342,11 @@ namespace NSDocxRenderer auto oMetrics = m_pFontManager->GetFontMetrics(); auto oParams = m_pFontManager->GetFontSelectParams(); + // use forced fold option + bool bForcedBold = oParams.bDefaultBold; + if (m_lCurrentCommand == c_nStrokeTextType && m_pFont->Bold) + bForcedBold = true; + m_pFontSelector->SelectFont(oParams, oMetrics, oText); _h = m_pFontManager->GetFontHeight(); @@ -368,7 +373,7 @@ namespace NSDocxRenderer m_pFontSelector->GetSelectedName(), m_pFont->Size, m_pFontSelector->IsSelectedItalic(), - m_pFontSelector->IsSelectedBold()); + m_pFontSelector->IsSelectedBold() || bForcedBold); pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 130ac7659b5..29ebe5029b0 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -4110,7 +4110,38 @@ namespace PdfReader m_pRenderer->put_FontPath(sFontPath); } - if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) + LONG lRendererType = 0; + m_pRenderer->get_Type(&lRendererType); + + bool bIsEmulateBold = false; + if (c_nDocxWriter == lRendererType && 2 == nRenderMode) + bIsEmulateBold = (S_OK == m_pRenderer->CommandLong(c_nSupportPathTextAsText, 0)) ? true : false; + + if (bIsEmulateBold) + { + m_pRenderer->BeginCommand(c_nStrokeTextType); + + LONG lOldStyle = 0; + m_pRenderer->get_FontStyle(&lOldStyle); + LONG lNewStyle = lOldStyle; + + if ((lNewStyle & 0x01) == 0) + { + lNewStyle |= 0x01; + m_pRenderer->put_FontStyle(lNewStyle); + } + + if (unGid) + m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + else + m_pRenderer->CommandDrawText(wsUnicodeText, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + + if (lOldStyle != lNewStyle) + m_pRenderer->put_FontStyle(lOldStyle); + + m_pRenderer->EndCommand(c_nStrokeTextType); + } + else if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) { m_pRenderer->BeginCommand(c_nStrokeTextType); From db5909fdf5a96b3bc9c22c4937c636d86d7cd335 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 26 Apr 2024 14:39:34 +0300 Subject: [PATCH 573/794] Fix bug #67716 --- .../3dParty/html/css/src/CCompiledStyle.cpp | 2 +- .../html/css/src/CCssCalculator_Private.cpp | 7 +- .../3dParty/html/css/src/StyleProperties.cpp | 4 +- Common/3dParty/html/htmltoxhtml.h | 104 +++++++----------- HtmlFile2/htmlfile2.cpp | 14 ++- 5 files changed, 59 insertions(+), 72 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 83a6d161be3..7e63f251d1f 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -12,7 +12,7 @@ #include "StaticFunctions.h" #include "ConstValues.h" -#define DEFAULT_FONT_SIZE 28 // 14 * 2 +#define DEFAULT_FONT_SIZE 14 namespace NSCSS { diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 9bc3f2671b0..62b93c88a79 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -516,7 +516,8 @@ namespace NSCSS std::vector arNodes = CalculateAllNodes(arSelectors); std::vector arPrevNodes; - + bool bInTable = false; + for (size_t i = 0; i < arSelectors.size(); ++i) { oStyle.AddParent(arSelectors[i].m_wsName); @@ -527,9 +528,11 @@ namespace NSCSS oStyle.m_oFont.GetLineHeight().Clear(); oStyle.m_oPadding.Clear(); oStyle.m_oMargin.Clear(); + bInTable = true; } - oStyle.m_oBorder.Clear(); + if (bInTable) + oStyle.m_oBorder.Clear(); CCompiledStyle oTempStyle; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 9dfb2e1c6b6..42a1c973d6c 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1508,7 +1508,7 @@ namespace NSCSS { m_enCollapse.SetMapping({{L"collapse", BorderCollapse::Collapse}, {L"separate", BorderCollapse::Separate}}, BorderCollapse::Separate); } - + void CBorder::Clear() { m_oLeft .Clear(); @@ -2258,7 +2258,7 @@ namespace NSCSS void CFont::UpdateSize(double dFontSize) { - if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure()) + if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure()) m_oSize.ConvertTo(NSCSS::Point, dFontSize); } diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 0e3e3c7621b..c1c1b38442e 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -23,7 +23,7 @@ static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder); -static std::string mhtTohtml(std::string& sFileContent); +static std::string mhtTohtml(const std::string &sFileContent); // Заменяет в строке s все символы s1 на s2 static void replace_all(std::string& s, const std::string& s1, const std::string& s2) @@ -202,59 +202,42 @@ static std::string QuotedPrintableDecode(const std::string& sContent, std::strin return sRes.GetData(); } -static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFound, - std::map& sRes, NSStringUtils::CStringBuilderA& oRes) +static void ReadMht(const std::string& sMhtContent, std::map& sRes, NSStringUtils::CStringBuilderA& oRes) { - // Content - size_t nContentTag = sFileContent.find("\n\n", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nContentTag = sFileContent.find("\r\r", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nContentTag = sFileContent.find("\r\n\r\n", nFound); - if(nContentTag == std::string::npos || nContentTag > nNextFound) - { - nFound = nNextFound; - return; - } - else - nContentTag += 4; - } - else - nContentTag += 2; - } - else - nContentTag += 2; + size_t unContentPosition = 0, unLastPosition = 0; // Content-Type - std::string sContentType = NSStringFinder::FindPropety(sFileContent, "content-type", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentType = NSStringFinder::FindPropety(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); if (sContentType.empty()) + return; + + if (NSStringFinder::Equals(sContentType, "multipart/alternative")) { - nFound = nNextFound; + oRes.WriteString(mhtTohtml(sMhtContent.substr(unLastPosition, sMhtContent.length() - unLastPosition))); return; } - if (NSStringFinder::Equals(sContentType, std::string("multipart/alternative"))) - nContentTag = nFound; + unContentPosition = std::max(unContentPosition, unLastPosition); - size_t nTag = 0, nTagEnd = 0; - // name - std::string sName = NSStringFinder::FindPropety(sFileContent, "name", {"="}, {";", "\\n", "\\r"}, nFound); +// std::string sName = NSStringFinder::FindPropety(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition); +// unContentPosition = std::max(unContentPosition, unLastPosition); // charset - std::string sCharset = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r"}, nFound); + std::string sCharset = NSStringFinder::FindPropety(sMhtContent, "charset", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition); + unContentPosition = std::max(unContentPosition, unLastPosition); NSStringFinder::CutInside(sCharset, "\""); // Content-Location - std::string sContentLocation = NSStringFinder::FindPropety(sFileContent, "content-location", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentLocation = NSStringFinder::FindPropety(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); + unContentPosition = std::max(unContentPosition, unLastPosition); if (sContentLocation.empty()) { // Content-ID - std::string sContentID = NSStringFinder::FindPropety(sFileContent, "content-id", {":"}, {";", "\\n", "\\r"}, nFound); + std::string sContentID = NSStringFinder::FindPropety(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); + unContentPosition = std::max(unContentPosition, unLastPosition); NSStringFinder::CutInside(sCharset, "<", ">"); if (!sContentID.empty()) @@ -262,36 +245,22 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun } // Content-Transfer-Encoding - std::string sContentEncoding = NSStringFinder::FindPropety(sFileContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, nFound);; - -// nTag = sFileContent.find("Content-Transfer-Encoding: ", nFound); -// if(nTag != std::string::npos && nTag < nContentTag) -// { -// nTagEnd = sFileContent.find_first_of(";\n\r", nTag); -// nTag += 27; -// if(nTagEnd != std::string::npos && nTagEnd < nContentTag) -// sContentEncoding = sFileContent.substr(nTag, nTagEnd - nTag); -// } + std::string sContentEncoding = NSStringFinder::FindPropety(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); + unContentPosition = std::max(unContentPosition, unLastPosition); // Content - nTagEnd = nNextFound - 2; - if(nTagEnd == std::string::npos || nTagEnd < nContentTag) - { - nFound = nNextFound; - return; - } - std::string sContent = sFileContent.substr(nContentTag, nTagEnd - nContentTag); + std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition); - std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); +// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName)); // std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); // Основной документ if (NSStringFinder::Equals(sContentType, "multipart/alternative")) oRes.WriteString(mhtTohtml(sContent)); - else if ((NSStringFinder::Find(sContentType, "text") && (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))) + else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/) || (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css"))) { // Стили заключаются в тэг "); } // Картинки - else if ((NSStringFinder::Find(sContentType, "image") || NSStringFinder::Equals(sExtention, L"gif") || NSStringFinder::Equals(sContentType, "application/octet-stream")) && + else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) && NSStringFinder::Equals(sContentEncoding, "base64")) { - if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico")) - sContentType = "image/jpg"; - else if(NSStringFinder::Equals(sExtention, L"gif")) - sContentType = "image/gif"; +// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico")) +// sContentType = "image/jpg"; +// else if(NSStringFinder::Equals(sExtention, L"gif")) +// sContentType = "image/gif"; int nSrcLen = (int)sContent.length(); int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); BYTE* pData = new BYTE[nDecodeLen]; @@ -338,7 +307,7 @@ static void ReadMht(std::string& sFileContent, size_t& nFound, size_t& nNextFoun } } -static std::string mhtTohtml(std::string& sFileContent) +static std::string mhtTohtml(const std::string& sFileContent) { std::map sRes; NSStringUtils::CStringBuilderA oRes; @@ -351,7 +320,7 @@ static std::string mhtTohtml(std::string& sFileContent) { size_t nFoundEnd = sFileContent.length(); nFound = 0; - ReadMht(sFileContent, nFound, nFoundEnd, sRes, oRes); + ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes); return oRes.GetData(); } @@ -371,9 +340,9 @@ static std::string mhtTohtml(std::string& sFileContent) if(nFoundEnd == std::string::npos) break; - ReadMht(sFileContent, nFound, nFoundEnd, sRes, oRes); + ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes); - nFound = sFileContent.find(sBoundary, nFoundEnd + nBoundaryLength);; + nFound = sFileContent.find(sBoundary, nFoundEnd); } std::string sFile = oRes.GetData(); @@ -387,10 +356,18 @@ static std::string mhtTohtml(std::string& sFileContent) while(found != std::string::npos) { size_t fq = sFile.find_last_of("\"\'>=", found); + + if (std::string::npos == fq) + break; + char ch = sFile[fq]; if(ch != '\"' && ch != '\'') fq++; size_t tq = sFile.find_first_of("\"\'<> ", found) + 1; + + if (std::string::npos == tq) + break; + if(sFile[tq] != '\"' && sFile[tq] != '\'') tq--; if(ch != '>') @@ -403,6 +380,7 @@ static std::string mhtTohtml(std::string& sFileContent) found = sFile.find(sName, tq); } } + return sFile; } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 298c4d7eb53..7689d751481 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -121,17 +121,23 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NS return L""; } -void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false) +void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false, bool bInP = false) { if (NULL == pXml) return; - pXml->WriteString(L""); + if (!bInP) + pXml->WriteString(L""); + + pXml->WriteString(L""); if (bVahish) pXml->WriteString(L""); - pXml->WriteString(L""); + pXml->WriteString(L""); + + if (!bInP) + pXml->WriteString(L""); } typedef enum @@ -2570,7 +2576,7 @@ class CHtmlFile2_Private if (wsAlt.empty()) { //TODO:: реализовать отображение того, что картинку не удалось получить - WriteEmptyParagraph(oXml); + WriteEmptyParagraph(oXml, false, m_bInP); return; } From 5108fa6b94b61fe77f868b776152c0dfd76d5017 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 26 Apr 2024 14:44:03 +0300 Subject: [PATCH 574/794] Fix bug 66740 --- X2tConverter/src/lib/pdf_oform.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/X2tConverter/src/lib/pdf_oform.h b/X2tConverter/src/lib/pdf_oform.h index b04aa776e60..24f54c2c358 100644 --- a/X2tConverter/src/lib/pdf_oform.h +++ b/X2tConverter/src/lib/pdf_oform.h @@ -45,9 +45,28 @@ namespace NExtractTools _UINT32 pdfoform2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sTempDocx = combinePath(convertParams.m_sTempDir, L"meta.docx"); + std::wstring sTempDocxInjected = combinePath(convertParams.m_sTempDir, L"meta.docx"); + std::wstring sTempDocx = sTempDocxInjected; _UINT32 nRes = pdfoform2docx(sFrom, sTempDocx, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sTempDocxInjected)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + { + sTempDocx = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + nRes = mscrypt2oox(sTempDocxInjected, sTempDocx, params, convertParams); + } + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + { + sTempDocx = combinePath(convertParams.m_sTempDir, L"uncrypt_file.oox"); + nRes = mitcrypt2oox(sTempDocxInjected, sTempDocx, params, convertParams); + } + } + } + if (SUCCEEDED_X2T(nRes)) { COfficeUtils oOfficeUtils(NULL); From 3acb44a5c907d6587adfcf34c15c6974df4ac172 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 26 Apr 2024 17:08:50 +0300 Subject: [PATCH 575/794] Fixed drop in assessment. fix bugs. --- .../StarMath2OOXML/TestSMConverter/main.cpp | 30 ++++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 4 +- .../StarMath2OOXML/cstarmathpars.cpp | 157 ++++++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 9 +- 4 files changed, 143 insertions(+), 57 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index f87f79e7e41..a993e8d7a7e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1304,6 +1304,36 @@ TEST(SMConvectorTest,UnarySignWithColor) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,rSubrSup) +{ + std::wstring wsString = L"2 rSub 20 1 rSup 28"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"220128"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,DifferentRegisters) +{ + std::wstring wsString = L"2 OvEr 10 unION 5"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"210\x22C35"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Quotes) +{ + std::wstring wsString = L"\"2 + 3\" over 10 2 \"+\" 5 over 3"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"2 + 3102+53"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 721cb591049..b62b20c5bbd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -327,9 +327,7 @@ namespace StarMath { StandartProperties(pXmlWrite,pAttribute); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false); pXmlWrite->WriteNodeEnd(L"m:dPr",false,false); - pXmlWrite->WriteNodeBegin(L"m:e",false); - pValueGrade->ConversionToOOXML(pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pValueGrade,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:d",false,false); } void CConversionSMtoOOXML::WriteCtrlPrNode(XmlUtils::CXmlWriter *pXmlWrite, CAttribute *pAttribute) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index f31356253c0..c948512b5c2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -257,6 +257,18 @@ namespace StarMath { m_stBaseAttribute.base_font_italic = bItal; } + std::wstring CParserStarMathString::ConvertToLowerCase(const std::wstring& wsToken) + { + if(!wsToken.empty() && wsToken[0] == L'%') + return wsToken; + std::wstring wsLowerCase; + for(wchar_t cOneElement:wsToken) + wsLowerCase+= std::tolower(cOneElement); + if(wsLowerCase.empty()) + return wsToken; + else + return wsLowerCase; + } //class methods CAttribute CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(0),m_unCount(0) { @@ -511,7 +523,7 @@ namespace StarMath case TypeElement::size: { std::wstring wsSize = pReader->GetElement(); - pReader->SetString(wsSize); + pReader->TokenProcessing(wsSize); int iTemp; if(CElementString::GetDigit(wsSize) != TypeElement::undefine) iTemp = std::stoi(wsSize); @@ -527,12 +539,12 @@ namespace StarMath } case TypeElement::font: { - pReader->SetString(pReader->GetElement()); - if(pReader->GetString() == L"sans") + pReader->TokenProcessing(); + if(pReader->GetLowerCaseString() == L"sans") m_wsNameFont = L"Liberation Sans"; - else if(pReader->GetString() == L"serif") + else if(pReader->GetLowerCaseString() == L"serif") m_wsNameFont = L"Liberation Serif"; - else if(pReader->GetString() == L"fixed") + else if(pReader->GetLowerCaseString() == L"fixed") m_wsNameFont = L"Liberation Mono"; else return false; @@ -624,7 +636,7 @@ namespace StarMath wsSum += std::to_wstring(iGreen); if(iBlue != -1) wsSum += std::to_wstring(iBlue); - pReader->SetString(wsSum); + pReader->TokenProcessing(wsSum); } bool CAttribute::CheckingForEmptiness() { @@ -668,7 +680,7 @@ namespace StarMath { switch (pReader->GetGlobalType()) { case TypeElement::String: - return new CElementString(pReader->GetString()); + return new CElementString(pReader->GetOriginalString()); case TypeElement::BinOperator: return new CElementBinOperator(pReader->GetLocalType()); case TypeElement::SetOperations: @@ -680,7 +692,7 @@ namespace StarMath if(pReader->GetLocalType() == TypeElement::func) { pReader->GetToken(); - return new CElementFunction(pReader->GetLocalType(),pReader->GetString()); + return new CElementFunction(pReader->GetLocalType(),pReader->GetLowerCaseString()); } else return new CElementFunction(pReader->GetLocalType()); @@ -692,7 +704,7 @@ namespace StarMath if(pReader->GetLocalType() == TypeElement::oper) { pReader->GetToken(); - return new CElementOperator(pReader->GetLocalType(),pReader->GetString()); + return new CElementOperator(pReader->GetLocalType(),pReader->GetLowerCaseString()); } else return new CElementOperator(pReader->GetLocalType()); @@ -760,17 +772,33 @@ namespace StarMath m_wsString = wsTokenString; } void CElementString::Parse(CStarMathReader* pReader) - { + { + if(m_wsString == L"\"") + { + m_wsString.clear(); + wchar_t wsOneToken = pReader->GetOneElement(); + while(wsOneToken !=L'"') + { + m_wsString+=wsOneToken; + if(pReader->CheckIteratorPosition()) + wsOneToken = pReader->GetOneElement(); + else + break; + } + } pReader->ClearReader(); } void CElementString::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { + if(m_wsString !=L"" && m_wsString!=L" ") + { pXmlWrite->WriteNodeBegin(L"m:r",false); CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute()); pXmlWrite->WriteNodeBegin(L"m:t",false); pXmlWrite->WriteString(m_wsString); pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); + } } std::wstring CElementString::GetString() { @@ -1984,6 +2012,8 @@ namespace StarMath TypeElement CElementIndex::GetIndex(const std::wstring &wsCheckToken) { if(L"^" == wsCheckToken) return TypeElement::upper; + else if(L"rsup" == wsCheckToken) return TypeElement::upper; + else if(L"rsub" == wsCheckToken) return TypeElement::lower; else if(L"_" == wsCheckToken) return TypeElement::lower; else if(L"lsup" == wsCheckToken) return TypeElement::lsup; else if(L"lsub" == wsCheckToken) return TypeElement::lsub; @@ -2604,134 +2634,142 @@ namespace StarMath { if(CheckIteratorPosition()) { - m_wsToken = GetElement(); - TypeElement enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); - if(enTypeFont != TypeElement::undefine || L"color" == m_wsToken) + TokenProcessing(); + TypeElement enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); + if(enTypeFont != TypeElement::undefine || L"color" == m_wsLowerCaseToken) m_pAttribute = new CAttribute(); - while((enTypeFont != TypeElement::undefine || L"color" == m_wsToken) && m_itStart != m_itEnd) + while((enTypeFont != TypeElement::undefine || L"color" == m_wsLowerCaseToken) && m_itStart != m_itEnd) { - if(L"color" == m_wsToken) + if(L"color" == m_wsLowerCaseToken) { - m_wsToken = GetElement(); - if(m_pAttribute->ParseColorAttribute(m_wsToken,this)) - m_wsToken.clear(); + TokenProcessing(); + if(m_pAttribute->ParseColorAttribute(m_wsLowerCaseToken,this)) + m_wsLowerCaseToken.clear(); } else if(enTypeFont != TypeElement::undefine) if(m_pAttribute->ParseFontAttribute(enTypeFont,this)) - m_wsToken.clear(); + m_wsLowerCaseToken.clear(); else - enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); - if((m_itStart != m_itEnd) && m_wsToken.empty()) + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); + if((m_itStart != m_itEnd) && m_wsLowerCaseToken.empty()) { - m_wsToken = GetElement(); - enTypeFont = CAttribute::GetTypeFontAttribute(m_wsToken); + TokenProcessing(); + enTypeFont = CAttribute::GetTypeFontAttribute(m_wsLowerCaseToken); } } if(m_pAttribute != nullptr && !m_pAttribute->CheckAttribute()) m_pAttribute = nullptr; - if(m_wsToken == L"left") m_wsToken = GetElement(); - else if(L"right" == m_wsToken ) m_wsToken = GetElement(); + if(m_wsLowerCaseToken == L"left") TokenProcessing(); + else if(L"right" == m_wsLowerCaseToken ) TokenProcessing(); } //std::wcout< m_stBracket; @@ -450,6 +452,7 @@ namespace StarMath void SetBaseAlignment(const unsigned int& iAlignment); void SetBaseItalic(const bool& bItal); void SetBaseBold(const bool& bBold); + static std::wstring ConvertToLowerCase(const std::wstring& wsToken); private: TBaseAttribute m_stBaseAttribute; std::vector m_arEquation; From 6b5f930a1e608489dd6c3658b100dfd8d0e40d7d Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 27 Apr 2024 01:44:26 +0300 Subject: [PATCH 576/794] Add custom image storage to docxrenderer --- DesktopEditor/common/CalculatorCRC32.h | 33 ++--- .../graphics/pro/js/drawingfile.json | 2 +- .../graphics/pro/js/wasm/src/drawingfile.h | 7 ++ DocxRenderer/DocxRenderer.cpp | 13 ++ DocxRenderer/DocxRenderer.h | 3 + .../src/logic/managers/ImageManager.cpp | 113 ++++++++++++++++++ .../src/logic/managers/ImageManager.h | 12 +- DocxRenderer/test/main.cpp | 7 +- 8 files changed, 166 insertions(+), 24 deletions(-) diff --git a/DesktopEditor/common/CalculatorCRC32.h b/DesktopEditor/common/CalculatorCRC32.h index 4c22530107b..0d003e2d888 100644 --- a/DesktopEditor/common/CalculatorCRC32.h +++ b/DesktopEditor/common/CalculatorCRC32.h @@ -34,24 +34,25 @@ #include -const int g_clFilePartSize = 20*1024; +const int g_clFilePartSize = 20 * 1024; class CCalculatorCRC32 -{ +{ public: CCalculatorCRC32() { - m_dwMagicWord = 0xEDB88320; - m_dwInitCrc = 0xFFFFFFFF; - m_bInitTable = false; + m_dwMagicWord = 0xEDB88320; + m_dwInitCrc = 0xFFFFFFFF; + m_bInitTable = false; } + public: unsigned int Calc(const unsigned char* pStream, unsigned int nSize) { InitCRCTable(); - unsigned int dwRes = m_dwInitCrc; - for (unsigned int i=0;i> 8); + dwRes = m_arCRCTable[(dwRes ^ pStream[i]) & 0xFF] ^ (dwRes >> 8); } dwRes = dwRes ^ 0xFFFFFFFF; @@ -64,13 +65,13 @@ class CCalculatorCRC32 if (m_bInitTable) return; - unsigned int dwTemp; - for (int i=0;i<256;i++) + unsigned int dwTemp; + for (int i = 0; i < 256; i++) { dwTemp = i; - for (int j=0;j<8;j++) + for (int j = 0; j < 8; j++) { - if (0x1==(dwTemp & 0x1)) + if (0x1 == (dwTemp & 0x1)) dwTemp = (dwTemp >> 1) ^ m_dwMagicWord; else dwTemp = dwTemp >> 1; @@ -80,10 +81,10 @@ class CCalculatorCRC32 m_bInitTable = true; } - unsigned int m_dwMagicWord; - unsigned int m_dwInitCrc; - unsigned int m_arCRCTable[255]; - bool m_bInitTable; + unsigned int m_dwMagicWord; + unsigned int m_dwInitCrc; + unsigned int m_arCRCTable[255]; + bool m_bInitTable; }; #endif // _ASC_COMMON_CALCULATOR_CRC32_ diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 9b77693ad47..f19239e88d7 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -86,7 +86,7 @@ }, { "folder": "../../../cximage/CxImage/", - "files": ["ximaenc.cpp", "ximaexif.cpp", "ximage.cpp", "ximainfo.cpp", "ximajpg.cpp", "ximalpha.cpp", "ximapal.cpp", "ximasel.cpp", "xmemfile.cpp", "ximapng.cpp", "ximabmp.cpp", "ximatran.cpp", "ximatif.cpp", "tif_xfile.cpp", "ximajas.cpp", "ximagif.cpp", "ximaico.cpp", "ximatga.cpp", "ximapcx.cpp", "ximawbmp.cpp", "ximamng.cpp", "ximapsd.cpp", "ximaska.cpp", "ximaraw.cpp"] + "files": ["ximaenc.cpp", "ximaexif.cpp", "ximage.cpp", "ximainfo.cpp", "ximajpg.cpp", "ximalpha.cpp", "ximapal.cpp", "ximasel.cpp", "xmemfile.cpp", "ximapng.cpp", "ximabmp.cpp", "ximatran.cpp", "ximatif.cpp", "tif_xfile.cpp", "ximajas.cpp", "ximagif.cpp", "ximaico.cpp", "ximatga.cpp", "ximapcx.cpp", "ximawbmp.cpp", "ximamng.cpp", "ximapsd.cpp", "ximaska.cpp", "ximaraw.cpp", "ximaint.cpp"] }, { "folder": "../../../cximage/jpeg/", diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index 0f159b34a0e..4a79910fb53 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -17,12 +17,14 @@ class CGraphicsFileDrawing NSFonts::IApplicationFonts* pApplicationFonts; NSFonts::IFontManager* pFontManager; NSHtmlRenderer::CHTMLRendererText* pTextRenderer; + NSDocxRenderer::IImageStorage* pImageStorage; int nType; public: CGraphicsFileDrawing(NSFonts::IApplicationFonts* pFonts) { pReader = NULL; pTextRenderer = NULL; + pImageStorage = NULL; pApplicationFonts = pFonts; pApplicationFonts->AddRef(); @@ -40,6 +42,7 @@ class CGraphicsFileDrawing RELEASEOBJECT(pTextRenderer); RELEASEOBJECT(pFontManager); RELEASEINTERFACE(pApplicationFonts); + RELEASEOBJECT(pImageStorage); nType = -1; } bool Open(BYTE* data, DWORD length, int _nType, const char* password) @@ -189,7 +192,11 @@ class CGraphicsFileDrawing BYTE* GetPageShapes(const int& nPageIndex, int mode) { + if (NULL == pImageStorage) + pImageStorage = NSDocxRenderer::CreateWasmImageStorage(); + CDocxRenderer oRenderer(pApplicationFonts); + oRenderer.SetExternalImageStorage(pImageStorage); oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); std::vector arShapes; diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 65457fb0fbf..5cba4ed5224 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -126,6 +126,14 @@ std::vector CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz xml_shapes.push_back(writer->GetData()); delete writer; } + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arImages) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXml(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } std::vector& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; if (!arComleteObjects.empty()) @@ -163,6 +171,11 @@ std::vector CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, return xml_shapes; } +void CDocxRenderer::SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage) +{ + m_pInternal->m_oDocument.m_oImageManager.m_pExternalStorage = pStorage; +} + void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage) { //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; diff --git a/DocxRenderer/DocxRenderer.h b/DocxRenderer/DocxRenderer.h index cfe625defda..c8ce4f21259 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -44,6 +44,7 @@ #endif #include "convert_params.h" +#include "src/logic/managers/ExternalImageStorage.h" class CDocxRenderer_Private; class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer @@ -196,6 +197,8 @@ class DOCXRENDERER_DECL_EXPORT CDocxRenderer : public IRenderer std::vector ScanPage(IOfficeDrawingFile* pFile, size_t nPage); std::vector ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage); + void SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage); + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type); virtual HRESULT AdvancedCommand(IAdvancedCommand* command); diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index a7cd7f98ee0..f5c89bf1caf 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -1,6 +1,116 @@ #include "ImageManager.h" #include "../../../../DesktopEditor/common/Directory.h" +namespace NSDocxRenderer +{ + IImageStorage::IImageStorage(){} + IImageStorage::~IImageStorage(){} + + class CDataImageStorage : public IImageStorage + { + private: + std::map> m_mapImageData; + std::map m_mapImages; + + int m_lMaxSizeImage{1200}; + int m_lNextIDImage{0}; + + CCalculatorCRC32 m_oCRC; + + public: + CDataImageStorage() : IImageStorage() + { + } + virtual ~CDataImageStorage() + { + } + + virtual std::shared_ptr GenerateImageID(Aggplus::CImage* pImage) + { + BYTE* pData = pImage->GetData(); + DWORD nWidth = pImage->GetWidth(); + DWORD nHeight = pImage->GetHeight(); + long nStride = pImage->GetStride(); + + int nSize = pImage->GetStride() * nHeight; + if (nSize < 0) + nSize = -nSize; + + DWORD dwSum = m_oCRC.Calc(pData, nSize); + + auto find = m_mapImageData.find(dwSum); + if (find != m_mapImageData.end()) + return find->second; + + ++m_lNextIDImage; + + auto pInfo = std::make_shared(); + pInfo->m_nId = m_lNextIDImage; + pInfo->m_eType = CImageManager::GetImageType(pImage); + pInfo->m_strFileName = L"image" + std::to_wstring(pInfo->m_nId) + ((pInfo->m_eType == CImageInfo::itJPG) ? L".jpg" : L".png"); + + CBgraFrame oBgraFrame; + oBgraFrame.put_Width(nWidth); + oBgraFrame.put_Height(nHeight); + oBgraFrame.put_Stride(nStride); + oBgraFrame.put_Data(pData); + bool bIsResized = false; + + if (nWidth > m_lMaxSizeImage || nHeight > m_lMaxSizeImage) + { + int lW = 0; + int lH = 0; + double dAspect = (double)nWidth / nHeight; + + if (nWidth >= nHeight) + { + lW = m_lMaxSizeImage; + lH = (int)((double)lW / dAspect); + if (lH < 1) lH = 1; + } + else + { + lH = m_lMaxSizeImage; + lW = (int)(dAspect * lH); + if (lW < 1) lW = 1; + } + + bIsResized = true; + oBgraFrame.Resize(lW, lH, false); + } + + BYTE* pEncodeBuffer = NULL; + int nEncodeBufferSize = 0; + oBgraFrame.Encode(pEncodeBuffer, nEncodeBufferSize, (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4); + + if (!bIsResized) + oBgraFrame.put_Data(NULL); + + int nBase64DataSize = NSBase64::Base64EncodeGetRequiredLength(nEncodeBufferSize); + char* pBase64Data = new char[nBase64DataSize]; + + NSBase64::Base64Encode(pEncodeBuffer, nEncodeBufferSize, (BYTE*)pBase64Data, &nBase64DataSize, NSBase64::B64_BASE64_FLAG_NOCRLF); + RELEASEARRAYOBJECTS(pEncodeBuffer); + + m_mapImages.insert(std::pair(pInfo->m_strFileName, std::string(pBase64Data, nBase64DataSize))); + RELEASEARRAYOBJECTS(pBase64Data); + + m_mapImageData.insert(std::pair>(dwSum, pInfo)); + return pInfo; + } + + virtual std::map* GetImages() + { + return &m_mapImages; + } + }; + + IImageStorage* CreateWasmImageStorage() + { + return new CDataImageStorage(); + } +} + namespace NSDocxRenderer { void CImageManager::Clear() @@ -86,6 +196,9 @@ namespace NSDocxRenderer std::shared_ptr CImageManager::GenerateImageID(Aggplus::CImage* pImage) { + if (m_pExternalStorage) + return m_pExternalStorage->GenerateImageID(pImage); + BYTE* pData = pImage->GetData(); int nSize = pImage->GetStride() * pImage->GetHeight(); if (nSize < 0) diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index 2d66dd1feaf..357b4c9d709 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -1,9 +1,6 @@ #pragma once #include "../../../../DesktopEditor/common/CalculatorCRC32.h" -#include "../../../../DesktopEditor/raster/BgraFrame.h" -#include "../../resources/ImageInfo.h" -#include -#include +#include "./ExternalImageStorage.h" namespace NSDocxRenderer { @@ -20,6 +17,8 @@ namespace NSDocxRenderer CCalculatorCRC32 m_oCRC; + IImageStorage* m_pExternalStorage = nullptr; + public: CImageManager(){}; @@ -42,10 +41,11 @@ namespace NSDocxRenderer std::shared_ptr GenerateImageID(const std::wstring& strFileName); - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - void FlipY(Aggplus::CImage* pImage); void FlipX(CBgraFrame* pImage); + + public: + static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); }; } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index 1e416fcf32e..5ada59aa562 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -170,14 +170,19 @@ int main(int argc, char *argv[]) //taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; taType = NSDocxRenderer::TextAssociationType::tatParagraphToShape; + NSDocxRenderer::IImageStorage* pExternalImagheStorage = NSDocxRenderer::CreateWasmImageStorage(); + //oDocxRenderer.SetExternalImageStorage(pExternalImagheStorage); + oDocxRenderer.SetTextAssociationType(taType); - //oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); + oDocxRenderer.Convert(pReader, sTextDirOut+sDocx); //auto shapes = oDocxRenderer.ScanPage(pReader, 0); //Если сразу нужен zip-архив //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); #endif RELEASEOBJECT(pReader); + + RELEASEOBJECT(pExternalImagheStorage); } pFonts->Release(); From ba4c5b31d13624bf882d78d2f2431900afd95876 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 27 Apr 2024 01:46:43 +0300 Subject: [PATCH 577/794] Fix previous commit --- .../src/logic/managers/ExternalImageStorage.h | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 DocxRenderer/src/logic/managers/ExternalImageStorage.h diff --git a/DocxRenderer/src/logic/managers/ExternalImageStorage.h b/DocxRenderer/src/logic/managers/ExternalImageStorage.h new file mode 100644 index 00000000000..06926606fbf --- /dev/null +++ b/DocxRenderer/src/logic/managers/ExternalImageStorage.h @@ -0,0 +1,28 @@ +#pragma once +#include "../../../../DesktopEditor/raster/BgraFrame.h" +#include "../../resources/ImageInfo.h" +#include +#include + +#ifndef DOCXRENDERER_USE_DYNAMIC_LIBRARY +#define DOCXRENDERER_DECL_EXPORT +#else +#include "../../../../DesktopEditor/common/base_export.h" +#define DOCXRENDERER_DECL_EXPORT Q_DECL_EXPORT +#endif + +namespace NSDocxRenderer +{ + class DOCXRENDERER_DECL_EXPORT IImageStorage + { + public: + IImageStorage(); + virtual ~IImageStorage(); + + public: + virtual std::shared_ptr GenerateImageID(Aggplus::CImage* pImage) = 0; + virtual std::map* GetImages() = 0; + }; + + DOCXRENDERER_DECL_EXPORT IImageStorage* CreateWasmImageStorage(); +} From 0b07bef0de5c377bfa19b18f3ebbcd8bdae7e9e2 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 27 Apr 2024 02:22:33 +0300 Subject: [PATCH 578/794] Fix for pptx shapes --- DocxRenderer/DocxRenderer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 5cba4ed5224..85bc381dcdf 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -162,6 +162,14 @@ std::vector CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, xml_shapes.push_back(writer->GetData()); delete writer; } + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arImages) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXmlPptx(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } std::vector& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; if (!arComleteObjects.empty()) From 03b568ad49c6dd2c7169d14a4a606fd5b675f95b Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 27 Apr 2024 12:24:30 +0300 Subject: [PATCH 579/794] fix bug #67673 --- OOXML/Common/ComplexTypes.cpp | 9 ++ OOXML/Common/ComplexTypes.h | 30 ++--- OOXML/Common/SimpleTypes_Word.cpp | 22 ++-- OOXML/DocxFormat/HeaderFooter.cpp | 187 +++++++++++++++++------------- OOXML/DocxFormat/HeaderFooter.h | 2 + 5 files changed, 143 insertions(+), 107 deletions(-) diff --git a/OOXML/Common/ComplexTypes.cpp b/OOXML/Common/ComplexTypes.cpp index 6fd06ffebe8..e31d7ad1b15 100644 --- a/OOXML/Common/ComplexTypes.cpp +++ b/OOXML/Common/ComplexTypes.cpp @@ -2366,6 +2366,15 @@ namespace Word WritingElement_ReadAttributes_Read_else_if(oReader, L"w:xAlign", m_oXAlign) WritingElement_ReadAttributes_Read_else_if(oReader, L"w:y", m_oY) WritingElement_ReadAttributes_Read_else_if(oReader, L"w:yAlign", m_oYAlign) +//2003 + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:x-align", m_oXAlign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:y-align", m_oYAlign) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hanchor", m_oHAnchor) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:vanchor", m_oVAnchor) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hspace", m_oHSpace) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:vspace", m_oVSpace) + WritingElement_ReadAttributes_Read_else_if(oReader, L"w:hrule", m_oHRule) + WritingElement_ReadAttributes_End(oReader) } diff --git a/OOXML/Common/ComplexTypes.h b/OOXML/Common/ComplexTypes.h index 885118e0015..b8e3b5dd2f2 100644 --- a/OOXML/Common/ComplexTypes.h +++ b/OOXML/Common/ComplexTypes.h @@ -1073,21 +1073,21 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable m_oAnchorLock; - nullable m_oDropCap; - nullable m_oH; - nullable m_oHAnchor; - nullable m_oHRule; - nullable m_oHSpace; - nullable m_oLines; - nullable m_oVAnchor; - nullable m_oVSpace; - nullable m_oW; - nullable m_oWrap; - nullable m_oX; - nullable m_oXAlign; - nullable m_oY; - nullable m_oYAlign; + nullable m_oAnchorLock; + nullable m_oDropCap; + nullable m_oH; + nullable m_oHAnchor; + nullable m_oHRule; + nullable m_oHSpace; + nullable m_oLines; + nullable m_oVAnchor; + nullable m_oVSpace; + nullable m_oW; + nullable m_oWrap; + nullable m_oX; + nullable m_oXAlign; + nullable m_oY; + nullable m_oYAlign; }; //-------------------------------------------------------------------------------- diff --git a/OOXML/Common/SimpleTypes_Word.cpp b/OOXML/Common/SimpleTypes_Word.cpp index 334169dd67c..9f8c41aba0c 100644 --- a/OOXML/Common/SimpleTypes_Word.cpp +++ b/OOXML/Common/SimpleTypes_Word.cpp @@ -1680,10 +1680,11 @@ namespace SimpleTypes EHeightRule CHeightRule::FromString(const std::wstring &sValue) { - if ( (L"atLeast") == sValue ) this->m_eValue = heightruleAtLeast; - else if ( (L"auto") == sValue ) this->m_eValue = heightruleAuto; - else if ( (L"exact") == sValue ) this->m_eValue = heightruleExact; - else this->m_eValue = heightruleAuto; + if (L"atLeast" == sValue) this->m_eValue = heightruleAtLeast; + else if (L"at-least" == sValue) this->m_eValue = heightruleAtLeast; + else if (L"auto" == sValue) this->m_eValue = heightruleAuto; + else if (L"exact" == sValue) this->m_eValue = heightruleExact; + else this->m_eValue = heightruleAuto; return this->m_eValue; } @@ -4333,12 +4334,13 @@ namespace SimpleTypes EWrap CWrap::FromString(const std::wstring &sValue) { - if ( (L"around") == sValue ) this->m_eValue = wrapAround; - else if ( (L"auto") == sValue ) this->m_eValue = wrapAuto; - else if ( (L"none") == sValue ) this->m_eValue = wrapNone; - else if ( (L"notBeside") == sValue ) this->m_eValue = wrapNotBeside; - else if ( (L"through") == sValue ) this->m_eValue = wrapThrough; - else if ( (L"tight") == sValue ) this->m_eValue = wrapTight; + if (L"around" == sValue ) this->m_eValue = wrapAround; + else if (L"auto" == sValue ) this->m_eValue = wrapAuto; + else if (L"none" == sValue ) this->m_eValue = wrapNone; + else if (L"notBeside" == sValue ) this->m_eValue = wrapNotBeside; + else if (L"not-beside" == sValue) this->m_eValue = wrapNotBeside; + else if (L"through" == sValue ) this->m_eValue = wrapThrough; + else if (L"tight" == sValue ) this->m_eValue = wrapTight; else this->m_eValue = wrapAuto; return this->m_eValue; diff --git a/OOXML/DocxFormat/HeaderFooter.cpp b/OOXML/DocxFormat/HeaderFooter.cpp index cb2ceb77025..7bfc0f950d7 100644 --- a/OOXML/DocxFormat/HeaderFooter.cpp +++ b/OOXML/DocxFormat/HeaderFooter.cpp @@ -91,93 +91,116 @@ namespace OOX } void CHdrFtr::fromXML(XmlUtils::CXmlLiteReader& oReader) { - std::wstring sName = oReader.GetName(); + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( _T("w:ftr") == sName ) + if (L"ftr" == sName) m_eType = et_w_ftr; - else if ( _T("w:hdr") == sName ) + else if (L"hdr" == sName) m_eType = et_w_hdr; else return; - OOX::Document* document = WritingElement::m_pMainDocument; - ReadAttributes(oReader); - if ( !oReader.IsEmptyNode() ) - { - int nDocumentDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nDocumentDepth ) ) - { - std::wstring sName = oReader.GetName(); - WritingElement *pItem = NULL; + if (oReader.IsEmptyNode()) + return; - if ( _T("w:altChunk") == sName ) - pItem = new Logic::CAltChunk( document ); - else if ( _T("w:bookmarkEnd") == sName ) - pItem = new Logic::CBookmarkEnd( document ); - else if ( _T("w:bookmarkStart") == sName ) - pItem = new Logic::CBookmarkStart( document ); - else if ( _T("w:commentRangeEnd") == sName ) - pItem = new Logic::CCommentRangeEnd( document ); - else if ( _T("w:commentRangeStart") == sName ) - pItem = new Logic::CCommentRangeStart( document ); - //else if ( _T("w:customXml") == sName ) - // pItem = new Logic::CCustomXml( document ); - else if ( _T("w:customXmlDelRangeEnd") == sName ) - pItem = new Logic::CCustomXmlDelRangeEnd( document ); - else if ( _T("w:customXmlDelRangeStart") == sName ) - pItem = new Logic::CCustomXmlDelRangeStart( document ); - else if ( _T("w:customXmlInsRangeEnd") == sName ) - pItem = new Logic::CCustomXmlInsRangeEnd( document ); - else if ( _T("w:customXmlInsRangeStart") == sName ) - pItem = new Logic::CCustomXmlInsRangeStart( document ); - else if ( _T("w:customXmlMoveFromRangeEnd") == sName ) - pItem = new Logic::CCustomXmlMoveFromRangeEnd( document ); - else if ( _T("w:customXmlMoveFromRangeStart") == sName ) - pItem = new Logic::CCustomXmlMoveFromRangeStart( document ); - else if ( _T("w:customXmlMoveToRangeEnd") == sName ) - pItem = new Logic::CCustomXmlMoveToRangeEnd( document ); - else if ( _T("w:customXmlMoveToRangeStart") == sName ) - pItem = new Logic::CCustomXmlMoveToRangeStart( document ); - else if ( _T("w:del") == sName ) - pItem = new Logic::CDel( document ); - else if ( _T("w:ins") == sName ) - pItem = new Logic::CIns( document ); - else if ( _T("w:moveFrom") == sName ) - pItem = new Logic::CMoveFrom( document ); - else if ( _T("w:moveFromRangeEnd") == sName ) - pItem = new Logic::CMoveFromRangeEnd( document ); - else if ( _T("w:moveFromRangeStart") == sName ) - pItem = new Logic::CMoveFromRangeStart( document ); - else if ( _T("w:moveTo") == sName ) - pItem = new Logic::CMoveTo( document ); - else if ( _T("w:moveToRangeEnd") == sName ) - pItem = new Logic::CMoveToRangeEnd( document ); - else if ( _T("w:moveToRangeStart") == sName ) - pItem = new Logic::CMoveToRangeStart( document ); - else if ( _T("m:oMath") == sName ) - pItem = new Logic::COMath( document ); - else if ( _T("m:oMathPara") == sName ) - pItem = new Logic::COMathPara( document ); - else if ( _T("w:p") == sName ) - pItem = new Logic::CParagraph( document, this ); - else if ( _T("w:permEnd") == sName ) - pItem = new Logic::CPermEnd( document ); - else if ( _T("w:permStart") == sName ) - pItem = new Logic::CPermStart( document ); - else if ( _T("w:proofErr") == sName ) - pItem = new Logic::CProofErr( document ); - else if ( _T("w:sdt") == sName ) - pItem = new Logic::CSdt( document ); - else if ( _T("w:tbl") == sName ) - pItem = new Logic::CTbl( document ); + int nHdrFtrDepth = oReader.GetDepth(); + CreateElements(oReader, nHdrFtrDepth); + } + void CHdrFtr::CreateElements(XmlUtils::CXmlLiteReader& oReader, int Depth) + { + OOX::Document* document = WritingElement::m_pMainDocument; - if ( pItem ) - { - pItem->fromXML(oReader); - m_arrItems.push_back( pItem ); - } + while (oReader.ReadNextSiblingNode(Depth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + WritingElement* pItem = NULL; + + if (L"altChunk" == sName) + pItem = new Logic::CAltChunk(document); + else if (L"bookmarkEnd" == sName) + pItem = new Logic::CBookmarkEnd(document); + else if (L"bookmarkStart" == sName) + pItem = new Logic::CBookmarkStart(document); + else if (L"commentRangeEnd" == sName) + pItem = new Logic::CCommentRangeEnd(document); + else if (L"commentRangeStart" == sName) + pItem = new Logic::CCommentRangeStart(document); + //else if ( L"customXml") == sName ) + // pItem = new Logic::CCustomXml( document ); + else if (L"customXmlDelRangeEnd" == sName) + pItem = new Logic::CCustomXmlDelRangeEnd(document); + else if (L"customXmlDelRangeStart" == sName) + pItem = new Logic::CCustomXmlDelRangeStart(document); + else if (L"customXmlInsRangeEnd" == sName) + pItem = new Logic::CCustomXmlInsRangeEnd(document); + else if (L"customXmlInsRangeStart" == sName) + pItem = new Logic::CCustomXmlInsRangeStart(document); + else if (L"customXmlMoveFromRangeEnd" == sName) + pItem = new Logic::CCustomXmlMoveFromRangeEnd(document); + else if (L"customXmlMoveFromRangeStart" == sName) + pItem = new Logic::CCustomXmlMoveFromRangeStart(document); + else if (L"customXmlMoveToRangeEnd" == sName) + pItem = new Logic::CCustomXmlMoveToRangeEnd(document); + else if (L"customXmlMoveToRangeStart" == sName) + pItem = new Logic::CCustomXmlMoveToRangeStart(document); + else if (L"del" == sName) + pItem = new Logic::CDel(document); + else if (L"ins" == sName) + pItem = new Logic::CIns(document); + else if (L"moveFrom" == sName) + pItem = new Logic::CMoveFrom(document); + else if (L"moveFromRangeEnd" == sName) + pItem = new Logic::CMoveFromRangeEnd(document); + else if (L"moveFromRangeStart" == sName) + pItem = new Logic::CMoveFromRangeStart(document); + else if (L"moveTo" == sName) + pItem = new Logic::CMoveTo(document); + else if (L"moveToRangeEnd" == sName) + pItem = new Logic::CMoveToRangeEnd(document); + else if (L"moveToRangeStart" == sName) + pItem = new Logic::CMoveToRangeStart(document); + else if (L"oMath" == sName) + pItem = new Logic::COMath(document); + else if (L"oMathPara" == sName) + pItem = new Logic::COMathPara(document); + else if (L"p" == sName) + pItem = new Logic::CParagraph(document, this); + else if (L"permEnd" == sName) + pItem = new Logic::CPermEnd(document); + else if (L"permStart" == sName) + pItem = new Logic::CPermStart(document); + else if (L"proofErr" == sName) + pItem = new Logic::CProofErr(document); + else if (L"sdt" == sName) + pItem = new Logic::CSdt(document); + else if (L"tbl" == sName) + pItem = new Logic::CTbl(document); + else if (L"body" == sName && !oReader.IsEmptyNode()) + { + int nWBodyDepth = oReader.GetDepth(); + CreateElements(oReader, nWBodyDepth); + } + else if (L"sect" == sName && !oReader.IsEmptyNode()) + { + int nWxSectDepth = oReader.GetDepth(); + CreateElements(oReader, nWxSectDepth); + } + else if (L"sub-section" == sName && !oReader.IsEmptyNode()) + { + int nWxSubSectDepth = oReader.GetDepth(); + CreateElements(oReader, nWxSubSectDepth); + } + else if (L"pBdrGroup" == sName && !oReader.IsEmptyNode()) + { + int nWxBdrGroupDepth = oReader.GetDepth(); + CreateElements(oReader, nWxBdrGroupDepth); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); } } } @@ -278,10 +301,10 @@ mc:Ignorable=\"w14 w15 wp14\">"); return m_eType; } void CHdrFtr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) -{ - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_ReadSingle( oReader, _T("w:type"), m_oType ) - WritingElement_ReadAttributes_End( oReader ) -} + { + WritingElement_ReadAttributes_Start_No_NS(oReader) + WritingElement_ReadAttributes_ReadSingle(oReader, L"type", m_oType ) + WritingElement_ReadAttributes_End_No_NS(oReader) + } } // namespace OOX diff --git a/OOXML/DocxFormat/HeaderFooter.h b/OOXML/DocxFormat/HeaderFooter.h index ac893eedd78..53991cbcd0b 100644 --- a/OOXML/DocxFormat/HeaderFooter.h +++ b/OOXML/DocxFormat/HeaderFooter.h @@ -63,6 +63,8 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlNode& oNode); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + void CreateElements(XmlUtils::CXmlLiteReader& oReader, int Depth); + virtual std::wstring toXML() const; virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; From 7f791ad265e06d8cd1c52e4522a19f778fee2c75 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Sat, 27 Apr 2024 17:27:11 +0600 Subject: [PATCH 580/794] fix bug #67544 --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 56 +++++++++++-------- .../XlsFile/Format/Auxiliary/HelpFunc.h | 4 +- .../Logic/Biff_structures/CellRangeRef.cpp | 30 +++++++--- .../Logic/Biff_structures/CellRangeRef.h | 13 ++++- .../Format/Logic/Biff_structures/CellRef.cpp | 28 +++++++--- .../Format/Logic/Biff_structures/CellRef.h | 11 +++- .../Format/Logic/Biff_structures/PtgAreaN.cpp | 3 +- .../Format/Logic/Biff_structures/PtgRefN.cpp | 2 +- 8 files changed, 99 insertions(+), 48 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 49cd1496ec7..74e5eb3547b 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -48,25 +48,28 @@ namespace AUX { -const int normalizeColumn(const int column) +const int normalizeColumn(const int column, const bool xlsb) { - if ((column & 0x00004000) == 0x00004000) - { - return 0x00004000 - 1; - } - else - { - int norm_col = column; - while (norm_col > 16383) - { - norm_col -= 16384; - } - while (norm_col < 0) - { - norm_col += 16384; // It is correct. must be on the second place after 16383 - } - return norm_col; - } + int maxCol = 0; + if(xlsb) + { + maxCol = 16383; + } + else + { + maxCol = 255; + } + int norm_col = column; + while (norm_col > maxCol) + { + norm_col -= (maxCol+1); + } + while (norm_col < 0) + { + norm_col += (maxCol+1); // It is correct. must be on the second place after maxCol(16383 or 255) + } + return norm_col; + } @@ -87,16 +90,25 @@ const std::wstring column2str(const int column, const bool col_rel) } -const int normalizeRow(const int row) +const int normalizeRow(const int row, bool xlsb) { + int maxRow = 0; + if(xlsb) + { + maxRow = 1048576; + } + else + { + maxRow = 65536; + } int norm_row = row; - while(norm_row > 1048576) + while(norm_row > maxRow) { - norm_row -= 0x100000; + norm_row -= maxRow; } while(norm_row < 0) { - norm_row += 0x100000; // It is correct. must be on the second place after 1048576 + norm_row += maxRow; // It is correct. must be on the second place after 1048576 } return norm_row; } diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index f839fa0f1f1..93c60f4f19a 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -42,8 +42,8 @@ namespace XLS namespace AUX { - const int normalizeColumn (const int column); - const int normalizeRow (const int row); + const int normalizeColumn (const int column, const bool xlsb = false); + const int normalizeRow (const int row, const bool xlsb = false); const std::wstring column2str (const int column, const bool col_rel); const std::wstring row2str (const int row, const bool row_rel); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp index 4de86dbffc3..5e7b73de5e4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp @@ -116,16 +116,28 @@ BiffStructurePtr CellRangeRef::clone() return BiffStructurePtr(new CellRangeRef(*this)); } -const std::wstring CellRangeRef::toString(const bool useShortForm) const +const std::wstring CellRangeRef::toString(const bool useShortForm, const bool xlsb) const { if(to_string_cache.empty()) { - int rowLast_norm = AUX::normalizeRow (rowLast); - int rowFirst_norm = AUX::normalizeRow (rowFirst); - int columnFirst_norm = AUX::normalizeColumn (columnFirst); - int columnLast_norm = AUX::normalizeColumn (columnLast); + int rowLast_norm = AUX::normalizeRow (rowLast, xlsb); + int rowFirst_norm = AUX::normalizeRow (rowFirst, xlsb); + int columnFirst_norm = AUX::normalizeColumn (columnFirst, xlsb); + int columnLast_norm = AUX::normalizeColumn (columnLast, xlsb); + int maxCol = 0; + int maxRow = 0; + if(xlsb) + { + maxCol = 16383; + maxRow = 1048575; + } + else + { + maxCol = 255; + maxRow = 65535; + } - if(0 == rowFirst_norm && 65535 == rowLast_norm ) // whole column or range of columns + if(0 == rowFirst_norm && maxRow == rowLast_norm ) // whole column or range of columns { if(useShortForm) { @@ -133,10 +145,10 @@ const std::wstring CellRangeRef::toString(const bool useShortForm) const } else { - rowLast_norm = 1048575; + rowLast_norm = maxRow; } } - if(0 == columnFirst_norm && 255 == columnLast_norm) // whole row or range of rows + if(0 == columnFirst_norm && maxCol == columnLast_norm) // whole row or range of rows { if(useShortForm) { @@ -144,7 +156,7 @@ const std::wstring CellRangeRef::toString(const bool useShortForm) const } else { - columnLast_norm = 16383; + columnLast_norm = maxCol; } } if(columnLast_norm == columnFirst_norm && rowFirst_norm == rowLast_norm) // single cell diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h index a1ecbcab552..6c9fa24d274 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h @@ -58,7 +58,7 @@ class CellRangeRef : public BiffStructure static const ElementType type = typeCellRangeRef; - const std::wstring toString(const bool useShortForm = true) const; + const std::wstring toString(const bool useShortForm = true, const bool xlsb = false) const; void fromString(const std::wstring& str); operator std::wstring () const; @@ -110,7 +110,16 @@ template diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp index d88b6b68528..82fb3c85ecd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp @@ -73,20 +73,32 @@ BiffStructurePtr CellRef::clone() return BiffStructurePtr(new CellRef(*this)); } -const std::wstring CellRef::toString() const +const std::wstring CellRef::toString(const bool xlsb) const { if (to_string_cache.empty()) - { - int row_norm = AUX::normalizeRow(row); - int column_norm = AUX::normalizeColumn(column); + { + int maxRow = 0; + int maxCol = 0; + if(xlsb) + { + maxRow = 1048575; + maxCol = 16383; + } + else + { + maxRow = 65535; + maxCol = 255; + } + int row_norm = AUX::normalizeRow(row, xlsb); + int column_norm = AUX::normalizeColumn(column, xlsb); - if (0 == row_norm && 65535 == row_norm) // whole column or range of columns + if (0 == row_norm && maxRow == row_norm) // whole column or range of columns { - row_norm = 1048575; + row_norm = maxRow; } - if (0 == column_norm && 255 == column_norm) // whole row or range of rows + if (0 == column_norm && maxCol == column_norm) // whole row or range of rows { - column_norm = 16383; + column_norm = maxCol; } return to_string_cache = AUX::loc2str(row_norm, rowRelative, column_norm, colRelative); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h index f2d617a035b..21a93f67a5c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h @@ -49,7 +49,7 @@ class CellRef : public BiffStructure static const ElementType type = typeCellRef; - const std::wstring toString() const; + const std::wstring toString(const bool xlsb = false) const; void fromString(const std::wstring& str); operator std::wstring () const; @@ -106,7 +106,14 @@ template> area; } - else { record >> areaXlsb; @@ -142,7 +141,7 @@ void PtgAreaN::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu else { - ptg_stack.push((areaXlsb + cell_base_ref).toString()); + ptg_stack.push((areaXlsb + cell_base_ref).toString(true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp index c673267f0e7..bc133fd809d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefN.cpp @@ -133,7 +133,7 @@ void PtgRefN::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful } else { - ptg_stack.push((loc_xlsb + cell_base_ref).toString()); + ptg_stack.push((loc_xlsb + cell_base_ref).toString(true)); } } From b17a6be4d57aa970b501ff640aaa7aa81a41914a Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 27 Apr 2024 14:27:17 +0300 Subject: [PATCH 581/794] fix bug #67679 --- Common/OfficeFileFormatChecker2.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 03fcfae5ba2..7ae78c1763a 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -850,7 +850,7 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) } else if (0 == sExt.compare(L".mht") || 0 == sExt.compare(L".mhtml")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT; - else if (0 == sExt.compare(L".csv") || 0 == sExt.compare(L".xlsx")) + else if (0 == sExt.compare(L".csv") || 0 == sExt.compare(L".xls") || 0 == sExt.compare(L".xlsx") || 0 == sExt.compare(L".xlsb")) nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; else if (0 == sExt.compare(L".html") || 0 == sExt.compare(L".htm")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML; @@ -858,9 +858,7 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_PDF; else if (0 == sExt.compare(L".doct")) // случай архива с html viewer nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY; - else if (0 == sExt.compare(L".xlsb")) - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB; - else // if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml")) //volsciv.rtf -или любой другой + else if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml") || 0 == sExt.compare(L".rtf") || 0 == sExt.compare(L".doc") || 0 == sExt.compare(L".docx")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) From 32b5dfc04af4faccc4391db15e79dc02a6caa926 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Sat, 27 Apr 2024 16:43:18 +0300 Subject: [PATCH 582/794] for bug #67352 --- OfficeUtils/src/ZipUtilsCP.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OfficeUtils/src/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index a4fedb41e08..306304fa7d8 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -646,6 +646,11 @@ namespace ZLibZipUtils StringDeque.push_front( aCurDirectories[i] ); zipDeque.push_front( zipDir + sDirName ); } + else if (sDirName == L"_rels") + { + StringDeque.push_front(aCurDirectories[i]); + zipDeque.push_front(zipDir + sDirName); + } else { StringDeque.push_back( aCurDirectories[i] ); @@ -663,9 +668,10 @@ namespace ZLibZipUtils { std::wstring cFileName = NSSystemPath::GetFileName(aCurFiles[i]); - if (std::wstring::npos != cFileName.find(L"mimetype") || - std::wstring::npos != cFileName.find(L"[Content_Types]")) // возможно и полное соответствие - { + if ( std::wstring::npos != cFileName.find(L"mimetype") || + std::wstring::npos != cFileName.find(L"[Content_Types]") || + cFileName == L".rels") + { file = NSSystemPath::Combine(szText, cFileName); zipFileName = zipDir + cFileName; From e69dc4f8982ef638fe7344773e3a9dce183f4593 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Sat, 27 Apr 2024 16:45:28 +0300 Subject: [PATCH 583/794] Remove unneeded files from compilation --- X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index 9bfe12baa0c..cda096bed82 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt @@ -147,8 +147,6 @@ link_libraries( # Add target library add_library(${LIB_NAME_X2T_CONVERTER} SHARED - ${CORE_DIR}/DesktopEditor/fontengine/FontsAssistant.cpp - ${CORE_DIR}/DesktopEditor/fontengine/ApplicationFontsWorker.cpp jni/X2t.cpp ) From 3d7fa985f7ba0b741589fa505f3a9f478e32fab1 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Wed, 1 May 2024 21:51:58 +0300 Subject: [PATCH 584/794] Change libraries list for x2t --- X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index cda096bed82..a3cc89735ce 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt @@ -79,7 +79,8 @@ message(STATUS "X2t Converter destination path: ${X2T_CONVERTER_DEST}") set(X2T_CONVERTER_LIBS ${ARG_PATH_LIB_BUILD_TOOLS}/${ANDROID_ABI}) message(STATUS "Prebuild libraries path: ${X2T_CONVERTER_LIBS}") -FILE(GLOB new_list "${X2T_CONVERTER_LIBS}/*.so") +SET(new_list libUnicodeConverter.so libkernel.so libkernel_network.so libgraphics.so libPdfFile.so libDjVuFile.so libXpsFile.so libHtmlFile2.so libFb2File.so libEpubFile.so libHtmlRenderer.so libDocxRenderer.so libdoctrenderer.so libx2t.so) + SET(libs_list "") FOREACH(file_path ${new_list}) GET_FILENAME_COMPONENT(file_path ${file_path} NAME) From 33fdfadcf770862e95e0359baa544acc47f796c5 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 2 May 2024 11:33:28 +0300 Subject: [PATCH 585/794] fix bug #66679 --- .../Binary/Presentation/BinaryFileReaderWriter.h | 1 + OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp | 15 +++++---------- OOXML/Binary/Sheets/Reader/ChartFromToBinary.h | 7 +++---- OOXML/PPTXFormat/Logic/SmartArt.cpp | 1 - 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 3c527443699..5a14f63d265 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -535,6 +535,7 @@ namespace NSBinPptxRW _INT32 m_nCountCharts = 1; _INT32 m_nCountDiagram = 1; _INT32 m_nCountActiveX = 1; + _INT32 m_nThemeOverrideCount = 1; BinDocxRW::CDocxSerializer* m_pMainDocument; int m_nDocumentType; diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp index d3c8a75654b..c076daa70b3 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp @@ -47,16 +47,10 @@ using namespace OOX::Spreadsheet; namespace BinXlsxRW { - SaveParams::SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes* _pContentTypes, CSVWriter* _pCSVWriter, bool bMacro) + SaveParams::SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes* _pContentTypes, CSVWriter* _pCSVWriter, bool bMacro) : + bMacroEnabled(bMacro), pContentTypes(_pContentTypes), sThemePath(_sThemePath), + sDrawingsPath(_sDrawingsPath), sEmbeddingsPath(_sEmbeddingsPath), pCSVWriter(_pCSVWriter) { - bMacroEnabled = bMacro; - pContentTypes = _pContentTypes; - sThemePath = _sThemePath; - sDrawingsPath = _sDrawingsPath; - sEmbeddingsPath = _sEmbeddingsPath; - - nThemeOverrideCount = 1; - pCSVWriter = _pCSVWriter; } const BYTE c_oserct_extlstEXT = 0; @@ -1134,7 +1128,7 @@ namespace BinXlsxRW } else if (c_oserct_chartspaceTHEMEOVERRIDE == type) { - std::wstring sThemeOverrideName = L"themeOverride" + std::to_wstring(m_oSaveParams.nThemeOverrideCount++) + L".xml"; + std::wstring sThemeOverrideName = L"themeOverride" + std::to_wstring(m_oBufferedStream.m_nThemeOverrideCount++) + L".xml"; std::wstring sThemeOverrideRelsPath = L"../theme/" + sThemeOverrideName; OOX::CPath pathThemeOverrideFile = m_oSaveParams.sThemePath + FILE_SEPARATOR_STR + sThemeOverrideName; @@ -7393,6 +7387,7 @@ namespace BinXlsxRW int nCurPos = m_oBcw.WriteItemStart(c_oserct_chartspaceCHART); WriteCT_Chart(*oVal.m_chart); m_oBcw.WriteItemEnd(nCurPos); + } if (oVal.m_spPr.IsInit()) { diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h index d6cd9a31e27..153a4330543 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h @@ -99,14 +99,13 @@ namespace BinXlsxRW { struct SaveParams { - SaveParams (const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes *pContentTypes, CSVWriter* pCSVWriter = NULL, bool bMacro = false); + SaveParams(const std::wstring& _sDrawingsPath, const std::wstring& _sEmbeddingsPath, const std::wstring& _sThemePath, OOX::CContentTypes *pContentTypes, CSVWriter* pCSVWriter = NULL, bool bMacro = false); smart_ptr pTheme; std::wstring sThemePath; std::wstring sDrawingsPath; std::wstring sEmbeddingsPath; OOX::CContentTypes* pContentTypes = NULL; - int nThemeOverrideCount = 0; CSVWriter* pCSVWriter = NULL; bool bMacroEnabled = false; }; @@ -114,9 +113,9 @@ namespace BinXlsxRW class BinaryChartReader : public Binary_CommonReader { NSBinPptxRW::CDrawingConverter* m_pOfficeDrawingConverter; - SaveParams& m_oSaveParams; + SaveParams& m_oSaveParams; public: - BinaryChartReader (NSBinPptxRW::CBinaryFileReader& oBufferedStream, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); + BinaryChartReader (NSBinPptxRW::CBinaryFileReader& oBufferedStream, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); int ReadCT_ChartFile (long length, OOX::Spreadsheet::CChartFile* poResult); int ReadCT_ChartExFile (long length, OOX::Spreadsheet::CChartExFile* poResult); diff --git a/OOXML/PPTXFormat/Logic/SmartArt.cpp b/OOXML/PPTXFormat/Logic/SmartArt.cpp index 528bd9f1ba1..ca865536900 100644 --- a/OOXML/PPTXFormat/Logic/SmartArt.cpp +++ b/OOXML/PPTXFormat/Logic/SmartArt.cpp @@ -650,7 +650,6 @@ namespace PPTX pWriter->StartRecord(/*c_oserct_chartspaceTHEMEOVERRIDE = */15); pThemeOverride->toPPTY(pWriter); pWriter->EndRecord(); - break; } else if (OOX::FileTypes::ChartStyle == container[i]->type()) { From 25b33244a40ad5d2e959aad3faa690f098afaeca Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Thu, 2 May 2024 15:57:47 +0300 Subject: [PATCH 586/794] fix bug #67011 --- .../Records/Drawing/ShapeContainer.cpp | 5 ++++ OOXML/PPTXFormat/Logic/Pic.cpp | 27 ++++++++++++++++++- OOXML/PPTXFormat/Logic/Timing/CTn.cpp | 1 + OOXML/PPTXFormat/Slide.cpp | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index ba8932f0f34..46cb8ddbb43 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp @@ -553,7 +553,12 @@ void CPPTElement::SetUpProperty(CElementPtr pElement, CTheme* pTheme, CSlideInfo bool bUsebRecolorFillAsPictures = (0x40 == (0x40 & flag2)); if (bUsebFilled) + { pElement->m_bIsFilled = bFilled; + if (pElement->m_oBrush.Type == c_BrushTypeNotSet) + pElement->m_oBrush.Type = c_BrushTypeSolid; + } + break; } diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 225dc853951..65b40dfdd66 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -896,8 +896,33 @@ namespace PPTX { if (oleObject.IsInit() && oleObject->isValid()) { + int _id = nvPicPr.cNvPr.id; + if (_id <= 0) + { + _id = pWriter->m_lObjectId; + ++pWriter->m_lObjectId; + } + else + { + if (pWriter->m_lObjectId <= (unsigned int)_id) + { + pWriter->m_lObjectId = _id + 1; + } + } + bOle = true; - pWriter->WriteString(L""); + pWriter->WriteString(L""); + pWriter->WriteString(L"WriteString(L" name=\"" + nvPicPr.cNvPr.name + L"\""); + pWriter->WriteString(L"/>"); + pWriter->WriteString(L""); + pWriter->WriteString(L""); + pWriter->WriteString(L""); + //pWriter->WriteString(L""); + //pWriter->WriteString(L""); + //pWriter->WriteString(L""); + pWriter->WriteString(L""); if (spPr.xfrm.IsInit()) { std::wstring oldName = spPr.xfrm->node_name; diff --git a/OOXML/PPTXFormat/Logic/Timing/CTn.cpp b/OOXML/PPTXFormat/Logic/Timing/CTn.cpp index b71c4abf383..ec49fdc9aa6 100644 --- a/OOXML/PPTXFormat/Logic/Timing/CTn.cpp +++ b/OOXML/PPTXFormat/Logic/Timing/CTn.cpp @@ -138,6 +138,7 @@ namespace PPTX pWriter->WriteAttribute(L"grpId", grpId); pWriter->WriteAttribute(L"afterEffect", afterEffect); pWriter->WriteAttribute(L"nodeType", nodeType); + pWriter->WriteAttribute(L"nodePh", nodePh); pWriter->EndAttributes(); if (stCondLst.IsInit()) diff --git a/OOXML/PPTXFormat/Slide.cpp b/OOXML/PPTXFormat/Slide.cpp index 1c7723b0f24..0765cc60410 100644 --- a/OOXML/PPTXFormat/Slide.cpp +++ b/OOXML/PPTXFormat/Slide.cpp @@ -200,6 +200,7 @@ namespace PPTX pWriter->WriteAttribute(L"xmlns:p", PPTX::g_Namespaces.p.m_strLink); pWriter->WriteAttribute(L"xmlns:m", PPTX::g_Namespaces.m.m_strLink); pWriter->WriteAttribute(L"xmlns:w", PPTX::g_Namespaces.w.m_strLink); + pWriter->WriteAttribute(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006"); pWriter->WriteAttribute(L"showMasterPhAnim", showMasterPhAnim); pWriter->WriteAttribute(L"showMasterSp", showMasterSp); From 013d6990ce8075a2954d6fea435996561020bc95 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 2 May 2024 18:32:32 +0300 Subject: [PATCH 587/794] Write RC to FreeText --- .../graphics/commands/AnnotField.cpp | 35 +++++++- DesktopEditor/graphics/commands/AnnotField.h | 19 ++++- PdfFile/PdfWriter.cpp | 84 ++++++++++++++++++- PdfFile/SrcReader/PdfAnnot.cpp | 1 + PdfFile/SrcWriter/Annotation.cpp | 9 +- PdfFile/SrcWriter/Annotation.h | 3 +- 6 files changed, 142 insertions(+), 9 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 3b6df74fcd9..d4841ebf67b 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -370,15 +370,20 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta return m_nType != -1; } +CAnnotFieldInfo::CMarkupAnnotPr::~CMarkupAnnotPr() +{ + for (int i = 0; i < m_arrRC.size(); ++i) + RELEASEOBJECT(m_arrRC[i]); +} BYTE CAnnotFieldInfo::CMarkupAnnotPr::GetRT() const { return m_nRT; } int CAnnotFieldInfo::CMarkupAnnotPr::GetFlag() const { return m_nFlag; } int CAnnotFieldInfo::CMarkupAnnotPr::GetPopupID() const { return m_nPopupID; } int CAnnotFieldInfo::CMarkupAnnotPr::GetIRTID() const { return m_nIRTID; } double CAnnotFieldInfo::CMarkupAnnotPr::GetCA() const { return m_dCA; } const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetT() { return m_wsT; } -const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetRC() { return m_wsRC; } const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetCD() { return m_wsCD; } const std::wstring& CAnnotFieldInfo::CMarkupAnnotPr::GetSubj() { return m_wsSubj; } +const std::vector& CAnnotFieldInfo::CMarkupAnnotPr::GetRC() { return m_arrRC; } void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nFlag = nFlags; @@ -389,7 +394,26 @@ void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader if (nFlags & (1 << 2)) m_dCA = pReader->ReadDouble(); if (nFlags & (1 << 3)) - m_wsRC = pReader->ReadString(); + { + int nFont = pReader->ReadInt(); + for (int i = 0; i < nFont; ++i) + { + CFontData* pFont = new CFontData(); + pFont->nAlignment = pReader->ReadByte(); + pFont->nFontFlag = pReader->ReadInt(); + if (pFont->nFontFlag & (1 << 5)) + pFont->dVAlign = pReader->ReadDouble(); + if (pFont->nFontFlag & (1 << 6)) + pFont->sActualFont = pReader->ReadString(); + pFont->dFontSise = pReader->ReadDouble(); + pFont->dColor[0] = pReader->ReadDouble(); + pFont->dColor[1] = pReader->ReadDouble(); + pFont->dColor[2] = pReader->ReadDouble(); + pFont->sFontFamily = pReader->ReadString(); + pFont->sText = pReader->ReadString(); + m_arrRC.push_back(pFont); + } + } if (nFlags & (1 << 4)) m_wsCD = pReader->ReadString(); if (nFlags & (1 << 5)) @@ -541,6 +565,7 @@ BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetLE() const { return m_nLE; } const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; } void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } +const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetIC() { return m_arrIC; } void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nQ = pReader->ReadByte(); @@ -563,6 +588,12 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead m_nLE = pReader->ReadByte(); if (nFlags & (1 << 20)) m_nIT = pReader->ReadByte(); + if (nFlags & (1 << 21)) + { + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + m_arrIC.push_back(pReader->ReadDouble()); + } } BYTE CAnnotFieldInfo::CCaretAnnotPr::GetSy() const { return m_nSy; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index a3ce19756ac..28e12950fa7 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -201,15 +201,29 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand class GRAPHICS_DECL CMarkupAnnotPr { public: + struct GRAPHICS_DECL CFontData + { + BYTE nAlignment; + int nFontFlag; + double dFontSise; + double dVAlign; + double dColor[3]; + std::wstring sFontFamily; + std::wstring sActualFont; + std::wstring sText; + }; + + virtual ~CMarkupAnnotPr(); + BYTE GetRT() const; int GetFlag() const; int GetPopupID() const; int GetIRTID() const; double GetCA() const; const std::wstring& GetT(); - const std::wstring& GetRC(); const std::wstring& GetCD(); const std::wstring& GetSubj(); + const std::vector& GetRC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -223,6 +237,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsRC; std::wstring m_wsCD; std::wstring m_wsSubj; + std::vector m_arrRC; }; class GRAPHICS_DECL CTextAnnotPr @@ -355,6 +370,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand const std::wstring& GetDS(); void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); const std::vector& GetCL(); + const std::vector& GetIC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -365,6 +381,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsDS; double m_dRD[4]{}; std::vector m_arrCL; + std::vector m_arrIC; }; class GRAPHICS_DECL CCaretAnnotPr diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 8b04f0579a1..c6b64e2b207 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1646,6 +1646,73 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie return S_OK; } +std::string GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData) +{ + const char* c_pHexStrings[] = + { + "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", + "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", + "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" + }; + + std::string sRes; + sRes += "font-size:"; + sRes += std::to_string(pFontData->dFontSise); + sRes += "pt;text-align:"; + switch (pFontData->nAlignment) + { + case 1: { sRes += "center"; break; } + case 2: { sRes += "right"; break; } + case 3: { sRes += "justify"; break; } + case 0: + default:{ sRes += "left"; break; } + } + + sRes += ";text-decoration:"; + if ((pFontData->nFontFlag >> 4) & 1) + sRes += "word"; + if ((pFontData->nFontFlag >> 3) & 1) + { + if ((pFontData->nFontFlag >> 4) & 1) + sRes += ' '; + sRes += "line-through"; + } + + sRes += ";color:#"; + sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[0] * 255.0)]; + sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[1] * 255.0)]; + sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[2] * 255.0)]; + sRes += ";font-weight:"; + sRes += (pFontData->nFontFlag >> 0) & 1 ? "bold" : "normal"; + sRes += ";font-style:"; + sRes += (pFontData->nFontFlag >> 1) & 1 ? "italic" : "normal"; + sRes += ";font-family:"; + std::wstring sFont = pFontData->sActualFont.empty() ? pFontData->sFontFamily : pFontData->sActualFont; + sRes += U_TO_UTF8(sFont); + + if (pFontData->dVAlign != 0) + { + sRes += ";vertical-align:"; + if (pFontData->dVAlign > 0) + sRes += '+'; + sRes += std::to_string(pFontData->dVAlign); + } + + return sRes; +} HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) @@ -1817,8 +1884,19 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pMarkupAnnot->SetCA(pPr->GetCA()); if (nFlags & (1 << 3)) { - // TODO - // pMarkupAnnot->SetRC(pPr->GetRC()); + std::string sRC = "

"; + std::vector arrRC = pPr->GetRC(); + for (int i = 0; i < arrRC.size(); ++i) + { + sRC += ""; + sRC += U_TO_UTF8(arrRC[i]->sText); //TODO to_unicode + sRC += ""; + } + sRC += "

"; + pMarkupAnnot->SetRC(sRC); } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); @@ -1962,6 +2040,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetLE(pPr->GetLE()); if (nFlags & (1 << 20)) pFreeTextAnnot->SetIT(pPr->GetIT()); + if (nFlags & (1 << 21)) + pFreeTextAnnot->SetIC(pPr->GetIC()); } else if (oInfo.IsCaret()) { diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 4823d4254cd..baa8e592e00 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2128,6 +2128,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : // 3 - Форматированный текст - RC std::string sRC = DictLookupString(&oAnnot, "RC", 3); + // std::cout << sRC << std::endl; // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock m_arrRC = AnnotMarkup::ReadRC(sRC); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index ba06c725952..7b89bc3fcc6 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -337,10 +337,9 @@ namespace PdfWriter if (!Get("T")) Add("T", new CStringObject(sValue.c_str(), true)); } - void CMarkupAnnotation::SetRC(const std::wstring& wsRC) + void CMarkupAnnotation::SetRC(const std::string& sRC) { - std::string sValue = U_TO_UTF8(wsRC); - Add("RC", new CStringObject(sValue.c_str(), true)); + Add("RC", new CStringObject(sRC.c_str())); } void CMarkupAnnotation::SetCD(const std::wstring& wsCD) { @@ -1101,6 +1100,10 @@ namespace PdfWriter for (int i = 0; i < arrCL.size(); ++i) pArray->Add(i % 2 == 0 ? (arrCL[i] + m_dPageX) : (m_dPageH - arrCL[i])); } + void CFreeTextAnnotation::SetIC(const std::vector& arrIC) + { + SetC(arrIC); + } //---------------------------------------------------------------------------------------- // CTextMarkupAnnotation //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index b833079367c..d76a4b23f18 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -219,7 +219,7 @@ namespace PdfWriter void SetRT(BYTE nRT); void SetCA(const double& dCA); void SetT(const std::wstring& wsT); - void SetRC(const std::wstring& wsRC); + void SetRC(const std::string& sRC); void SetCD(const std::wstring& wsCD); void SetSubj(const std::wstring& wsSubj); @@ -362,6 +362,7 @@ namespace PdfWriter void SetDS(const std::wstring& wsDS); void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4); void SetCL(const std::vector& arrCL); + void SetIC(const std::vector& arrIC); }; class CCaretAnnotation : public CMarkupAnnotation { From 23c54255e3bd4aa77066681e2a5e3c7611b65148 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 3 May 2024 13:55:29 +0600 Subject: [PATCH 588/794] Fix ptg conversion --- .../Biff_structures/ListParsedFormula.cpp | 27 +++ .../Logic/Biff_structures/SyntaxPtg.cpp | 20 +-- OOXML/XlsxFormat/Table/Tables.cpp | 162 +++++++++--------- 3 files changed, 114 insertions(+), 95 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp index 24d9e811307..675f3c8943f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp @@ -31,6 +31,7 @@ */ #include "ListParsedFormula.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.h" namespace XLS { @@ -42,6 +43,19 @@ ListParsedFormula::ListParsedFormula() : ParsedFormula(CellRef()) ListParsedFormula& ListParsedFormula::operator=(const std::wstring& value) { ParsedFormula::operator = (value); + if(!rgce.sequence.empty()) + { + auto lastValType = GETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } return *this; } @@ -127,6 +141,19 @@ ListParsedArrayFormula::ListParsedArrayFormula() : ArrayParsedFormula(false, Cel ListParsedArrayFormula& ListParsedArrayFormula::operator=(const std::wstring& value) { ArrayParsedFormula::operator = (value); + if(!rgce.sequence.empty()) + { + auto lastValType = GETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast(rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index fe99f26850d..bbad79043b3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -484,7 +484,6 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: insider = results_1.str(0); - insider = boost::algorithm::erase_all_copy(insider, L"\n"); if (insider == L"[#Data]") { if (boost::regex_search(first, last, results_1, reg_inside_table2)) @@ -534,8 +533,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (boost::regex_search(first, last, results_1, reg_inside_table3)) { - insider = results_1.str(0); - insider = boost::algorithm::erase_all_copy(insider, L"\n"); + insider = results_1.str(0); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -547,12 +545,12 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (ptgList.colFirst == 65535) { ptgList.columns = 0x01; - ptgList.colFirst = indexColumn; + ptgList.colFirst = indexColumn; + ptgList.colLast = indexColumn; if (boost::regex_search(first, last, results_1, reg_inside_table3)) { - insider = results_1.str(0); - insider = boost::algorithm::erase_all_copy(insider, L"\n"); + insider = results_1.str(0); if (!insider.empty() && insider[0] != '[') insider.erase(0, 1); @@ -566,8 +564,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: } else if(boost::regex_search(first, last, results_1, reg_inside_table5)) { - insider = results_1.str(0); - insider = boost::algorithm::erase_all_copy(insider, L"\n"); + insider = results_1.str(0); insider = boost::algorithm::erase_first_copy(insider, L":"); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) @@ -588,8 +585,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: else if(boost::regex_search(first, last, results_1, reg_inside_table5)) { insider = results_1.str(0); - insider = boost::algorithm::erase_first_copy(insider, L","); - insider = boost::algorithm::erase_all_copy(insider, L"\n"); + insider = boost::algorithm::erase_first_copy(insider, L","); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { @@ -597,6 +593,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { ptgList.columns = 0x01; ptgList.colFirst = indexColumn; + ptgList.colLast = indexColumn; } } first = results_1[0].second; @@ -622,6 +619,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { ptgList.columns = 0x01; ptgList.colFirst = 0; + ptgList.colLast = 0; first = results_1[0].second; } return true; @@ -630,7 +628,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: { _UINT16 indexColumn = -1; ptgList.rowType = 0x00; - auto insider = boost::algorithm::erase_all_copy(results_1.str(0), L"\n"); + auto insider = results_1.str(0); if (XMLSTUFF::isColumn(boost::algorithm::erase_last_copy(boost::algorithm::erase_first_copy(insider, L"["), L"]"), indexTable, indexColumn)) { diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index b278fd6203a..c7cbe495aa7 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -275,84 +275,81 @@ namespace Spreadsheet { auto ptr(new XLSB::LISTCOL); XLS::BaseObjectPtr objectPtr(ptr); - if(m_oDataCellStyle.IsInit() || m_oTotalsRowDxfId.IsInit() || m_oHeaderRowCellStyle.IsInit() || m_oHeaderRowDxfId.IsInit() - || m_oTotalsRowCellStyle.IsInit()|| m_oDataDxfId.IsInit() || m_oId.IsInit() || m_oName.IsInit() || m_oQueryTableFieldId.IsInit() - || m_oTotalsRowLabel.IsInit() || m_oUniqueName.IsInit() || m_oTotalsRowFunction.IsInit() ) - { - auto ptr1(new XLSB::BeginListCol); - ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; - if(m_oDataCellStyle.IsInit()) - ptr1->stStyleInsertRow = m_oDataCellStyle.get(); - else - ptr1->stStyleInsertRow = 0xFFFFFFFF; - if(m_oTotalsRowDxfId.IsInit()) - ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); - else - ptr1->nDxfInsertRow = 0xFFFFFFFF; - if(m_oHeaderRowDxfId.IsInit()) - ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); - else - ptr1->stStyleHeader = 0xFFFFFFFF; - if(m_oHeaderRowDxfId.IsInit()) - ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); - else - ptr1->nDxfHdr = 0xFFFFFFFF; - if(m_oTotalsRowCellStyle.IsInit()) - ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); - else - ptr1->stStyleAgg = 0xFFFFFFFF; + auto ptr1(new XLSB::BeginListCol); + ptr->m_BrtBeginListCol = XLS::BaseObjectPtr{ptr1}; + if(m_oDataCellStyle.IsInit()) + ptr1->stStyleInsertRow = m_oDataCellStyle.get(); + else + ptr1->stStyleInsertRow.setSize(0xFFFFFFFF); + if(m_oTotalsRowDxfId.IsInit()) + ptr1->nDxfInsertRow = m_oTotalsRowDxfId->GetValue(); + else + ptr1->nDxfInsertRow = 0xFFFFFFFF; - if(m_oDataDxfId.IsInit()) - ptr1->nDxfAgg = m_oDataDxfId->GetValue(); - else - ptr1->nDxfAgg = 0xFFFFFFFF; - if(m_oId.IsInit()) - ptr1->idField = m_oId->GetValue(); - else - ptr1->idField = 0; + if(m_oHeaderRowDxfId.IsInit()) + ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); + else + ptr1->stStyleHeader.setSize(0xFFFFFFFF); + if(m_oHeaderRowDxfId.IsInit()) + ptr1->nDxfHdr = m_oHeaderRowDxfId->GetValue(); + else + ptr1->nDxfHdr = 0xFFFFFFFF; + if(m_oTotalsRowCellStyle.IsInit()) + ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); + else + ptr1->stStyleAgg.setSize(0xFFFFFFFF); - if(m_oName.IsInit()) - ptr1->stCaption = m_oName.get(); - else - ptr1->stCaption = 0xFFFFFFFF; - if(m_oQueryTableFieldId.IsInit()) - ptr1->idqsif = m_oQueryTableFieldId->GetValue(); - else - ptr1->idqsif = 0; + if(m_oDataDxfId.IsInit()) + ptr1->nDxfAgg = m_oDataDxfId->GetValue(); + else + ptr1->nDxfAgg = 0xFFFFFFFF; + if(m_oId.IsInit()) + ptr1->idField = m_oId->GetValue(); + else + ptr1->idField = 0; - if(m_oTotalsRowLabel.IsInit()) - ptr1->stTotal = m_oTotalsRowLabel.get(); - else - ptr1->stTotal = 0xFFFFFFFF; + if(m_oName.IsInit()) + ptr1->stCaption = m_oName.get(); + else + ptr1->stCaption.setSize(0xFFFFFFFF); + if(m_oQueryTableFieldId.IsInit()) + ptr1->idqsif = m_oQueryTableFieldId->GetValue(); + else + ptr1->idqsif = 0; - if(m_oUniqueName.IsInit()) - ptr1->stName = m_oUniqueName.get(); - else - ptr1->stName = 0xFFFFFFFF; - if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; - else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) - ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; - else + if(m_oTotalsRowLabel.IsInit()) + ptr1->stTotal = m_oTotalsRowLabel.get(); + else + ptr1->stTotal.setSize(0xFFFFFFFF); + + if(m_oUniqueName.IsInit()) + ptr1->stName = m_oUniqueName.get(); + else + ptr1->stName.setSize(0xFFFFFFFF); + if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionNone) ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; - } + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionAverage) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_AVERAGE; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCount) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNT; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCountNums) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_COUNTNUMS; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMax) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MAX; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionMin) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_MIN; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionSum) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_SUM; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionStdDev) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_STDDEV; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionVar) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_VAR; + else if (m_oTotalsRowFunction == SimpleTypes::Spreadsheet::ETotalsRowFunction::totalrowfunctionCustom) + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_CUSTOM; + else + ptr1->ilta = XLSB::ListTotalRowFunction::ILTA_NONE; + if(m_oCalculatedColumnFormula.IsInit()) { auto fmla(new XLSB::ListCCFmla); @@ -502,11 +499,8 @@ namespace Spreadsheet { auto ptr(new XLSB::LISTCOLS); XLS::BaseObjectPtr objectPtr(ptr); - auto ptr1(new XLSB::BeginListCols); - ptr1->nCols = m_arrItems.size(); - ptr->m_BrtBeginListCols = XLS::BaseObjectPtr{ptr1}; - for(auto i:m_arrItems) - ptr->m_arLISTCOL.push_back(i->toBin()); + for(auto i:m_arrItems) + ptr->m_arLISTCOL.push_back(i->toBin()); return objectPtr; } void CTableColumns::ReadAttributes(std::vector& obj) @@ -624,7 +618,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") { if(i->m_oName.IsInit()) { - i->m_oName = boost::algorithm::erase_all_copy(i->m_oName.get(), L"_x000a_"); + i->m_oName = boost::algorithm::replace_all_copy(i->m_oName.get(), L"_x000a_", L"\n"); std::unordered_map>::iterator pFind = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(m_oId->GetValue()); if (pFind != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) { @@ -679,7 +673,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") else if(m_oDisplayName.IsInit()) ptr1->stName = m_oDisplayName.get(); else - ptr1->stName = 0xFFFFFFFF; + ptr1->stName.setSize(0xFFFFFFFF); if(m_oTotalsRowCount.IsInit()) ptr1->crwTotals = m_oTotalsRowCount->GetValue(); else @@ -693,7 +687,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oDisplayName.IsInit()) ptr1->stDisplayName = m_oDisplayName.get(); else - ptr1->stDisplayName = 0xFFFFFFFF; + ptr1->stDisplayName.setSize(0xFFFFFFFF); if(m_oTableBorderDxfId.IsInit()) ptr1->nDxfBorder = m_oTableBorderDxfId->GetValue(); @@ -703,7 +697,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oComment.IsInit()) ptr1->stComment = m_oComment.get(); else - ptr1->stComment = 0xFFFFFFFF; + ptr1->stComment.setSize(0xFFFFFFFF); if(m_oConnectionId.IsInit()) ptr1->dwConnID = m_oConnectionId->GetValue(); @@ -718,7 +712,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oDataCellStyle.IsInit()) ptr1->stStyleData = m_oDataCellStyle.get(); else - ptr1->stStyleData = 0xFFFFFFFF; + ptr1->stStyleData.setSize(0xFFFFFFFF); if(m_oHeaderRowBorderDxfId.IsInit()) ptr1->nDxfHeaderBorder = m_oHeaderRowBorderDxfId->GetValue(); @@ -728,7 +722,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oHeaderRowCellStyle.IsInit()) ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); else - ptr1->stStyleHeader = 0xFFFFFFFF; + ptr1->stStyleHeader.setSize(0xFFFFFFFF); if(m_oHeaderRowDxfId.IsInit()) ptr1->nDxfHeader = m_oHeaderRowDxfId->GetValue(); @@ -770,7 +764,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") if(m_oTotalsRowCellStyle.IsInit()) ptr1->stStyleAgg = m_oTotalsRowCellStyle.get(); else - ptr1->stStyleAgg = 0xFFFFFFFF; + ptr1->stStyleAgg.setSize(0xFFFFFFFF); if(m_oTotalsRowDxfId.IsInit()) ptr1->nDxfAgg = m_oTotalsRowDxfId->GetValue(); From a6d9af576dbed3ad2ef346ab81ceb4ee515de0c7 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 3 May 2024 12:38:06 +0300 Subject: [PATCH 589/794] . --- OOXML/Binary/Document/BinReader/Readers.cpp | 15 +++++++++++++++ .../BinWriter/BinReaderWriterDefines.h | 5 ++++- OOXML/Binary/Document/BinWriter/BinWriters.cpp | 18 ++++++++++++++++++ OOXML/DocxFormat/Logic/SectionProperty.h | 8 ++++---- OdfFile/Reader/Format/chart_build_oox.cpp | 6 +++--- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/Readers.cpp b/OOXML/Binary/Document/BinReader/Readers.cpp index fda10726226..53f19b99a8e 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/Readers.cpp @@ -1877,6 +1877,21 @@ int Binary_pPrReader::Read_pageNumType(BYTE type, long length, void* poResult) pCPageNumber->m_oStart.Init(); pCPageNumber->m_oStart->SetValue(m_oBufferedStream.GetLong()); } + else if (c_oSerProp_secPrPageNumType::fmt == type) + { + pCPageNumber->m_oFmt.Init(); + pCPageNumber->m_oFmt->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSerProp_secPrPageNumType::chapStyle == type) + { + pCPageNumber->m_oChapStyle.Init(); + pCPageNumber->m_oChapStyle->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerProp_secPrPageNumType::chapSep == type) + { + pCPageNumber->m_oChapSep.Init(); + pCPageNumber->m_oChapSep->SetValueFromByte(m_oBufferedStream.GetUChar()); + } else res = c_oSerConstants::ReadUnknown; return res; diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index ba1246ee425..e3966154bea 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -487,7 +487,10 @@ extern int g_nCurFormatVersion; };} namespace c_oSerProp_secPrPageNumType{enum c_oSerProp_secPrPageNumType { - start = 0 + start = 0, + fmt = 1, + chapStyle = 2, + chapSep = 3 };} namespace c_oSerProp_secPrLineNumType{enum c_oSerProp_secPrLineNumType { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index e4f0b698e42..035a051f719 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -1671,6 +1671,24 @@ void Binary_pPrWriter::WritePageNumType(const ComplexTypes::Word::CPageNumber& p m_oBcw.m_oStream.WriteLONG(pPageNumber.m_oStart->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } + if (pPageNumber.m_oFmt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::fmt); + m_oBcw.m_oStream.WriteBYTE(pPageNumber.m_oFmt->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pPageNumber.m_oChapStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::chapStyle); + m_oBcw.m_oStream.WriteLONG(pPageNumber.m_oChapStyle->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pPageNumber.m_oChapSep.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrPageNumType::chapSep); + m_oBcw.m_oStream.WriteBYTE(pPageNumber.m_oChapSep->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } } void Binary_pPrWriter::WriteLineNumType(const ComplexTypes::Word::CLineNumber& pLineNumber) { diff --git a/OOXML/DocxFormat/Logic/SectionProperty.h b/OOXML/DocxFormat/Logic/SectionProperty.h index 2d2fdeb8dc4..ef2907f7c2b 100644 --- a/OOXML/DocxFormat/Logic/SectionProperty.h +++ b/OOXML/DocxFormat/Logic/SectionProperty.h @@ -281,10 +281,10 @@ namespace ComplexTypes void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable m_oChapSep; - nullable m_oChapStyle; - nullable m_oFmt; - nullable m_oStart; + nullable m_oChapSep; + nullable m_oChapStyle; + nullable m_oFmt; + nullable m_oStart; }; //-------------------------------------------------------------------------------- diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index 0b72a70e1b1..e8bbb55a742 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -209,7 +209,7 @@ void object_odf_context::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(), 1); } else if(object_type_ == 4 && office_spreadsheet_) { @@ -261,7 +261,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.start_math_formula(); - office_math_->oox_convert(Context.get_math_context(),2); + office_math_->oox_convert(Context.get_math_context(), 2); Context.end_math_formula(); Context.get_drawing_context().get_text_stream_frame() = temp_stream.str(); @@ -307,7 +307,7 @@ void object_odf_context::pptx_convert(oox::pptx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context(),1); + office_math_->oox_convert(Context.get_math_context(), 1); } else if(object_type_ == 4 && office_spreadsheet_) { From 95d8fd287109167514b8831c0eeab0d3fb62acf9 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 3 May 2024 13:17:41 +0300 Subject: [PATCH 590/794] Fix bug #67767 --- Common/3dParty/html/css/src/CCompiledStyle.cpp | 3 +-- Common/3dParty/html/css/src/CCssCalculator_Private.cpp | 8 ++++++++ Common/3dParty/html/css/src/StyleProperties.cpp | 9 +++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 7e63f251d1f..8504f7ee073 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -110,7 +110,7 @@ namespace NSCSS void CCompiledStyle::AddStyle(const std::map& mStyle, const unsigned int unLevel, const bool& bHardMode) { const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true; - const double dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Twips) : DEFAULT_FONT_SIZE; + const double dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE; for (std::pair pPropertie : mStyle) { @@ -180,7 +180,6 @@ namespace NSCSS break; m_oMargin.SetTop(pPropertie.second, unLevel, bHardMode); - m_oMargin.UpdateTop(dFontSize); break; } CASE(L"margin-right"): diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 62b93c88a79..085e945bc2d 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -564,6 +564,14 @@ namespace NSCSS if (!bIsSettings) { + std::map, CCompiledStyle*>::const_iterator itFound = std::find_if(m_mUsedStyles.begin(), m_mUsedStyles.end(), [oStyle](const std::pair, CCompiledStyle*>& oValue){ return (*oValue.second) == oStyle; }); + + if (m_mUsedStyles.end() != itFound) + { + oStyle = *itFound->second; + return true; + } + oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); CCompiledStyle *pTemp = new CCompiledStyle(oStyle); diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 42a1c973d6c..4b1aa1f6596 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -374,7 +374,7 @@ namespace NSCSS bool CDigit::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode)) + if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode) || unLevel < m_unLevel) return false; std::wstring wsNewValue = wsValue; @@ -404,7 +404,12 @@ namespace NSCSS m_enUnitMeasure = oValue.m_enUnitMeasure; } else if (NSCSS::Percent == oValue.m_enUnitMeasure) - m_oValue *= oValue.m_oValue / 100.; + { + if (m_unLevel == oValue.m_unLevel) + m_oValue = oValue.m_oValue; + else + m_oValue *= oValue.m_oValue / 100.; + } else m_oValue = oValue.ToDouble(m_enUnitMeasure); From 234c1766dce097d91134ee65d288f1642f33c57e Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 3 May 2024 13:18:26 +0300 Subject: [PATCH 591/794] Fix bug #67770 --- HtmlFile2/htmlfile2.cpp | 77 +++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 2fdd4f83dea..fa9624a57bd 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1494,6 +1494,18 @@ class CHtmlFile2_Private return true; } + bool OpenP(NSStringUtils::CStringBuilder* pXml) + { + if (m_bInP) + return false; + + pXml->WriteString(L""); + m_bInP = true; + m_bWasPStyle = false; + + return true; + } + bool OpenR(NSStringUtils::CStringBuilder* pXml) { if (m_bInR) @@ -1532,16 +1544,29 @@ class CHtmlFile2_Private m_bInT = false; } + void CheckA(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) + { + for (std::vector::const_reverse_iterator itNode = arSelectors.crbegin(); itNode < arSelectors.crend(); ++itNode) + { + if (NodeBelongToTable(itNode->m_wsName)) + break; + + if (L"a" == itNode->m_wsName) + { + pXml->WriteString(L""); + break; + } + } + } + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) { m_bWasSpace = true; if (!m_bInP) return; - - for (const NSCSS::CNode& item : arSelectors) - if (item.m_wsName == L"a") - pXml->WriteString(L""); + + CheckA(pXml, arSelectors); CloseT(pXml); CloseR(pXml); @@ -2479,6 +2504,32 @@ class CHtmlFile2_Private if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); + const bool bInP{m_bInP}, bWasPStyle{m_bWasPStyle}; + + NSStringUtils::CStringBuilder oInsideData; + m_bInP = true; + m_bWasPStyle = true; + + if(!readStream(&oInsideData, sSelectors, oTS)) + { + oInsideData.WriteString(L""); + wrRPr(&oInsideData, sSelectors, oTS); + oInsideData.WriteString(L""); + oInsideData.WriteEncodeXmlString(sAlt); + oInsideData.WriteString(L""); + } + + if (0 != oInsideData.GetCurSize() && L"" == oInsideData.GetSubData(0, 6)) + { + CloseP(oXml, sSelectors); + oXml->WriteString(oInsideData.GetSubData(6, oInsideData.GetCurSize() - 6)); + sNote.clear(); + return; + } + + m_bInP = bInP; + m_bWasPStyle = bWasPStyle; + wrP(oXml, sSelectors, oTS); // Перекрестная ссылка внутри файла if(bCross) @@ -2511,14 +2562,8 @@ class CHtmlFile2_Private } oXml->WriteString(L"\">"); - if(!readStream(oXml, sSelectors, oTS)) - { - oXml->WriteString(L""); - wrRPr(oXml, sSelectors, oTS); - oXml->WriteString(L""); - oXml->WriteEncodeXmlString(sAlt); - oXml->WriteString(L""); - } + oXml->WriteString(oInsideData.GetData()); + if (m_bInP) { oXml->WriteString(L""); @@ -2545,6 +2590,7 @@ class CHtmlFile2_Private oXml->WriteString(L""); } } + sNote = L""; } @@ -2742,12 +2788,7 @@ class CHtmlFile2_Private std::wstring wrP(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) - { - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } + OpenP(oXml); if (m_bWasPStyle) return L""; From 5c6aaed51f359ad03a0e3a59520e02960833d420 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 3 May 2024 13:18:53 +0300 Subject: [PATCH 592/794] Fix svg file size --- .../raster/Metafile/svg/CSvgFile.cpp | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index 3d920e91f0e..08a7727073e 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -42,30 +42,40 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight SVG::TRect oWindow = m_oContainer.GetWindow(); - dX = oWindow.m_oX .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); - dY = oWindow.m_oY .ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); + dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); dWidth = 0.; dHeight = 0.; if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero()) { - if (NSCSS::Percent != oWindow.m_oWidth.GetUnitMeasure() && !m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) - dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel)); + if (NSCSS::Percent == oWindow.m_oWidth.GetUnitMeasure()) + { + if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel)); + else + dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + } else dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel); } - else if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero()) + else dWidth = m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel); if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero()) { - if (NSCSS::Percent != oWindow.m_oHeight.GetUnitMeasure() && !m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) - dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel)); + if (NSCSS::Percent == oWindow.m_oHeight.GetUnitMeasure()) + { + if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel)); + else + dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + } else dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel); } - else if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero()) + else dHeight = m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel); if (0. == dWidth) From ddc413a1b3ca8c892e63d084a873813a2aaf332b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 13:39:03 +0300 Subject: [PATCH 593/794] Fix EditPage when adding Link in edit mode --- PdfFile/PdfFile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 62e04cd7753..c69218d3b14 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1177,6 +1177,13 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Link: { CLinkCommand* pCommand = (CLinkCommand*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + { + PdfWriter::CPage* pCurrent = m_pInternal->pWriter->GetPage(); + m_pInternal->pEditor->EditPage(pCommand->GetPage()); + m_pInternal->pWriter->GetDocument()->SetCurPage(pCurrent); + m_pInternal->pWriter->EditPage(pCurrent); + } return m_pInternal->pWriter->AddLink(pCommand->GetX(), pCommand->GetY(), pCommand->GetW(), pCommand->GetH(), pCommand->GetDestX(), pCommand->GetDestY(), pCommand->GetPage()); } From ee85c3597ee45599a2aa5e74b24c977bb8a801b0 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 3 May 2024 15:06:19 +0300 Subject: [PATCH 594/794] fix bug #67011 --- OOXML/PPTXFormat/Logic/GraphicFrame.cpp | 8 ++++++++ OOXML/PPTXFormat/Logic/Pic.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp index 5ac86fbd345..4b34dc8e6f6 100644 --- a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp +++ b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp @@ -530,6 +530,14 @@ namespace PPTX if (olePic.is_init()) { + if (nvGraphicFramePr.IsInit()) + { + if (olePic->nvPicPr.cNvPr.id < 1) + olePic->nvPicPr.cNvPr.id = nvGraphicFramePr->cNvPr.id; + + if (olePic->nvPicPr.cNvPr.name.empty()) + olePic->nvPicPr.cNvPr.name = nvGraphicFramePr->cNvPr.name; + } olePic->toPPTY(pWriter); return; } diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 65b40dfdd66..163df8d7f7c 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -912,7 +912,7 @@ namespace PPTX bOle = true; pWriter->WriteString(L""); - pWriter->WriteString(L"WriteString(L"WriteString(L" name=\"" + nvPicPr.cNvPr.name + L"\""); pWriter->WriteString(L"/>"); From e107a67f5573a500a0c7d2b762fe967466d7d314 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 15:36:14 +0300 Subject: [PATCH 595/794] Fix delete Link annot in edit mode --- PdfFile/PdfEditor.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ecd6e54ec39..5b0dc80aaea 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -868,8 +868,33 @@ bool CPdfEditor::EditPage(int nPageIndex) { Object oTemp; char* chKey = pageObj.dictGetKey(nIndex); - if (strcmp("Resources", chKey) == 0 || strcmp("Annots", chKey) == 0) + if (strcmp("Resources", chKey) == 0) pageObj.dictGetVal(nIndex, &oTemp); + else if (strcmp("Annots", chKey) == 0) + { + // ВРЕМЕНО удаление Link аннотаций при редактировании + pageObj.dictGetVal(nIndex, &oTemp); + if (oTemp.isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pPage->Add("Annots", pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oAnnot, oSubtype; + if (oTemp.arrayGet(nIndex, &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Link")) + { + oAnnot.free(); oSubtype.free(); + continue; + } + oAnnot.free(); oSubtype.free(); + oTemp.arrayGetNF(nIndex, &oAnnot); + DictToCDictObject(&oAnnot, pArray, false, ""); + oAnnot.free(); + } + oTemp.free(); + continue; + } + } else if (strcmp("Contents", chKey) == 0) { pageObj.dictGetVal(nIndex, &oTemp); From 9dceffdbeb1eac2936509242a901fa654bbe737c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 15:36:51 +0300 Subject: [PATCH 596/794] Fix write RC to NSStringUtils::CStringBuilder --- PdfFile/OnlineOfficeBinToPdf.cpp | 4 +- PdfFile/PdfWriter.cpp | 130 ++++++++++++++++--------------- PdfFile/SrcWriter/Annotation.cpp | 5 +- PdfFile/SrcWriter/Annotation.h | 2 +- 4 files changed, 73 insertions(+), 68 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index fdc6bc08ad2..b41b122b247 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -153,7 +153,7 @@ namespace NSOnlineOfficeBinToPdf Undefined = 255 }; - bool AddBinToPdf(CPdfFile* pPdf, BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams) + bool AddBinToPdf(CPdfFile* pPdf, BYTE* pBuffer, unsigned int nBufferLen, CConvertFromBinParams* pParams) { CMetafileToRenderterPDF oCorrector(pPdf); oCorrector.SetTempDirectory(pPdf->GetTempDirectory()); @@ -167,7 +167,7 @@ namespace NSOnlineOfficeBinToPdf oCorrector.InitPicker(pPdf->GetFonts()); } - NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nLen); + NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nBufferLen); while (oReader.Check()) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index c6b64e2b207..67e44e90d04 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1646,72 +1646,48 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie return S_OK; } -std::string GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData) -{ - const char* c_pHexStrings[] = - { - "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", - "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", - "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", - "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", - "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" - }; - - std::string sRes; - sRes += "font-size:"; - sRes += std::to_string(pFontData->dFontSise); - sRes += "pt;text-align:"; +void GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData, NSStringUtils::CStringBuilder& oRC) +{ + oRC += L"font-size:"; + oRC.AddDouble(pFontData->dFontSise, 2); + oRC += L"pt;text-align:"; switch (pFontData->nAlignment) { - case 1: { sRes += "center"; break; } - case 2: { sRes += "right"; break; } - case 3: { sRes += "justify"; break; } + case 1: { oRC += L"center"; break; } + case 2: { oRC += L"right"; break; } + case 3: { oRC += L"justify"; break; } case 0: - default:{ sRes += "left"; break; } + default:{ oRC += L"left"; break; } } - sRes += ";text-decoration:"; + oRC += L";text-decoration:"; if ((pFontData->nFontFlag >> 4) & 1) - sRes += "word"; + oRC += L"word"; if ((pFontData->nFontFlag >> 3) & 1) { if ((pFontData->nFontFlag >> 4) & 1) - sRes += ' '; - sRes += "line-through"; - } - - sRes += ";color:#"; - sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[0] * 255.0)]; - sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[1] * 255.0)]; - sRes += c_pHexStrings[(unsigned char)(pFontData->dColor[2] * 255.0)]; - sRes += ";font-weight:"; - sRes += (pFontData->nFontFlag >> 0) & 1 ? "bold" : "normal"; - sRes += ";font-style:"; - sRes += (pFontData->nFontFlag >> 1) & 1 ? "italic" : "normal"; - sRes += ";font-family:"; - std::wstring sFont = pFontData->sActualFont.empty() ? pFontData->sFontFamily : pFontData->sActualFont; - sRes += U_TO_UTF8(sFont); + oRC += L" "; + oRC += L"line-through"; + } + + oRC += L";color:#"; + oRC.WriteHexColor3((unsigned char)(pFontData->dColor[0] * 255.0), + (unsigned char)(pFontData->dColor[1] * 255.0), + (unsigned char)(pFontData->dColor[2] * 255.0)); + oRC += L";font-weight:"; + oRC += (pFontData->nFontFlag >> 0) & 1 ? L"bold" : L"normal"; + oRC += L";font-style:"; + oRC += (pFontData->nFontFlag >> 1) & 1 ? L"italic" : L"normal"; + oRC += L";font-family:"; + oRC += pFontData->sActualFont.empty() ? pFontData->sFontFamily : pFontData->sActualFont; if (pFontData->dVAlign != 0) { - sRes += ";vertical-align:"; + oRC += L";vertical-align:"; if (pFontData->dVAlign > 0) - sRes += '+'; - sRes += std::to_string(pFontData->dVAlign); + oRC += L"+"; + oRC.AddDouble(pFontData->dVAlign, 2); } - - return sRes; } HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { @@ -1882,21 +1858,45 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pMarkupAnnot->SetT(pPr->GetT()); if (nFlags & (1 << 2)) pMarkupAnnot->SetCA(pPr->GetCA()); + std::wstring sDefaultStyle; if (nFlags & (1 << 3)) { - std::string sRC = "

"; + NSStringUtils::CStringBuilder oRC; + oRC += L"

"; std::vector arrRC = pPr->GetRC(); + + if (!arrRC.empty()) + { + NSStringUtils::CStringBuilder oDS; + oDS += L"font: Helvetica,sans-serif "; + oDS.AddDouble(arrRC[0]->dFontSise, 2); + oDS += L"pt; text-align:"; + switch (arrRC[0]->nAlignment) + { + case 1: { oDS += L"center"; break; } + case 2: { oDS += L"right"; break; } + case 3: { oDS += L"justify"; break; } + case 0: + default:{ oDS += L"left"; break; } + } + oDS += L"; color:"; + oDS.WriteHexColor3((unsigned char)(arrRC[0]->dColor[0] * 255.0), + (unsigned char)(arrRC[0]->dColor[1] * 255.0), + (unsigned char)(arrRC[0]->dColor[2] * 255.0)); + sDefaultStyle = oDS.GetData(); + } + for (int i = 0; i < arrRC.size(); ++i) { - sRC += ""; - sRC += U_TO_UTF8(arrRC[i]->sText); //TODO to_unicode - sRC += ""; + oRC += L""; + oRC.WriteEncodeXmlString(arrRC[i]->sText); + oRC += L""; } - sRC += "

"; - pMarkupAnnot->SetRC(sRC); + oRC += L"

"; + pMarkupAnnot->SetRC(oRC.GetData()); + std::cout << U_TO_UTF8(oRC.GetData()) << std::endl; } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); @@ -2034,8 +2034,12 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } if (nFlags & (1 << 16)) pFreeTextAnnot->SetCL(pPr->GetCL()); - if (nFlags & (1 << 17)) - pFreeTextAnnot->SetDS(pPr->GetDS()); + + std::wstring sDS = pPr->GetDS(); + if (sDS.empty()) + sDS = sDefaultStyle; + pFreeTextAnnot->SetDS(sDS); + if (nFlags & (1 << 18)) pFreeTextAnnot->SetLE(pPr->GetLE()); if (nFlags & (1 << 20)) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 7b89bc3fcc6..0a0c97fd29d 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -337,9 +337,10 @@ namespace PdfWriter if (!Get("T")) Add("T", new CStringObject(sValue.c_str(), true)); } - void CMarkupAnnotation::SetRC(const std::string& sRC) + void CMarkupAnnotation::SetRC(const std::wstring& wsRC) { - Add("RC", new CStringObject(sRC.c_str())); + std::string sValue = U_TO_UTF8(wsRC); + Add("RC", new CStringObject(sValue.c_str(), true)); } void CMarkupAnnotation::SetCD(const std::wstring& wsCD) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index d76a4b23f18..ca6d358a839 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -219,7 +219,7 @@ namespace PdfWriter void SetRT(BYTE nRT); void SetCA(const double& dCA); void SetT(const std::wstring& wsT); - void SetRC(const std::string& sRC); + void SetRC(const std::wstring& wsRC); void SetCD(const std::wstring& wsCD); void SetSubj(const std::wstring& wsSubj); From d516c625eb1b06713e5c544711267207021d3710 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 13:39:03 +0300 Subject: [PATCH 597/794] Fix EditPage when adding Link in edit mode --- PdfFile/PdfFile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 62e04cd7753..c69218d3b14 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1177,6 +1177,13 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Link: { CLinkCommand* pCommand = (CLinkCommand*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + { + PdfWriter::CPage* pCurrent = m_pInternal->pWriter->GetPage(); + m_pInternal->pEditor->EditPage(pCommand->GetPage()); + m_pInternal->pWriter->GetDocument()->SetCurPage(pCurrent); + m_pInternal->pWriter->EditPage(pCurrent); + } return m_pInternal->pWriter->AddLink(pCommand->GetX(), pCommand->GetY(), pCommand->GetW(), pCommand->GetH(), pCommand->GetDestX(), pCommand->GetDestY(), pCommand->GetPage()); } From 30e09e731bf87adcdd4704c00857386a98485bd1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 15:36:14 +0300 Subject: [PATCH 598/794] Fix delete Link annot in edit mode --- PdfFile/PdfEditor.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ecd6e54ec39..5b0dc80aaea 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -868,8 +868,33 @@ bool CPdfEditor::EditPage(int nPageIndex) { Object oTemp; char* chKey = pageObj.dictGetKey(nIndex); - if (strcmp("Resources", chKey) == 0 || strcmp("Annots", chKey) == 0) + if (strcmp("Resources", chKey) == 0) pageObj.dictGetVal(nIndex, &oTemp); + else if (strcmp("Annots", chKey) == 0) + { + // ВРЕМЕНО удаление Link аннотаций при редактировании + pageObj.dictGetVal(nIndex, &oTemp); + if (oTemp.isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pPage->Add("Annots", pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oAnnot, oSubtype; + if (oTemp.arrayGet(nIndex, &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Link")) + { + oAnnot.free(); oSubtype.free(); + continue; + } + oAnnot.free(); oSubtype.free(); + oTemp.arrayGetNF(nIndex, &oAnnot); + DictToCDictObject(&oAnnot, pArray, false, ""); + oAnnot.free(); + } + oTemp.free(); + continue; + } + } else if (strcmp("Contents", chKey) == 0) { pageObj.dictGetVal(nIndex, &oTemp); From 6de671ccd51d44eb5fab6ba24a567464e359c0fa Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 3 May 2024 15:57:29 +0300 Subject: [PATCH 599/794] Added language consideration when converting EPUB files --- EpubFile/src/CBookInfo.cpp | 7 ++++ EpubFile/src/CBookInfo.h | 1 + EpubFile/src/CEpubFile.cpp | 12 +++--- HtmlFile2/HtmlFile2.pro | 3 +- HtmlFile2/htmlfile2.cpp | 37 +++++++++++++---- HtmlFile2/htmlfile2.h | 6 +++ HtmlFile2/src/Languages.h | 84 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 HtmlFile2/src/Languages.h diff --git a/EpubFile/src/CBookInfo.cpp b/EpubFile/src/CBookInfo.cpp index 928f4ed924f..0f31c89958f 100644 --- a/EpubFile/src/CBookInfo.cpp +++ b/EpubFile/src/CBookInfo.cpp @@ -146,6 +146,13 @@ const std::wstring CBookInfo::GetLanguages() const return sLanguages; } +const std::wstring CBookInfo::GetLanguage() const +{ + if (m_arLanguages.empty()) + return L""; + return m_arLanguages.front(); +} + const std::wstring CBookInfo::GetContibutors() const { if (m_arContributors.empty()) diff --git a/EpubFile/src/CBookInfo.h b/EpubFile/src/CBookInfo.h index 86023084d0a..343adc8067c 100644 --- a/EpubFile/src/CBookInfo.h +++ b/EpubFile/src/CBookInfo.h @@ -30,6 +30,7 @@ class CBookInfo const std::wstring GetCreators() const; const std::wstring GetPublishers() const; const std::wstring GetLanguages() const; + const std::wstring GetLanguage() const; const std::wstring GetContibutors() const; const std::wstring GetDescriptions() const; const std::wstring GetSubjects() const; diff --git a/EpubFile/src/CEpubFile.cpp b/EpubFile/src/CEpubFile.cpp index 0dc7da562b5..7ef264aef4e 100644 --- a/EpubFile/src/CEpubFile.cpp +++ b/EpubFile/src/CEpubFile.cpp @@ -137,11 +137,13 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s CHtmlFile2 oFile; CHtmlParams oFileParams; - oFileParams.SetAuthors(m_oBookInfo.GetCreators()); - oFileParams.SetGenres (m_oBookInfo.GetSubjects()); - oFileParams.SetTitle (m_oBookInfo.GetTitle()); - oFileParams.SetDate (m_oBookInfo.GetDate()); - oFileParams.SetDescription(m_oBookInfo.GetDescriptions()); + oFileParams.SetAuthors (m_oBookInfo.GetCreators()); + oFileParams.SetGenres (m_oBookInfo.GetSubjects()); + oFileParams.SetTitle (m_oBookInfo.GetTitle()); + oFileParams.SetDate (m_oBookInfo.GetDate()); + oFileParams.SetDescription (m_oBookInfo.GetDescriptions()); + oFileParams.SetLanguage (m_oBookInfo.GetLanguage()); + oFileParams.SetPageBreakBefore(true); std::wstring sDocxFileTempDir = m_sTempDir + L"/tmp"; diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index f4ffd804490..97f6dd3cde2 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -31,4 +31,5 @@ ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network) SOURCES += htmlfile2.cpp HEADERS += htmlfile2.h \ - ./src/StringFinder.h + ./src/StringFinder.h \ + ./src/Languages.h diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index fa9624a57bd..d9174dbde87 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -27,6 +27,7 @@ #include "../DesktopEditor/raster/Metafile/svg/CSvgFile.h" #include "htmlfile2.h" +#include "src/Languages.h" #include @@ -41,16 +42,14 @@ #define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips #define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips +#define DEFAULT_LANGUAGE std::wstring(L"en-US") +#define DEFAULT_FONT_FAMILY std::wstring(L"Times New Roman") +#define DEFAULT_FONT_SIZE 24 + #define SAVE_NORMALIZED_HTML 0 std::wstring rStyle = L" a area b strong bdo bdi big br center cite dfn em i var code kbd samp tt del s font img ins u mark q rt sup small sub svg input basefont button label data object noscript output abbr time ruby progress hgroup meter span acronym "; -//struct CTree -//{ -// NSCSS::CNode m_oNode; -// std::vector m_arrChild; -//}; - // Ячейка таблицы struct CTc { @@ -1055,6 +1054,8 @@ class CHtmlFile2_Private m_oNumberXml.AddCharSafe(167); m_oNumberXml += L"\"/>"; + std::wstring wsCurrentLanguage; + // core.xml std::wstring sCore = L""; if(oParams) @@ -1089,6 +1090,14 @@ class CHtmlFile2_Private sCore += EncodeXmlString(oParams->m_sDescription); sCore += L""; } + if (!oParams->m_sLanguage.empty()) + { + wsCurrentLanguage = IndentifyLanguage(oParams->m_sLanguage); + + sCore += L""; + sCore += wsCurrentLanguage; + sCore += L""; + } } sCore += L""; NSFile::CFileBinary oCoreWriter; @@ -1117,13 +1126,25 @@ class CHtmlFile2_Private if(oParams && !oParams->m_sdocDefaults.empty()) m_oStylesXml += oParams->m_sdocDefaults; else - m_oStylesXml += L""; + { + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + + m_oStylesXml += L""; + } // normal по умолчанию if(oParams && !oParams->m_sNormal.empty()) m_oStylesXml += oParams->m_sNormal; else - m_oStylesXml += L""; + { + m_oStylesXml += L""; + m_oStylesXml += L""; + m_oStylesXml += L""; + } // Маркированный список m_oStylesXml += L""; diff --git a/HtmlFile2/htmlfile2.h b/HtmlFile2/htmlfile2.h index 9ecb12486df..80ed8f1214a 100644 --- a/HtmlFile2/htmlfile2.h +++ b/HtmlFile2/htmlfile2.h @@ -19,6 +19,7 @@ struct CHtmlParams std::wstring m_sBookTitle; // Название std::wstring m_sDate; // Дата std::wstring m_sDescription; // описание + std::wstring m_sLanguage; // Язык bool m_bNeedPageBreakBefore; // Новый html с новой страницы std::wstring m_sdocDefaults; // Стиль docDefaults std::wstring m_sNormal; // Стиль normal @@ -64,6 +65,11 @@ struct CHtmlParams { m_sBookTitle = sTitle; } + + void SetLanguage(const std::wstring& sLanguage) + { + m_sLanguage = sLanguage; + } }; class CHtmlFile2_Private; diff --git a/HtmlFile2/src/Languages.h b/HtmlFile2/src/Languages.h new file mode 100644 index 00000000000..e267415ebec --- /dev/null +++ b/HtmlFile2/src/Languages.h @@ -0,0 +1,84 @@ +#ifndef LANGUAGES_LIST_H +#define LANGUAGES_LIST_H + +#include +#include +#include + +const static std::map m_Languages_HTML +{ + //Язык, Регион + {L"en", L"US"}, // Английский - США + {L"ru", L"RU"}, // Русский - Россия + {L"es", L"ES"}, // Испанский - Испания + {L"de", L"DE"}, // Немецкий - Германия + {L"fr", L"FR"}, // Французский - Франция + {L"it", L"IT"}, // Итальянский - Италия + {L"pt", L"PT"}, // Португальский - Португалия + {L"pl", L"PL"}, // Польский - Польша + {L"nl", L"NL"}, // Нидерландский - Нидерланды + {L"sv", L"SE"}, // Шведский - Швеция + {L"nb", L"NO"}, // Норвежский - Новегия + {L"da", L"DK"}, // Датский - Дания + {L"fi", L"FI"}, // Финский - Финляндия + {L"el", L"GR"}, // Греческий - Греция + {L"tr", L"TR"}, // Турецкий - Турция + {L"ar", L"SA"}, // Арабский - Саудовская Аравия + {L"he", L"IL"}, // Иврит - Израиль + {L"ja", L"JP"}, // Японский - Япония + {L"zh", L"CN"}, // Китайский (упрощенный) - Китай + {L"hu", L"HU"}, // Венгерский - Венгрия + {L"cs", L"CZ"}, // Чешский - Чехия + {L"ro", L"RO"}, // Румынский - Румыния + {L"bg", L"BG"}, // Болгарский - Болгария + {L"hr", L"HR"}, // Хорватский - Хорватия + {L"sr", L"Latn-RS"}, //Сербский - Сербия + {L"sl", L"SI"}, // Словенский - Словения + {L"lt", L"LT"}, // Литовский - Литва + {L"lv", L"LV"}, // Латышский - Латвия + {L"et", L"EE"}, // Эстонский - Эстония + {L"uk", L"UA"}, // Украинский - Украина + {L"be", L"BY"}, // Белорусский - Беларусь + {L"kk", L"KZ"}, // Казахский - Казахстан + {L"hi", L"IN"}, // Хинди - Индия + {L"th", L"TH"}, // Тайский - Таиланд + {L"vi", L"VN"}, // Вьетнамский - Вьетнам + {L"id", L"ID"}, // Индонезийский - Индонезия + {L"ms", L"MY"}, // Малайский - Малайзия + {L"fil", L"PH"}, // Филиппинский - Филиппины + {L"ko", L"KR"}, // Корейский - Южная Корея + {L"is", L"IS"}, // Исландский - Исландия + {L"ga", L"IE"}, // Ирландский - Ирландия + {L"cy", L"GB"}, // Валлийский - Великобритания + {L"ca", L"ES"}, // Каталанский - Испания + {L"eu", L"ES"}, // Баскский - Испания + {L"gl", L"ES"}, // Галисийский - Испания + {L"af", L"ZA"}, // Африкаанс - Южная Африка + {L"zu", L"ZA"}, // Зулу - Южная Африка + {L"ha", L"Latn-NG"}, // Хауса - Нигерия + {L"yo", L"NG"}, // Йоруба - Нигерия + {L"sw", L"KE"}, // Суахили - Кения + {L"am", L"ET"}, // Амхарский - Эфиопия + {L"ti", L"ET"}, // Тигринья - Эфиопия + {L"ur", L"PK"}, // Урду - Пакистан + {L"pa", L"IN"}, // Панджаби - Индия + {L"gu", L"IN"}, // Гуджарати - Индия + {L"ta", L"IN"}, // Тамильский - Индия + {L"te", L"IN"}, // Телугу - Индия + {L"ml", L"IN"}, // Малаялам - Индия + {L"kn", L"IN"} // Каннада - Индия +}; + +static std::wstring IndentifyLanguage(std::wstring wsLanguage) +{ + std::transform(wsLanguage.begin(), wsLanguage.end(), wsLanguage.begin(), towlower); + + std::map::const_iterator itFounded = m_Languages_HTML.find(wsLanguage); + + if (m_Languages_HTML.end() != itFounded) + return itFounded->first + L"-" + itFounded->second; + + return std::wstring(); +} + +#endif // LANGUAGES_LIST_H From 715facaefc40119e535bf706e6a6b69e134c6e83 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 3 May 2024 17:32:37 +0300 Subject: [PATCH 600/794] Create AP for FreeText --- PdfFile/PdfWriter.cpp | 41 +++++++++++++++++++++++++------- PdfFile/PdfWriter.h | 1 + PdfFile/SrcWriter/Annotation.cpp | 36 ++++++++++++++++++++++++++++ PdfFile/SrcWriter/Annotation.h | 7 ++++++ 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 67e44e90d04..1408a110b00 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2022,30 +2022,49 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } else if (oInfo.IsFreeText()) { - CAnnotFieldInfo::CFreeTextAnnotPr* pPr = oInfo.GetFreeTextAnnotPr(); + CAnnotFieldInfo::CFreeTextAnnotPr* pFTPr = oInfo.GetFreeTextAnnotPr(); PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot; - pFreeTextAnnot->SetQ(pPr->GetQ()); + pFreeTextAnnot->SetQ(pFTPr->GetQ()); if (nFlags & (1 << 15)) { double dRD1, dRD2, dRD3, dRD4; - pPr->GetRD(dRD1, dRD2, dRD3, dRD4); + pFTPr->GetRD(dRD1, dRD2, dRD3, dRD4); pFreeTextAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); } if (nFlags & (1 << 16)) - pFreeTextAnnot->SetCL(pPr->GetCL()); + pFreeTextAnnot->SetCL(pFTPr->GetCL()); - std::wstring sDS = pPr->GetDS(); + std::wstring sDS = pFTPr->GetDS(); if (sDS.empty()) sDS = sDefaultStyle; pFreeTextAnnot->SetDS(sDS); if (nFlags & (1 << 18)) - pFreeTextAnnot->SetLE(pPr->GetLE()); + pFreeTextAnnot->SetLE(pFTPr->GetLE()); if (nFlags & (1 << 20)) - pFreeTextAnnot->SetIT(pPr->GetIT()); + pFreeTextAnnot->SetIT(pFTPr->GetIT()); if (nFlags & (1 << 21)) - pFreeTextAnnot->SetIC(pPr->GetIC()); + pFreeTextAnnot->SetIC(pFTPr->GetIC()); + + std::vector arrRC = pPr->GetRC(); + double dFontSize = 10.0; + if (!arrRC.empty()) + { + dFontSize = arrRC[0]->dFontSise; + std::wstring wsFontName = arrRC[0]->sActualFont.empty() ? arrRC[0]->sFontFamily : arrRC[0]->sActualFont; + if (wsFontName == L"Times-Roman" || wsFontName == L"Times-Bold" || wsFontName == L"Times-BoldItalic" || wsFontName == L"Times-Italic") + wsFontName = L"Times New Roman"; + int nStyle = arrRC[0]->nFontFlag; + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + } + if (m_bNeedUpdateTextFont) + UpdateFont(); + pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); // Можно указать полный шрифт? + + DrawFreeTextAnnot(pFreeTextAnnot, pPr->GetRC(), oInfo.GetC()); } else if (oInfo.IsCaret()) { @@ -3861,3 +3880,9 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit RELEASEARRAYOBJECTS(pCodes); RELEASEARRAYOBJECTS(ppFonts); } +void CPdfWriter::DrawFreeTextAnnot(PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC) +{ + // TODO шрифты + pFreeTextAnnot->StartAP(arrC); + pFreeTextAnnot->EndAP(); +} diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index b031adfde00..6e7907853ef 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -244,6 +244,7 @@ class CPdfWriter void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); + void DrawFreeTextAnnot(PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC); private: NSFonts::IFontManager* m_pFontManager; diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 0a0c97fd29d..7a68ead6096 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1056,6 +1056,42 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText) { + m_pAppearance = NULL; + } + void CFreeTextAnnotation::StartAP(const std::vector& arrC) + { + m_pAppearance = new CAnnotAppearance(m_pXref, this); + if (!m_pAppearance) + return; + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + + // TODO рисование + } + void CFreeTextAnnotation::EndAP() + { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->EndDraw(); + } + void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC) + { + CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); + const char* sFontName = pFieldsResources->GetFontName(pFont); + + std::string sDA = GetColor(arrC, false); + if (sFontName) + { + sDA.append(" /"); + sDA.append(sFontName); + } + + sDA.append(" "); + sDA.append(std::to_string(dFontSize)); + sDA.append(" Tf"); + + Add("DA", new CStringObject(sDA.c_str())); } void CFreeTextAnnotation::SetQ(BYTE nQ) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index ca6d358a839..a7b95482445 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -349,6 +349,9 @@ namespace PdfWriter }; class CFreeTextAnnotation : public CMarkupAnnotation { + private: + CAnnotAppearance* m_pAppearance; + public: CFreeTextAnnotation(CXref* pXref); EAnnotType GetAnnotationType() const override @@ -356,6 +359,10 @@ namespace PdfWriter return AnnotFreeText; } + void StartAP(const std::vector& arrC); + void EndAP(); + void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC); + void SetQ(BYTE nQ); void SetIT(BYTE nIT); void SetLE(BYTE nLE); From f1544a6f6c21fed5835e11a024495cadd7672798 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Fri, 3 May 2024 22:50:16 +0300 Subject: [PATCH 601/794] Fix bug#67829 --- .../3dParty/html/css/src/StyleProperties.cpp | 23 ++++++++++- Common/3dParty/html/css/src/StyleProperties.h | 3 ++ HtmlFile2/htmlfile2.cpp | 38 ++++++++++++++----- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 4b1aa1f6596..e4b8be90b58 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -25,7 +25,7 @@ namespace NSCSS } CString::CString() - : CValue(L"", 0, false) + : CValue(L"", 0, false) {} CString::CString(const std::wstring &wsValue, unsigned int unLevel, bool bImportant) @@ -1508,6 +1508,15 @@ namespace NSCSS m_oColor == oBorderSide.m_oColor; } + CBorderSide &CBorderSide::operator =(const CBorderSide &oBorderSide) + { + m_oWidth = oBorderSide.m_oWidth; + m_oStyle = oBorderSide.m_oStyle; + m_oColor = oBorderSide.m_oColor; + + return *this; + } + // BORDER CBorder::CBorder() { @@ -1744,6 +1753,18 @@ namespace NSCSS m_oBottom == oBorder.m_oBottom; } + CBorder &CBorder::operator =(const CBorder &oBorder) + { + m_oLeft = oBorder.m_oLeft; + m_oTop = oBorder.m_oTop; + m_oRight = oBorder.m_oRight; + m_oBottom = oBorder.m_oBottom; + + m_enCollapse = oBorder.m_enCollapse; + + return *this; + } + // TEXT CText::CText() {} diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 1d3e2c762fc..cfe494a916d 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -444,6 +444,7 @@ namespace NSCSS CBorderSide& operator+=(const CBorderSide& oBorderSide); bool operator==(const CBorderSide& oBorderSide) const; + CBorderSide& operator =(const CBorderSide& oBorderSide); private: CDigit m_oWidth; CString m_oStyle; @@ -513,6 +514,8 @@ namespace NSCSS CBorder& operator+=(const CBorder& oBorder); bool operator==(const CBorder& oBorder) const; + + CBorder& operator =(const CBorder& oBorder); private: CBorderSide m_oLeft; CBorderSide m_oTop; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index d9174dbde87..e2bdf5d29f1 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -196,34 +196,49 @@ struct TTableCellStyle std::wstring m_wsVAlign; TTableCellStyle(){} - + bool Empty() { return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty(); } + + void Copy(const TTableCellStyle* pTableCellStyle) + { + if (NULL == pTableCellStyle) + return; + + m_oWidth = pTableCellStyle->m_oWidth; + m_oHeight = pTableCellStyle->m_oHeight; + m_oBorder = pTableCellStyle->m_oBorder; + m_oPadding = pTableCellStyle->m_oPadding; + m_oBackground = pTableCellStyle->m_oBackground; + + m_wsHAlign = pTableCellStyle->m_wsHAlign; + m_wsVAlign = pTableCellStyle->m_wsVAlign; + } }; class CTableCell { public: CTableCell() - : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_enMode(ParseModeBody) + : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_enMode(ParseModeBody) {} - CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged) - : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_enMode(ParseModeBody) + CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty) + : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_bIsEmpty(bIsEmpty), m_enMode(ParseModeBody) {} CTableCell(CTableCell& oCell) : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), - m_enMode(oCell.m_enMode), m_oStyles(oCell.m_oStyles) + m_bIsEmpty(oCell.m_bIsEmpty), m_enMode(oCell.m_enMode), m_oStyles(oCell.m_oStyles) { m_oData.SetText(oCell.m_oData.GetData()); } bool Empty() { - return 0 == m_oData.GetCurSize(); + return m_bIsEmpty; } CTableCell* Copy() @@ -233,10 +248,9 @@ class CTableCell static CTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL) { - CTableCell *pCell = new CTableCell(unColspan, 1, m_bIsMerged); + CTableCell *pCell = new CTableCell(unColspan, 1, m_bIsMerged, true); - if (NULL != pStyle) - pCell->m_oStyles = *pStyle; + pCell->m_oStyles.Copy(pStyle); return pCell; } @@ -413,6 +427,7 @@ class CTableCell UINT m_unRowSpan; bool m_bIsMerged; + bool m_bIsEmpty; ERowParseMode m_enMode; TTableCellStyle m_oStyles; @@ -2206,7 +2221,7 @@ class CHtmlFile2_Private void ParseTableRows(CTable& oTable, std::vector& sSelectors, const CTextSettings& oTS, ERowParseMode eMode) { std::vector arRowspanElements; - + int nDeath = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nDeath)) { @@ -2234,6 +2249,9 @@ class CHtmlFile2_Private { CTableCell *pCell = new CTableCell(); + if (NULL == pCell) + continue; + pCell->SetMode(eMode); GetSubClass(pCell->GetData(), sSelectors); From 051ae3fab6449708aafdfca99efa64dae94573fe Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sat, 4 May 2024 00:33:35 +0300 Subject: [PATCH 602/794] Fix bug #67836 --- .../3dParty/html/css/src/CCompiledStyle.cpp | 5 ++ Common/3dParty/html/css/src/CCompiledStyle.h | 1 + .../html/css/src/CCssCalculator_Private.cpp | 29 ++--------- .../html/css/src/CCssCalculator_Private.h | 2 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 50 ++++++++++++------- .../html/css/src/xhtml/CDocumentStyle.h | 13 ++--- .../html/css/src/xhtml/CXmlElement.cpp | 2 +- .../3dParty/html/css/src/xhtml/CXmlElement.h | 2 +- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 8504f7ee073..76617ed6a1c 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -488,6 +488,11 @@ namespace NSCSS return arParentsName; } + std::set CCompiledStyle::GetParentsNamesSet() const + { + return m_arParentsStyles; + } + void CCompiledStyle::SetID(const std::wstring& sId) { m_sId = sId; diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 73cca6b0f62..7877945a6b3 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -48,6 +48,7 @@ namespace NSCSS void AddParent(const std::wstring& sParentName); std::vector GetParentsName() const; + std::set GetParentsNamesSet() const; void SetID(const std::wstring& sId); std::wstring GetId() const; diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 085e945bc2d..d4d6621dba2 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -52,13 +52,6 @@ namespace NSCSS m_mData.clear(); - #ifdef CSS_CALCULATOR_WITH_XHTML - for (std::map, CCompiledStyle*>::iterator iter = m_mUsedStyles.begin(); iter != m_mUsedStyles.end(); ++iter) - delete iter->second; - - m_mUsedStyles.clear(); - #endif - if (NULL != m_mStatictics) delete m_mStatictics; } @@ -494,11 +487,11 @@ namespace NSCSS if (!bIsSettings) { - const std::map, CCompiledStyle*>::iterator oItem = m_mUsedStyles.find(arSelectors); + const std::map, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors); if (oItem != m_mUsedStyles.end()) { - oStyle = *oItem->second; + oStyle = oItem->second; return true; } } @@ -562,22 +555,10 @@ namespace NSCSS oStyle += oTempStyle; } - if (!bIsSettings) - { - std::map, CCompiledStyle*>::const_iterator itFound = std::find_if(m_mUsedStyles.begin(), m_mUsedStyles.end(), [oStyle](const std::pair, CCompiledStyle*>& oValue){ return (*oValue.second) == oStyle; }); - - if (m_mUsedStyles.end() != itFound) - { - oStyle = *itFound->second; - return true; - } - - oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); + oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes)); - CCompiledStyle *pTemp = new CCompiledStyle(oStyle); - - m_mUsedStyles[arSelectors] = pTemp; - } + if (!bIsSettings && !oStyle.Empty()) + m_mUsedStyles[arSelectors] = oStyle; return true; } diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 814da70b583..7bda5a79375 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -37,7 +37,7 @@ namespace NSCSS std::map *m_mStatictics; // Количество повторений свойств id и style у селекторов #ifdef CSS_CALCULATOR_WITH_XHTML - std::map, CCompiledStyle*> m_mUsedStyles; + std::map, CCompiledStyle> m_mUsedStyles; std::map GetPageData(const std::wstring& wsPageName); void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index a7cead51aea..8adb0dab1ef 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -12,31 +12,47 @@ namespace NSCSS { - CStyleUsed::CStyleUsed(const std::wstring &wsId, bool bIsPStyle) - : m_bIsPStyle(bIsPStyle), m_wsId(wsId) + CStyleUsed::CStyleUsed(const CCompiledStyle &oStyle, bool bIsPStyle) + : m_oStyle(oStyle), m_bIsPStyle(bIsPStyle) {} + bool CheckArrays(const std::vector& arInitial, const std::set& arFirst, const std::set& arSecond) + { + std::set arInitialSet(arInitial.begin(), arInitial.end()); + + std::vector arCommonElements1; + std::vector arCommonElements2; + + std::set_intersection(arInitialSet.begin(), arInitialSet.end(), arFirst.begin(), arFirst.end(), std::back_inserter(arCommonElements1)); + std::set_intersection(arInitialSet.begin(), arInitialSet.end(), arSecond.begin(), arSecond.end(), std::back_inserter(arCommonElements2)); + + if (arCommonElements1.size() != arCommonElements2.size()) + return false; + + return arCommonElements1 == arCommonElements2; + } + bool CStyleUsed::operator==(const CStyleUsed &oUsedStyle) const { - return (m_bIsPStyle == oUsedStyle.m_bIsPStyle) && (m_wsId == oUsedStyle.m_wsId); + return m_bIsPStyle == oUsedStyle.m_bIsPStyle && + CheckArrays(Names_Standard_Styles, m_oStyle.GetParentsNamesSet(), oUsedStyle.m_oStyle.GetParentsNamesSet()) && + m_oStyle == oUsedStyle.m_oStyle; } std::wstring CStyleUsed::getId() { if (m_bIsPStyle) - return m_wsId; + return m_oStyle.GetId(); - return m_wsId + L"-c"; + return m_oStyle.GetId() + L"-c"; } - void CStyleUsed::setId(const std::wstring &sId) + CDocumentStyle::CDocumentStyle() : m_arStandardStyles(Names_Standard_Styles) { - m_wsId = sId; + for (const std::wstring& oNameStandardStyle : Names_Standard_Styles) + m_arStandardStyles.push_back(oNameStandardStyle + L"-c"); } - CDocumentStyle::CDocumentStyle() : m_arStandardStyles({L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"h1-c", - L"h2-c", L"h3-c", L"h4-c", L"h5-c", L"h6-c", L"p-c", L"p", L"div-c", L"div", L"a-c"}) {} - CDocumentStyle::~CDocumentStyle() { m_arStandardStyles. clear(); @@ -438,6 +454,7 @@ namespace NSCSS void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) { ConvertStyle(oStyle, oXmlElement, false); + if (oStyle.Empty() && oXmlElement.Empty()) return; @@ -482,9 +499,9 @@ namespace NSCSS return false; } - CStyleUsed structStyle(oStyle.GetId(), false); + CStyleUsed structStyle(oStyle, false); - std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); + std::vector::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); if (oItem != m_arStyleUsed.end()) { @@ -544,8 +561,8 @@ namespace NSCSS return true; } - CStyleUsed structStyle(oStyle.GetId(), true); - std::list::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); + CStyleUsed structStyle(oStyle, true); + std::vector::iterator oItem = std::find(m_arStyleUsed.begin(), m_arStyleUsed.end(), structStyle); if (oItem != m_arStyleUsed.end()) { @@ -559,11 +576,6 @@ namespace NSCSS if (oXmlElement.Empty()) return false; - structStyle.setId(oXmlElement.GetStyleId()); - - if (structStyle.getId().empty()) - structStyle.setId(m_sId); - m_arStyleUsed.push_back(structStyle); m_sStyle += oXmlElement.GetPStyle(); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 87b132bd9ba..470e306e7bd 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -10,27 +10,28 @@ namespace NSCSS { class CStyleUsed { + CCompiledStyle m_oStyle; bool m_bIsPStyle; - std::wstring m_wsId; public: - CStyleUsed(const std::wstring& wsId, bool bIsPStyle); + CStyleUsed(const CCompiledStyle& oStyle, bool bIsPStyle); bool operator==(const CStyleUsed& oUsedStyle) const; std::wstring getId(); - void setId(const std::wstring& sId); }; + static const std::vector Names_Standard_Styles = {L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6",L"p", L"div"}; + class CSSCALCULATOR_EXPORT CDocumentStyle { typedef NSConstValues::NSProperties::BasicProperties BProperties; typedef NSConstValues::NSProperties::ParagraphProperties PProperties; typedef NSConstValues::NSProperties::RunnerProperties RProperties; - std::list m_arStandardStylesUsed; - std::list m_arStandardStyles; - std::list m_arStyleUsed; + std::vector m_arStandardStylesUsed; + std::vector m_arStandardStyles; + std::vector m_arStyleUsed; std::wstring m_sStyle; std::wstring m_sId; diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 8341aba31fd..199e1f2dd4b 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -298,7 +298,7 @@ CXmlElement& CXmlElement::operator=(const CXmlElement& oElement) return *this; } -bool CXmlElement::operator==(const CXmlElement &oElement) +bool CXmlElement::operator==(const CXmlElement &oElement) const { return m_mBasicValues == oElement.m_mBasicValues && m_mPStyleValues == oElement.m_mPStyleValues && diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.h b/Common/3dParty/html/css/src/xhtml/CXmlElement.h index 4a7b0fa4bd8..8c5835abe76 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.h +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.h @@ -47,7 +47,7 @@ class CXmlElement CXmlElement& operator+=(const CXmlElement& oElement); CXmlElement& operator= (const CXmlElement& oelement); - bool operator== (const CXmlElement& oElement); + bool operator== (const CXmlElement& oElement) const; }; #endif // CXMLELEMENT_H From a2e76364e9e90e1728260df60d43e8c62cbba7d1 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sat, 4 May 2024 15:19:06 +0300 Subject: [PATCH 603/794] Fix bug #67827 --- .../3dParty/html/css/src/StyleProperties.cpp | 4 +- Common/3dParty/html/htmltoxhtml.h | 67 ++++++++++------- HtmlFile2/htmlfile2.cpp | 33 ++------- HtmlFile2/src/StringFinder.h | 71 ++++++++++--------- 4 files changed, 85 insertions(+), 90 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index e4b8be90b58..c2ffb22901c 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -63,7 +63,7 @@ namespace NSCSS if (m_bImportant && !bImportant) return false; - if (arValiableValues.end() != std::find(arValiableValues.begin(), arValiableValues.end(), wsNewValue))\ + if (arValiableValues.end() != std::find(arValiableValues.begin(), arValiableValues.end(), wsNewValue)) { m_oValue = wsNewValue; m_unLevel = unLevel; @@ -1131,7 +1131,7 @@ namespace NSCSS bool CDisplay::SetDisplay(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return m_oHAlign.SetValue(wsValue, NSConstValues::DISPLAY_VALUES, unLevel, bHardMode); + return m_oDisplay.SetValue(wsValue, NSConstValues::DISPLAY_VALUES, unLevel, bHardMode); } const CDigit& CDisplay::GetX() const diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index c1c1b38442e..b417716bcff 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -40,10 +40,10 @@ static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) { if (bNeedConvert) { // Определение кодировки - std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\""}); + std::string sEncoding = NSStringFinder::FindPropety(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\""}).m_sValue; if (sEncoding.empty()) - sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}); + sEncoding = NSStringFinder::FindPropety(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue; if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding)) { @@ -204,49 +204,60 @@ static std::string QuotedPrintableDecode(const std::string& sContent, std::strin static void ReadMht(const std::string& sMhtContent, std::map& sRes, NSStringUtils::CStringBuilderA& oRes) { - size_t unContentPosition = 0, unLastPosition = 0; + size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos; + NSStringFinder::TFoundedData oData; + // Content-Type - std::string sContentType = NSStringFinder::FindPropety(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); + oData = NSStringFinder::FindPropety(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"}); + const std::string sContentType{oData.m_sValue}; if (sContentType.empty()) return; - + if (NSStringFinder::Equals(sContentType, "multipart/alternative")) { - oRes.WriteString(mhtTohtml(sMhtContent.substr(unLastPosition, sMhtContent.length() - unLastPosition))); + oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition))); return; } - unContentPosition = std::max(unContentPosition, unLastPosition); + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetBegin = oData.m_unEndPosition; // name // std::string sName = NSStringFinder::FindPropety(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition); // unContentPosition = std::max(unContentPosition, unLastPosition); - // charset - std::string sCharset = NSStringFinder::FindPropety(sMhtContent, "charset", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition); - unContentPosition = std::max(unContentPosition, unLastPosition); - NSStringFinder::CutInside(sCharset, "\""); - // Content-Location - std::string sContentLocation = NSStringFinder::FindPropety(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); - unContentPosition = std::max(unContentPosition, unLastPosition); + oData = NSStringFinder::FindPropety(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"}); + std::string sContentLocation{oData.m_sValue}; + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); - if (sContentLocation.empty()) - { - // Content-ID - std::string sContentID = NSStringFinder::FindPropety(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); - unContentPosition = std::max(unContentPosition, unLastPosition); - NSStringFinder::CutInside(sCharset, "<", ">"); + // Content-ID + oData = NSStringFinder::FindPropety(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"}); + std::string sContentID{oData.m_sValue}; + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + NSStringFinder::CutInside(sContentID, "<", ">"); - if (!sContentID.empty()) - sContentLocation = "cid:" + sContentID; - } + if (sContentLocation.empty() && !sContentID.empty()) + sContentLocation = "cid:" + sContentID; // Content-Transfer-Encoding - std::string sContentEncoding = NSStringFinder::FindPropety(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}, 0, unLastPosition); - unContentPosition = std::max(unContentPosition, unLastPosition); + oData = NSStringFinder::FindPropety(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}); + const std::string sContentEncoding{oData.m_sValue}; + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + + // charset + std::string sCharset = "utf-8"; + + if (unCharsetBegin < unCharsetEnd) + { + sCharset = NSStringFinder::FindPropety(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue; + NSStringFinder::CutInside(sCharset, "\""); + } // Content std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition); @@ -312,9 +323,11 @@ static std::string mhtTohtml(const std::string& sFileContent) std::map sRes; NSStringUtils::CStringBuilderA oRes; - size_t nFound = 0; // Поиск boundary - std::string sBoundary = NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""}, 0, nFound); + NSStringFinder::TFoundedData oData{NSStringFinder::FindPropety(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})}; + + size_t nFound{oData.m_unEndPosition}; + std::string sBoundary{oData.m_sValue}; if (sBoundary.empty()) { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index e2bdf5d29f1..077447b99f6 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1580,21 +1580,6 @@ class CHtmlFile2_Private m_bInT = false; } - void CheckA(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) - { - for (std::vector::const_reverse_iterator itNode = arSelectors.crbegin(); itNode < arSelectors.crend(); ++itNode) - { - if (NodeBelongToTable(itNode->m_wsName)) - break; - - if (L"a" == itNode->m_wsName) - { - pXml->WriteString(L""); - break; - } - } - } - void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector& arSelectors) { m_bWasSpace = true; @@ -1602,8 +1587,6 @@ class CHtmlFile2_Private if (!m_bInP) return; - CheckA(pXml, arSelectors); - CloseT(pXml); CloseR(pXml); @@ -2934,8 +2917,10 @@ class CHtmlFile2_Private std::wstring sImageName = sImageId + L'.' + sExtention; CBgraFrame oBgraFrame; if (!oBgraFrame.OpenFile(m_sDst + L"/word/media/i" + sImageName)) + { + NSFile::CFileBinary::Remove(m_sDst + L"/word/media/i" + sImageName); return; - + } // Прописать рельсы if (bNew) { @@ -2995,15 +2980,9 @@ class CHtmlFile2_Private { if(sNote.empty()) return; - if (!m_bInP) - { - oXml->WriteString(L""); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L""); - m_bInP = true; - m_bWasPStyle = false; - } + + OpenP(oXml); + oXml->WriteString(L"WriteString(std::to_wstring(m_nFootnoteId)); oXml->WriteString(L"\"/>"); diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index e66b1b00456..01479d37255 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -13,6 +13,18 @@ namespace NSStringFinder { + template, std::allocator>> + struct TFoundedData + { + size_t m_unBeginPosition; + size_t m_unEndPosition; + StringType m_sValue; + + TFoundedData() + : m_unBeginPosition(0), m_unEndPosition(0) + {} + }; + template, std::allocator>> StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) { @@ -66,70 +78,61 @@ namespace NSStringFinder } template, std::allocator>> - StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) + TFoundedData FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting) { if (sString.length() < unStarting) - return StringType(); + return TFoundedData(); - std::string sRegexValue = "(?i)" + std::string(sProperty.begin(), sProperty.end()); + std::wstring wsRegexValue = L"(?i)" + std::wstring(sProperty.begin(), sProperty.end()); if (!arDelimiters.empty()) { - sRegexValue += "\\s*["; - for (const StringType& sDelimiter : arDelimiters) - sRegexValue += std::string(sDelimiter.begin(), sDelimiter.end()) + "|"; - sRegexValue.pop_back(); - sRegexValue += "]{1}"; + wsRegexValue += L"\\s*["; + for (const StringType& wsDelimiter : arDelimiters) + wsRegexValue += std::wstring(wsDelimiter.begin(), wsDelimiter.end()) + L"|"; + wsRegexValue.pop_back(); + wsRegexValue += L"]{1}"; } if (!arEndings.empty()) { - std::string sEndingValue; + std::wstring wsEndingValue; for (const StringType& sEnding : arEndings) - sEndingValue += std::string(sEnding.begin(), sEnding.end()) + "|"; + wsEndingValue += std::wstring(sEnding.begin(), sEnding.end()) + L"|"; - sEndingValue.pop_back(); + wsEndingValue.pop_back(); - sRegexValue += "\\s*(.[^" + sEndingValue + "]*)\\s*[" + sEndingValue + "]?"; + wsRegexValue += L"\\s*(.[^" + wsEndingValue + L"]*)\\s*[" + wsEndingValue + L"]?"; } else - sRegexValue += "\\s*(.*)[\\n|\\r]?"; + wsRegexValue += L"\\s*(.*)[\\n|\\r]?"; - boost::regex oRegex(sRegexValue); + boost::wregex oRegex(wsRegexValue); boost::match_results oResult; if (!boost::regex_search(sString.begin() + unStarting, sString.end(), oResult, oRegex)) - return StringType(); + return TFoundedData(); - unEndPosition = unStarting + oResult.position() + oResult.length(); + TFoundedData oData; - StringType sValue(oResult[1]); - boost::algorithm::trim(sValue); + oData.m_unBeginPosition = unStarting + oResult.position(); + oData.m_unEndPosition = unStarting + oResult.position() + oResult.length(); - return sValue; - } + oData.m_sValue = oResult[1]; + boost::algorithm::trim(oData.m_sValue); - std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) - { - return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting, unEndPosition); + return oData; } - std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting, size_t& unEndPosition) + TFoundedData FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) { - return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting, unEndPosition); + return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting); } - std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) + TFoundedData FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) { - size_t unEndPosition = 0; - return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting, unEndPosition); - } - - std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) - { - size_t unEndPosition = 0; - return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting, unEndPosition); + return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting); } template From c88c1aac9624bda0efe1b5f7a3ce93df70ccef69 Mon Sep 17 00:00:00 2001 From: Michael Efremov Date: Sat, 4 May 2024 20:52:51 +0300 Subject: [PATCH 604/794] [android] Fix copy libs and build --- .../build/Android/libx2t/build.gradle.kts | 25 +++++++------------ .../libx2t/src/main/cpp/CMakeLists.txt | 15 ----------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/X2tConverter/build/Android/libx2t/build.gradle.kts b/X2tConverter/build/Android/libx2t/build.gradle.kts index ba6e880f933..8f2c3dcb394 100644 --- a/X2tConverter/build/Android/libx2t/build.gradle.kts +++ b/X2tConverter/build/Android/libx2t/build.gradle.kts @@ -58,7 +58,6 @@ android { "-DANDROID_STL=c++_static", "-DANDROID_ARM_NEON=TRUE", "-DARG_PATH_LIB_BUILD_TOOLS=${getProjectPath(extra.get("PATH_LIB_BUILD_TOOLS") as String)}", - "-DARG_PATH_LIB_DST=${getProjectPath(extra.get("PATH_LIB_DST") as String, true)}", "-DARG_PATH_SRC_CORE=${getProjectPath(extra.get("PATH_SRC_CORE") as String)}", "-DARG_NAME_LIB=${extra.get("NAME_LIB")}" ) @@ -83,12 +82,6 @@ android { sourceSets { getByName("main") { java.srcDir("src/main/java") - jniLibs.srcDirs( - arrayOf( - extra.get("PATH_LIB_DST") as String, - extra.get("PATH_LIB_BUILD_TOOLS") as String - ) - ) } } @@ -113,15 +106,15 @@ android { packaging { jniLibs.useLegacyPackaging = true - arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64").forEach { abi -> - val dh = file("${extra.get("PATH_LIB_BUILD_TOOLS")}/$abi") - dh.listFiles()?.forEach { - if (it.name.contains(".so")) - jniLibs.pickFirsts.add("lib/$abi/${it.name}") - } - jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB")}.so") - jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB_KERNEL_NETWORK")}.so") - } +// arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64").forEach { abi -> +// val dh = file("${extra.get("PATH_LIB_BUILD_TOOLS")}/$abi") +// dh.listFiles()?.forEach { +// if (it.name.contains(".so")) +// jniLibs.pickFirsts.add("lib/$abi/${it.name}") +// } +// jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB")}.so") +// jniLibs.pickFirsts.add("lib/$abi/lib${extra.get("NAME_LIB_KERNEL_NETWORK")}.so") +// } } } diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index a3cc89735ce..0ce57130a30 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt @@ -47,13 +47,6 @@ elseif (NOT EXISTS ${ARG_PATH_LIB_BUILD_TOOLS}) message(STATUS "Destination 3dParty path doesn't exist, created!") endif() -# X2t destination path -if (NOT DEFINED ARG_PATH_LIB_DST) - message(FATAL_ERROR "You must set argument \"ARG_PATH_LIB_DST\" with path to x2t.so destination...") -elseif (NOT EXISTS ${ARG_PATH_LIB_DST}) - file(MAKE_DIRECTORY ${ARG_PATH_LIB_DST}) - message(STATUS "Destination library path doesn't exist, created!") -endif() # Core source path if (NOT DEFINED ARG_PATH_SRC_CORE) @@ -72,8 +65,6 @@ set(LIB_NAME_X2T_CONVERTER ${ARG_NAME_LIB}) # ---------- Paths sources ---------- # Core src dir path set(CORE_DIR ${ARG_PATH_SRC_CORE}) -set(X2T_CONVERTER_DEST ${ARG_PATH_LIB_DST}/${ANDROID_ABI}) -message(STATUS "X2t Converter destination path: ${X2T_CONVERTER_DEST}") # Prebuild libraries path set(X2T_CONVERTER_LIBS ${ARG_PATH_LIB_BUILD_TOOLS}/${ANDROID_ABI}) @@ -157,12 +148,6 @@ FOREACH(lib ${libs_list}) ${X2T_CONVERTER_LIBS}/${lib}) ENDFOREACH() - -# Export lib to common libs path -set_target_properties(${LIB_NAME_X2T_CONVERTER} - PROPERTIES LIBRARY_OUTPUT_DIRECTORY - ${X2T_CONVERTER_DEST} -) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library From 63bd2a1cbfb1314b22b9cc90ea19810790024254 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 6 May 2024 15:49:48 +0500 Subject: [PATCH 605/794] Fix bug #67815 --- OdfFile/Reader/Converter/oox_drawing.cpp | 1 + OdfFile/Writer/Format/odf_drawing_context.cpp | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_drawing.cpp b/OdfFile/Reader/Converter/oox_drawing.cpp index 42b27e20499..19b7ec51135 100644 --- a/OdfFile/Reader/Converter/oox_drawing.cpp +++ b/OdfFile/Reader/Converter/oox_drawing.cpp @@ -239,6 +239,7 @@ void oox_serialize_effects(std::wostream & strm, const std::vectorcurrent_graphic_properties->common_shadow_attlist_.draw_shadow_offset_x_ = length(length(dist_pt, length::pt).get_value_unit(length::cm), length::cm); - - if (dist_pt_y > 0) - impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt_y, length::pt).get_value_unit(length::cm), length::cm); - else - impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt, length::pt).get_value_unit(length::cm), length::cm); + impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_offset_y_ = length(length(dist_pt_y, length::pt).get_value_unit(length::cm), length::cm); impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_ = shadow_type1(shadow_type1::Visible); if (opacity) impl_->current_graphic_properties->common_shadow_attlist_.draw_shadow_opacity_ = *opacity; From a44e22c726167d3d1e573d8653908589abccb2e6 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 6 May 2024 14:34:06 +0300 Subject: [PATCH 606/794] fix bug #67818 --- MsBinaryFile/PptFile/Drawing/Attributes.h | 3 ++- MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp | 11 ++++++----- MsBinaryFile/PptFile/PPTXWriter/ImageManager.h | 4 ++-- .../PptFile/Reader/PPTDocumentInfoOneUser.cpp | 3 ++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/MsBinaryFile/PptFile/Drawing/Attributes.h b/MsBinaryFile/PptFile/Drawing/Attributes.h index 701ef71cf0e..7029dedc8d3 100644 --- a/MsBinaryFile/PptFile/Drawing/Attributes.h +++ b/MsBinaryFile/PptFile/Drawing/Attributes.h @@ -91,8 +91,9 @@ namespace PPT _UINT32 m_dwID = 0; std::wstring m_strFilePath; + std::wstring m_strFileExt; - std::wstring m_name; + std::wstring m_name; std::wstring m_progName; // clip diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index 6bee2915ff5..a13e0b41a9a 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -72,14 +72,14 @@ void CMediaManager::SetTempMedia(const std::wstring& strSrc) OOX::CPath pathSrc(strSrc); m_strTempMedia = pathSrc.GetPath(); } -std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput) +std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput, const std::wstring& strExt) { - return GenerateMedia(strInput, L"video", m_lIndexNextVideo, L".avi"); + return GenerateMedia(strInput, L"video", m_lIndexNextVideo, strExt.empty() ? L".avi" : strExt); } -std::wstring CMediaManager::GenerateAudio(const std::wstring &strInput) +std::wstring CMediaManager::GenerateAudio(const std::wstring &strInput, const std::wstring& strExt) { - return GenerateMedia(strInput, L"audio", m_lIndexNextAudio, L".wav"); + return GenerateMedia(strInput, L"audio", m_lIndexNextAudio, strExt.empty() ? L".wav" : strExt); } std::wstring CMediaManager::GenerateImage(const std::wstring &strInput) @@ -195,6 +195,7 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring& strInput, const st { return L""; } + //todooo ? test format if (strOutput != strInput) { NSDirectory::CreateDirectory(m_strDstMedia); @@ -214,7 +215,7 @@ void CMediaManager::WriteAudioCollection(const std::vector &a for (auto& audio : audioCont) { - auto pathAudio = GenerateAudio(audio.m_strFilePath); + auto pathAudio = GenerateAudio(audio.m_strFilePath, audio.m_strFileExt); } } diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h index bf0bcae0243..5e357909ec8 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h @@ -64,8 +64,8 @@ class CMediaManager void SetDstMedia(const std::wstring& strDst); void SetTempMedia(const std::wstring& strSrc); - std::wstring GenerateVideo(const std::wstring& strInput); - std::wstring GenerateAudio(const std::wstring& strInput); + std::wstring GenerateVideo(const std::wstring& strInput, const std::wstring& strExt = L""); + std::wstring GenerateAudio(const std::wstring& strInput, const std::wstring& strExt = L""); std::wstring GenerateOleObject(const std::wstring& strInput); std::wstring GenerateImage(const std::wstring& strInput); std::wstring GenerateImageJPEG(const std::wstring& strInput); diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp index bb3ed69f996..695ef503bed 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -2353,9 +2353,10 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) { PPT::CExFilesInfo oInfo; - oInfo.m_strFilePath = m_oExMedia.m_strPresentationDirectory + FILE_SEPARATOR_STR + oArrayStrings[0]->m_strText + L".audio"; + oInfo.m_strFilePath = m_oExMedia.m_strPresentationDirectory + FILE_SEPARATOR_STR + L"audio" + std::to_wstring(m_oExMedia.m_arAudioCollection.size() + 1) + L".audio"; oInfo.m_dwID = (_UINT32)XmlUtils::GetInteger(oArrayStrings[2]->m_strText.c_str()); oInfo.m_name = oArrayStrings[0]->m_strText; + oInfo.m_strFileExt = oArrayStrings[1]->m_strText; m_oExMedia.m_arAudioCollection.push_back(oInfo); oArrayData[0]->SaveToFile(oInfo.m_strFilePath); From 441716773fb62340143230f7d8572d326927d307 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Mon, 6 May 2024 15:12:02 +0300 Subject: [PATCH 607/794] Add property for strip x2t library --- X2tConverter/build/Qt/X2tConverter.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/X2tConverter/build/Qt/X2tConverter.pro b/X2tConverter/build/Qt/X2tConverter.pro index da91d2545d3..28349a3c889 100644 --- a/X2tConverter/build/Qt/X2tConverter.pro +++ b/X2tConverter/build/Qt/X2tConverter.pro @@ -22,6 +22,10 @@ build_x2t_as_library { CONFIG += plugin !core_debug:shared:QMAKE_LFLAGS += -exported_symbols_list $$PWD/../../src/dylib/export + + build_strip_debug { + QMAKE_LFLAGS += -Wl,--strip-debug + } } include(X2tConverter.pri) From 0439347bc3d006a9e3595ea1483b4cf73ab0e631 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Mon, 6 May 2024 15:49:01 +0300 Subject: [PATCH 608/794] fix bug #67782 --- OdfFile/Reader/Format/styles.cpp | 5 + OdfFile/Reader/Format/styles.h | 3 +- OdfFile/Writer/Converter/DocxConverter.cpp | 166 +++++++++++---------- OdfFile/Writer/Format/styles.cpp | 1 + OdfFile/Writer/Format/styles.h | 3 +- 5 files changed, 94 insertions(+), 84 deletions(-) diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index 1128147ca7d..df767c64426 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -2160,6 +2160,7 @@ void text_linenumbering_configuration::add_attributes(const xml::attributes_wc_p CP_APPLY_ATTR(L"text:number-position", text_number_position_); //inner, left, outer, right CP_APPLY_ATTR(L"text:offset", text_offset_); CP_APPLY_ATTR(L"text:restart-on-page", text_restart_on_page_); + CP_APPLY_ATTR(L"text:start", text_start_); } void text_linenumbering_configuration::add_child_element(xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { @@ -2187,6 +2188,10 @@ void text_linenumbering_configuration::docx_serialize(std::wostream & strm, oox: { CP_XML_ATTR(L"w:restart", L"continuous"); } + if (text_start_) + { + CP_XML_ATTR(L"w:start", *text_start_); + } if (text_offset_) { CP_XML_ATTR(L"w:distance", 20. * text_offset_->get_value_unit(length::pt)); diff --git a/OdfFile/Reader/Format/styles.h b/OdfFile/Reader/Format/styles.h index 61cf51eaaa8..a68f51ff38d 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -1024,7 +1024,8 @@ class text_linenumbering_configuration : public office_element_impltext_context()->set_type_break(-1, 0); - + bool continuous = false; if (oox_section_pr->m_oType.IsInit() && oox_section_pr->m_oType->m_oVal.IsInit()) { - switch(oox_section_pr->m_oType->m_oVal->GetValue()) - { - case SimpleTypes::sectionmarkContinious : - continuous = true; + switch (oox_section_pr->m_oType->m_oVal->GetValue()) + { + case SimpleTypes::sectionmarkContinious: + continuous = true; break; - case SimpleTypes::sectionmarkNextColumn : - case SimpleTypes::sectionmarkEvenPage : - case SimpleTypes::sectionmarkNextPage : - case SimpleTypes::sectionmarkOddPage : + case SimpleTypes::sectionmarkNextColumn: + case SimpleTypes::sectionmarkEvenPage: + case SimpleTypes::sectionmarkNextPage: + case SimpleTypes::sectionmarkOddPage: // возможен разрыв break; } } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool bDefault = (master_name == L"Standard"); - + if (!bDefault) { if (!last_section_properties && (!bSection || continuous == false || oox_section_pr->m_oTitlePg.IsInit())) - { + { last_section_properties = oox_section_pr; } else if (!bSection || continuous == false) @@ -1908,7 +1908,7 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b apply_HF_from(last_section_properties, oox_section_pr); } } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (!bSection || continuous == false) { odt_context->page_layout_context()->add_master_page(master_name); @@ -1918,14 +1918,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { _CP_OPT(odf_types::length) top, left, right, bottom, header, footer, gutter, header_min, footer_min; - convert(oox_section_pr->m_oPgMar->m_oBottom.GetPointer(), bottom); - convert(oox_section_pr->m_oPgMar->m_oLeft.GetPointer(), left); - convert(oox_section_pr->m_oPgMar->m_oRight.GetPointer(), right); - convert(oox_section_pr->m_oPgMar->m_oTop.GetPointer(), top); - convert(oox_section_pr->m_oPgMar->m_oHeader.GetPointer(), header); - convert(oox_section_pr->m_oPgMar->m_oFooter.GetPointer(), footer); - convert(oox_section_pr->m_oPgMar->m_oGutter.GetPointer(), gutter); - + convert(oox_section_pr->m_oPgMar->m_oBottom.GetPointer(), bottom); + convert(oox_section_pr->m_oPgMar->m_oLeft.GetPointer(), left); + convert(oox_section_pr->m_oPgMar->m_oRight.GetPointer(), right); + convert(oox_section_pr->m_oPgMar->m_oTop.GetPointer(), top); + convert(oox_section_pr->m_oPgMar->m_oHeader.GetPointer(), header); + convert(oox_section_pr->m_oPgMar->m_oFooter.GetPointer(), footer); + convert(oox_section_pr->m_oPgMar->m_oGutter.GetPointer(), gutter); + footer_min = footer; header_min = header; @@ -1934,8 +1934,8 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b double bottom_cm = bottom->get_value_unit(length::cm); double footer_cm = footer ? footer->get_value_unit(length::cm) : 0; double length_cm = bottom_cm - footer_cm; - - if ( length_cm < 0 ) + + if (length_cm < 0) { footer_min = length(-length_cm, length::cm); footer.reset(); @@ -1953,13 +1953,13 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (top) { double length_cm = top->get_value_unit(length::cm) - (header ? header->get_value_unit(length::cm) : 0); - - if ( length_cm > 2.4 ) + + if (length_cm > 2.4) { top = header; header = length(fabs(length_cm), length::cm); } - else if ( length_cm < 0 ) + else if (length_cm < 0) { header_min = length(-length_cm, length::cm); header.reset(); @@ -1979,14 +1979,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b std::wstring top, left, right, bottom; convert(oox_section_pr->m_oPgBorders->m_oBottom.GetPointer(), bottom); - convert(oox_section_pr->m_oPgBorders->m_oLeft.GetPointer() , left); - convert(oox_section_pr->m_oPgBorders->m_oRight.GetPointer() , right); - convert(oox_section_pr->m_oPgBorders->m_oTop.GetPointer() , top); - + convert(oox_section_pr->m_oPgBorders->m_oLeft.GetPointer(), left); + convert(oox_section_pr->m_oPgBorders->m_oRight.GetPointer(), right); + convert(oox_section_pr->m_oPgBorders->m_oTop.GetPointer(), top); + odt_context->page_layout_context()->set_page_border(top, left, bottom, right); - - if (oox_section_pr->m_oPgBorders->m_oOffsetFrom.IsInit() && + + if (oox_section_pr->m_oPgBorders->m_oOffsetFrom.IsInit() && (oox_section_pr->m_oPgBorders->m_oOffsetFrom->GetValue() == SimpleTypes::pageborderoffsetPage)) { odt_context->page_layout_context()->set_page_border_offset(2); @@ -2010,14 +2010,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oPgBorders->m_oLeft.IsInit()) { int type = (oox_section_pr->m_oPgBorders->m_oBottom->m_oVal.IsInit() ? oox_section_pr->m_oPgBorders->m_oLeft->m_oVal->GetValue() : SimpleTypes::bordervalueSingle); - + if (oox_section_pr->m_oPgBorders->m_oLeft->m_oSpace.IsInit()) odt_context->page_layout_context()->set_page_border_padding(3, oox_section_pr->m_oPgBorders->m_oLeft->m_oSpace->ToPoints()); } if (oox_section_pr->m_oPgBorders->m_oRight.IsInit()) { int type = (oox_section_pr->m_oPgBorders->m_oBottom->m_oVal.IsInit() ? oox_section_pr->m_oPgBorders->m_oRight->m_oVal->GetValue() : SimpleTypes::bordervalueSingle); - + if (oox_section_pr->m_oPgBorders->m_oRight->m_oSpace.IsInit()) odt_context->page_layout_context()->set_page_border_padding(4, oox_section_pr->m_oPgBorders->m_oRight->m_oSpace->ToPoints()); } @@ -2028,9 +2028,9 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oPgBorders->m_oTop.IsInit() && oox_section_pr->m_oPgBorders->m_oTop->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oTop->m_oShadow->ToBool()) shadow = true; if (oox_section_pr->m_oPgBorders->m_oLeft.IsInit() && oox_section_pr->m_oPgBorders->m_oLeft->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oLeft->m_oShadow->ToBool()) shadow = true; if (oox_section_pr->m_oPgBorders->m_oRight.IsInit() && oox_section_pr->m_oPgBorders->m_oRight->m_oShadow.IsInit() && oox_section_pr->m_oPgBorders->m_oRight->m_oShadow->ToBool()) shadow = true; - + if (shadow) odt_context->page_layout_context()->set_page_border_shadow(true); - + if (oox_section_pr->m_oPgBorders->m_oDisplay.IsInit()) { // todooo @@ -2065,9 +2065,9 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { convert(docx_flat_document->m_pBgPict.GetPointer(), 1); } - //nullable m_oTextDirection; - //nullable m_oRtlGutter; - //nullable m_oVAlign; + //nullable m_oTextDirection; + //nullable m_oRtlGutter; + //nullable m_oVAlign; if (oox_section_pr->m_oPgNumType.IsInit()) { @@ -2075,23 +2075,23 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b _CP_OPT(int) start; if (oox_section_pr->m_oPgNumType->m_oFmt.IsInit()) format = oox_section_pr->m_oPgNumType->m_oFmt->GetValue(); - if (oox_section_pr->m_oPgNumType->m_oStart.IsInit()) start = oox_section_pr->m_oPgNumType->m_oStart->GetValue(); + if (oox_section_pr->m_oPgNumType->m_oStart.IsInit()) start = oox_section_pr->m_oPgNumType->m_oStart->GetValue(); - odt_context->page_layout_context()->set_page_number_format( format, start); - //nullable > m_oChapSep; - //nullable > m_oChapStyle; + odt_context->page_layout_context()->set_page_number_format(format, start); + //nullable > m_oChapSep; + //nullable > m_oChapStyle; } - + if (continuous == false || oox_section_pr->m_oTitlePg.IsInit() || bAlways) { - OOX::Logic::CSectionProperty* s = last_section_properties ? last_section_properties : oox_section_pr; - - bool present_title_page = s->m_oTitlePg.IsInit() ? true : false; - bool present_odd_even_pages = odt_context->page_layout_context()->even_and_left_headers_; - - bool add_title_header = false, add_title_footer = false; - bool add_odd_even_pages_header = false, add_odd_even_pages_footer = false; - bool add_default_header = false, add_default_footer = false; + OOX::Logic::CSectionProperty* s = last_section_properties ? last_section_properties : oox_section_pr; + + bool present_title_page = s->m_oTitlePg.IsInit() ? true : false; + bool present_odd_even_pages = odt_context->page_layout_context()->even_and_left_headers_; + + bool add_title_header = false, add_title_footer = false; + bool add_odd_even_pages_header = false, add_odd_even_pages_footer = false; + bool add_default_header = false, add_default_footer = false; std::vector types; @@ -2099,14 +2099,14 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { if (s->m_arrHeaderReference[i] == NULL) continue; - int type = s->m_arrHeaderReference[i]->m_oType.IsInit() ? s->m_arrHeaderReference[i]->m_oType->GetValue() : 0 ; + int type = s->m_arrHeaderReference[i]->m_oType.IsInit() ? s->m_arrHeaderReference[i]->m_oType->GetValue() : 0; if (type == 2 && !present_title_page) continue; if (type == 1 && !present_odd_even_pages) continue; - if (type == 2 && present_title_page) add_title_header = true; - if (type == 1 && present_odd_even_pages) add_odd_even_pages_header = true; //swap even & odd ? - if (type == 0) add_default_header = true; + if (type == 2 && present_title_page) add_title_header = true; + if (type == 1 && present_odd_even_pages) add_odd_even_pages_header = true; //swap even & odd ? + if (type == 0) add_default_header = true; if (odt_context->start_header(type)) { @@ -2122,22 +2122,22 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b odt_context->end_header_footer(); } } - if (!add_title_header && present_title_page) odt_context->add_empty_header(2); - if (!add_odd_even_pages_header && present_odd_even_pages) odt_context->add_empty_header(1); - if (!add_default_header && (present_odd_even_pages || present_title_page)) odt_context->add_empty_header(0); + if (!add_title_header && present_title_page) odt_context->add_empty_header(2); + if (!add_odd_even_pages_header && present_odd_even_pages) odt_context->add_empty_header(1); + if (!add_default_header && (present_odd_even_pages || present_title_page)) odt_context->add_empty_header(0); - for (size_t i=0; i< s->m_arrFooterReference.size(); i++) + for (size_t i = 0; i < s->m_arrFooterReference.size(); i++) { if (s->m_arrFooterReference[i] == NULL) continue; - int type = s->m_arrFooterReference[i]->m_oType.IsInit() ? s->m_arrFooterReference[i]->m_oType->GetValue() :0 ; + int type = s->m_arrFooterReference[i]->m_oType.IsInit() ? s->m_arrFooterReference[i]->m_oType->GetValue() : 0; if (type == 2 && !present_title_page) continue; if (type == 1 && !present_odd_even_pages) continue; - if (type == 2 && present_title_page) add_title_footer = true; - if (type == 1 && present_odd_even_pages) add_odd_even_pages_footer = true; - if (type == 0) add_default_footer = true; + if (type == 2 && present_title_page) add_title_footer = true; + if (type == 1 && present_odd_even_pages) add_odd_even_pages_footer = true; + if (type == 0) add_default_footer = true; if (odt_context->start_footer(type)) { @@ -2150,12 +2150,12 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b } } - odt_context->end_header_footer(); + odt_context->end_header_footer(); } } - if (!add_title_footer && present_title_page) odt_context->add_empty_footer(2); - if (!add_odd_even_pages_footer && present_odd_even_pages) odt_context->add_empty_footer(1); - if (!add_default_footer && (present_odd_even_pages || present_title_page)) odt_context->add_empty_footer(0); + if (!add_title_footer && present_title_page) odt_context->add_empty_footer(2); + if (!add_odd_even_pages_footer && present_odd_even_pages) odt_context->add_empty_footer(1); + if (!add_default_footer && (present_odd_even_pages || present_title_page)) odt_context->add_empty_footer(0); if (!bDefault) odt_context->is_paragraph_in_current_section_ = true; @@ -2164,16 +2164,17 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b // odt_context->page_layout_context()->last_master()->get_name() : L""); } if (oox_section_pr->m_oLnNumType.IsInit()) - {//linenumbering-configuration один для всех секций и всех разметок страниц ((( - хуевый OpenOffice (также не начала нумерации) - //Ms Office тоже фуфло - нет нумерации алфавитами и римскими, нет разделителей + { odf_writer::office_element_ptr lnNum_elm; odf_writer::create_element(L"text", L"linenumbering-configuration", lnNum_elm, odf_context()); - odf_writer::text_linenumbering_configuration *linenumbering = dynamic_cast(lnNum_elm.get()); + odf_writer::text_linenumbering_configuration* linenumbering = dynamic_cast(lnNum_elm.get()); if (!linenumbering) return; linenumbering->text_style_name_ = odt_context->styles_context()->find_free_name(style_family::LineNumbering); linenumbering->text_number_lines_ = true; + linenumbering->style_num_format_ = odf_types::style_numformat::arabic; + linenumbering->text_number_position_ = L"left"; if (oox_section_pr->m_oLnNumType->m_oCountBy.IsInit()) { @@ -2182,19 +2183,20 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b if (oox_section_pr->m_oLnNumType->m_oDistance.IsInit()) { linenumbering->text_offset_ = odf_types::length(oox_section_pr->m_oLnNumType->m_oDistance->ToPoints(), odf_types::length::pt); - } - if (oox_section_pr->m_oLnNumType->m_oRestart.IsInit()) + } + else { - if (oox_section_pr->m_oLnNumType->m_oRestart->GetValue() == SimpleTypes::linenumberrestartNewPage) - { - linenumbering->text_restart_on_page_ = true; - } - else - { - } + linenumbering->text_offset_ = odf_types::length(0.5, odf_types::length::cm); } - if (oox_section_pr->m_oLnNumType->m_oStart.IsInit()) + if ((oox_section_pr->m_oLnNumType->m_oRestart.IsInit() && (oox_section_pr->m_oLnNumType->m_oRestart->GetValue() == SimpleTypes::linenumberrestartNewPage)) + || false == oox_section_pr->m_oLnNumType->m_oRestart.IsInit()) { + linenumbering->text_restart_on_page_ = true; + } + + if (oox_section_pr->m_oLnNumType->m_oStart.IsInit()) + {//нет в формате ??? + linenumbering->text_start_ = oox_section_pr->m_oLnNumType->m_oStart->GetValue(); } odt_context->styles_context()->add_style(lnNum_elm, false, true, style_family::LineNumbering); diff --git a/OdfFile/Writer/Format/styles.cpp b/OdfFile/Writer/Format/styles.cpp index 053ea2984e5..9408af114d3 100644 --- a/OdfFile/Writer/Format/styles.cpp +++ b/OdfFile/Writer/Format/styles.cpp @@ -1423,6 +1423,7 @@ void text_linenumbering_configuration::serialize(std::wostream & strm) CP_XML_ATTR_OPT(L"text:count-empty-lines", text_count_empty_lines_); CP_XML_ATTR_OPT(L"text:count-in-text-boxes", text_count_in_text_boxes_); CP_XML_ATTR_OPT(L"text:increment", text_increment_); + CP_XML_ATTR_OPT(L"text:start", text_start_); CP_XML_ATTR_OPT(L"text:number-position", text_number_position_); //inner, left, outer, right CP_XML_ATTR_OPT(L"text:offset", text_offset_); CP_XML_ATTR_OPT(L"text:restart-on-page", text_restart_on_page_); diff --git a/OdfFile/Writer/Format/styles.h b/OdfFile/Writer/Format/styles.h index c0acce8f6e1..a932d5dc1f4 100644 --- a/OdfFile/Writer/Format/styles.h +++ b/OdfFile/Writer/Format/styles.h @@ -841,7 +841,8 @@ class text_linenumbering_configuration : public office_element_impl Date: Mon, 6 May 2024 16:03:34 +0300 Subject: [PATCH 609/794] . --- Common/OfficeFileFormatChecker2.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 7ae78c1763a..9d9caba1306 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -1118,35 +1118,38 @@ bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileNa hresult = OfficeUtils.LoadFileFromArchive(fileName, L"mimetype", &pBuffer, nBufferSize); if (hresult == S_OK && pBuffer != NULL) { - if (NULL != strstr((char *)pBuffer, ottFormatLine)) + if (48 <= nBufferSize && NULL != strstr((char *)pBuffer, ottFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT; } - else if (NULL != strstr((char *)pBuffer, otsFormatLine)) + else if (55 <= nBufferSize && NULL != strstr((char *)pBuffer, otsFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS; } - else if (NULL != strstr((char *)pBuffer, otpFormatLine)) + else if (56 <= nBufferSize && NULL != strstr((char *)pBuffer, otpFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP; } - else if (NULL != strstr((char *)pBuffer, odtFormatLine) || NULL != strstr((char *)pBuffer, sxwFormatLine)) + else if ((39 <= nBufferSize && NULL != strstr((char *)pBuffer, odtFormatLine)) || + (30 <= nBufferSize && NULL != strstr((char *)pBuffer, sxwFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; } - else if (NULL != strstr((char *)pBuffer, odsFormatLine) || NULL != strstr((char *)pBuffer, sxcFormatLine)) + else if ((46 <= nBufferSize && NULL != strstr((char *)pBuffer, odsFormatLine)) || + (28 <= nBufferSize && NULL != strstr((char *)pBuffer, sxcFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; } - else if (NULL != strstr((char *)pBuffer, odpFormatLine) || NULL != strstr((char *)pBuffer, sxiFormatLine)) + else if ((47 <= nBufferSize && NULL != strstr((char *)pBuffer, odpFormatLine)) || + (31 <= nBufferSize && NULL != strstr((char *)pBuffer, sxiFormatLine))) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP; } - else if (NULL != strstr((char*)pBuffer, odgFormatLine)) + else if (43 <= nBufferSize && NULL != strstr((char*)pBuffer, odgFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG; } - else if (NULL != strstr((char *)pBuffer, epubFormatLine)) + else if (20 <= nBufferSize && NULL != strstr((char *)pBuffer, epubFormatLine)) { nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB; } @@ -1683,7 +1686,8 @@ bool COfficeFileFormatChecker::isXpsFile(const std::wstring &fileName) { // http://schemas.microsoft.com/xps/2005/06/fixedrepresentation // http://schemas.openxps.org/oxps/v1.0/fixedrepresentation - if (NULL != strstr((char *)pBuffer, "fixedrepresentation") && (NULL != strstr((char *)pBuffer, "/xps/") || NULL != strstr((char *)pBuffer, "/oxps/"))) + if ((19 <= nBufferSize && NULL != strstr((char *)pBuffer, "fixedrepresentation") && (NULL != strstr((char *)pBuffer, "/xps/")) || + (6 <= nBufferSize && NULL != strstr((char *)pBuffer, "/oxps/")))) { nFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS; } From 283d611ad76c76c60c0af8ff9e3e3ed1829cfeaf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 6 May 2024 20:44:19 +0600 Subject: [PATCH 610/794] Fix sparkline conversion --- OOXML/XlsxFormat/Worksheets/Sparkline.cpp | 99 +++++++++++++++++++++-- OOXML/XlsxFormat/Worksheets/Sparkline.h | 2 + 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp index ca5d524267b..d407a3461ff 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp @@ -92,6 +92,32 @@ namespace OOX m_oSqRef = oReader.GetText3(); } } + XLS::BaseObjectPtr CSparkline::toBin() + { + auto ptr(new XLSB::Sparkline); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->FRTheader.fFormula = false; + ptr->FRTheader.fRef = false; + ptr->FRTheader.fRelID = false; + ptr->FRTheader.fSqref = false; + + if(m_oRef.IsInit()) + { + XLSB::FRTFormula formula; + formula.formula = m_oRef.get(); + ptr->FRTheader.rgFormulas.array.push_back(formula); + ptr->FRTheader.fFormula = true; + } + if(m_oSqRef.IsInit()) + { + XLSB::FRTSqref sqref; + sqref.sqrfx.strValue = m_oSqRef.get(); + ptr->FRTheader.rgSqrefs.array.push_back(sqref); + ptr->FRTheader.fSqref = true; + } + + return objectPtr; + } void CSparkline::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -175,6 +201,17 @@ namespace OOX m_arrItems.push_back(new CSparkline(sparkline)); } } + std::vector CSparklines::toBin() + { + std::vector sparclineVector; + + for(auto i:m_arrItems) + { + sparclineVector.push_back(i->toBin()); + } + + return sparclineVector; + } EElementType CSparklines::getType () const { return et_x_Sparklines; @@ -422,9 +459,21 @@ namespace OOX else ptr->fDateAxis = 0; if(m_oDisplayEmptyCellsAs.IsInit()) - ptr->fShowEmptyCellAsZero = (m_oDisplayEmptyCellsAs == OOX::Spreadsheet::ST_DispBlanksAs::st_dispblanksasZERO) ? 0x01 : 0x00; - else - ptr->fShowEmptyCellAsZero = false; + { + switch(m_oDisplayEmptyCellsAs.get()) + { + case st_dispblanksasZERO: + ptr->fShowEmptyCellAsZero = 0; + break; + case st_dispblanksasSPAN: + ptr->fShowEmptyCellAsZero = 2; + break; + case st_dispblanksasGAP: + default: + ptr->fShowEmptyCellAsZero = 1; + break; + } + } if(m_oMarkers.IsInit()) ptr->fMarkers = m_oMarkers->GetValue(); else @@ -461,11 +510,43 @@ namespace OOX ptr->fRTL = m_oRightToLeft->GetValue(); else ptr->fRTL = false; - if(m_oMaxAxisType.IsInit() && m_oMaxAxisType == SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Individual) + if(m_oMaxAxisType.IsInit()) + { + + if(m_oMaxAxisType.get()== SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Group) + { + ptr->fIndividualAutoMax = false; + ptr->fGroupAutoMax = true; + } + else + { + ptr->fIndividualAutoMax = true; + ptr->fGroupAutoMax = false; + } + } + else + { ptr->fIndividualAutoMax = true; - else - ptr->fIndividualAutoMax = false; - + ptr->fGroupAutoMax = false; + } + if(m_oMinAxisType.IsInit()) + { + if(m_oMinAxisType.get()== SimpleTypes::Spreadsheet::ESparklineAxisMinMax::Group) + { + ptr->fIndividualAutoMin = false; + ptr->fGroupAutoMin = true; + } + else + { + ptr->fIndividualAutoMin = true; + ptr->fGroupAutoMin = false; + } + } + else + { + ptr->fIndividualAutoMin = true; + ptr->fGroupAutoMin = false; + } if(m_oColorSeries.IsInit()) ptr->brtcolorSeries = m_oColorSeries->toColor(); @@ -518,6 +599,10 @@ namespace OOX ptr->FRTheader.rgFormulas.array[0].formula = m_oRef.get(); ptr->FRTheader.fFormula = true; } + for(auto i:m_oSparklines->m_arrItems) + { + ptr1->m_arBrtSparkline.push_back(i->toBin()); + } return objectPtr; } diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.h b/OOXML/XlsxFormat/Worksheets/Sparkline.h index 938fc399d0f..7c1c8086f43 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.h +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -88,6 +89,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + std::vector toBin(); virtual EElementType getType () const; private: From f1fbcf653b82824de2808e56695b40c01246646a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 6 May 2024 17:48:12 +0300 Subject: [PATCH 611/794] Create StartDrawFreeText --- PdfFile/PdfFile.cpp | 1 + PdfFile/SrcWriter/Annotation.cpp | 198 +++++++++++++++++++++---------- PdfFile/SrcWriter/Annotation.h | 2 + PdfFile/SrcWriter/Field.cpp | 4 + PdfFile/SrcWriter/Field.h | 2 + 5 files changed, 147 insertions(+), 60 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index c69218d3b14..fd18d2a69cb 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -48,6 +48,7 @@ class CPdfEditor { public: void Close() {} + bool EditPage(int nPageIndex) { return false; } bool EditAnnot(int nPageIndex, int nID) { return false; } bool DeleteAnnot(int nID) { return false; } bool EditWidgets(IAdvancedCommand* pCommand) { return false; } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 7a68ead6096..6020eb598ed 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -132,8 +132,7 @@ namespace PdfWriter sDA.append(bCaps ? "K" : "k"); else if (arr.size() == 1) sDA.append(bCaps ? "G" : "g"); - // else - // sDA.append(bCaps ? "SC" : "sc"); + return sDA; } std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) @@ -800,6 +799,17 @@ namespace PdfWriter pStream->WriteReal(y3); pStream->WriteStr(" c\012"); } + void StreamWriteRect(CStream* pStream, double x1, double y1, double x2, double y2) + { + pStream->WriteReal(x1); + pStream->WriteChar(' '); + pStream->WriteReal(y1); + pStream->WriteChar(' '); + pStream->WriteReal(x2); + pStream->WriteChar(' '); + pStream->WriteReal(y2); + pStream->WriteStr(" re\012"); + } void SreamWriteCircle(CStream* pStream, double cx, double cy, double r) { double bezierCircle = 0.55228475 * r; @@ -809,7 +819,7 @@ namespace PdfWriter SreamWriteXYCurve(pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); SreamWriteXYCurve(pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); } - void DrawLineArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) + void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) { double lineEndSize1 = 3, pi = 3.14159265358979323846; switch (nType) @@ -907,6 +917,65 @@ namespace PdfWriter } } } + void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) + { + double dDX = x2 - x1; + double dDY = y2 - y1; + double dLen = sqrt(dDX * dDX + dDY * dDY); + if (dLen > 0) + { + dDX /= dLen; + dDY /= dLen; + } + + double lx1, ly1, lx2, ly2; + double ax1, ay1, ax2, ay2; + double bx1, by1, bx2, by2; + if (dLL != 0) + { + ax1 = x1 + dLLO * dDY; + ay1 = y1 - dLLO * dDX; + lx1 = ax1 + dLL * dDY; + ly1 = ay1 - dLL * dDX; + bx1 = lx1 + dLLE * dDY; + by1 = ly1 - dLLE * dDX; + ax2 = x2 + dLLO * dDY; + ay2 = y2 - dLLO * dDX; + lx2 = ax2 + dLL * dDY; + ly2 = ay2 - dLL * dDX; + bx2 = lx2 + dLLE * dDY; + by2 = ly2 - dLLE * dDX; + } + else + { + lx1 = x1; + ly1 = y1; + lx2 = x2; + ly2 = y2; + ax1 = ay1 = ax2 = ay2 = 0; + bx1 = by1 = bx2 = by2 = 0; + } + + double tx1, ty1, tx2, ty2; + AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); + AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); + + if (dLL != 0) + { + SreamWriteXYMove(pStream, ax1, ay1); + SreamWriteXYLine(pStream, bx1, by1); + + SreamWriteXYMove(pStream, ax2, ay2); + SreamWriteXYLine(pStream, bx2, by2); + } + + SreamWriteXYMove(pStream, tx1, ty1); + SreamWriteXYLine(pStream, tx2, ty2); + pStream->WriteStr("S\012"); + + DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); + DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); + } void CLineAnnotation::SetAP() { CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); @@ -980,62 +1049,7 @@ namespace PdfWriter if (pObj && pObj->GetType() == object_type_REAL) dLLO = ((CRealObject*)pObj)->Get(); - double dDX = dL[2] - dL[0]; - double dDY = dL[3] - dL[1]; - double dLen = sqrt(dDX * dDX + dDY * dDY); - if (dLen > 0) - { - dDX /= dLen; - dDY /= dLen; - } - - double lx1, ly1, lx2, ly2; - double ax1, ay1, ax2, ay2; - double bx1, by1, bx2, by2; - if (dLL != 0) - { - ax1 = dL[0] + dLLO * dDY; - ay1 = dL[1] - dLLO * dDX; - lx1 = ax1 + dLL * dDY; - ly1 = ay1 - dLL * dDX; - bx1 = lx1 + dLLE * dDY; - by1 = ly1 - dLLE * dDX; - ax2 = dL[2] + dLLO * dDY; - ay2 = dL[3] - dLLO * dDX; - lx2 = ax2 + dLL * dDY; - ly2 = ay2 - dLL * dDX; - bx2 = lx2 + dLLE * dDY; - by2 = ly2 - dLLE * dDX; - } - else - { - lx1 = dL[0]; - ly1 = dL[1]; - lx2 = dL[2]; - ly2 = dL[3]; - ax1 = ay1 = ax2 = ay2 = 0; - bx1 = by1 = bx2 = by2 = 0; - } - - double tx1, ty1, tx2, ty2; - AdjustLineEndpoint(m_nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); - AdjustLineEndpoint(m_nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); - - if (dLL != 0) - { - SreamWriteXYMove(pStream, ax1, ay1); - SreamWriteXYLine(pStream, bx1, by1); - - SreamWriteXYMove(pStream, ax2, ay2); - SreamWriteXYLine(pStream, bx2, by2); - } - - SreamWriteXYMove(pStream, tx1, ty1); - SreamWriteXYLine(pStream, tx2, ty2); - pStream->WriteStr("S\012"); - - DrawLineArrow(pStream, m_nLE1, tx1, ty1, dDX, dDY, dBorderSize); - DrawLineArrow(pStream, m_nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); + DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); } //---------------------------------------------------------------------------------------- // CPopupAnnotation @@ -1056,6 +1070,8 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText) { + m_nIT = 0; + m_nLE = ELineEndType::None; m_pAppearance = NULL; } void CFreeTextAnnotation::StartAP(const std::vector& arrC) @@ -1065,8 +1081,68 @@ namespace PdfWriter return; Add("AP", m_pAppearance); CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + CStream* pStream = pNormal->GetStream(); + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + pNormal->Add("BBox", pArray); + + pArray->Add(GetRect().fLeft); + pArray->Add(GetRect().fBottom); + pArray->Add(GetRect().fRight); + pArray->Add(GetRect().fTop); + + pArray = new CArrayObject(); + if (!pArray) + return; + + pNormal->Add("Matrix", pArray); + pArray->Add(1); + pArray->Add(0); + pArray->Add(0); + pArray->Add(1); + pArray->Add(-GetRect().fLeft); + pArray->Add(-GetRect().fBottom); + + if (GetBorderType() == EBorderType::Dashed) + pStream->WriteStr(GetBorderDash().c_str()); + + double dBorderSize = GetBorderWidth(); + pStream->WriteReal(dBorderSize); + pStream->WriteStr(" w\012"); + + CObjectBase* pObj = Get("C"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); + pStream->WriteStr("\012"); + } + + pStream->WriteStr(GetColor(arrC, true).c_str()); + pStream->WriteStr("\012"); + + // TODO Облачная граница + + pObj = Get("CL"); + if (m_nIT == 1 && pObj && pObj->GetType() == object_type_ARRAY) + { + CArrayObject* pArr = (CArrayObject*)pObj; + DrawLineArrow(pStream, dBorderSize, ((CRealObject*)(pArr->Get(0)))->Get(), ((CRealObject*)(pArr->Get(1)))->Get(), + ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get(), m_nLE, ELineEndType::None); + if (pArr->GetCount() == 6) + { + SreamWriteXYMove(pStream, ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get()); + SreamWriteXYLine(pStream, ((CRealObject*)(pArr->Get(4)))->Get(), ((CRealObject*)(pArr->Get(5)))->Get()); + pStream->WriteStr("S\012"); + } + } + + StreamWriteRect(pStream, 0, 0, 0, 0); + pStream->WriteStr("B\012"); - // TODO рисование + // re внутренняя область + // BT/ET текст } void CFreeTextAnnotation::EndAP() { @@ -1112,10 +1188,12 @@ namespace PdfWriter } Add("IT", sValue.c_str()); + m_nIT = nIT; } void CFreeTextAnnotation::SetLE(BYTE nLE) { Add("LE", AddLE(nLE).c_str()); + m_nLE = ELineEndType(nLE); } void CFreeTextAnnotation::SetDS(const std::wstring& wsDS) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index a7b95482445..ed937e942f3 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -350,6 +350,8 @@ namespace PdfWriter class CFreeTextAnnotation : public CMarkupAnnotation { private: + BYTE m_nIT; + ELineEndType m_nLE; CAnnotAppearance* m_pAppearance; public: diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 460a2c2d8ff..7d7f0e82d03 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -2817,4 +2817,8 @@ namespace PdfWriter m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); } + void CAnnotAppearanceObject::StartDrawFreeText(const std::string& sColor) + { + + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 6280a8d038f..36b4cf9e6ce 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -416,6 +416,8 @@ namespace PdfWriter void DrawTextUpArrow(const std::string& sColor); void DrawTextUpLeftArrow(const std::string& sColor); + void StartDrawFreeText(const std::string& sColor); + CStream* GetStream() { return m_pStream; } bool m_bStart; From bce25e97882f01daba5851a5680f92c79bcaad72 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Mon, 6 May 2024 22:14:57 +0300 Subject: [PATCH 612/794] Fix mac build --- Common/3dParty/boost/boost.pri | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index 919b60a42b3..7a0278cea43 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -1,16 +1,18 @@ INCLUDEPATH += $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/include CORE_BOOST_LIBS = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib +core_ios:CONFIG += disable_enum_constexpr_conversion +core_android:CONFIG += disable_enum_constexpr_conversion +core_mac:CONFIG += disable_enum_constexpr_conversion + core_android { INCLUDEPATH += $$PWD/build/android/include CORE_BOOST_LIBS = $$PWD/build/android/lib/$$CORE_BUILDS_PLATFORM_PREFIX DEFINES += "_HAS_AUTO_PTR_ETC=0" - QMAKE_CFLAGS += -Wno-enum-constexpr-conversion - QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } -core_ios { +disable_enum_constexpr_conversion { QMAKE_CFLAGS += -Wno-enum-constexpr-conversion QMAKE_CXXFLAGS += -Wno-enum-constexpr-conversion } From c03ec969669dc2c9eb74eec50733c51ff923ae0c Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Tue, 7 May 2024 10:40:24 +0300 Subject: [PATCH 613/794] . --- .../XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp index 675f3c8943f..e0b11daa652 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ListParsedFormula.cpp @@ -31,7 +31,7 @@ */ #include "ListParsedFormula.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.h" +#include "PtgList.h" namespace XLS { From fd664bafaed4898da62d6be3ae072d9864267dc4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 7 May 2024 14:20:46 +0600 Subject: [PATCH 614/794] Fix bug #67867 --- OOXML/XlsbFormat/WorkBookStream.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/OOXML/XlsbFormat/WorkBookStream.cpp b/OOXML/XlsbFormat/WorkBookStream.cpp index f0ef8874406..050304b305e 100644 --- a/OOXML/XlsbFormat/WorkBookStream.cpp +++ b/OOXML/XlsbFormat/WorkBookStream.cpp @@ -492,6 +492,7 @@ void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_) { XTI* xti = dynamic_cast(extern_sheet->rgXTI[i].get()); if (!xti) continue; + if(externals->m_arSUP.size() <= xti->iSupBook) continue; SUP* index_book = dynamic_cast(externals->m_arSUP[xti->iSupBook].get()); if (!index_book) continue; From 88aba1cb02eb448240198180d9059a4375dd8151 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 7 May 2024 11:43:20 +0300 Subject: [PATCH 615/794] Fix MK.IF.A default value --- PdfFile/SrcReader/PdfAnnot.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index baa8e592e00..a1d358cb7ed 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -561,14 +561,11 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot // 3 - Смещение - A if (oIF.dictLookup("A", &oObj)->isArray()) { + m_dA1 = 0.5, m_dA2 = 0.5; Object oObj2; m_unIFFlag |= (1 << 3); m_dA1 = ArrGetNum(&oObj, 0); - if (!m_dA1) - m_dA1 = 0.5; m_dA2 = ArrGetNum(&oObj, 1); - if (!m_dA2) - m_dA2 = 0.5; } oObj.free(); // 4 - Полное соответствие - FB From 194d1c220865de6676af6414227acb09d0af39fc Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 7 May 2024 15:04:29 +0600 Subject: [PATCH 616/794] Fix bug #67864 --- .../XlsFile/Format/Logic/Biff_structures/PtgList.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp index fae7a7ed1cd..f43c6ce7512 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp @@ -135,7 +135,12 @@ void PtgList::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful case 0x00: break; case 0x01: case 0x02: - formula += L",['" + arrColumn->second[colFirst] + L"]"; if(columns == 0x01) break; + if(colFirst >= arrColumn->second.size()) + break; + formula += L",['" + arrColumn->second[colFirst] + L"]"; + if(columns == 0x01) break; + if(colLast >= arrColumn->second.size()) + break; formula += L":[" + arrColumn->second[colLast] + L"]"; break; } } From 680c3824f7c003ba592c8dd37e164666b6b2dfe2 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 7 May 2024 16:00:34 +0600 Subject: [PATCH 617/794] Fix bug #67860 --- .../XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp index c30bc9c4a11..38aef91d89b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp @@ -161,7 +161,8 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f if (ixals == 0xffff) { std::wstring strRange; - if(-1 == itabFirst) + if(-1 == itabFirst || global_info->sheets_info.size() <= itabFirst + || global_info->sheets_info.size() <= itabLast) { strRange = L"#REF"; } From 10afcda7a3849b68b4a23d3d23750d78f694cf4b Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Tue, 7 May 2024 14:31:02 +0400 Subject: [PATCH 618/794] Add new signal to `CVlcPlayer` --- Common/3dParty/libvlc/vlcmedia.cpp | 1 - Common/3dParty/libvlc/vlcplayer.cpp | 10 ++++++++-- Common/3dParty/libvlc/vlcplayer.h | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Common/3dParty/libvlc/vlcmedia.cpp b/Common/3dParty/libvlc/vlcmedia.cpp index 1516189b75d..b7be6b3522b 100644 --- a/Common/3dParty/libvlc/vlcmedia.cpp +++ b/Common/3dParty/libvlc/vlcmedia.cpp @@ -1,6 +1,5 @@ #include "vlcmedia.h" -#include #include CVlcMedia::CVlcMedia(libvlc_instance_t* pVlcInstance, const QString& sFile, bool bEventForwarding) diff --git a/Common/3dParty/libvlc/vlcplayer.cpp b/Common/3dParty/libvlc/vlcplayer.cpp index d6addf4f9ed..3763504147c 100644 --- a/Common/3dParty/libvlc/vlcplayer.cpp +++ b/Common/3dParty/libvlc/vlcplayer.cpp @@ -1,7 +1,5 @@ #include "vlcplayer.h" -#include - CVlcPlayer::CVlcPlayer(QWidget* parent) : QWidget(parent) { // initialize vlc media player @@ -19,6 +17,8 @@ CVlcPlayer::CVlcPlayer(QWidget* parent) : QWidget(parent) } libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerTimeChanged , onTimeChanged, this); libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerPositionChanged , onPositionChanged, this); + + libvlc_event_attach(m_pEventManager, libvlc_MediaPlayerVout , onVideoOutputChanged, this); } CVlcPlayer::~CVlcPlayer() @@ -45,6 +45,12 @@ void CVlcPlayer::onPositionChanged(const libvlc_event_t* pEvent, void* pData) emit pVlcPlayer->positionChanged(pEvent->u.media_player_position_changed.new_position); } +void CVlcPlayer::onVideoOutputChanged(const libvlc_event_t* pEvent, void* pData) +{ + CVlcPlayer* pVlcPlayer = reinterpret_cast(pData); + emit pVlcPlayer->videoOutputChanged(pEvent->u.media_player_vout.new_count); +} + void CVlcPlayer::integrateIntoWidget(QWidget* pWidget) { #if defined(_MAC) diff --git a/Common/3dParty/libvlc/vlcplayer.h b/Common/3dParty/libvlc/vlcplayer.h index c0563ce8588..b23cd5abb9a 100644 --- a/Common/3dParty/libvlc/vlcplayer.h +++ b/Common/3dParty/libvlc/vlcplayer.h @@ -20,6 +20,7 @@ class CVlcPlayer : public QWidget static void onStateChanged(const libvlc_event_t* pEvent, void *pData); static void onTimeChanged(const libvlc_event_t* pEvent, void *pData); static void onPositionChanged(const libvlc_event_t* pEvent, void *pData); + static void onVideoOutputChanged(const libvlc_event_t* pEvent, void *pData); public: void integrateIntoWidget(QWidget* pWidget); @@ -37,6 +38,7 @@ class CVlcPlayer : public QWidget void setPosition(float fPos); float position(); + // NOTE: isAudio() will always return true until event libvlc_MediaPlayerVout is occurred (see onVideoOutputChanged()) bool isAudio(); bool isPlaying(); libvlc_state_t getState(); @@ -45,6 +47,7 @@ class CVlcPlayer : public QWidget void stateChanged(int newState); void timeChanged(qint64 nNewTime); void positionChanged(float fNewPos); + void videoOutputChanged(int nVoutCount); public: libvlc_media_player_t* m_pVlcPlayer; From a68f18c9f25dc54421b7cede4093302ffe242d4d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 7 May 2024 19:55:22 +0600 Subject: [PATCH 619/794] Fix bug #67897 --- OOXML/XlsbFormat/WorkBookStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsbFormat/WorkBookStream.cpp b/OOXML/XlsbFormat/WorkBookStream.cpp index 050304b305e..c9f2c30062e 100644 --- a/OOXML/XlsbFormat/WorkBookStream.cpp +++ b/OOXML/XlsbFormat/WorkBookStream.cpp @@ -522,7 +522,7 @@ void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_) else if (xti->itabFirst < global_info_->sheets_info.size()) { strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L""); - if (xti->itabFirst != xti->itabLast) + if (xti->itabFirst != xti->itabLast && xti->itabLast < global_info_->sheets_info.size()) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L""); } From de1c08d65a2ba012f7550ae92000d1d76700c42a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 7 May 2024 20:40:12 +0600 Subject: [PATCH 620/794] Fix bug #67898 --- MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp index ca0dabd0420..2ff7d550bf4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp @@ -807,8 +807,8 @@ void GlobalsSubstream::UpdateDefineNames() else { std::vector ar(ind_sheet + 1); - - ar[ind_sheet] = value; + if(ar.size() > ind_sheet) + ar[ind_sheet] = value; //ar.push_back(value); global_info_->mapDefineNames.insert(std::make_pair(name, ar)); From bb2967c3eaab3d12cd25702a1d024a65318fa016 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 7 May 2024 17:43:26 +0300 Subject: [PATCH 621/794] Write RD and CA for FreeText AP.N --- PdfFile/SrcWriter/Annotation.cpp | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 6020eb598ed..fd3d7e7c425 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1122,6 +1122,22 @@ namespace PdfWriter pStream->WriteStr(GetColor(arrC, true).c_str()); pStream->WriteStr("\012"); + pObj = Get("CA"); + if (pObj && pObj->GetType() == object_type_REAL) + { + float dAlpha = ((CRealObject*)pObj)->Get(); + if (dAlpha != 1) + { + CExtGrState* pExtGrState = m_pDocument->GetExtGState(dAlpha, dAlpha); + const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); + if (sExtGrStateName) + { + pStream->WriteEscapeName(sExtGrStateName); + pStream->WriteStr(" gs\012"); + } + } + } + // TODO Облачная граница pObj = Get("CL"); @@ -1138,11 +1154,21 @@ namespace PdfWriter } } - StreamWriteRect(pStream, 0, 0, 0, 0); + double dRDLeft = 0.0, dRDTop = 0.0, dRDRight = 0.0, dRDBottom = 0.0; + pObj = Get("RD"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + CArrayObject* pArr = (CArrayObject*)pObj; + dRDLeft = ((CRealObject*)(pArr->Get(0)))->Get(); + dRDTop = ((CRealObject*)(pArr->Get(1)))->Get(); + dRDRight = ((CRealObject*)(pArr->Get(2)))->Get(); + dRDBottom = ((CRealObject*)(pArr->Get(3)))->Get(); + } + StreamWriteRect(pStream, GetRect().fLeft + dRDLeft + dBorderSize / 2, + GetRect().fTop + dRDTop + dBorderSize / 2, + GetRect().fRight - GetRect().fLeft - dRDRight - dRDLeft - dBorderSize, + GetRect().fBottom - GetRect().fTop - dRDBottom - dRDTop - dBorderSize); pStream->WriteStr("B\012"); - - // re внутренняя область - // BT/ET текст } void CFreeTextAnnotation::EndAP() { From 3104f84768906391fd63827edcc01132338ed5b9 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 8 May 2024 10:53:05 +0300 Subject: [PATCH 622/794] fix bug #67876 --- OOXML/Binary/Document/BinReader/Readers.h | 3 +- .../Document/DocWrapper/DocxSerializer.cpp | 254 +++++++++--------- .../Document/DocWrapper/DocxSerializer.h | 4 +- .../Document/DocWrapper/XlsxSerializer.cpp | 4 + .../Document/DocWrapper/XlsxSerializer.h | 2 + OOXML/Binary/Presentation/PPTXWriter.cpp | 4 + OOXML/Binary/Presentation/PPTXWriter.h | 5 +- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 8 +- OOXML/Binary/Sheets/Writer/BinaryReader.h | 2 +- .../DrawingConverter/ASCOfficePPTXFile.h | 6 +- .../ASCOfficePPTXFileRealization.cpp | 8 +- OOXML/PPTXFormat/Presentation.cpp | 3 +- X2tConverter/src/lib/docx.h | 1 + X2tConverter/src/lib/pptx.h | 1 + X2tConverter/src/lib/xlsx.h | 1 + 15 files changed, 171 insertions(+), 135 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/Readers.h b/OOXML/Binary/Document/BinReader/Readers.h index d04c875f17e..d32e5bde641 100644 --- a/OOXML/Binary/Document/BinReader/Readers.h +++ b/OOXML/Binary/Document/BinReader/Readers.h @@ -509,9 +509,10 @@ class BinaryFileReader Writers::FileWriter& m_oFileWriter; std::wstring m_sFileInDir; bool m_bMacro = false; - bool m_bMacroRead = false; bool m_bOForm = false; public: + bool m_bMacroRead = false; + BinaryFileReader(std::wstring& sFileInDir, NSBinPptxRW::CBinaryFileReader& oBufferedStream, Writers::FileWriter& oFileWriter, bool bMacro = false, bool bOForm = false); int ReadFile(); int ReadMainTable(); diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index b4d887a3e65..20b1760ee03 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp @@ -320,165 +320,167 @@ bool BinDocxRW::CDocxSerializer::CreateDocxFolders(std::wstring strDirectory, st } bool BinDocxRW::CDocxSerializer::loadFromFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sThemePath, const std::wstring& sMediaPath, const std::wstring& sEmbedPath) { - bool bResultOk = false; RELEASEOBJECT(m_pCurFileWriter); NSFile::CFileBinary oFile; - if(oFile.OpenFile(sSrcFileName)) - { - DWORD nBase64DataSize = 0; - BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; - oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); - oFile.CloseFile(); + if (false == oFile.OpenFile(sSrcFileName)) return false; + + bool bResultOk = false; - //проверяем формат - bool bValidFormat = false; - std::wstring sSignature(g_sFormatSignature); - int nSigLength = (int)sSignature.length(); - - if ((int)nBase64DataSize > nSigLength) + DWORD nBase64DataSize = 0; + BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; + oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); + oFile.CloseFile(); + + //проверяем формат + bool bValidFormat = false; + std::wstring sSignature(g_sFormatSignature); + int nSigLength = (int)sSignature.length(); + + if ((int)nBase64DataSize > nSigLength) + { + std::string sCurSig((char*)pBase64Data, nSigLength); + if (sSignature == std::wstring(sCurSig.begin(), sCurSig.end())) { - std::string sCurSig((char*)pBase64Data, nSigLength); - if(sSignature == std::wstring(sCurSig.begin(), sCurSig.end())) - { - bValidFormat = true; - } + bValidFormat = true; } - if(bValidFormat) - { - //Читаем из файла версию и длину base64 - int nIndex = nSigLength; - int nType = 0; - std::string version = ""; - std::string dst_len = ""; - - while (nIndex < nBase64DataSize) - { - nIndex++; - BYTE _c = pBase64Data[nIndex]; - if (_c == ';') - { - if(0 == nType) - { - nType = 1; - continue; - } - else - { - nIndex++; - break; - } - } - if(0 == nType) - version += _c; - else - dst_len += _c; - } - int nVersion = g_nFormatVersion; - if(!version.empty()) - { - version = version.substr(1); - g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); - } - bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + } + if (bValidFormat) + { + //Читаем из файла версию и длину base64 + int nIndex = nSigLength; + int nType = 0; + std::string version = ""; + std::string dst_len = ""; - NSBinPptxRW::CDrawingConverter oDrawingConverter; - NSBinPptxRW::CBinaryFileReader& oBufferedStream = *oDrawingConverter.m_pReader; - int nDataSize = 0; - BYTE* pData = NULL; - if (!bIsNoBase64) + while (nIndex < nBase64DataSize) + { + nIndex++; + BYTE _c = pBase64Data[nIndex]; + if (_c == ';') { - nDataSize = atoi(dst_len.c_str()); - pData = new BYTE[nDataSize]; - if(Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) + if (0 == nType) { - oBufferedStream.Init(pData, 0, nDataSize); + nType = 1; + continue; } else { - RELEASEARRAYOBJECTS(pData); + nIndex++; + break; } } + if (0 == nType) + version += _c; else + dst_len += _c; + } + int nVersion = g_nFormatVersion; + if (!version.empty()) + { + version = version.substr(1); + g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); + } + bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + + NSBinPptxRW::CDrawingConverter oDrawingConverter; + NSBinPptxRW::CBinaryFileReader& oBufferedStream = *oDrawingConverter.m_pReader; + int nDataSize = 0; + BYTE* pData = NULL; + if (!bIsNoBase64) + { + nDataSize = atoi(dst_len.c_str()); + pData = new BYTE[nDataSize]; + if (Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) { - nDataSize = nBase64DataSize; - pData = pBase64Data; oBufferedStream.Init(pData, 0, nDataSize); - oBufferedStream.Seek(nIndex); } - - - if (NULL != pData) + else { - oDrawingConverter.SetMainDocument(this); - oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"word"); + RELEASEARRAYOBJECTS(pData); + } + } + else + { + nDataSize = nBase64DataSize; + pData = pBase64Data; + oBufferedStream.Init(pData, 0, nDataSize); + oBufferedStream.Seek(nIndex); + } - oDrawingConverter.SetMediaDstPath(sMediaPath); - oDrawingConverter.SetEmbedDstPath(sEmbedPath); - - m_pCurFileWriter = new Writers::FileWriter(sDstPath, m_sFontDir, false, nVersion, &oDrawingConverter, sThemePath); + if (NULL != pData) + { + oDrawingConverter.SetMainDocument(this); + oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"word"); - //папка с картинками - std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName); - std::wstring sFileInDir = strFileInDir.c_str(); + oDrawingConverter.SetMediaDstPath(sMediaPath); + oDrawingConverter.SetEmbedDstPath(sEmbedPath); - oDrawingConverter.SetSrcPath(sFileInDir); - - BinaryFileReader oBinaryFileReader(sFileInDir, oBufferedStream, *m_pCurFileWriter, m_bIsMacro, m_bIsOForm); - oBinaryFileReader.ReadFile(); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //themes - m_pCurFileWriter->m_oTheme.Write(sThemePath); + m_pCurFileWriter = new Writers::FileWriter(sDstPath, m_sFontDir, false, nVersion, &oDrawingConverter, sThemePath); - OOX::CContentTypes *pContentTypes = oDrawingConverter.GetContentTypes(); - //docProps - OOX::CPath pathDocProps = sDstPath + FILE_SEPARATOR_STR + _T("docProps"); - NSDirectory::CreateDirectory(pathDocProps.GetPath()); - - OOX::CPath DocProps = std::wstring(_T("docProps")); + //папка с картинками + std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName); + std::wstring sFileInDir = strFileInDir.c_str(); - if (NULL != m_pCurFileWriter->m_pApp) - { - m_pCurFileWriter->m_pApp->write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); - } - else - { - OOX::CApp pApp(NULL); - pApp.SetDefaults(); - pApp.write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); - } + oDrawingConverter.SetSrcPath(sFileInDir); - if (NULL != m_pCurFileWriter->m_pCore) - { - m_pCurFileWriter->m_pCore->write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); - } - else - { - OOX::CCore pCore(NULL); - pCore.SetDefaults(); - pCore.write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); - } + BinaryFileReader oBinaryFileReader(sFileInDir, oBufferedStream, *m_pCurFileWriter, m_bIsMacro, m_bIsOForm); + oBinaryFileReader.ReadFile(); - if (NULL != m_pCurFileWriter->m_pCustomProperties) - { - m_pCurFileWriter->m_pCustomProperties->write(pathDocProps + FILE_SEPARATOR_STR + _T("custom.xml"), DocProps, *pContentTypes); - } + m_bIsMacro = m_bIsMacro && oBinaryFileReader.m_bMacroRead; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //themes + m_pCurFileWriter->m_oTheme.Write(sThemePath); -///////////////////////////////////////////////////////////////////////////////////// - m_pCurFileWriter->Write(); - pContentTypes->Write(sDstPath); + OOX::CContentTypes* pContentTypes = oDrawingConverter.GetContentTypes(); + //docProps + OOX::CPath pathDocProps = sDstPath + FILE_SEPARATOR_STR + _T("docProps"); + NSDirectory::CreateDirectory(pathDocProps.GetPath()); - bResultOk = true; + OOX::CPath DocProps = std::wstring(_T("docProps")); + if (NULL != m_pCurFileWriter->m_pApp) + { + m_pCurFileWriter->m_pApp->write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); } - if (!bIsNoBase64) + else { - RELEASEARRAYOBJECTS(pData); + OOX::CApp pApp(NULL); + pApp.SetDefaults(); + pApp.write(pathDocProps + FILE_SEPARATOR_STR + _T("app.xml"), DocProps, *pContentTypes); + } + + if (NULL != m_pCurFileWriter->m_pCore) + { + m_pCurFileWriter->m_pCore->write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); + } + else + { + OOX::CCore pCore(NULL); + pCore.SetDefaults(); + pCore.write(pathDocProps + FILE_SEPARATOR_STR + _T("core.xml"), DocProps, *pContentTypes); + } + + if (NULL != m_pCurFileWriter->m_pCustomProperties) + { + m_pCurFileWriter->m_pCustomProperties->write(pathDocProps + FILE_SEPARATOR_STR + _T("custom.xml"), DocProps, *pContentTypes); } + ///////////////////////////////////////////////////////////////////////////////////// + m_pCurFileWriter->Write(); + pContentTypes->Write(sDstPath); + + bResultOk = true; + + } + if (!bIsNoBase64) + { + RELEASEARRAYOBJECTS(pData); } - RELEASEARRAYOBJECTS(pBase64Data); + } + RELEASEARRAYOBJECTS(pBase64Data); + return bResultOk; } bool BinDocxRW::CDocxSerializer::getXmlContent(NSBinPptxRW::CBinaryFileReader& oBufferedStream, long lLength, std::wstring& sOutputXml) @@ -613,6 +615,10 @@ void BinDocxRW::CDocxSerializer::setMacroEnabled(bool val) { m_bIsMacro = val; } +bool BinDocxRW::CDocxSerializer::getMacroEnabled() +{ + return m_bIsMacro; +} void BinDocxRW::CDocxSerializer::setOFormEnabled(bool val) { m_bIsOForm = val; diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h index 57d7935976c..bd03c346f1d 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.h @@ -82,7 +82,9 @@ namespace BinDocxRW void setIsNoBase64Save (bool val); void setIsNoBase64 (bool val); void setSaveChartAsImg (bool val); - void setMacroEnabled (bool val); void setOFormEnabled (bool val); + + void setMacroEnabled (bool val); + bool getMacroEnabled(); }; } diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp index 962160cd71c..8155853ffa6 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp @@ -286,6 +286,10 @@ namespace BinXlsxRW{ { m_bIsMacro = val; } + bool CXlsxSerializer::getMacroEnabled() + { + return m_bIsMacro; + } bool CXlsxSerializer::writeChartXlsx(const std::wstring& sDstFile, NSCommon::smart_ptr &file) { diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h index d0b3c381c04..e0d4fc04173 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h @@ -71,7 +71,9 @@ namespace BinXlsxRW { void setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir); void setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter); void setIsNoBase64 (bool val); + void setMacroEnabled (bool val); + bool getMacroEnabled (); _UINT32 xml2Xlsx (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions); diff --git a/OOXML/Binary/Presentation/PPTXWriter.cpp b/OOXML/Binary/Presentation/PPTXWriter.cpp index 2d9fd164ffc..47d45c37b05 100644 --- a/OOXML/Binary/Presentation/PPTXWriter.cpp +++ b/OOXML/Binary/Presentation/PPTXWriter.cpp @@ -57,6 +57,10 @@ namespace NSBinPptxRW CPPTXWriter::~CPPTXWriter() { } + bool CPPTXWriter::GetMacroEnabled() + { + return m_oPresentation.m_bMacroEnabled; + } void CPPTXWriter::Init(std::wstring strFolder, bool bMacro) { m_strDstFolder = strFolder; diff --git a/OOXML/Binary/Presentation/PPTXWriter.h b/OOXML/Binary/Presentation/PPTXWriter.h index 51194a45a52..b14c951cfa2 100644 --- a/OOXML/Binary/Presentation/PPTXWriter.h +++ b/OOXML/Binary/Presentation/PPTXWriter.h @@ -88,10 +88,13 @@ namespace NSBinPptxRW void Init(std::wstring strFolder, bool bMacro = false); void OpenPPTY(BYTE* pBuffer, int len, std::wstring srcFolder, std::wstring strThemesFolder); void ReadMasterInfo(LONG nIndexMaster); + void SetRequiredDefaultsApp(); - void CreateDefaultApp(); void SetRequiredDefaultsCore(); + bool GetMacroEnabled(); + + void CreateDefaultApp(); void CreateDefaultCore(); void CreateDefaultViewProps(); void CreateDefaultTableStyles(); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index bd0089227d3..5b9d8f61d8a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -8552,7 +8552,7 @@ int BinaryFileReader::Xml2Xlsx(const std::wstring& sSrcFileName, std::wstring sD delete pXlsxFlat; return 0; } -int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bMacro) +int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool &bMacro) { bool bResultOk = false; @@ -8689,6 +8689,8 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD oXlsx.PrepareToWrite(); oXlsx.Write(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; } else if (BinXlsxRW::c_oFileTypes::XLSB == fileType) { @@ -8708,6 +8710,8 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD oXlsb.PrepareToWrite(); oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; } else { @@ -8719,7 +8723,7 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD bResultOk = oCSVWriter.Start(sDstPathCSV); if (!bResultOk) return AVS_FILEUTILS_ERROR_CONVERT; - SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), &oCSVWriter); + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), &oCSVWriter, false); try { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 17ede45e952..d1551af149a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -448,7 +448,7 @@ namespace BinXlsxRW { public: BinaryFileReader(); - int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bMacro = false); + int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool &bMacro); int ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); void initWorkbook(OOX::Spreadsheet::CWorkbook* pWorkbook); diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h index a4f61a6edbc..1516e096604 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h @@ -74,8 +74,10 @@ class CPPTXFile void SetThemesDir (std::wstring bsDir); void SetUseSystemFonts (bool useSystemFonts); - void SetIsNoBase64 (bool val); - void SetMacroEnabled (bool val); + void SetIsNoBase64 (bool val); + + void SetMacroEnabled (bool val); + bool GetMacroEnabled (); _UINT32 OpenFileToPPTY (std::wstring bsInput, std::wstring bsOutput); _UINT32 OpenDirectoryToPPTY (std::wstring bsInput, std::wstring bsOutput); diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp index ba599090a9a..091a4cb702e 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp @@ -176,6 +176,10 @@ void CPPTXFile::SetMacroEnabled(bool val) { m_bIsMacro = val; } +bool CPPTXFile::GetMacroEnabled() +{ + return m_bIsMacro; +} _UINT32 CPPTXFile::OpenFileToPPTY(std::wstring bsInput, std::wstring bsOutput) { if (m_strTempDir.empty()) m_strTempDir = NSDirectory::GetTempPath(); @@ -261,7 +265,7 @@ _UINT32 CPPTXFile::ConvertPPTYToPPTX(std::wstring bsInput, std::wstring bsOutput BYTE* pSrcBuffer = new BYTE[lFileSize]; oFileBinary.ReadFile(pSrcBuffer, (DWORD)lFileSize); oFileBinary.CloseFile(); - + std::wstring strBsInput = bsInput; std::wstring srcFolder = NSDirectory::GetFolderPath(strBsInput); @@ -275,8 +279,8 @@ _UINT32 CPPTXFile::ConvertPPTYToPPTX(std::wstring bsInput, std::wstring bsOutput { hRes = S_FALSE; } - RELEASEARRAYOBJECTS(pSrcBuffer); + m_bIsMacro = oWriter.GetMacroEnabled(); return hRes; } diff --git a/OOXML/PPTXFormat/Presentation.cpp b/OOXML/PPTXFormat/Presentation.cpp index d7eb9890b72..46ba195f6b2 100644 --- a/OOXML/PPTXFormat/Presentation.cpp +++ b/OOXML/PPTXFormat/Presentation.cpp @@ -371,8 +371,9 @@ namespace PPTX } } } - pReader->Seek(_end_pos); + + m_bMacroEnabled = m_pVbaProject.IsInit(); } void Presentation::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const diff --git a/X2tConverter/src/lib/docx.h b/X2tConverter/src/lib/docx.h index 66148a5f704..224935cdfce 100644 --- a/X2tConverter/src/lib/docx.h +++ b/X2tConverter/src/lib/docx.h @@ -180,6 +180,7 @@ namespace NExtractTools if (SUCCEEDED_X2T(nRes)) { nRes = m_oCDocxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sThemePath, sMediaPath, sEmbedPath) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + params.m_bMacro = m_oCDocxSerializer.getMacroEnabled(); } // удаляем EditorWithChanges, потому что он не в Temp if (sFrom != sTargetBin) diff --git a/X2tConverter/src/lib/pptx.h b/X2tConverter/src/lib/pptx.h index aedc08340b7..9da4314f32f 100644 --- a/X2tConverter/src/lib/pptx.h +++ b/X2tConverter/src/lib/pptx.h @@ -169,6 +169,7 @@ namespace NExtractTools pptx_file->SetFontDir(params.getFontPath()); nRes = (S_OK == pptx_file->ConvertPPTYToPPTX(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, convertParams.m_sThemesDir)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + params.m_bMacro = pptx_file->GetMacroEnabled(); delete pptx_file; } // удаляем EditorWithChanges, потому что он не в Temp diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 3e7e5e8132d..5a894bff43e 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -284,6 +284,7 @@ namespace NExtractTools if (SUCCEEDED_X2T(nRes)) { nRes = oCXlsxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sMediaPath, sEmbedPath); + params.m_bMacro = oCXlsxSerializer.getMacroEnabled(); } // удаляем EditorWithChanges, потому что он не в Temp if (sFrom != sTargetBin) From dabe547fb41cbac0850bf169ab991be14b9976cf Mon Sep 17 00:00:00 2001 From: Michael Efremov Date: Wed, 8 May 2024 11:32:29 +0300 Subject: [PATCH 623/794] [android] Build only arm arch --- X2tConverter/build/Android/libx2t/build.gradle.kts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/X2tConverter/build/Android/libx2t/build.gradle.kts b/X2tConverter/build/Android/libx2t/build.gradle.kts index 8f2c3dcb394..458116abac0 100644 --- a/X2tConverter/build/Android/libx2t/build.gradle.kts +++ b/X2tConverter/build/Android/libx2t/build.gradle.kts @@ -63,19 +63,25 @@ android { ) } } - - ndk { - abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) - } } buildTypes { release { isMinifyEnabled = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + ndk { + abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) + } } debug { isJniDebuggable = true + ndk { + if (System.getProperty("os.arch") == "aarch64") { + abiFilters.add("arm64-v8a") + } else { + abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) + } + } } } From 39748f9d9e3526425c4c9d86c41ccad5ea368962 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 8 May 2024 11:49:04 +0300 Subject: [PATCH 624/794] fix bug #67895 --- MsBinaryFile/PptFile/Drawing/Document.h | 4 +- MsBinaryFile/PptFile/Main/PPTFormatLib.cpp | 6 +-- MsBinaryFile/PptFile/PPTXWriter/Converter.cpp | 4 +- MsBinaryFile/PptFile/Reader/ClassesAtom.cpp | 4 +- .../PptFile/Reader/PPTDocumentInfo.cpp | 12 +++--- MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h | 2 +- .../PptFile/Reader/PPTDocumentInfoOneUser.cpp | 40 ++++++++++--------- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/MsBinaryFile/PptFile/Drawing/Document.h b/MsBinaryFile/PptFile/Drawing/Document.h index a3dff96e2c7..62a5c11fbfe 100644 --- a/MsBinaryFile/PptFile/Drawing/Document.h +++ b/MsBinaryFile/PptFile/Drawing/Document.h @@ -52,10 +52,10 @@ class CDocument CThemePtr m_pNotesMaster; CThemePtr m_pHandoutMaster; - bool m_bMacros; + bool m_bMacroEnabled; std::wstring m_sVbaProjectFile; - CDocument() : m_bMacros (true) + CDocument() : m_bMacroEnabled(true) { m_lSlideWidth = 0; m_lSlideHeight = 0; diff --git a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp index c985bfa9f9a..4a20e696f36 100644 --- a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp +++ b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp @@ -53,7 +53,7 @@ COfficePPTFile::~COfficePPTFile() CloseFile(); } -_UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstring & password, bool &bMacros) +_UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstring & password, bool &bMacro) { CloseFile(); @@ -76,7 +76,7 @@ _UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstr PPT::CPPTFileReader* pptReader = (PPT::CPPTFileReader*)m_pReader; pptReader->m_oDocumentInfo.m_strPassword = password; - pptReader->m_oDocumentInfo.m_bMacros = bMacros; + pptReader->m_oDocumentInfo.m_bMacroEnabled = bMacro; if (pptReader->IsPowerPoint() == false) { @@ -98,7 +98,7 @@ _UINT32 COfficePPTFile::OpenFile(const std::wstring & sFileName, const std::wstr //pptReader->ReadEncryptedSummary(); pptReader->ReadDocument(); - bMacros = pptReader->m_oDocumentInfo.m_bMacros; + bMacro = pptReader->m_oDocumentInfo.m_bMacroEnabled; m_Status = READMODE; return S_OK; diff --git a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp index f68adec4daf..943564f3c67 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -239,7 +239,7 @@ namespace PPT \ "; - if (m_pDocument->m_bMacros) + if (m_pDocument->m_bMacroEnabled) { strContentTypes += L"\ "; @@ -535,7 +535,7 @@ namespace PPT strPresRels += L""; strPresRels += L""; - if (m_pDocument->m_bMacros) + if (m_pDocument->m_bMacroEnabled) { std::wstring strVbaProject = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; diff --git a/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp b/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp index c22eabd85da..e173a623cb6 100644 --- a/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp +++ b/MsBinaryFile/PptFile/Reader/ClassesAtom.cpp @@ -68,8 +68,8 @@ void CUserEdit::FromAtom(CRecordUserEditAtom *pAtom) CCurrentUser::CCurrentUser() { - m_bIsEncrypt = false; - m_nOffsetToCurrentEdit = 0; + m_bIsEncrypt = false; + m_nOffsetToCurrentEdit = 0; } CCurrentUser::~CCurrentUser() diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp index 8814c00b2ed..067edc02759 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp @@ -33,7 +33,7 @@ using namespace PPT; -CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacros(true), m_pStream(NULL) +CPPTDocumentInfo::CPPTDocumentInfo() : m_oCurrentUser(), m_bMacroEnabled(true), m_pStream(NULL) { } @@ -79,14 +79,13 @@ bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE pInfo->m_pDocumentInfo = this; - pInfo->m_bEncrypt = m_oCurrentUser.m_bIsEncrypt; - pInfo->m_strPassword = m_strPassword; - pInfo->m_bMacros = m_bMacros; + pInfo->m_bEncrypt = m_oCurrentUser.m_bIsEncrypt; + pInfo->m_strPassword = m_strPassword; + pInfo->m_bMacroEnabled = m_bMacroEnabled; bool bResult = pInfo->ReadFromStream(&oUserAtom, pStream); - m_bMacros = pInfo->m_bMacros; - offsetToEdit = pInfo->m_oUser.m_nOffsetLastEdit; + offsetToEdit = pInfo->m_oUser.m_nOffsetLastEdit; m_oCurrentUser.m_bIsEncrypt = pInfo->m_bEncrypt; if (bResult == false) @@ -106,7 +105,6 @@ bool CPPTDocumentInfo::ReadFromStream(CRecordCurrentUserAtom *pCurrentUser, POLE pInfo = NULL; } - return true; } std::wstring CPPTDocumentInfo::GetBinFromStg(const std::wstring& name, _UINT32 nRef) diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h index 40dde44c550..dfa8caa5eb2 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.h @@ -47,7 +47,7 @@ class CPPTDocumentInfo std::vector m_arUsers; std::map m_mapStoreImageFile; std::wstring m_strPassword; - bool m_bMacros; + bool m_bMacroEnabled; std::wstring m_app_xml; std::wstring m_core_xml; diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp index 695ef503bed..70603dae79e 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -409,26 +409,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) m_mapHandoutMasters.insert(std::pair<_UINT32, CRecordSlide*>(0, pSlide)); } } - if (m_bMacros) - { - m_bMacros = false; - std::vector oArrayDocInfo; - m_oDocument.GetRecordsByType(&oArrayDocInfo, true, true); - CRecordVBAInfoAtom* pVbaAtom = nullptr; - if (!oArrayDocInfo.empty()) - pVbaAtom = oArrayDocInfo[0]->getVBAInfoAtom(); - - if (pVbaAtom) - { - if (pVbaAtom->m_nHasMacros) - { - m_sVbaProjectFile = m_pDocumentInfo->GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); - - m_bMacros = (false == m_sVbaProjectFile.empty()); - } - } - } return true; } //-------------------------------------------------------------------------------------------- @@ -480,6 +461,27 @@ void CPPTUserInfo::ReadExtenalObjects() m_bIsSetupEmpty = TRUE; m_arrBlipStore[0]->SetUpPicturesInfos(&m_arOffsetPictures); } + + if (m_bMacroEnabled) + { + m_bMacroEnabled = false; + std::vector oArrayDocInfo; + m_oDocument.GetRecordsByType(&oArrayDocInfo, true, true); + + CRecordVBAInfoAtom* pVbaAtom = nullptr; + if (!oArrayDocInfo.empty()) + pVbaAtom = oArrayDocInfo[0]->getVBAInfoAtom(); + + if (pVbaAtom) + { + if (pVbaAtom->m_nHasMacros) + { + m_sVbaProjectFile = m_pDocumentInfo->GetBinFromStg(L"vbaProject.bin", pVbaAtom->m_nObjStgDataRef); + + m_bMacroEnabled = (false == m_sVbaProjectFile.empty()); + } + } + } } void CPPTUserInfo::FromDocument() From b32728c9f0968ceac31a24ea358ff5543e883a3f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 8 May 2024 12:06:28 +0300 Subject: [PATCH 625/794] fix bug #66842 --- OdfFile/DataTypes/iconset_type.cpp | 10 ++++++---- .../Reader/Converter/xlsx_conditionalFormatting.cpp | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/OdfFile/DataTypes/iconset_type.cpp b/OdfFile/DataTypes/iconset_type.cpp index 8239ab3a778..b2b1b8ec903 100644 --- a/OdfFile/DataTypes/iconset_type.cpp +++ b/OdfFile/DataTypes/iconset_type.cpp @@ -147,13 +147,15 @@ iconset_type iconset_type::parse(const std::wstring & Str) return iconset_type( Quarters5 ); else if (tmp == L"5rating") return iconset_type( Rating5 ); - else if (tmp == L"5Boxes") + else if (tmp == L"5boxes") return iconset_type( Boxes5 ); - else if (tmp == L"3Stars") + else if (tmp == L"3stars") return iconset_type(Stars3); - else if (tmp == L"3Triangles") + else if (tmp == L"3triangles") return iconset_type(Triangles3); - else + else if (tmp == L"4rating") + return iconset_type(Rating4); + else { return iconset_type( Arrows3 ); } diff --git a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp index a6358c9f98a..009df1e93ff 100644 --- a/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp +++ b/OdfFile/Reader/Converter/xlsx_conditionalFormatting.cpp @@ -266,6 +266,7 @@ class xlsx_conditionalFormatting_context::Impl { if (c.rules[j].icon_set_type) { + int h = *c.rules[j].icon_set_type; switch (*c.rules[j].icon_set_type) { case 1: CP_XML_ATTR(L"iconSet", L"3ArrowsGray"); break; @@ -286,7 +287,7 @@ class xlsx_conditionalFormatting_context::Impl case 16: CP_XML_ATTR(L"iconSet", L"5Rating"); break; case 17: CP_XML_ATTR(L"iconSet", L"3Triangles"); break; case 18: CP_XML_ATTR(L"iconSet", L"3Stars"); break; - case 19: CP_XML_ATTR(L"iconSet", L"5Boxes"); break; + case 19: CP_XML_ATTR(L"iconSet", L"5Boxes"); break; //todooo to ext case 0: default: CP_XML_ATTR(L"iconSet", L"3Arrows"); break; break; From 7e7bc0eb0eda2635434cfb68448c3c15930dfb4d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 8 May 2024 15:39:02 +0600 Subject: [PATCH 626/794] Fix bug #67891 --- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp | 14 +++++++------- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h | 6 +++--- .../Format/Logic/Biff_structures/CellRangeRef.cpp | 10 +++++----- OOXML/XlsxFormat/Worksheets/MergeCells.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 8 ++++---- .../XlsxFormat/Worksheets/WorksheetChildOther.cpp | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 74e5eb3547b..38bbc1fdeb5 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -73,9 +73,9 @@ const int normalizeColumn(const int column, const bool xlsb) } -const std::wstring column2str(const int column, const bool col_rel) +const std::wstring column2str(const int column, const bool col_rel, const bool xlsb) { - int column_value = normalizeColumn(column); + int column_value = normalizeColumn(column, xlsb); const int radix = L'Z' - L'A' + 1; std::wstring ret_val; ++column_value; @@ -90,7 +90,7 @@ const std::wstring column2str(const int column, const bool col_rel) } -const int normalizeRow(const int row, bool xlsb) +const int normalizeRow(const int row, const bool xlsb) { int maxRow = 0; if(xlsb) @@ -114,16 +114,16 @@ const int normalizeRow(const int row, bool xlsb) } -const std::wstring row2str(const int row, const bool row_rel) +const std::wstring row2str(const int row, const bool row_rel, const bool xlsb) { - int row_value = normalizeRow(row); + int row_value = normalizeRow(row, xlsb); return (row_rel ? L"" : L"$") + STR::int2wstr(row_value + 1, 10); } -const std::wstring loc2str(const int row, const bool row_rel, const int column, const bool col_rel) +const std::wstring loc2str(const int row, const bool row_rel, const int column, const bool col_rel, const bool xlsb) { - return column2str(column, col_rel) + row2str(row, row_rel); + return column2str(column, col_rel, xlsb) + row2str(row, row_rel, xlsb); } diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index 93c60f4f19a..305d4066912 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -45,9 +45,9 @@ namespace AUX const int normalizeColumn (const int column, const bool xlsb = false); const int normalizeRow (const int row, const bool xlsb = false); - const std::wstring column2str (const int column, const bool col_rel); - const std::wstring row2str (const int row, const bool row_rel); - const std::wstring loc2str (const int row, const bool row_rel, const int column, const bool col_rel); + const std::wstring column2str (const int column, const bool col_rel, const bool xlsb = false); + const std::wstring row2str (const int row, const bool row_rel, const bool xlsb = false); + const std::wstring loc2str (const int row, const bool row_rel, const int column, const bool col_rel, const bool xlsb = false); void str2loc (const std::wstring& str, int& row, bool& row_rel, int& column, bool& col_rel); void str2loc (std::wstring::const_iterator& str_begin, std::wstring::const_iterator& str_end, int& row, bool& row_rel, int& column, bool& col_rel); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp index 5e7b73de5e4..8c05c0ff1ab 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp @@ -141,7 +141,7 @@ const std::wstring CellRangeRef::toString(const bool useShortForm, const bool xl { if(useShortForm) { - return to_string_cache = AUX::column2str(columnFirst_norm, columnFirstRelative) + L':' + AUX::column2str(columnLast_norm, columnLastRelative); + return to_string_cache = AUX::column2str(columnFirst_norm, columnFirstRelative, xlsb) + L':' + AUX::column2str(columnLast_norm, columnLastRelative, xlsb); } else { @@ -152,7 +152,7 @@ const std::wstring CellRangeRef::toString(const bool useShortForm, const bool xl { if(useShortForm) { - return to_string_cache = AUX::row2str(rowFirst_norm, rowFirstRelative) + L':' + AUX::row2str(rowLast_norm, rowLastRelative); + return to_string_cache = AUX::row2str(rowFirst_norm, rowFirstRelative, xlsb) + L':' + AUX::row2str(rowLast_norm, rowLastRelative, xlsb); } else { @@ -161,12 +161,12 @@ const std::wstring CellRangeRef::toString(const bool useShortForm, const bool xl } if(columnLast_norm == columnFirst_norm && rowFirst_norm == rowLast_norm) // single cell { - return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative); + return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative, xlsb); } else { - return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative) + - L':' + AUX::loc2str(rowLast_norm, rowLastRelative, columnLast_norm, columnLastRelative); + return to_string_cache = AUX::loc2str(rowFirst_norm, rowFirstRelative, columnFirst_norm, columnFirstRelative, xlsb) + + L':' + AUX::loc2str(rowLast_norm, rowLastRelative, columnLast_norm, columnLastRelative, xlsb); } } return to_string_cache; diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index b677a0291aa..911b6499df6 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -91,7 +91,7 @@ namespace OOX void CMergeCell::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast(obj.get()); - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CMergeCells::CMergeCells(OOX::Document *pMain) : WritingElementWithChilds(pMain) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index d0da1cf9dd9..58e26148561 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1050,7 +1050,7 @@ namespace OOX auto formula = dynamic_cast(obj.get()); m_sText = formula->formula.getAssembledFormula(); m_oRef.Init(); - m_oRef = formula->rfx.toString(); + m_oRef = formula->rfx.toString(true, true); } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: @@ -1063,7 +1063,7 @@ namespace OOX m_oAca = formula->fAlwaysCalc; } m_oRef.Init(); - m_oRef = formula->rfx.toString(); + m_oRef = formula->rfx.toString(true, true); } break; case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: @@ -1078,7 +1078,7 @@ namespace OOX } m_oRef.Init(); - m_oRef = dataTable->rfx.toString(); + m_oRef = dataTable->rfx.toString(true, true); if(dataTable->fRw) { @@ -2501,7 +2501,7 @@ namespace OOX } - auto wRef = XLSB::RgceLoc(m_oRow.get(), m_oCol.get(), true, true).toString(); + auto wRef = XLSB::RgceLoc(m_oRow.get(), m_oCol.get(), true, true).toString(true); m_oRef = std::string(wRef.begin(), wRef.end()); if(pSource != nullptr) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 8fd1f883851..e5c54f10d44 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -933,7 +933,7 @@ namespace OOX { auto ptr = static_cast(obj.get()); if (ptr != nullptr) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CSheetFormatPr::CSheetFormatPr() @@ -3105,7 +3105,7 @@ namespace OOX m_oName = ptr->xstrName.value(); if (!ptr->rfx.toString().empty()) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); if (!ptr->xstrSheet.value().empty()) m_oSheet = ptr->xstrSheet.value(); From 7ae79f20b8d3f71632a52e15cdf37e88e3e2cec6 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 8 May 2024 15:12:22 +0500 Subject: [PATCH 627/794] Fix bug #67822 --- OdfFile/Reader/Format/draw_frame_pptx.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 83927b78982..c4bc03f11d8 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -493,6 +493,10 @@ void draw_object_ole::pptx_convert(oox::pptx_conversion_context & Context) if (Context.get_mediaitems()->is_internal_path(href, folderPath)) { std::wstring objectPath = folderPath + FILE_SEPARATOR_STR + href; + NSFile::CFileBinary objectFile; + objectFile.OpenFile(objectPath); + if (objectFile.SizeFile() == 0) + return; std::wstring prog, extension; oox::_rels_type relsType; From d8bed77b679fcbc8d24b71c63086ad42b4f62d66 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 8 May 2024 17:05:49 +0500 Subject: [PATCH 628/794] Fix bug #67823 --- OdfFile/Reader/Converter/xlsx_drawing.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OdfFile/Reader/Converter/xlsx_drawing.cpp b/OdfFile/Reader/Converter/xlsx_drawing.cpp index 8648095719c..e673b5fd07a 100644 --- a/OdfFile/Reader/Converter/xlsx_drawing.cpp +++ b/OdfFile/Reader/Converter/xlsx_drawing.cpp @@ -174,6 +174,7 @@ void xml_serialize_image(std::wostream & strm, _xlsx_drawing & val, const std::w CP_XML_NODE(L"a:avLst"); } oox_serialize_ln(CP_XML_STREAM(), val.additional); + oox_serialize_effects(CP_XML_STREAM(), val.additional); } xml_serialize_text(CP_XML_STREAM(), val, ns); } @@ -209,6 +210,7 @@ void xml_serialize_shape(std::wostream & strm, _xlsx_drawing & val, const std::w val.serialize_shape(CP_XML_STREAM()); oox_serialize_ln(CP_XML_STREAM(),val.additional, val.lined); + oox_serialize_effects(CP_XML_STREAM(), val.additional); } // xdr:spPr xml_serialize_text(CP_XML_STREAM(), val, ns); From f32ace9737a881b83dc697b984d2526ed950b50b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 8 May 2024 18:50:17 +0600 Subject: [PATCH 629/794] Fix bug #67923 --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp index 23e26495310..adceb38459e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgParen.cpp @@ -51,7 +51,8 @@ BiffStructurePtr PtgParen::clone() void PtgParen::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) { - ptg_stack.top() = L'(' + ptg_stack.top() + L')'; + if(!ptg_stack.empty()) + ptg_stack.top() = L'(' + ptg_stack.top() + L')'; } From aab5cfe30c02841a162e02a9eb82092b0a290df1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 8 May 2024 19:15:45 +0600 Subject: [PATCH 630/794] Fix bug #67922 --- .../XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp index c035265ac9b..5245262d0bb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp @@ -160,10 +160,10 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu { strRange = L"#REF"; } - else + else if(global_info->sheets_info.size() > itabFirst) { strRange = XMLSTUFF::name2sheet_name(global_info->sheets_info[itabFirst].name, L""); - if (itabFirst != itabLast) + if (itabFirst != itabLast && global_info->sheets_info.size() > itabLast) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info->sheets_info[itabLast].name, L""); } From e2992c2a796da289932e2ca4edb06d4353594235 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 8 May 2024 19:33:43 +0600 Subject: [PATCH 631/794] Fix bug #67919 --- .../XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp index 27a0749a50b..98747d53de4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRefErr3d.cpp @@ -91,7 +91,7 @@ void PtgRefErr3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool return; } - if (ixti != 0xffff) + if (ixti != 0xffff && global_info->arXti_External.size() > ixti) { std::wstring link = global_info->arXti_External[ixti].link; if (!link.empty()) From 5c7b7615dd4a47c27c3afe02100698e78c61af1c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 8 May 2024 17:40:11 +0300 Subject: [PATCH 632/794] Fix find FreeText Fonts object --- PdfFile/SrcReader/PdfAnnot.cpp | 47 +++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index a1d358cb7ed..4a601af8400 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2314,6 +2314,45 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana { AnnotMarkup::SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); } +bool FindFonts(Object* oStream, int nDepth, Object* oResFonts) +{ + if (nDepth > 5) + return false; + + Object oResources; + if (!oStream->streamGetDict()->lookup("Resources", &oResources)->isDict()) + { + oResources.free(); + return false; + } + + if (oResources.dictLookup("Font", oResFonts)->isDict()) + { + oResources.free(); + return true; + } + + Object oXObject; + if (oResources.dictLookup("XObject", &oXObject)->isDict()) + { + for (int i = 0, nLength = oXObject.dictGetLength(); i < nLength; ++i) + { + Object oXObj; + if (!oXObject.dictGetVal(i, &oXObj)->isStream()) + { + oXObj.free(); + continue; + } + if (FindFonts(&oXObj, nDepth + 1, oResFonts)) + { + oXObj.free(); oXObject.free(); oResources.free(); + return true; + } + } + } + oXObject.free(); + return false; +} std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector& arrRC, int nTypeFonts) { std::map mRes; @@ -2325,7 +2364,13 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object oAnnotRef->fetch(pXref, &oAnnot); Object oAP, oN, oR, oFonts; - if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream() || !oN.streamGetDict()->lookup("Resources", &oR)->isDict() || !oR.dictLookup("Font", &oFonts)->isDict()) + if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream()) + { + oAP.free(); oN.free(); oR.free(); oFonts.free(); + return mRes; + } + + if (!FindFonts(&oN, 0, &oFonts)) { oAP.free(); oN.free(); oR.free(); oFonts.free(); return mRes; From 40e76857511270c1955a5fded2e245ed5cd9f23c Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 10 May 2024 10:40:07 +0300 Subject: [PATCH 633/794] fix bug #67941 --- MsBinaryFile/DocFile/OleObject.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/MsBinaryFile/DocFile/OleObject.cpp b/MsBinaryFile/DocFile/OleObject.cpp index 7d039d1e871..ce936581044 100644 --- a/MsBinaryFile/DocFile/OleObject.cpp +++ b/MsBinaryFile/DocFile/OleObject.cpp @@ -127,7 +127,6 @@ bool OleObject::processLinkInfoStream( const std::wstring& linkStream ) VirtualStreamReader reader( pLinkStream, 0, false); processLinkInfoStream(reader); - delete pLinkStream; res = true; } if (pLinkStream) delete pLinkStream; From 84e4797ddfe056cdaacf62b1e2b2409ecbc77f17 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Fri, 10 May 2024 10:53:02 +0300 Subject: [PATCH 634/794] fix bug #67940 --- OdfFile/Writer/Converter/MathConverter.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/OdfFile/Writer/Converter/MathConverter.cpp b/OdfFile/Writer/Converter/MathConverter.cpp index 775989c86d7..abea02d0cdf 100644 --- a/OdfFile/Writer/Converter/MathConverter.cpp +++ b/OdfFile/Writer/Converter/MathConverter.cpp @@ -529,6 +529,7 @@ namespace Oox2Odf bool OoxConverter::convert(OOX::Logic::COpEmu *oox_op_emu) { if (!oox_op_emu) return false; + if (!oox_op_emu->m_val.IsInit()) return false; if (oox_op_emu->m_val->ToBool())// == L"true") ||(oox_op_emu->m_val == L"1")) return true; @@ -854,6 +855,7 @@ namespace Oox2Odf std::wstring OoxConverter::convert(OOX::Logic::CType *oox_type) { if (!oox_type) return L""; + if (!oox_type->m_val.IsInit()) return L""; std::wstring val = oox_type->m_val->ToString(); @@ -1031,6 +1033,7 @@ namespace Oox2Odf bool OoxConverter::convert(OOX::Logic::CPos *oox_pos) { if (!oox_pos) return false; + if (!oox_pos->m_val.IsInit()) return false; if (oox_pos->m_val->ToString() == L"top") return true; else return false; @@ -1626,6 +1629,7 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CSubHide *oox_subHide) { if (!oox_subHide) return false; + if (!oox_subHide->m_val.IsInit()) return false; bool result = oox_subHide->m_val->ToBool(); return result; @@ -1634,6 +1638,8 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CSupHide *oox_supHide) { if (!oox_supHide) return false; + if (!oox_supHide->m_val.IsInit()) return false; + bool result = oox_supHide->m_val->ToBool(); return result; } @@ -1651,7 +1657,7 @@ std::wstring str1, str2; tmp->stretchy_ = false; } - if (!oox_chr) + if (!oox_chr || (oox_chr && !oox_chr->m_val.IsInit())) { annotation() += L"int "; elm->add_text(L"∫"); @@ -1747,7 +1753,8 @@ std::wstring str1, str2; bool OoxConverter::convert(OOX::Logic::CDegHide *oox_deg_hide) { if (!oox_deg_hide) return false; - + if (!oox_deg_hide->m_val.IsInit()) return false; + return oox_deg_hide->m_val->ToBool(); } From 83e020f4924e214d4d4b16793947329802a82a2d Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Thu, 9 May 2024 15:51:25 +0300 Subject: [PATCH 635/794] Fix bug #67916 --- .../raster/Metafile/Common/MetaFileUtils.h | 78 +++++++++++++------ .../Metafile/Emf/EmfParser/CEmfParser.cpp | 4 + .../Metafile/Emf/EmfParser/CEmfPlusParser.cpp | 3 + .../Metafile/Wmf/WmfParser/CWmfParser.cpp | 3 + 4 files changed, 64 insertions(+), 24 deletions(-) diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h index ae76ba586dd..7767bd9c977 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h @@ -93,7 +93,7 @@ namespace MetaFile { public: - CDataStream() : pBuffer(NULL) + CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pEnd(NULL), pCur(NULL) { } @@ -103,10 +103,25 @@ namespace MetaFile void SetStream(BYTE* pBuf, unsigned int unSize) { - pBuffer = pBuf; - pCur = pBuf; - pEnd = pBuf + unSize; - }; + pBuffer = pBuf; + pCur = pBuf; + pBufferEnd = pBuf + unSize; + pEnd = pBufferEnd; + } + + void SetCurrentBlockSize(unsigned int unSize) + { + if (pCur + unSize >= pBufferEnd) + pEnd = pBufferEnd; + else + pEnd = pCur + unSize; + } + + void ClearCurrentBlockSize() + { + pEnd = pBufferEnd; + } + BYTE* GetCurPtr() { return pCur; @@ -120,7 +135,7 @@ namespace MetaFile unsigned char unResult = pCur[0]; pCur++; return unResult; - }; + } unsigned short ReadUShort() { if (pCur + 1 >= pEnd) @@ -129,7 +144,7 @@ namespace MetaFile unsigned short ushResult = (pCur[0]) | ((pCur[1]) << 8); pCur += 2; return ushResult; - }; + } unsigned int ReadULong() { if (pCur + 3 >= pEnd) @@ -138,7 +153,7 @@ namespace MetaFile unsigned int unResult = (unsigned int)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24)); pCur += 4; return unResult; - }; + } double ReadDouble() { if (pCur + 3 >= pEnd) @@ -159,19 +174,19 @@ namespace MetaFile int lFracValue = (int)(pCur[3]); pCur += 4; return (double)(lIntValue + (lFracValue / 16.0)); - }; + } char ReadChar() { return (char)ReadUChar(); - }; + } short ReadShort() { return (short)ReadUShort(); - }; + } int ReadLong() { return (int)ReadULong(); - }; + } void ReadBytes(unsigned char* pBuffer, unsigned int ulSize) { size_t ulRemainSize = (pEnd - pCur); @@ -181,7 +196,7 @@ namespace MetaFile { pBuffer[ulIndex] = ReadChar(); } - }; + } void ReadBytes(unsigned short* pBuffer, unsigned int ulSize) { size_t ulRemainSize = (pEnd - pCur) / 2; @@ -1047,7 +1062,7 @@ namespace MetaFile bool IsEof() const { - if (pCur >= pEnd) + if (pCur >= pBufferEnd) return true; return false; @@ -1060,7 +1075,10 @@ namespace MetaFile void Skip(unsigned int ulSkip) { - pCur += ulSkip; + if (pCur + ulSkip >= pEnd) + pCur = pEnd; + else + pCur += ulSkip; } void SeekBack(unsigned int ulSkipBack) @@ -1071,6 +1089,7 @@ namespace MetaFile void SeekToStart() { pCur = pBuffer; + ClearCurrentBlockSize(); } unsigned int CanRead() @@ -1085,21 +1104,31 @@ namespace MetaFile *this >> oText; // Читаем OutputString - const unsigned int unCharsCount = oText.unChars; - int nSkip = oText.unOffString - (unOffset + 40); // 40 - размер структуры TEmfEmrText - Skip(nSkip); - T* pString = new T[unCharsCount + 1]; + oText.unChars = std::min(oText.unChars, (UINT)(CanRead() / sizeof(T))); + + if (0 == oText.unChars) + return; + + if (oText.unOffString - 40 > unOffset) + Skip(oText.unOffString - (unOffset + 40)); // 40 - размер структуры TEmfEmrText + + T* pString = new T[oText.unChars + 1]; if (pString) { - pString[unCharsCount] = 0x00; - ReadBytes(pString, unCharsCount); + pString[oText.unChars] = 0x00; + ReadBytes(pString, oText.unChars); oText.pOutputString = pString; } // Читаем OutputDx - nSkip = oText.unOffDx - oText.unOffString - 2 * unCharsCount; - Skip(nSkip); - const unsigned int unDxCount = oText.unOptions & ETO_PDY ? 2 * unCharsCount : unCharsCount; + if (oText.unChars < (UINT32_MAX / 2) && (oText.unOffDx > oText.unOffString) && (oText.unOffDx - oText.unOffString > 2 * oText.unChars)) + Skip(oText.unOffDx - oText.unOffString - 2 * oText.unChars); + + const unsigned int unDxCount = (oText.unOptions & ETO_PDY ? 2 * oText.unChars : oText.unChars); + + if ((CanRead() / 4) < unDxCount || 0 == unDxCount) + return; + unsigned int* pDx = new unsigned int[unDxCount]; if (pDx) { @@ -1116,6 +1145,7 @@ namespace MetaFile private: BYTE *pBuffer; + BYTE *pBufferEnd; BYTE *pCur; BYTE *pEnd; }; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp index 078a3bdac2b..f46fecb4b54 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp @@ -63,6 +63,8 @@ namespace MetaFile m_ulRecordPos = m_oStream.Tell(); m_ulRecordSize = ulSize - 8; + m_oStream.SetCurrentBlockSize(m_ulRecordSize); + if (ulType < EMR_MIN || ulType > EMR_MAX) { if (ENHMETA_SIGNATURE != m_oHeader.ulSignature || 0x00010000 != m_oHeader.ulVersion) @@ -213,6 +215,8 @@ namespace MetaFile m_oStream.Skip(need_skip); ulRecordIndex++; + m_oStream.ClearCurrentBlockSize(); + } while (!CheckError()); if (!CheckError()) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index d0ef37afbb5..542837ff1f6 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -234,6 +234,8 @@ namespace MetaFile m_oStream >> unSize; m_oStream >> m_ulRecordSize; + m_oStream.SetCurrentBlockSize(m_ulRecordSize); + unsigned int unRecordPos = m_oStream.Tell(); LOGGING(ActionNamesEmfPlus[unShType] << L" DataSize = " << m_ulRecordSize) @@ -318,6 +320,7 @@ namespace MetaFile LOGGING(L"Skip: " << nNeedSkip) + m_oStream.ClearCurrentBlockSize(); m_ulRecordSize = 0; }while(m_oStream.CanRead() >= 12 && !m_bEof); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp index 33803d513a6..34ec3fa88cb 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp @@ -52,6 +52,8 @@ namespace MetaFile m_unRecordSize = unSize * 2; // Размер указан в WORD + m_oStream.SetCurrentBlockSize(m_unRecordSize); + switch (ushType) { //----------------------------------------------------------- @@ -161,6 +163,7 @@ namespace MetaFile // Пропускаем лишние байты, которые могли быть в записи int need_skip = m_unRecordSize - (m_oStream.Tell() - m_unRecordPos); m_oStream.Skip(need_skip); + m_oStream.ClearCurrentBlockSize(); }; if (!m_bEof) From 9779e53fe77bdc22318bcb005378fc6ac96cf918 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sun, 12 May 2024 21:50:04 +0300 Subject: [PATCH 636/794] The algorithm for checking arrays has been rewritten --- .../html/css/src/xhtml/CDocumentStyle.cpp | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 8adb0dab1ef..b544b161159 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -1,6 +1,7 @@ #include "CDocumentStyle.h" #include +#include #include #include #include @@ -18,17 +19,29 @@ namespace NSCSS bool CheckArrays(const std::vector& arInitial, const std::set& arFirst, const std::set& arSecond) { - std::set arInitialSet(arInitial.begin(), arInitial.end()); + std::unordered_set arInitialSet(arInitial.begin(), arInitial.end()); std::vector arCommonElements1; std::vector arCommonElements2; - - std::set_intersection(arInitialSet.begin(), arInitialSet.end(), arFirst.begin(), arFirst.end(), std::back_inserter(arCommonElements1)); - std::set_intersection(arInitialSet.begin(), arInitialSet.end(), arSecond.begin(), arSecond.end(), std::back_inserter(arCommonElements2)); - + + for (const std::wstring& wsValue : arFirst) + { + if (arInitialSet.count(wsValue) > 0) + arCommonElements1.push_back(wsValue); + } + + for (const std::wstring& wsValue : arSecond) + { + if (arInitialSet.count(wsValue) > 0) + arCommonElements2.push_back(wsValue); + } + if (arCommonElements1.size() != arCommonElements2.size()) return false; + std::sort(arCommonElements1.begin(), arCommonElements1.end()); + std::sort(arCommonElements2.begin(), arCommonElements2.end()); + return arCommonElements1 == arCommonElements2; } From b53527c9fdb2316e597b481dab1de0ed27cd980f Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 13 May 2024 14:53:32 +0600 Subject: [PATCH 637/794] Fix bug #67936 --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp index cc3fad865b0..5c695229e0b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgName.cpp @@ -102,7 +102,7 @@ void PtgName::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful std::wstring ptg; - if ((global_info) && (nameindex <= global_info->arDefineNames.size())) + if ((global_info) && (nameindex <= global_info->arDefineNames.size()) && nameindex) { ptg = global_info->arDefineNames[nameindex-1]; } From 155103b40fd2b1afdad230f51cea3d638a3b471d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 13 May 2024 15:30:01 +0600 Subject: [PATCH 638/794] Fix bug #67933 --- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp index 3628c065a63..547e7bd2c9d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgNameX.cpp @@ -126,7 +126,7 @@ void PtgNameX::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu } if (name.empty()) { - if (nameindex <= global_info->arDefineNames.size()) + if (global_info && nameindex && nameindex <= global_info->arDefineNames.size()) { name = global_info->arDefineNames[nameindex - 1]; From f008857ab2cfcb751631516066d09f1135628f8d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 13 May 2024 18:12:23 +0300 Subject: [PATCH 639/794] Find Font for FreeText --- .../graphics/commands/AnnotField.cpp | 21 +++- DesktopEditor/graphics/commands/AnnotField.h | 8 +- PdfFile/PdfWriter.cpp | 110 +++++++++++++++++- PdfFile/PdfWriter.h | 8 +- PdfFile/SrcWriter/Annotation.cpp | 64 ++++++---- PdfFile/SrcWriter/Annotation.h | 3 + PdfFile/SrcWriter/Field.cpp | 1 + PdfFile/SrcWriter/Field.h | 1 + 8 files changed, 182 insertions(+), 34 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index d4841ebf67b..0e112c3bfa9 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -358,7 +358,7 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta else if (IsPolygonLine()) m_pPolygonLinePr->Read(pReader, nType, nFlags); else if (IsFreeText()) - m_pFreeTextPr->Read(pReader, nFlags); + m_pFreeTextPr->Read(pReader, nFlags, pCorrector); else if (IsCaret()) m_pCaretPr->Read(pReader, nFlags); } @@ -566,7 +566,15 @@ const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetIC() { return m_arrIC; } -void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) +BYTE* CAnnotFieldInfo::CFreeTextAnnotPr::GetRender(LONG& nLen, std::wstring& sMediaDirectory, std::wstring& sInternalMediaDirectory, std::wstring& sThemesDirectory) +{ + nLen = m_nRenderLen; + sMediaDirectory = m_sMediaDirectory; + sInternalMediaDirectory = m_sInternalMediaDirectory; + sThemesDirectory = m_sThemesDirectory; + return m_pRender; +} +void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, IMetafileToRenderter* pCorrector) { m_nQ = pReader->ReadByte(); if (nFlags & (1 << 15)) @@ -594,6 +602,15 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead for (int i = 0; i < n; ++i) m_arrIC.push_back(pReader->ReadDouble()); } + if (nFlags & (1 << 22)) + { + m_nRenderLen = pReader->ReadInt(); + m_pRender = pReader->GetCurrentBuffer(); + m_sMediaDirectory = pCorrector->GetMediaDirectory(); + m_sInternalMediaDirectory = pCorrector->GetInternalMediaDirectory(); + m_sThemesDirectory = pCorrector->GetThemesDirectory(); + pReader->Skip(m_nRenderLen - 4); + } } BYTE CAnnotFieldInfo::CCaretAnnotPr::GetSy() const { return m_nSy; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 28e12950fa7..02a36ac08f5 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -371,8 +371,9 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); const std::vector& GetCL(); const std::vector& GetIC(); + BYTE* GetRender(LONG& nLen, std::wstring& sMediaDirectory, std::wstring& sInternalMediaDirectory, std::wstring& sThemesDirectory); - void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, IMetafileToRenderter* pCorrector); private: BYTE m_nQ; @@ -382,6 +383,11 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand double m_dRD[4]{}; std::vector m_arrCL; std::vector m_arrIC; + LONG m_nRenderLen; + BYTE* m_pRender; + std::wstring m_sMediaDirectory; + std::wstring m_sInternalMediaDirectory; + std::wstring m_sThemesDirectory; }; class GRAPHICS_DECL CCaretAnnotPr diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 1408a110b00..bd655f6879a 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -51,6 +51,7 @@ #include "../../DesktopEditor/graphics/pro/Image.h" #include "../../DesktopEditor/common/StringExt.h" #include "../../DesktopEditor/graphics/GraphicsPath.h" +#include "../../DesktopEditor/graphics/MetafileToRenderer.h" #include "../../UnicodeConverter/UnicodeConverter.h" #include "../../Common/Network/FileTransporter/include/FileTransporter.h" @@ -1896,7 +1897,6 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } oRC += L"

"; pMarkupAnnot->SetRC(oRC.GetData()); - std::cout << U_TO_UTF8(oRC.GetData()) << std::endl; } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); @@ -2046,6 +2046,19 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetIT(pFTPr->GetIT()); if (nFlags & (1 << 21)) pFreeTextAnnot->SetIC(pFTPr->GetIC()); + if (nFlags & (1 << 22)) + { + // TODO перенаправить рендер в нужный объект + LONG nLen = 0; + std::wstring sMediaDirectory, sInternalMediaDirectory, sThemesDirectory; + BYTE* pRender = pFTPr->GetRender(nLen, sMediaDirectory, sInternalMediaDirectory, sThemesDirectory); + IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); + pCorrector->SetMediaDirectory(sMediaDirectory); + pCorrector->SetInternalMediaDirectory(sInternalMediaDirectory); + pCorrector->SetThemesDirectory(sThemesDirectory); + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLen, pCorrector); + RELEASEOBJECT(pCorrector); + } std::vector arrRC = pPr->GetRC(); double dFontSize = 10.0; @@ -2064,7 +2077,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF UpdateFont(); pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); // Можно указать полный шрифт? - DrawFreeTextAnnot(pFreeTextAnnot, pPr->GetRC(), oInfo.GetC()); + DrawFreeTextAnnot(pAppFonts, pFreeTextAnnot, pPr->GetRC(), oInfo.GetC()); } else if (oInfo.IsCaret()) { @@ -3880,9 +3893,98 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit RELEASEARRAYOBJECTS(pCodes); RELEASEARRAYOBJECTS(ppFonts); } -void CPdfWriter::DrawFreeTextAnnot(PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC) +void CPdfWriter::DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC) { - // TODO шрифты pFreeTextAnnot->StartAP(arrC); + + for (int i = 0; i < arrRC.size(); ++i) + { + // TODO следующая итерация может продолжаться на той-же строке + // найти оставшееся пространство и записаться в него сколько получиться + // если не всё, то остаток писать на следующую строку + + // TODO высота строки должна вычисляться по самому высокому шрифту и глифу + // Возможно, стоит найти как это реализовано на отрисовке docx на js + + bool isBold = (arrRC[i]->nFontFlag >> 0) & 1; + bool isItalic = (arrRC[i]->nFontFlag >> 1) & 1; + double dFontSize = arrRC[i]->dFontSise; + double dWidth = pFreeTextAnnot->GetRect().fRight - pFreeTextAnnot->GetRect().fLeft - pFreeTextAnnot->GetRD().fRight - pFreeTextAnnot->GetRD().fLeft; + double dHeight = pFreeTextAnnot->GetRect().fTop - pFreeTextAnnot->GetRect().fBottom - pFreeTextAnnot->GetRD().fTop - pFreeTextAnnot->GetRD().fBottom; + BYTE nAlign = arrRC[i]->nAlignment; + double dShiftBorder = pFreeTextAnnot->GetBorderWidth(); + PdfWriter::CFontCidTrueType* pFont = GetFont(arrRC[i]->sActualFont.empty() ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont, isBold, isItalic); + if (!pFont) + continue; + PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); + + unsigned int unLen = 0; + unsigned int* pUnicodes = NULL; + unsigned short* pCodes = NULL; + PdfWriter::CFontCidTrueType** ppFonts = NULL; + bool bFont = GetFontData(pAppFonts, arrRC[i]->sText, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + continue; + } + + unsigned short* pCodes2 = new unsigned short[unLen]; + unsigned int* pWidths = new unsigned int[unLen]; + + unsigned short ushSpaceCode = 0xFFFF; + unsigned short ushNewLineCode = 0xFFFE; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = 0; + if (0x0020 == pUnicodes[unIndex]) + ushCode = ushSpaceCode; + else if (0x000D == pUnicodes[unIndex] || 0x000A == pUnicodes[unIndex]) + ushCode = ushNewLineCode; + + pCodes2[unIndex] = ushCode; + pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); + } + + m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); + + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; + + m_oLinesManager.CalculateLines(dFontSize, dWidth); + + pFreeTextAnnot->GetRect(); + + unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); + double dLineShiftY = dHeight - dShiftBorder * 2 - dLineHeight + pFreeTextAnnot->GetRect().fBottom + pFreeTextAnnot->GetRD().fBottom; + for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + { + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pFreeTextAnnot->AddTextToAP(dFontSize, dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2], ppFonts + unLineStart, NULL); + + dLineShiftY -= dLineHeight; + + // TODO зачеркнутый, подчеркнутый текст, верхний и нижний регистр + } + + RELEASEARRAYOBJECTS(pCodes2); + RELEASEARRAYOBJECTS(pWidths); + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + } + pFreeTextAnnot->EndAP(); } diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 6e7907853ef..b25d7c29b95 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -241,10 +241,10 @@ class CPdfWriter unsigned char* EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs = NULL); unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); - void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); - void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); - void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); - void DrawFreeTextAnnot(PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawChoiceWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); + void DrawButtonWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); + void DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC); private: NSFonts::IFontManager* m_pFontManager; diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index fd3d7e7c425..a621ad3c929 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -917,7 +917,7 @@ namespace PdfWriter } } } - void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) + void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLX = 0, double dLY = 0, double dLL = 0, double dLLO = 0, double dLLE = 0) { double dDX = x2 - x1; double dDY = y2 - y1; @@ -960,7 +960,7 @@ namespace PdfWriter AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); - if (dLL != 0) + if (dLL) { SreamWriteXYMove(pStream, ax1, ay1); SreamWriteXYLine(pStream, bx1, by1); @@ -971,6 +971,8 @@ namespace PdfWriter SreamWriteXYMove(pStream, tx1, ty1); SreamWriteXYLine(pStream, tx2, ty2); + if (dLX && dLY) + SreamWriteXYLine(pStream, dLX, dLY); pStream->WriteStr("S\012"); DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); @@ -1049,7 +1051,7 @@ namespace PdfWriter if (pObj && pObj->GetType() == object_type_REAL) dLLO = ((CRealObject*)pObj)->Get(); - DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); + DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, 0, 0, dLL, dLLE, dLLO); } //---------------------------------------------------------------------------------------- // CPopupAnnotation @@ -1144,39 +1146,50 @@ namespace PdfWriter if (m_nIT == 1 && pObj && pObj->GetType() == object_type_ARRAY) { CArrayObject* pArr = (CArrayObject*)pObj; - DrawLineArrow(pStream, dBorderSize, ((CRealObject*)(pArr->Get(0)))->Get(), ((CRealObject*)(pArr->Get(1)))->Get(), - ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get(), m_nLE, ELineEndType::None); + double dLX = 0, dLY = 0; if (pArr->GetCount() == 6) { - SreamWriteXYMove(pStream, ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get()); - SreamWriteXYLine(pStream, ((CRealObject*)(pArr->Get(4)))->Get(), ((CRealObject*)(pArr->Get(5)))->Get()); - pStream->WriteStr("S\012"); + dLX = ((CRealObject*)(pArr->Get(4)))->Get(); + dLY = ((CRealObject*)(pArr->Get(5)))->Get(); } + DrawLineArrow(pStream, dBorderSize, ((CRealObject*)(pArr->Get(0)))->Get(), ((CRealObject*)(pArr->Get(1)))->Get(), + ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get(), m_nLE, ELineEndType::None, dLX, dLY); } - double dRDLeft = 0.0, dRDTop = 0.0, dRDRight = 0.0, dRDBottom = 0.0; - pObj = Get("RD"); - if (pObj && pObj->GetType() == object_type_ARRAY) - { - CArrayObject* pArr = (CArrayObject*)pObj; - dRDLeft = ((CRealObject*)(pArr->Get(0)))->Get(); - dRDTop = ((CRealObject*)(pArr->Get(1)))->Get(); - dRDRight = ((CRealObject*)(pArr->Get(2)))->Get(); - dRDBottom = ((CRealObject*)(pArr->Get(3)))->Get(); - } - StreamWriteRect(pStream, GetRect().fLeft + dRDLeft + dBorderSize / 2, - GetRect().fTop + dRDTop + dBorderSize / 2, - GetRect().fRight - GetRect().fLeft - dRDRight - dRDLeft - dBorderSize, - GetRect().fBottom - GetRect().fTop - dRDBottom - dRDTop - dBorderSize); - pStream->WriteStr("B\012"); + StreamWriteRect(pStream, GetRect().fLeft + m_oRD.fLeft + dBorderSize / 2, + GetRect().fBottom + m_oRD.fBottom + dBorderSize / 2, + GetRect().fRight - GetRect().fLeft - m_oRD.fRight - m_oRD.fLeft - dBorderSize, + GetRect().fTop - GetRect().fBottom - m_oRD.fBottom - m_oRD.fTop - dBorderSize); + pStream->WriteStr("B\012q\0121 0 0 1 0 0 cm\012"); + StreamWriteRect(pStream, GetRect().fLeft + m_oRD.fLeft + dBorderSize * 2, + GetRect().fBottom + m_oRD.fBottom + dBorderSize * 2, + GetRect().fRight - GetRect().fLeft - m_oRD.fRight - m_oRD.fLeft - dBorderSize * 4, + GetRect().fTop - GetRect().fBottom - m_oRD.fBottom - m_oRD.fTop - dBorderSize * 4); + pStream->WriteStr("W\012n\0120 g\0120 G\0121 w\012BT\012"); } void CFreeTextAnnotation::EndAP() { if (!m_pAppearance) return; CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + pNormal->EndText(); pNormal->EndDraw(); } + void CFreeTextAnnotation::AddTextToAP(double dFontSize, const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, double dR, double dG, double dB, CFontCidTrueType** ppFonts, const double* pShifts) + { + if (!m_pAppearance) + return; + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); + CStream* pStream = pNormal->GetStream(); + pNormal->SetFontSize(dFontSize); + pStream->WriteStr(std::to_string(dR).c_str()); + pStream->WriteChar(' '); + pStream->WriteStr(std::to_string(dG).c_str()); + pStream->WriteChar(' '); + pStream->WriteStr(std::to_string(dB).c_str()); + pStream->WriteStr(" rg\012"); + pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts); + } void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC) { CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); @@ -1195,6 +1208,10 @@ namespace PdfWriter Add("DA", new CStringObject(sDA.c_str())); } + TRect& CFreeTextAnnotation::GetRD() + { + return m_oRD; + } void CFreeTextAnnotation::SetQ(BYTE nQ) { Add("Q", (int)nQ); @@ -1229,6 +1246,7 @@ namespace PdfWriter void CFreeTextAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) { AddRD(this, dRD1, dRD2, dRD3, dRD4); + m_oRD = { dRD1, dRD2, dRD3, dRD4 }; } void CFreeTextAnnotation::SetCL(const std::vector& arrCL) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index ed937e942f3..16df6efa6ee 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -352,6 +352,7 @@ namespace PdfWriter private: BYTE m_nIT; ELineEndType m_nLE; + TRect m_oRD; CAnnotAppearance* m_pAppearance; public: @@ -364,6 +365,8 @@ namespace PdfWriter void StartAP(const std::vector& arrC); void EndAP(); void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC); + void AddTextToAP(double dFontSize, const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, double dR, double dG, double dB, CFontCidTrueType** ppFonts = NULL, const double* pShifts = NULL); + TRect& GetRD(); void SetQ(BYTE nQ); void SetIT(BYTE nIT); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 7d7f0e82d03..d9094c04c26 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1624,6 +1624,7 @@ namespace PdfWriter m_pStream = new CMemoryStream(); m_pFont = NULL; m_dFontSize = 10.0; + m_bStart = true; if (m_pXref) SetStream(m_pXref, m_pStream); diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 36b4cf9e6ce..ca7dd30d31e 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -419,6 +419,7 @@ namespace PdfWriter void StartDrawFreeText(const std::string& sColor); CStream* GetStream() { return m_pStream; } + void SetFontSize(double dFontSize) { m_dFontSize = dFontSize; } bool m_bStart; From e6842f50b3a59622ef8dea9d567dddc41a96ae4e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 14 May 2024 15:20:51 +0600 Subject: [PATCH 640/794] Fix bug #bug66658 --- .../Worksheets/ConditionalFormatting.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 43b98d19819..8830027dfcd 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1967,59 +1967,59 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) { if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::today) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTODAY; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TODAY; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::tomorrow) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTOMORROW; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_TOMORROW; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::yesterday) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODYESTERDAY; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_YESTERDAY; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::last7Days) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLAST7DAYS; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LAST7DAYS; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastMonth) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTMONTH; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTMONTH; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextMonth) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTMONTH; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTMONTH; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisWeek) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISWEEK; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISWEEK; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::nextWeek) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODNEXTWEEK; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_NEXTWEEK; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::lastWeek) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODLASTWEEK; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_LASTWEEK; } else if (m_oTimePeriod == SimpleTypes::Spreadsheet::ETimePeriod::thisMonth) { - ptr->iTemplate.value().get() = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_TIMEPERIODTHISMONTH; ptr->iParam = XLSB::CFDateOper::CF_TIMEPERIOD_THISMONTH; } } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) { - ptr->iTemplate= XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; + ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; ptr->iParam = m_oStdDev->GetValue(); } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) From 46e56afa5c167225212a65a37e72d54e875e5c4d Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Tue, 14 May 2024 14:31:24 +0300 Subject: [PATCH 641/794] bug fix(crashes, parsing correction) --- .../StarMath2OOXML/TestSMConverter/main.cpp | 286 ++++++++++-------- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 108 ++++--- .../StarMath2OOXML/cconversionsmtoooxml.h | 4 +- .../StarMath2OOXML/cstarmathpars.cpp | 151 ++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 49 +-- .../Converter/StarMath2OOXML/typeConversion.h | 7 +- OdfFile/Reader/Format/chart_build_oox.cpp | 2 +- OdfFile/Reader/Format/math_elements.cpp | 2 +- 8 files changed, 326 insertions(+), 283 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index a993e8d7a7e..c0db5e051b2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -10,7 +10,7 @@ TEST(SMConvectorTest, BinOperatorPlus) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"2+3"; + std::wstring XmlString = L"2+3"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -20,7 +20,7 @@ TEST(SMConvectorTest,BinOperatorOver) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"23"; + std::wstring XmlString = L"23"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -30,7 +30,7 @@ TEST(SMConvectorTest,BinOperatorCdot) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"5\u00B78"; + std::wstring XmlString = L"5\u00B78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -40,7 +40,7 @@ TEST(SMConvectorTest,BinOperatorTimes) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"5\u00D78"; + std::wstring XmlString = L"5\u00D78"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -50,7 +50,7 @@ TEST(SMConvectorTest,BinOperatorMultipl) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"4*2"; + std::wstring XmlString = L"4*2"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -60,7 +60,7 @@ TEST(SMConvectorTest,BinOperatorDiv) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"4\u00F72"; + std::wstring XmlString = L"4\u00F72"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -70,7 +70,7 @@ TEST(SMConvectorTest,BinOperatorDivision) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"42"; + std::wstring XmlString = L"42"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -80,7 +80,7 @@ TEST(SMConvectorTest,BinOperatorOplus) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2295179"; + std::wstring XmlString = L"226\u2295179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -90,7 +90,7 @@ TEST(SMConvectorTest,BinOperatorOdot) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2299179"; + std::wstring XmlString = L"226\u2299179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -100,7 +100,7 @@ TEST(SMConvectorTest,BinOperatorOtimes) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsBinOperator)); - std::wstring XmlString = L"226\u2297179"; + std::wstring XmlString = L"226\u2297179"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -110,7 +110,7 @@ TEST(SMConvectorTest,OperatorSum) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"5"; + std::wstring XmlString = L"5"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -120,7 +120,7 @@ TEST(SMConvectorTest,OperatorSumFrom) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -130,7 +130,7 @@ TEST(SMConvectorTest,OperatorSumTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"105"; + std::wstring XmlString = L"105"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -140,7 +140,7 @@ TEST(SMConvectorTest,OperatorSumFromTo) StarMath::CParserStarMathString m_oTempO; StarMath::CConversionSMtoOOXML m_oTest; m_oTest.StartConversion(m_oTempO.Parse(wsOperator)); - std::wstring XmlString = L"666777567"; + std::wstring XmlString = L"666777567"; EXPECT_EQ(m_oTest.GetOOXML(),XmlString); } @@ -150,7 +150,7 @@ TEST(SMConvectorTest,SetOperationUnion) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23\u22C345"; + std::wstring wsXmlString = L"23\u22C345"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -160,7 +160,7 @@ TEST(SMConvectorTest,SetOperationIntersection) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"15\u22C21234"; + std::wstring wsXmlString = L"15\u22C21234"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -170,7 +170,7 @@ TEST(SMConvectorTest,SetOperationSetminus) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"7\u221615745"; + std::wstring wsXmlString = L"7\u221615745"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -180,7 +180,7 @@ TEST(SMConvectorTest,SetOperationSetquotient) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"91\u221545"; + std::wstring wsXmlString = L"91\u221545"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -190,7 +190,7 @@ TEST(SMConvectorTest,SetOperationSubset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22822"; + std::wstring wsXmlString = L"1\u22822"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -200,7 +200,7 @@ TEST(SMConvectorTest,SetOperationSubseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"77\u228666"; + std::wstring wsXmlString = L"77\u228666"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -210,7 +210,7 @@ TEST(SMConvectorTest,SetOperationSupset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"11\u228322"; + std::wstring wsXmlString = L"11\u228322"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -220,7 +220,7 @@ TEST(SMConvectorTest,SetOperationSupseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22872"; + std::wstring wsXmlString = L"1\u22872"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -230,7 +230,7 @@ TEST(SMConvectorTest,SetOperationNsubset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"21\u22842"; + std::wstring wsXmlString = L"21\u22842"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -240,7 +240,7 @@ TEST(SMConvectorTest,SetOperationNsubseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"782\u2288250"; + std::wstring wsXmlString = L"782\u2288250"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -250,7 +250,7 @@ TEST(SMConvectorTest,SetOperationNsupset) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22852"; + std::wstring wsXmlString = L"1\u22852"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -260,7 +260,7 @@ TEST(SMConvectorTest,SetOperationNsupseteq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22892"; + std::wstring wsXmlString = L"1\u22892"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -270,7 +270,7 @@ TEST(SMConvectorTest,SetOperationIn) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1\u22082"; + std::wstring wsXmlString = L"1\u22082"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -280,7 +280,7 @@ TEST(SMConvectorTest,SetOperationNotin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3\u22094"; + std::wstring wsXmlString = L"3\u22094"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -290,7 +290,7 @@ TEST(SMConvectorTest,SetOperationOwns) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"5\u220B6"; + std::wstring wsXmlString = L"5\u220B6"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -300,7 +300,7 @@ TEST(SMConvectorTest,ConnectionDlarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"7\u21D08"; + std::wstring wsXmlString = L"7\u21D08"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -310,7 +310,7 @@ TEST(SMConvectorTest,ConnectionDlrarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"9\u21D410"; + std::wstring wsXmlString = L"9\u21D410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -320,7 +320,7 @@ TEST(SMConvectorTest,ConnectionDrarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"11\u21D212"; + std::wstring wsXmlString = L"11\u21D212"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -330,7 +330,7 @@ TEST(SMConvectorTest,ConnectionEquals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"13=14"; + std::wstring wsXmlString = L"13=14"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -340,7 +340,7 @@ TEST(SMConvectorTest,ConnectionNotequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"15\u226016"; + std::wstring wsXmlString = L"15\u226016"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -350,7 +350,7 @@ TEST(SMConvectorTest,ConnectionLearrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"17<18"; + std::wstring wsXmlString = L"17<18"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -360,7 +360,7 @@ TEST(SMConvectorTest,ConnectionLearrowequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"19\u226420"; + std::wstring wsXmlString = L"19\u226420"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -370,7 +370,7 @@ TEST(SMConvectorTest,ConnectionRiarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"21>22"; + std::wstring wsXmlString = L"21>22"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -380,7 +380,7 @@ TEST(SMConvectorTest,ConnectionRiarrowequals) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23\u226524"; + std::wstring wsXmlString = L"23\u226524"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -390,7 +390,7 @@ TEST(SMConvectorTest,ConnectionDllearrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"25\u226A26"; + std::wstring wsXmlString = L"25\u226A26"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -400,7 +400,7 @@ TEST(SMConvectorTest,ConnectionDlriarrow) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"27\u226B28"; + std::wstring wsXmlString = L"27\u226B28"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -410,7 +410,7 @@ TEST(SMConvectorTest,ConnectionApprox) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"29\u224830"; + std::wstring wsXmlString = L"29\u224830"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -420,7 +420,7 @@ TEST(SMConvectorTest,ConnectionSim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"31\u223C32"; + std::wstring wsXmlString = L"31\u223C32"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -430,7 +430,7 @@ TEST(SMConvectorTest,ConnectionSimeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"33\u224334"; + std::wstring wsXmlString = L"33\u224334"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -440,7 +440,7 @@ TEST(SMConvectorTest,ConnectionEquiv) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"35\u226136"; + std::wstring wsXmlString = L"35\u226136"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -450,7 +450,7 @@ TEST(SMConvectorTest,ConnectionProp) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"37\u221D38"; + std::wstring wsXmlString = L"37\u221D38"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -460,7 +460,7 @@ TEST(SMConvectorTest,ConnectionParallel) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"39\u222530"; + std::wstring wsXmlString = L"39\u222530"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -470,7 +470,7 @@ TEST(SMConvectorTest,ConnectionOrtho) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"41\u22A542"; + std::wstring wsXmlString = L"41\u22A542"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -480,7 +480,7 @@ TEST(SMConvectorTest,ConnectionDivides) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"43\u222344"; + std::wstring wsXmlString = L"43\u222344"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -490,7 +490,7 @@ TEST(SMConvectorTest,ConnectionNdivides) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"45\u222446"; + std::wstring wsXmlString = L"45\u222446"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -500,7 +500,7 @@ TEST(SMConvectorTest,ConnectionToward) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"47\u219248"; + std::wstring wsXmlString = L"47\u219248"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -510,7 +510,7 @@ TEST(SMConvectorTest,ConnectionTransl) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"49\u22B750"; + std::wstring wsXmlString = L"49\u22B750"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -520,7 +520,7 @@ TEST(SMConvectorTest,ConnectionTransr) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"51\u22B652"; + std::wstring wsXmlString = L"51\u22B652"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -530,7 +530,7 @@ TEST(SMConvectorTest,ConnectionDef) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"53\u225D54"; + std::wstring wsXmlString = L"53\u225D54"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -540,7 +540,7 @@ TEST(SMConvectorTest,ConnectionPrec) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"55\u227A56"; + std::wstring wsXmlString = L"55\u227A56"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -550,7 +550,7 @@ TEST(SMConvectorTest,ConnectionSucc) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"57\u227B58"; + std::wstring wsXmlString = L"57\u227B58"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -560,7 +560,7 @@ TEST(SMConvectorTest,ConnectionPreccurlyeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"59\u227C60"; + std::wstring wsXmlString = L"59\u227C60"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -570,7 +570,7 @@ TEST(SMConvectorTest,ConnectionSucccurlyeq) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"61\u227D62"; + std::wstring wsXmlString = L"61\u227D62"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -580,7 +580,7 @@ TEST(SMConvectorTest,ConnectionPrecsim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"63\u227E64"; + std::wstring wsXmlString = L"63\u227E64"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -590,7 +590,7 @@ TEST(SMConvectorTest,ConnectionSuccsim) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"65\u227F66"; + std::wstring wsXmlString = L"65\u227F66"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -600,7 +600,7 @@ TEST(SMConvectorTest,ConnectionNprec) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"67\u228068"; + std::wstring wsXmlString = L"67\u228068"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -610,7 +610,7 @@ TEST(SMConvectorTest,ConnectionNsucc) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"69\u228170"; + std::wstring wsXmlString = L"69\u228170"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -620,7 +620,7 @@ TEST(SMConvectorTest,BracketRound) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3"; + std::wstring wsXmlString = L"2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -630,7 +630,7 @@ TEST(SMConvectorTest,BracketSquare) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"4-5"; + std::wstring wsXmlString = L"4-5"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -640,7 +640,7 @@ TEST(SMConvectorTest,BracketLdbracket) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"6+7"; + std::wstring wsXmlString = L"6+7"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -650,7 +650,7 @@ TEST(SMConvectorTest,BracketLbrace) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"8-9"; + std::wstring wsXmlString = L"8-9"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -660,7 +660,7 @@ TEST(SMConvectorTest,BracketLangle) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1011"; + std::wstring wsXmlString = L"1011"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -670,7 +670,7 @@ TEST(SMConvectorTest,BracketLceil) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"12\u229613"; + std::wstring wsXmlString = L"12\u229613"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -680,7 +680,7 @@ TEST(SMConvectorTest,BracketLfloor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"14\u22C315"; + std::wstring wsXmlString = L"14\u22C315"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -690,7 +690,7 @@ TEST(SMConvectorTest,BracketLline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"1617"; + std::wstring wsXmlString = L"1617"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -700,7 +700,7 @@ TEST(SMConvectorTest,BracketLdline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"18\u229519"; + std::wstring wsXmlString = L"18\u229519"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -710,7 +710,7 @@ TEST(SMConvectorTest,FunctionCos) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cos2+3"; + std::wstring wsXmlString = L"cos2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -720,7 +720,7 @@ TEST(SMConvectorTest,FunctionSin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sin45"; + std::wstring wsXmlString = L"sin45"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -730,7 +730,7 @@ TEST(SMConvectorTest,FunctionTan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"tan67"; + std::wstring wsXmlString = L"tan67"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -740,7 +740,7 @@ TEST(SMConvectorTest,FunctionCot) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cot89"; + std::wstring wsXmlString = L"cot89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -750,7 +750,7 @@ TEST(SMConvectorTest,FunctionSinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"sinh2\u22833"; + std::wstring wsXmlString = L"sinh2\u22833"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -760,7 +760,7 @@ TEST(SMConvectorTest,FunctionCosh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cosh2+3"; + std::wstring wsXmlString = L"cosh2+3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -770,7 +770,7 @@ TEST(SMConvectorTest,FunctionTanh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"tanh11\u229712"; + std::wstring wsXmlString = L"tanh11\u229712"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -780,7 +780,7 @@ TEST(SMConvectorTest,FunctionCoth222) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"coth222"; + std::wstring wsXmlString = L"coth222"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -790,7 +790,7 @@ TEST(SMConvectorTest,FunctionArcsin) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arcsin13\u229614"; + std::wstring wsXmlString = L"arcsin13\u229614"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -800,7 +800,7 @@ TEST(SMConvectorTest,FunctionArccos) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arccos15-16"; + std::wstring wsXmlString = L"arccos15-16"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -810,7 +810,7 @@ TEST(SMConvectorTest,FunctionArctan) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arctan1718"; + std::wstring wsXmlString = L"arctan1718"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -820,7 +820,7 @@ TEST(SMConvectorTest,FunctionArccot) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arccot20+30"; + std::wstring wsXmlString = L"arccot20+30"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -830,7 +830,7 @@ TEST(SMConvectorTest,FunctionArsinh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arsinh231510"; + std::wstring wsXmlString = L"arsinh231510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -840,7 +840,7 @@ TEST(SMConvectorTest,FunctionArcosh) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"35+27arcosh2378"; + std::wstring wsXmlString = L"35+27arcosh2378"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -850,7 +850,7 @@ TEST(SMConvectorTest,FunctionArtanhArcoth) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"arcoth30\u2282artanh27"; + std::wstring wsXmlString = L"arcoth30\u2282artanh27"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -860,7 +860,7 @@ TEST(SMConvectorTest,MatrixBinom) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"27\u2283277arcoth89"; + std::wstring wsXmlString = L"27\u2283277arcoth89"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -870,7 +870,7 @@ TEST(SMConvectorTest,MatrixMatrix) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; + std::wstring wsXmlString = L"28-5210\u22C3310*10100cosh102\u229510100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -880,7 +880,7 @@ TEST(SMConvectorTest,MatrixStack) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"210231234"; + std::wstring wsXmlString = L"210231234"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -890,7 +890,7 @@ TEST(SMConvectorTest,IndexLower) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2512"; + std::wstring wsXmlString = L"2512"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -900,7 +900,7 @@ TEST(SMConvectorTest,IndexUpper) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"cos52410"; + std::wstring wsXmlString = L"cos52410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -910,7 +910,7 @@ TEST(SMConvectorTest,IndexLsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+3cos1527"; + std::wstring wsXmlString = L"2+3cos1527"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -920,7 +920,7 @@ TEST(SMConvectorTest,IndexLsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"22222103"; + std::wstring wsXmlString = L"22222103"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -930,7 +930,7 @@ TEST(SMConvectorTest,BracketWithIndexOverbrace) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"231010010"; + std::wstring wsXmlString = L"231010010"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -940,7 +940,7 @@ TEST(SMConvectorTest,OperatorLllint) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2102+3100"; + std::wstring wsXmlString = L"2102+3100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -950,7 +950,7 @@ TEST(SMConvectorTest,BracketLdlineAttribute) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"10100+3+10"; + std::wstring wsXmlString = L"10100+3+10"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -960,7 +960,7 @@ TEST(SMConvectorTest,Example11) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; + std::wstring wsXmlString = L"fx=n=0\u221Efnx0n\u0021x-x0n"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -970,7 +970,7 @@ TEST(SMConvectorTest,AttributeGrade) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"E=mc2ba\u221E"; + std::wstring wsXmlString = L"E=mc2ba\u221E"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -980,7 +980,7 @@ TEST(SMConvectorTest,Example2) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; + std::wstring wsXmlString =L"C=\u03C0\u00B7d=2\u00B7\u03C0\u00B7r"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -990,7 +990,7 @@ TEST(SMConvectorTest,Example3) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"c=a2+b2"; + std::wstring wsXmlString =L"c=a2+b2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1000,7 +1000,7 @@ TEST(SMConvectorTest,Example4) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"F=m\u00D7a"; + std::wstring wsXmlString =L"F=m\u00D7a"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1010,7 +1010,7 @@ TEST(SMConvectorTest,Example5) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"E=mc2"; + std::wstring wsXmlString =L"E=mc2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1020,7 +1020,7 @@ TEST(SMConvectorTest,Example6) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; + std::wstring wsXmlString =L"G\u03BC\u03BD+\u039Bg\u03BC\u03BD=8\u03C0Gc4T\u03BC\u03BD"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1030,7 +1030,7 @@ TEST(SMConvectorTest,Example8) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; + std::wstring wsXmlString =L"ddt\u2202L\u2202q=\u2202L\u2202q"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1040,7 +1040,7 @@ TEST(SMConvectorTest,Example9) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"abf'xdx=fb-fa"; + std::wstring wsXmlString =L"abf'xdx=fb-fa"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1050,7 +1050,7 @@ TEST(SMConvectorTest,Example10) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; + std::wstring wsXmlString =L"\u03B4rt\u2248e\u03BBt\u03B4r0"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1060,7 +1060,7 @@ TEST(SMConvectorTest,LimAndCsub) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"lim21015244"; + std::wstring wsXmlString =L"lim21015244"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1070,7 +1070,7 @@ TEST(SMConvectorTest,LimSupAndCsup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"lim sup10210100"; + std::wstring wsXmlString =L"lim sup10210100"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1080,7 +1080,7 @@ TEST(SMConvectorTest,OverWithoutLeft) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"\u00B12105"; + std::wstring wsXmlString =L"\u00B12105"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1090,7 +1090,7 @@ TEST(SMConvectorTest,Newline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23102"; + std::wstring wsXmlString = L"23102"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1100,7 +1100,7 @@ TEST(SMConvectorTest,IndexAndBinOp) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2\u22C33410"; + std::wstring wsXmlString = L"2\u22C33410"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1110,7 +1110,7 @@ TEST(SMConvectorTest,Example7) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; + std::wstring wsXmlString = L"\u0394t'=\u0394t1-v2c2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1120,7 +1120,7 @@ TEST(SMConvectorTest,UnarySign) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3+69\u2213510"; + std::wstring wsXmlString = L"3+69\u2213510"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1130,7 +1130,7 @@ TEST(SMConvectorTest,Example13) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; + std::wstring wsXmlString = L"3x3-7x2+14x-8+78+49+378+49"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1140,7 +1140,7 @@ TEST(SMConvectorTest,Example14) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; + std::wstring wsXmlString = L"i=0\u221E-1i2i+1x2i+1=sinx"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1150,7 +1150,7 @@ TEST(SMConvectorTest,Example15) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"limx->0sinxx=1"; + std::wstring wsXmlString = L"limx\u27940sinxx=1"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1160,7 +1160,7 @@ TEST(SMConvectorTest,Example16) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; + std::wstring wsXmlString = L"0\u221Ex2e-xdx=2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1170,7 +1170,7 @@ TEST(SMConvectorTest,Example17) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"a2b+b2a\u22652ab"; + std::wstring wsXmlString = L"a2b+b2a\u22652ab"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1180,7 +1180,7 @@ TEST(SMConvectorTest,Example18) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"541021"; + std::wstring wsXmlString = L"541021"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1190,7 +1190,7 @@ TEST(SMConvectorTest,IndexWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"5867243"; + std::wstring wsXmlString = L"5867243"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1200,7 +1200,7 @@ TEST(SMConvectorTest,FunctionWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"10e2723"; + std::wstring wsXmlString = L"10e2723"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1210,7 +1210,7 @@ TEST(SMConvectorTest,IncorrectSizeAndFontInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"bolt2"; + std::wstring wsXmlString = L"bolt2"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1220,7 +1220,7 @@ TEST(SMConvectorTest,IncorrectRGBColorInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2550257210"; + std::wstring wsXmlString = L"2550257210"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1230,7 +1230,7 @@ TEST(SMConvectorTest,IncorrectHexColorInput) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; + std::wstring wsXmlString = L"RGBRGBRGBRGBRGB"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1240,7 +1240,7 @@ TEST(SMConvectorTest,IndexWithoutElement) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"23"; + std::wstring wsXmlString = L"23"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1250,7 +1250,7 @@ TEST(SMConvectorTest,Neg) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"-1\u00AC105\u22287"; + std::wstring wsXmlString = L"-1\u00AC105\u22287"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1260,7 +1260,7 @@ TEST(SMConvectorTest,Frac) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; + std::wstring wsXmlString = L"n=1\u221E1n2+1n3=pi26+zeta3"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1270,7 +1270,7 @@ TEST(SMConvectorTest,BracketIndexOnTopAndOperationOnSet) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"3+105\u221612"; + std::wstring wsXmlString = L"3+105\u221612"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1280,7 +1280,7 @@ TEST(SMConvectorTest,SqrtWithIndex) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2log28=4"; + std::wstring wsXmlString = L"2log28=4"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1290,7 +1290,7 @@ TEST(SMConvectorTest,Binom) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2=432+1abc5"; + std::wstring wsXmlString = L"2=432+1abc5"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1300,7 +1300,7 @@ TEST(SMConvectorTest,UnarySignWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2+10\u2216593"; + std::wstring wsXmlString = L"2+10\u2216593"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1310,7 +1310,7 @@ TEST(SMConvectorTest,rSubrSup) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"220128"; + std::wstring wsXmlString = L"220128"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1320,7 +1320,7 @@ TEST(SMConvectorTest,DifferentRegisters) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"210\x22C35"; + std::wstring wsXmlString = L"210\x22C35"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1330,7 +1330,27 @@ TEST(SMConvectorTest,Quotes) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"2 + 3102+53"; + std::wstring wsXmlString = L"2 + 3102+53"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,NumberWithDot) +{ + std::wstring wsString = L"goal.25 over 100"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"goal.25100"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,OperatorWithoutValue) +{ + std::wstring wsString = L"lim_{x->5}"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"limx\u27945"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 0767de31f17..7fc55240c14 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -44,59 +44,67 @@ namespace StarMath { void CConversionSMtoOOXML::StartConversion(std::vector arPars, const unsigned int& iAlignment) { m_pXmlWrite = new XmlUtils::CXmlWriter; - std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; - switch(iAlignment) + if(!arPars.empty()) { - case 0: - wsAlignment = L"center"; - break; - case 1: - wsAlignment = L"left"; - break; - case 2: - wsAlignment = L"right"; - break; - default: - wsAlignment = L"center"; - break; - } - if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) - { - wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; - wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; - wsAlignment += L"Group"; - } - m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); - if(iAlignment>= 0 && iAlignment <= 2) - { - m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); - m_pXmlWrite->WriteNodeBegin(L"m:jc",true); - m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); - m_pXmlWrite->WriteNodeEnd(L"",true,true); - m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); - } - m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); - for(CElement* oTempElement:arPars) - { - if(oTempElement != nullptr) + std::wstring wsNodeMath(L"m:oMath"),wsNodeMathPara(L"m:oMathPara"),wsAlignment; + switch(iAlignment) { - if(CParserStarMathString::CheckNewline(oTempElement)) + case 0: + wsAlignment = L"center"; + break; + case 1: + wsAlignment = L"left"; + break; + case 2: + wsAlignment = L"right"; + break; + default: + wsAlignment = L"center"; + break; + } + if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) + { + wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; + wsAlignment += L"Group"; + } + m_pXmlWrite->WriteNodeBegin(wsNodeMathPara,false); + if(iAlignment>= 0 && iAlignment <= 2) + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathParaPr",false); + m_pXmlWrite->WriteNodeBegin(L"m:jc",true); + m_pXmlWrite->WriteAttribute(L"m:val",wsAlignment); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:oMathParaPr",false,false); + } + m_pXmlWrite->WriteNodeBegin(wsNodeMath,false); + for(CElement* oTempElement:arPars) + { + if(oTempElement != nullptr) { - m_pXmlWrite->WriteNodeBegin(L"m:r",false); - m_pXmlWrite->WriteNodeBegin(L"w:br",true); - m_pXmlWrite->WriteNodeEnd(L"",true,true); - m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); - m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); - m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + if(CParserStarMathString::CheckNewline(oTempElement)) + { + m_pXmlWrite->WriteNodeBegin(L"m:r",false); + m_pXmlWrite->WriteNodeBegin(L"w:br",true); + m_pXmlWrite->WriteNodeEnd(L"",true,true); + m_pXmlWrite->WriteNodeEnd(L"m:r",false,false); + m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + } + else + oTempElement->ConversionToOOXML(m_pXmlWrite); } - else - oTempElement->ConversionToOOXML(m_pXmlWrite); } } + else + { + m_pXmlWrite->WriteNodeBegin(L"m:oMathPara",false); + m_pXmlWrite->WriteNodeBegin(L"m:oMath",false); + } m_pXmlWrite->WriteNodeEnd(L"m:oMath",false,false); m_pXmlWrite->WriteNodeEnd(L"m:oMathPara",false,false); } - void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { if(TypeConversion::docx == enTypeConversion || TypeConversion::undefine == enTypeConversion) { @@ -134,10 +142,10 @@ namespace StarMath { if(pAttribute->GetSize() == 0) { pXmlWrite->WriteNodeBegin(L"w:sz",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeBegin(L"w:szCs",true); - pXmlWrite->WriteAttribute(L"w:val",L"40"); + pXmlWrite->WriteAttribute(L"w:val",L"30"); pXmlWrite->WriteNodeEnd(L"w",true,true); } else if(pAttribute->GetSize() != 0) @@ -182,7 +190,7 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w:rPr",false,false); } } - else if(TypeConversion::pptx == enTypeConversion) + else if(TypeConversion::pptx == enTypeConversion || TypeConversion::xlsx == enTypeConversion) { if(pAttribute !=nullptr) { @@ -481,14 +489,14 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:t",false,false); pXmlWrite->WriteNodeEnd(L"m:r",false,false); } - void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite,const std::wstring& wsNameNode,CElement* pValue, const TypeElement& enType,CAttribute* pAttribute,const std::wstring& wsName,CElement* pIndex) + void CConversionSMtoOOXML::WriteLimUpOrLowNode(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring& wsNameNode, CElement* pValue, const TypeElement& enType, CAttribute* pAttribute, const TypeConversion &enTypeConvers, const std::wstring& wsName, CElement* pIndex) { pXmlWrite->WriteNodeBegin(wsNameNode,false); pXmlWrite->WriteNodeBegin(wsNameNode+L"Pr",false); - CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,pValue->GetTypeConversion()); + CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,enTypeConvers); pXmlWrite->WriteNodeEnd(wsNameNode+L"Pr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,pValue->GetTypeConversion()); + CConversionSMtoOOXML::WriteRPrFName(enType,pXmlWrite,pAttribute,wsName,enTypeConvers); pXmlWrite->WriteNodeEnd(L"m:e",false,false); if(pValue!= nullptr && pIndex != nullptr) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 6bcc84f713c..9ec88401478 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -42,7 +42,7 @@ namespace StarMath { public: CConversionSMtoOOXML(); ~CConversionSMtoOOXML(); - void StartConversion(std::vector arPars, const unsigned int& iAlignment = -1); + void StartConversion(std::vector arPars, const unsigned int& iAlignment = 0); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); @@ -57,7 +57,7 @@ namespace StarMath { static void WriteRPrFName(const TypeElement& enTypeOp,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const std::wstring& wsNameOp,const TypeConversion &enTypeConversion); static void WriteStyNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsAttributeNode); static void WritePreserveBlock(XmlUtils::CXmlWriter* pXmlWrite, CAttribute *pAttribute,const TypeConversion &enTypeConversion); - static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); + static void WriteLimUpOrLowNode(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsNameNode,CElement* pValue,const TypeElement& enType,CAttribute* pAttribute,const TypeConversion& enTypeConvers, const std::wstring& wsName = L"oper",CElement* pIndex = nullptr); static void ElementConversion(XmlUtils::CXmlWriter* pXmlWrite,CElement* pElement); void EndConversion(); std::wstring GetOOXML(); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 6ed94b2b19e..eaa0773af14 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -32,6 +32,7 @@ #include "cstarmathpars.h" #include "cconversionsmtoooxml.h" + namespace StarMath { //class methods CParsStarMath @@ -41,14 +42,14 @@ namespace StarMath for(CElement* pElement:m_arEquation) delete pElement; } - std::vector CParserStarMathString::Parse(std::wstring& wsParseString,int iTypeConversion,const TBaseAttribute* pBaseAttribute) + std::vector CParserStarMathString::Parse(std::wstring& wsParseString, int iTypeConversion) { - TypeConversion enTypeConvers = (TypeConversion)iTypeConversion; + TypeConversion enTypeConvers = (TypeConversion)iTypeConversion; std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); - CStarMathReader* pReader = new CStarMathReader(itStart,itEnd,enTypeConvers); - pReader->SetBaseAttribute(pBaseAttribute); - if(pBaseAttribute != nullptr && (pBaseAttribute->base_alignment >= 0 && pBaseAttribute->base_alignment <= 2)) - SetAlignment(pBaseAttribute->base_alignment); + CStarMathReader* pReader = new CStarMathReader(itStart,itEnd,enTypeConvers); + pReader->SetBaseAttribute(m_stBaseAttribute); +// if(m_stBaseAttribute != nullptr && (m_stBaseAttribute->base_alignment >= 0 && m_stBaseAttribute->base_alignment <= 2)) +// SetAlignment(m_stBaseAttribute->base_alignment); while(pReader->CheckIteratorPosition()) { if(!m_arEquation.empty()) @@ -60,7 +61,7 @@ namespace StarMath { if(pReader->GetLocalType() == TypeElement::newline) { - m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); + m_arEquation.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); pReader->ClearReader(); } CElement* pTempElement = ParseElement(pReader); @@ -236,7 +237,7 @@ namespace StarMath } const unsigned int& CParserStarMathString::GetAlignment() { - return m_iAlignment; + return m_stBaseAttribute.base_alignment; } void CParserStarMathString::SetBaseFont(const std::wstring &wsNameFont) { @@ -823,7 +824,7 @@ namespace StarMath for(wchar_t cOneElement: wsToken) { - if(!isdigit(cOneElement) || L'\0' == cOneElement) return TypeElement::undefine; + if(!iswdigit(cOneElement) || L'\0' == cOneElement) return TypeElement::undefine; } return TypeElement::String; } @@ -833,7 +834,7 @@ namespace StarMath for(wchar_t cOneElement: wsToken) { - if(!isalpha(cOneElement)) return TypeElement::undefine; + if(!iswalpha(cOneElement)) return TypeElement::undefine; } return TypeElement::String; } @@ -1255,8 +1256,8 @@ namespace StarMath else if(L"laplace" == wsToken) return TypeElement::laplace; else if(L"fourier" == wsToken) return TypeElement::fourier; else if(L"backepsilon" == wsToken) return TypeElement::backepsilon; - else if(L"leftarrow" == wsToken) return TypeElement::leftarrow; - else if(L"rightarrow" == wsToken) return TypeElement::rightarrow; + else if(L"leftarrow" == wsToken || L"<-" == wsToken) return TypeElement::leftarrow; + else if(L"rightarrow" == wsToken || L"->" == wsToken) return TypeElement::rightarrow; else if(L"uparrow" == wsToken) return TypeElement::uparrow; else if(L"downarrow" == wsToken) return TypeElement::downarrow; else if(L"dotslow" == wsToken) return TypeElement::dotslow; @@ -1628,16 +1629,16 @@ namespace StarMath m_wsType = L"\u2261"; break; case TypeElement::rightarrow: - m_wsType = L"\u1F872"; + m_wsType = L"\u2794"; break; case TypeElement::leftarrow: - m_wsType = L"\u1F870"; + m_wsType = L"\u2190"; break; case TypeElement::uparrow: - m_wsType = L"\u1F871"; + m_wsType = L"\uF871"; break; case TypeElement::downarrow: - m_wsType = L"\u1F873"; + m_wsType = L"\uF873"; break; case TypeElement::dotsaxis: m_wsType = L"\u22EF"; @@ -2551,9 +2552,9 @@ namespace StarMath CConversionSMtoOOXML::PropertiesFuncPr(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeBegin(L"m:fName",false); if((m_pValueFrom != nullptr || m_pLowerIndex != nullptr) && (m_pValueTo == nullptr && m_pUpperIndex == nullptr)) - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pLowerIndex); else if((m_pValueTo != nullptr || m_pUpperIndex != nullptr ) && (m_pValueFrom == nullptr && m_pLowerIndex == nullptr)) - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),m_wsName,m_pUpperIndex); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limUpp",m_pValueTo,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pUpperIndex); else if ((m_pValueFrom != nullptr || m_pLowerIndex != nullptr )&& (m_pValueTo != nullptr || m_pUpperIndex != nullptr)) { pXmlWrite->WriteNodeBegin(L"m:limUpp",false); @@ -2561,7 +2562,7 @@ namespace StarMath CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,nullptr,GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:limUppPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),m_wsName,m_pLowerIndex); + CConversionSMtoOOXML::WriteLimUpOrLowNode(pXmlWrite,L"m:limLow",m_pValueFrom,m_enTypeOperator,GetAttribute(),this->GetTypeConversion(),m_wsName,m_pLowerIndex); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeBegin(L"m:lim",false); if(m_pUpperIndex !=nullptr) @@ -2849,11 +2850,11 @@ namespace StarMath m_itStart++; break; } - else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back())) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || L'>' == *m_itStart || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back() && L'<' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back()) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back()) || L'=' == *m_itStart)))) { return m_wsElement; } - else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || (L'+' == *m_itStart && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart)) ) ) ) + else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || ((L'+' == *m_itStart || L'>' == *m_itStart) && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart || L'-' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart )) ) ) ) { m_wsElement.push_back(*m_itStart); m_itStart++; @@ -2931,7 +2932,7 @@ namespace StarMath { break; } - if(CElementBracket::GetBracketOpen(m_wsToken) != TypeElement::undefine) + if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine) { inBracketInside +=1; } @@ -2997,11 +2998,11 @@ namespace StarMath } bool CStarMathReader::CheckIsalhpaForGetElement(const wchar_t &cToken, const wchar_t &cLastToken) { - if(isalpha(cToken)) + if(iswalpha(cToken)) { if(L'%' == cLastToken) return false; - if(isalpha(cLastToken)) + if(iswalpha(cLastToken)) return false; } else @@ -3090,33 +3091,11 @@ namespace StarMath CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); pXmlWrite->WriteNodeBegin(L"m:e",false); -// switch(m_enTypeBracketWithIndex) -// { -// case TypeElement::overbrace: -// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); -// break; -// case TypeElement::underbrace: -// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); -// break; -// default: -// break; -// } CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeEnd(L"m:groupChr",false,false); pXmlWrite->WriteNodeEnd(L"m:e",false,false); pXmlWrite->WriteNodeBegin(L"m:lim",false); -// switch(m_enTypeBracketWithIndex) -// { -// case TypeElement::overbrace: -// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); -// break; -// case TypeElement::underbrace: -// CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); -// break; -// default: -// break; -// } CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); pXmlWrite->WriteNodeEnd(L"m:lim",false,false); pXmlWrite->WriteNodeEnd(wsNameNode,false,false); @@ -3283,44 +3262,76 @@ namespace StarMath switch(m_enTypeMatrix) { case TypeElement::matrix: + case TypeElement::stack: + { + if(m_pFirstArgument != nullptr) { - CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); - std::vector pTempValue = pTempBracket->GetBracketValue(); - for(CElement* pOneElement:pTempValue) + if(m_pFirstArgument->GetBaseType() == TypeElement::Bracket) { - if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol && pOneElement->GetBaseType()!= TypeElement::undefine) + CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); + std::vector pTempValue = pTempBracket->GetBracketValue(); + for(CElement* pOneElement:pTempValue) { - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); - } - else if(pOneElement->GetBaseType() == TypeElement::SpecialSymbol) - { - CElementSpecialSymbol* pTempSpecial = dynamic_cast(pOneElement); - if(pTempSpecial->GetType() == TypeElement::transition) + if(pOneElement->GetBaseType() != TypeElement::undefine && pOneElement->GetBaseType() != TypeElement::SpecialSymbol && m_enTypeMatrix == TypeElement::stack) { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:mr",false,false); pXmlWrite->WriteNodeBegin(L"m:mr",false); } + else if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol && pOneElement->GetBaseType()!= TypeElement::undefine && m_enTypeMatrix == TypeElement::matrix) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); + } + else if(pOneElement->GetBaseType()!= TypeElement::undefine && pOneElement->GetBaseType() == TypeElement::SpecialSymbol && m_enTypeMatrix == TypeElement::matrix) + { + CElementSpecialSymbol* pTempSpecial = dynamic_cast(pOneElement); + if(pTempSpecial->GetType() == TypeElement::transition) + { + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + else if(pTempSpecial->GetType() != TypeElement::grid) + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); + } } - else if(pOneElement->GetBaseType() != TypeElement::undefine) - CConversionSMtoOOXML::ElementConversion(pXmlWrite,pOneElement); + } + else if(m_enTypeMatrix == TypeElement::matrix) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + } + else if (m_enTypeMatrix == TypeElement::stack) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); } break; } - case TypeElement::stack: + else if(m_pFirstArgument == nullptr && m_enTypeMatrix == TypeElement::matrix) { - CElementBracket* pTempBracket = dynamic_cast(m_pFirstArgument); - std::vector pTempValue = pTempBracket->GetBracketValue(); - for(CElement* pOneElement:pTempValue) - { - if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol) - { - CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); - pXmlWrite->WriteNodeEnd(L"m:mr",false,false); - pXmlWrite->WriteNodeBegin(L"m:mr",false); - } - } + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); break; } + else if(m_pFirstArgument == nullptr && m_enTypeMatrix == TypeElement::stack) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",nullptr,pXmlWrite); + break; + } + } case TypeElement::binom: { CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pFirstArgument,pXmlWrite); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 025fdc6836d..d33a080839a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -39,7 +39,10 @@ #include #include #include +#include +#include #include "../../../../DesktopEditor/xml/include/xmlwriter.h" +#include "../../../../OOXML/Base/Unit.h" namespace StarMath { @@ -100,7 +103,7 @@ namespace StarMath class CStarMathReader { public: - CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion); + CStarMathReader(std::wstring::iterator& itStart, std::wstring::iterator& itEnd,const TypeConversion &enTypeConversion); ~CStarMathReader(); bool GetToken(); //getting a subtype and setting the global type of a token to variables m_enUnderType and m_enGlobalType @@ -131,8 +134,8 @@ namespace StarMath void ReadingTheNextToken(); void SetMarkForUnar(const bool& bMark); bool GetMarkForUnar(); - void SetTypeConversion(const TypeConversion &enTypeCon); - TypeConversion GetTypeConversion(); + void SetTypeConversion(const TypeConversion &enTypeCon); + TypeConversion GetTypeConversion(); private: bool CheckTokenForGetElement(const wchar_t& cToken); bool CheckIsalhpaForGetElement(const wchar_t& cToken,const wchar_t& cLastToken); @@ -142,7 +145,7 @@ namespace StarMath std::wstring m_wsLowerCaseToken,m_wsOriginalToken; CAttribute* m_pAttribute; CAttribute* m_pBaseAttribute; - TypeConversion m_enTypeCon; + TypeConversion m_enTypeCon; std::stack m_stBracket; }; @@ -150,7 +153,7 @@ namespace StarMath { public: CElement(); - CElement(const TypeElement& enTypeBase, const TypeConversion& enTypeConversion); + CElement(const TypeElement& enTypeBase, const TypeConversion& enTypeConversion); virtual ~CElement(); virtual void Parse(CStarMathReader* pReader) = 0; //The function creates the class we need (by determining the class type by a variable m_enGlobalType from the class CStarMathReader) @@ -161,17 +164,17 @@ namespace StarMath void SetBaseType(const TypeElement& enType); CAttribute* GetAttribute(); const TypeElement& GetBaseType(); - const TypeConversion& GetTypeConversion(); + const TypeConversion& GetTypeConversion(); private: CAttribute* m_pAttribute; TypeElement m_enBaseType; - TypeConversion m_enTypeConversion; + TypeConversion m_enTypeConversion; }; class CElementIndex: public CElement { public: - CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementIndex(); void SetValueIndex(CElement* pElement); void SetLeftArg(CElement* pElement); @@ -198,14 +201,14 @@ namespace StarMath TypeElement m_enTypeIndex; }; - class CElementString: public CElement + class CElementString: public CElement { public: - CElementString(const std::wstring& wsTokenString, const TypeConversion &enTypeConversion); + CElementString(const std::wstring& wsTokenString, const TypeConversion &enTypeConversion); virtual ~CElementString(); void SetString(const std::wstring& wsTokenString); std::wstring GetString(); - static TypeElement GetDigit(const std::wstring& wsCheckToken); + static TypeElement GetDigit(const std::wstring& wsCheckToken); static TypeElement GetWord(const std::wstring& wsToken); void SetAttribute(CAttribute* pAttribute) override; private: @@ -217,7 +220,7 @@ namespace StarMath class CElementBinOperator: public CElement { public: - CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementBinOperator(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBinOperator(); void SetLeftArg(CElement* pElement); void SetRightArg(CElement* pElement); @@ -242,7 +245,7 @@ namespace StarMath class CElementOperator: public CElement { public: - CElementOperator(const TypeElement& enType, const TypeConversion &enTypeConversion ,const std::wstring& wsNameOp = L""); + CElementOperator(const TypeElement& enType, const TypeConversion &enTypeConversion ,const std::wstring& wsNameOp = L""); virtual ~CElementOperator(); void SetValueOperator(CElement* pElement); CElement* GetValueOperator(); @@ -270,7 +273,7 @@ namespace StarMath class CElementGrade: public CElement { public: - CElementGrade(const TypeConversion &enTypeConversion); + CElementGrade(const TypeConversion &enTypeConversion); virtual ~CElementGrade(); void SetValueGrade(CElement* pElement); void SetValueFrom(CElement* pElement); @@ -288,7 +291,7 @@ namespace StarMath class CElementBracket: public CElement { public: - CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBracket(); void SetBracketValue(const std::vector& arValue); static TypeElement GetBracketOpen(const std::wstring& wsToken); @@ -306,7 +309,7 @@ namespace StarMath class CElementBracketWithIndex: public CElement { public: - CElementBracketWithIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementBracketWithIndex(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementBracketWithIndex(); void SetLeftArg(CElement* pElement); void SetBracketValue(CElement* pElement); @@ -325,7 +328,7 @@ namespace StarMath class CElementSetOperations: public CElement { public: - CElementSetOperations(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementSetOperations(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementSetOperations(); void SetLeftArg(CElement* pElement); CElement* GetLeftArg(); @@ -345,7 +348,7 @@ namespace StarMath class CElementConnection: public CElement { public: - CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementConnection(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementConnection(); void SetRightArg(CElement* pElement); CElement* GetRightArg(); @@ -365,7 +368,7 @@ namespace StarMath class CElementFunction: public CElement { public: - CElementFunction(const TypeElement& enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameFunc = L""); + CElementFunction(const TypeElement& enType, const TypeConversion &enTypeConversion,const std::wstring& wsNameFunc = L""); virtual ~CElementFunction(); void SetValueFunction(CElement* pElement); CElement* GetValueFunction(); @@ -385,7 +388,7 @@ namespace StarMath class CElementSpecialSymbol: public CElement { public: - CElementSpecialSymbol(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementSpecialSymbol(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementSpecialSymbol(); static TypeElement GetSpecialSymbol(std::wstring& wsToken); void SetValue(CElement* pValue); @@ -403,7 +406,7 @@ namespace StarMath class CElementMatrix: public CElement { public: - CElementMatrix(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementMatrix(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementMatrix(); void SetFirstArgument(CElement* pElement); void SetSecondArgument(CElement* pElement); @@ -420,7 +423,7 @@ namespace StarMath class CElementDiacriticalMark: public CElement { public: - CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementDiacriticalMark(const TypeElement& enType,const TypeConversion &enTypeConversion); virtual ~CElementDiacriticalMark(); void SetValueMark(CElement* pValue); static TypeElement GetMark(const std::wstring& wsToken); @@ -437,7 +440,7 @@ namespace StarMath public: CParserStarMathString(); ~CParserStarMathString(); - std::vector Parse(std::wstring& wsParseString,int iTypeConversion,const TBaseAttribute* pBaseAttribute = nullptr); + std::vector Parse(std::wstring& wsParseString,int iTypeConversion = 0); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h index f13733e5c5d..9e9ad4d3de3 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeConversion.h @@ -4,9 +4,10 @@ namespace StarMath { enum class TypeConversion { - undefine, - pptx, - docx, + undefine, + pptx, + docx, + xlsx, }; } diff --git a/OdfFile/Reader/Format/chart_build_oox.cpp b/OdfFile/Reader/Format/chart_build_oox.cpp index 0b72a70e1b1..2ec5bfe082e 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -209,7 +209,7 @@ void object_odf_context::xlsx_convert(oox::xlsx_conversion_context & Context) Context.get_math_context().base_font_bold_ = baseFontBold_; Context.get_math_context().start(); - office_math_->oox_convert(Context.get_math_context()); + office_math_->oox_convert(Context.get_math_context(),3); } else if(object_type_ == 4 && office_spreadsheet_) { diff --git a/OdfFile/Reader/Format/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index 8bc27716dd6..a47bea07012 100644 --- a/OdfFile/Reader/Format/math_elements.cpp +++ b/OdfFile/Reader/Format/math_elements.cpp @@ -125,7 +125,7 @@ void math_semantics::oox_convert(oox::math_context &Context, int iTypeConversion parser.SetBaseItalic(Context.base_font_italic_); parser.SetBaseBold(Context.base_font_bold_); - /*result = */converter.StartConversion(parser.Parse(annotation_text,iTypeConversion)); + /*result = */converter.StartConversion(parser.Parse(annotation_text,iTypeConversion),parser.GetAlignment()); Context.output_stream() << converter.GetOOXML(); From 73dc77087034134463f1a8fb339420dd1149537c Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 14 May 2024 17:41:48 +0600 Subject: [PATCH 642/794] Fix bug #66678 --- OOXML/XlsxFormat/Table/Tables.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index c7cbe495aa7..0408e1abc7c 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -1456,8 +1456,12 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") ptr->fPersist = m_PreserveSortFilterLayout.get(); if(m_UnboundColumnsLeft.IsInit()) ptr->ccolExtraLeft = m_UnboundColumnsLeft->GetValue(); + else + ptr->ccolExtraLeft = 0; if(m_UnboundColumnsRight.IsInit()) ptr->ccolExtraRight = m_UnboundColumnsRight->GetValue(); + else + ptr->ccolExtraRight = 0; if(m_oQueryTableFields.IsInit()) ptr1->m_QSIFS = m_oQueryTableFields->toBin(); From 5617968a0c30fc98878fb705c64032fbd37dd6f7 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Tue, 14 May 2024 17:51:19 +0500 Subject: [PATCH 643/794] Fix bug #67926 --- OOXML/PPTXFormat/Logic/Pic.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 163df8d7f7c..a57e12c544f 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -913,8 +913,7 @@ namespace PPTX bOle = true; pWriter->WriteString(L""); pWriter->WriteString(L"WriteString(L" name=\"" + nvPicPr.cNvPr.name + L"\""); + pWriter->WriteString(L" name=\"" + nvPicPr.cNvPr.name + L"\""); pWriter->WriteString(L"/>"); pWriter->WriteString(L""); pWriter->WriteString(L""); From 7dbe7eb3e13bd5698c9e1a77e4794eade7fb8d38 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 14 May 2024 19:16:08 +0600 Subject: [PATCH 644/794] Fix bug #66677 --- .../XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp | 2 +- .../Format/Logic/Biff_structures/StringPtgParser.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp index c0927f95141..52e9b358649 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp @@ -529,7 +529,7 @@ Ftab_Cetab::ValuesDetermination::ValuesDetermination() params_fixed.insert(ParamsFixed(0x01DE, 1, L"CUBESET")); params_fixed.insert(ParamsFixed(0x01DF, 1, L"CUBESETCOUNT")); params_fixed.insert(ParamsFixed(0x01E0, 2, L"IFERROR")); - params_fixed.insert(ParamsFixed(0x01E1, 2, L"COUNTIFS")); + params_fixed.insert(ParamsFixed(0x01E1, -1, L"COUNTIFS")); params_fixed.insert(ParamsFixed(0x01E2, 3, L"SUMIFS")); params_fixed.insert(ParamsFixed(0x01E3, 2, L"AVERAGEIF")); params_fixed.insert(ParamsFixed(0x01E4, 3, L"AVERAGEIFS")); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 980924d3fc1..71432f85935 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -597,6 +597,12 @@ std::vector StringPtgParser::PosValArgs(const unsigned int &index) const argVector.push_back(false); argVector.push_back(true); break; + case 0x01E1: + for(auto i = 0; i < 127; i++) + { + argVector.push_back(false); + argVector.push_back(true); + } default: break; } From 2dc0956b3c5de69bf879ec8d3ac97a9f5a801711 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 14 May 2024 17:52:04 +0300 Subject: [PATCH 645/794] Create CAnnotRenderer --- .../graphics/commands/AnnotField.cpp | 12 +- DesktopEditor/graphics/commands/AnnotField.h | 4 +- PdfFile/PdfFile.pro | 2 + PdfFile/PdfWriter.cpp | 209 ++++-- PdfFile/SrcWriter/AnnotRenderer.cpp | 680 ++++++++++++++++++ PdfFile/SrcWriter/AnnotRenderer.h | 197 +++++ PdfFile/SrcWriter/States.h | 30 +- 7 files changed, 1037 insertions(+), 97 deletions(-) create mode 100644 PdfFile/SrcWriter/AnnotRenderer.cpp create mode 100644 PdfFile/SrcWriter/AnnotRenderer.h diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 0e112c3bfa9..155dc2e6f66 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -358,7 +358,7 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta else if (IsPolygonLine()) m_pPolygonLinePr->Read(pReader, nType, nFlags); else if (IsFreeText()) - m_pFreeTextPr->Read(pReader, nFlags, pCorrector); + m_pFreeTextPr->Read(pReader, nFlags); else if (IsCaret()) m_pCaretPr->Read(pReader, nFlags); } @@ -566,15 +566,12 @@ const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } const std::vector& CAnnotFieldInfo::CFreeTextAnnotPr::GetIC() { return m_arrIC; } -BYTE* CAnnotFieldInfo::CFreeTextAnnotPr::GetRender(LONG& nLen, std::wstring& sMediaDirectory, std::wstring& sInternalMediaDirectory, std::wstring& sThemesDirectory) +BYTE* CAnnotFieldInfo::CFreeTextAnnotPr::GetRender(LONG& nLen) { nLen = m_nRenderLen; - sMediaDirectory = m_sMediaDirectory; - sInternalMediaDirectory = m_sInternalMediaDirectory; - sThemesDirectory = m_sThemesDirectory; return m_pRender; } -void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, IMetafileToRenderter* pCorrector) +void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nQ = pReader->ReadByte(); if (nFlags & (1 << 15)) @@ -606,9 +603,6 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead { m_nRenderLen = pReader->ReadInt(); m_pRender = pReader->GetCurrentBuffer(); - m_sMediaDirectory = pCorrector->GetMediaDirectory(); - m_sInternalMediaDirectory = pCorrector->GetInternalMediaDirectory(); - m_sThemesDirectory = pCorrector->GetThemesDirectory(); pReader->Skip(m_nRenderLen - 4); } } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 02a36ac08f5..86c018b08f9 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -371,9 +371,9 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); const std::vector& GetCL(); const std::vector& GetIC(); - BYTE* GetRender(LONG& nLen, std::wstring& sMediaDirectory, std::wstring& sInternalMediaDirectory, std::wstring& sThemesDirectory); + BYTE* GetRender(LONG& nLen); - void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, IMetafileToRenderter* pCorrector); + void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); private: BYTE m_nQ; diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index 9de26c11ee4..f1cc7223dd4 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -170,6 +170,7 @@ HEADERS += \ SrcWriter/Utils.h \ SrcWriter/Metadata.h \ SrcWriter/ICCProfile.h \ + SrcWriter/AnnotRenderer.h \ SrcWriter/States.h SOURCES += \ @@ -198,6 +199,7 @@ SOURCES += \ SrcWriter/Streams.cpp \ SrcWriter/Utils.cpp \ SrcWriter/Metadata.cpp \ + SrcWriter/AnnotRenderer.cpp \ SrcWriter/States.cpp # PdfFile diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index bd655f6879a..64b76b3ac76 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -29,8 +29,8 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Directory.h" +#include "../DesktopEditor/common/File.h" +#include "../DesktopEditor/common/Directory.h" #include "PdfWriter.h" @@ -42,19 +42,20 @@ #include "SrcWriter/FontTT.h" #include "SrcWriter/Destination.h" #include "SrcWriter/Field.h" +#include "SrcWriter/AnnotRenderer.h" -#include "../../DesktopEditor/graphics/Image.h" -#include "../../DesktopEditor/graphics/structures.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Image.h" -#include "../../DesktopEditor/common/StringExt.h" -#include "../../DesktopEditor/graphics/GraphicsPath.h" -#include "../../DesktopEditor/graphics/MetafileToRenderer.h" +#include "../DesktopEditor/graphics/Image.h" +#include "../DesktopEditor/graphics/structures.h" +#include "../DesktopEditor/raster/BgraFrame.h" +#include "../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../DesktopEditor/graphics/pro/Fonts.h" +#include "../DesktopEditor/graphics/pro/Image.h" +#include "../DesktopEditor/common/StringExt.h" +#include "../DesktopEditor/graphics/GraphicsPath.h" +#include "../DesktopEditor/graphics/MetafileToRenderer.h" -#include "../../UnicodeConverter/UnicodeConverter.h" -#include "../../Common/Network/FileTransporter/include/FileTransporter.h" +#include "../UnicodeConverter/UnicodeConverter.h" +#include "../Common/Network/FileTransporter/include/FileTransporter.h" #if defined(GetTempPath) #undef GetTempPath @@ -2046,20 +2047,6 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetIT(pFTPr->GetIT()); if (nFlags & (1 << 21)) pFreeTextAnnot->SetIC(pFTPr->GetIC()); - if (nFlags & (1 << 22)) - { - // TODO перенаправить рендер в нужный объект - LONG nLen = 0; - std::wstring sMediaDirectory, sInternalMediaDirectory, sThemesDirectory; - BYTE* pRender = pFTPr->GetRender(nLen, sMediaDirectory, sInternalMediaDirectory, sThemesDirectory); - IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); - pCorrector->SetMediaDirectory(sMediaDirectory); - pCorrector->SetInternalMediaDirectory(sInternalMediaDirectory); - pCorrector->SetThemesDirectory(sThemesDirectory); - NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLen, pCorrector); - RELEASEOBJECT(pCorrector); - } - std::vector arrRC = pPr->GetRC(); double dFontSize = 10.0; if (!arrRC.empty()) @@ -2075,9 +2062,17 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } if (m_bNeedUpdateTextFont) UpdateFont(); - pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); // Можно указать полный шрифт? - - DrawFreeTextAnnot(pAppFonts, pFreeTextAnnot, pPr->GetRC(), oInfo.GetC()); + pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); + if (nFlags & (1 << 22)) + { + LONG nLen = 0; + BYTE* pRender = pFTPr->GetRender(nLen); + PdfWriter::CAnnotRenderer* pAnnotRenderer = new PdfWriter::CAnnotRenderer(pAppFonts); + IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLen, pCorrector); + RELEASEOBJECT(pCorrector); + RELEASEOBJECT(pAnnotRenderer); + } } else if (oInfo.IsCaret()) { @@ -3897,26 +3892,35 @@ void CPdfWriter::DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWri { pFreeTextAnnot->StartAP(arrC); - for (int i = 0; i < arrRC.size(); ++i) + struct CGlypgs { - // TODO следующая итерация может продолжаться на той-же строке - // найти оставшееся пространство и записаться в него сколько получиться - // если не всё, то остаток писать на следующую строку + unsigned int unLen; + unsigned int* pUnicodes; + unsigned short* pCodes; + PdfWriter::CFontCidTrueType** ppFonts; + double dFontSize; + BYTE nAlign; + unsigned int unStart; + PdfWriter::CFontTrueType* pFontTT; + double dR; + double dG; + double dB; + }; - // TODO высота строки должна вычисляться по самому высокому шрифту и глифу - // Возможно, стоит найти как это реализовано на отрисовке docx на js + std::vector arrGlyphs; - bool isBold = (arrRC[i]->nFontFlag >> 0) & 1; - bool isItalic = (arrRC[i]->nFontFlag >> 1) & 1; - double dFontSize = arrRC[i]->dFontSise; - double dWidth = pFreeTextAnnot->GetRect().fRight - pFreeTextAnnot->GetRect().fLeft - pFreeTextAnnot->GetRD().fRight - pFreeTextAnnot->GetRD().fLeft; - double dHeight = pFreeTextAnnot->GetRect().fTop - pFreeTextAnnot->GetRect().fBottom - pFreeTextAnnot->GetRD().fTop - pFreeTextAnnot->GetRD().fBottom; - BYTE nAlign = arrRC[i]->nAlignment; - double dShiftBorder = pFreeTextAnnot->GetBorderWidth(); + double dWidth = pFreeTextAnnot->GetRect().fRight - pFreeTextAnnot->GetRect().fLeft - pFreeTextAnnot->GetRD().fRight - pFreeTextAnnot->GetRD().fLeft; + double dHeight = pFreeTextAnnot->GetRect().fTop - pFreeTextAnnot->GetRect().fBottom - pFreeTextAnnot->GetRD().fTop - pFreeTextAnnot->GetRD().fBottom; + double dShiftBorder = pFreeTextAnnot->GetBorderWidth(); + + unsigned int unAllLen = 0; + for (int i = 0; i < arrRC.size(); ++i) + { + bool isBold = (arrRC[i]->nFontFlag >> 0) & 1; + bool isItalic = (arrRC[i]->nFontFlag >> 1) & 1; PdfWriter::CFontCidTrueType* pFont = GetFont(arrRC[i]->sActualFont.empty() ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont, isBold, isItalic); if (!pFont) continue; - PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); unsigned int unLen = 0; unsigned int* pUnicodes = NULL; @@ -3931,59 +3935,106 @@ void CPdfWriter::DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWri continue; } - unsigned short* pCodes2 = new unsigned short[unLen]; - unsigned int* pWidths = new unsigned int[unLen]; + arrGlyphs.push_back({unLen, pUnicodes, pCodes, ppFonts, arrRC[i]->dFontSise, arrRC[i]->nAlignment, unAllLen, m_pDocument->CreateTrueTypeFont(pFont), + arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2]}); + unAllLen += unLen; + } - unsigned short ushSpaceCode = 0xFFFF; - unsigned short ushNewLineCode = 0xFFFE; - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + unsigned short* pCodes2 = new unsigned short[unAllLen]; + unsigned int* pWidths = new unsigned int[unAllLen]; + double* pFontSizes = new double[unAllLen]; + + unsigned short ushSpaceCode = 0xFFFF; + unsigned short ushNewLineCode = 0xFFFE; + unsigned int unIndexI = 0; + + for (int i = 0; i < arrGlyphs.size(); ++i) + { + for (unsigned int unIndex = 0; unIndex < arrGlyphs[i].unLen; ++unIndex) { unsigned short ushCode = 0; - if (0x0020 == pUnicodes[unIndex]) + if (0x0020 == arrGlyphs[i].pUnicodes[unIndex]) ushCode = ushSpaceCode; - else if (0x000D == pUnicodes[unIndex] || 0x000A == pUnicodes[unIndex]) + else if (0x000D == arrGlyphs[i].pUnicodes[unIndex] || 0x000A == arrGlyphs[i].pUnicodes[unIndex]) ushCode = ushNewLineCode; - pCodes2[unIndex] = ushCode; - pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); + pCodes2[unIndexI] = ushCode; + pWidths[unIndexI] = arrGlyphs[i].ppFonts[unIndex]->GetWidth(arrGlyphs[i].pCodes[unIndex]); + pFontSizes[unIndexI] = arrGlyphs[i].dFontSize; + unIndexI++; } + } - m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); + m_oLinesManager.Init(pCodes2, pFontSizes, pWidths, unAllLen, ushSpaceCode, ushNewLineCode); + m_oLinesManager.CalculateLines(0, dWidth); - double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; - double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; + unsigned int unLinesCount = m_oLinesManager.GetLinesCount(), unIndex = 0; + double _dLineShiftX = 0, dLineShiftY = dHeight + pFreeTextAnnot->GetRect().fBottom + pFreeTextAnnot->GetRD().fBottom - dShiftBorder * 2 - m_oLinesManager.GetLineHeight(0); + for (int i = 0; i < arrGlyphs.size(); ++i) + { + BYTE nAlign = arrGlyphs[i].nAlign; + dLineShiftY -= (arrGlyphs[i].pFontTT->m_dAscent + std::abs(arrGlyphs[i].pFontTT->m_dDescent)) * arrGlyphs[i].dFontSize / arrGlyphs[i].pFontTT->m_dUnitsPerEm; + // double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; - m_oLinesManager.CalculateLines(dFontSize, dWidth); + double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - pFreeTextAnnot->GetRect(); + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pFreeTextAnnot->AddTextToAP(arrGlyphs[i].dFontSize, dLineShiftX, dLineShiftY, arrGlyphs[i].pCodes, arrGlyphs[i].unLen, arrGlyphs[i].dR, arrGlyphs[i].dG, arrGlyphs[i].dB, arrGlyphs[i].ppFonts, NULL); - unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); - double dLineShiftY = dHeight - dShiftBorder * 2 - dLineHeight + pFreeTextAnnot->GetRect().fBottom + pFreeTextAnnot->GetRD().fBottom; - for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + while (unIndex < unLinesCount && unLineStart < arrGlyphs[i].unStart + arrGlyphs[i].unLen) { - unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); - double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); - if (2 == nAlign) - dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - else if (1 == nAlign) - dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + unLineStart = m_oLinesManager.GetLineStartPos(++unIndex); + dLineShiftY -= m_oLinesManager.GetLineHeight(unIndex); + } + } - int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); - if (nInLineCount > 0) - pFreeTextAnnot->AddTextToAP(dFontSize, dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2], ppFonts + unLineStart, NULL); + /* + for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + { + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + BYTE nAlign = 0; + while (unPos < arrGlyphs.size() && unLineStart < arrGlyphs[unPos].unStart + arrGlyphs[unPos].unLen) + unPos++; - dLineShiftY -= dLineHeight; + //double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = m_oLinesManager.GetLineHeight(unIndex); //(pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; + double dLineShiftY = _dLineShiftY - dLineHeight; - // TODO зачеркнутый, подчеркнутый текст, верхний и нижний регистр - } + double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - RELEASEARRAYOBJECTS(pCodes2); - RELEASEARRAYOBJECTS(pWidths); + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pFreeTextAnnot->AddTextToAP(dFontSize, dLineShiftX, dLineShiftY, pCodes2 + unLineStart, nInLineCount, arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2], ppFonts + unLineStart, NULL); - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); + dLineShiftY -= dLineHeight; + + // TODO зачеркнутый, подчеркнутый текст, верхний и нижний регистр + } + */ + + m_oLinesManager.Clear(); + + RELEASEARRAYOBJECTS(pCodes2); + RELEASEARRAYOBJECTS(pWidths); + RELEASEARRAYOBJECTS(pFontSizes); + + for (int i = 0; i < arrGlyphs.size(); ++i) + { + RELEASEARRAYOBJECTS(arrGlyphs[i].pUnicodes); + RELEASEARRAYOBJECTS(arrGlyphs[i].pCodes); + RELEASEARRAYOBJECTS(arrGlyphs[i].ppFonts); } pFreeTextAnnot->EndAP(); diff --git a/PdfFile/SrcWriter/AnnotRenderer.cpp b/PdfFile/SrcWriter/AnnotRenderer.cpp new file mode 100644 index 00000000000..8276c4b7995 --- /dev/null +++ b/PdfFile/SrcWriter/AnnotRenderer.cpp @@ -0,0 +1,680 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "AnnotRenderer.h" + +#include "../../DesktopEditor/graphics/GraphicsPath.h" + +#define MM_2_PT(X) ((X) * 72.0 / 25.4) +#define PT_2_MM(X) ((X) * 25.4 / 72.0) + +#define LONG_2_BOOL(X) ((X) ? true : false) + +namespace PdfWriter +{ +CAnnotRenderer::CAnnotRenderer(NSFonts::IApplicationFonts* pAppFonts) +{ + m_pAppFonts = pAppFonts; + m_bNeedUpdateTextFont = true; +} +CAnnotRenderer::~CAnnotRenderer() +{ + +} + +// тип рендерера----------------------------------------------------------------------------- +HRESULT CAnnotRenderer::get_Type(LONG* lType) +{ + return S_OK; +} +//-------- Функции для работы со страницей -------------------------------------------------- +HRESULT CAnnotRenderer::NewPage() +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_Height(double* dHeight) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_Height(const double& dHeight) +{ + m_dPageHeight = dHeight; + return S_OK; +} +HRESULT CAnnotRenderer::get_Width(double* dWidth) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_Width(const double& dWidth) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_DpiX(double* dDpiX) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_DpiY(double* dDpiY) +{ + return S_OK; +} + +// pen -------------------------------------------------------------------------------------- +HRESULT CAnnotRenderer::get_PenColor(LONG* lColor) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenColor(const LONG& lColor) +{ + m_oPen.SetColor(lColor); + return S_OK; +} +HRESULT CAnnotRenderer::get_PenAlpha(LONG* lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenAlpha(const LONG& lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenSize(double* dSize) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenSize(const double& dSize) +{ + m_oPen.SetSize(dSize); + return S_OK; +} +HRESULT CAnnotRenderer::get_PenDashStyle(BYTE* nDashStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenDashStyle(const BYTE& nDashStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenLineStartCap(BYTE* nCapStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenLineStartCap(const BYTE& nCapStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenLineEndCap(BYTE* nCapStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenLineEndCap(const BYTE& nCapStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenLineJoin(BYTE* nJoinStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenLineJoin(const BYTE& nJoinStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenDashOffset(double* dOffset) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenDashOffset(const double& dOffset) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenAlign(LONG* lAlign) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenAlign(const LONG& lAlign) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_PenMiterLimit(double* dMiter) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_PenMiterLimit(const double& dMiter) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PenDashPattern(double* pPattern, LONG lCount) +{ + return S_OK; +} + +// brush ------------------------------------------------------------------------------------ +HRESULT CAnnotRenderer::get_BrushType(LONG* lType) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushType(const LONG& lType) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushColor1(LONG* lColor) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushColor1(const LONG& lColor) +{ + if (lColor != m_oBrush.GetColor1()) + m_oBrush.SetColor1(lColor); + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushAlpha1(LONG* lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushAlpha1(const LONG& lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushColor2(LONG* lColor) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushColor2(const LONG& lColor) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushAlpha2(LONG* lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushAlpha2(const LONG& lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushTexturePath(std::wstring* wsPath) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushTexturePath(const std::wstring& wsPath) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushTextureMode(LONG* lMode) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushTextureMode(const LONG& lMode) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushTextureAlpha(LONG* lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushTextureAlpha(const LONG& lAlpha) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_BrushLinearAngle(double* dAngle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushLinearAngle(const double& dAngle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) +{ + return S_OK; +} +HRESULT CAnnotRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) +{ + return S_OK; +} + +// font ------------------------------------------------------------------------------------- +HRESULT CAnnotRenderer::get_FontName(std::wstring* wsName) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontName(const std::wstring& wsName) +{ + if (wsName != m_oFont.GetName()) + { + m_oFont.SetName(wsName); + m_bNeedUpdateTextFont = true; + } + return S_OK; +} +HRESULT CAnnotRenderer::get_FontPath(std::wstring* wsPath) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontPath(const std::wstring& wsPath) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_FontSize(double* dSize) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontSize(const double& dSize) +{ + if (fabs(dSize - m_oFont.GetSize()) > 0.001) + m_oFont.SetSize(dSize); + return S_OK; +} +HRESULT CAnnotRenderer::get_FontStyle(LONG* lStyle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontStyle(const LONG& lStyle) +{ + if (lStyle != m_oFont.GetStyle()) + { + m_oFont.SetStyle(lStyle); + m_bNeedUpdateTextFont = true; + } + return S_OK; +} +HRESULT CAnnotRenderer::get_FontStringGID(INT* bGid) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontStringGID(const INT& bGid) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_FontCharSpace(double* dSpace) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontCharSpace(const double& dSpace) +{ + return S_OK; +} +HRESULT CAnnotRenderer::get_FontFaceIndex(int* lFaceIndex) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_FontFaceIndex(const int& lFaceIndex) +{ + return S_OK; +} + +//-------- Функции для вывода текста -------------------------------------------------------- +HRESULT CAnnotRenderer::CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandDrawTextCHAR2 (unsigned int* pUnicodes, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) +{ + unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); + if (!pCodes) + return DrawTextToRenderer(&unGid, 1, dX, dY) ? S_OK : S_FALSE; + return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; +} + +//-------- Маркеры для команд --------------------------------------------------------------- +HRESULT CAnnotRenderer::BeginCommand(const DWORD& lType) +{ + return S_OK; +} +HRESULT CAnnotRenderer::EndCommand(const DWORD& dwType) +{ + /* + if (c_nClipType == dwType) + { + m_oCommandManager.Flush(); + m_pPage->GrSave(); + m_lClipDepth++; + UpdateTransform(); + + m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_lClipMode); + } + else if (c_nResetClipType == dwType) + { + m_oCommandManager.Flush(); + while (m_lClipDepth) + { + m_pPage->GrRestore(); + m_lClipDepth--; + } + } + */ + return S_OK; +} + +//-------- Функции для работы с Graphics Path ----------------------------------------------- +HRESULT CAnnotRenderer::PathCommandMoveTo(const double& dX, const double& dY) +{ + m_oPath.MoveTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandLineTo(const double& dX, const double& dY) +{ + m_oPath.LineTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandLinesTo(double* pPoints, const int& nCount) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) +{ + m_oPath.CurveTo(MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dX2), MM_2_PT(m_dPageHeight - dY2), MM_2_PT(dXe), MM_2_PT(m_dPageHeight - dYe)); + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandClose() +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandEnd() +{ + m_oPath.Clear(); + return S_OK; +} +HRESULT CAnnotRenderer::DrawPath(const LONG& lType) +{ + /* + m_oCommandManager.Flush(); + + bool bStroke = LONG_2_BOOL(lType & c_nStroke); + bool bFill = LONG_2_BOOL(lType & c_nWindingFillMode); + bool bEoFill = LONG_2_BOOL(lType & c_nEvenOddFillMode); + + m_pPage->GrSave(); + UpdateTransform(); + + if (bStroke) + UpdatePen(); + + std::wstring sTextureOldPath = L""; + std::wstring sTextureTmpPath = L""; + + if (bFill || bEoFill) + { + if (c_BrushTypeTexture == m_oBrush.GetType()) + { + sTextureOldPath = m_oBrush.GetTexturePath(); + sTextureTmpPath = GetDownloadFile(sTextureOldPath, wsTempDirectory); + + if (!sTextureTmpPath.empty()) + m_oBrush.SetTexturePath(sTextureTmpPath); + } + + UpdateBrush(pAppFonts, wsTempDirectory); + } + + if (!m_pShading) + { + m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill); + } + else + { + if (bFill || bEoFill) + { + m_pPage->GrSave(); + m_oPath.Clip(m_pPage, bEoFill); + + if (NULL != m_pShadingExtGrState) + m_pPage->SetExtGrState(m_pShadingExtGrState); + + m_pPage->DrawShading(m_pShading); + m_pPage->GrRestore(); + } + + if (bStroke) + m_oPath.Draw(m_pPage, bStroke, false, false); + } + + m_pPage->GrRestore(); + + if (!sTextureTmpPath.empty()) + { + m_oBrush.SetTexturePath(sTextureOldPath); + + if (NSFile::CFileBinary::Exists(sTextureTmpPath)) + NSFile::CFileBinary::Remove(sTextureTmpPath); + } + + */ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandStart() +{ + m_oPath.Clear(); + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandGetCurrentPoint(double* dX, double* dY) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} + +//-------- Функции для вывода изображений --------------------------------------------------- +HRESULT CAnnotRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH) +{ + return S_OK; +} +HRESULT CAnnotRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) +{ + return S_OK; +} + +// transform -------------------------------------------------------------------------------- +HRESULT CAnnotRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) +{ + m_oCommandManager.Flush(); + m_oTransform.Set(dM11, dM12, dM21, dM22, dX, dY); + return S_OK; +} +HRESULT CAnnotRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) +{ + return S_OK; +} +HRESULT CAnnotRenderer::ResetTransform() +{ + return S_OK; +} + +// clip ------------------------------------------------------------------------------------ +HRESULT CAnnotRenderer::get_ClipMode(LONG* lMode) +{ + return S_OK; +} +HRESULT CAnnotRenderer::put_ClipMode(const LONG& lMode) +{ + return S_OK; +} + +// additiaonal params ---------------------------------------------------------------------- +HRESULT CAnnotRenderer::CommandLong(const LONG& lType, const LONG& lCommand) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandDouble(const LONG& lType, const double& dCommand) +{ + return S_OK; +} +HRESULT CAnnotRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) +{ + return S_OK; +} + +// внутренние функции ---------------------------------------------------------------------- +bool CAnnotRenderer::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) +{ + if (!pCodes || !unLen) + return false; + + CTransform& t = m_oTransform; + m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); + + CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); + pText->SetFont(m_pFont); + pText->SetSize(m_oFont.GetSize()); + pText->SetColor(m_oBrush.GetColor1()); + pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); + pText->SetCharSpace(MM_2_PT(m_oFont.GetCharSpace())); + pText->SetNeedDoBold(m_oFont.IsNeedDoBold()); + pText->SetNeedDoItalic(m_oFont.IsNeedDoItalic()); + + return true; +} +bool CAnnotRenderer::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) +{ + Aggplus::CGraphicsPathSimpleConverter simplifier; + simplifier.SetRenderer(this); + m_pFontManager->LoadFontByName(m_oFont.GetName(), m_oFont.GetSize(), (int)m_oFont.GetStyle(), 72.0, 72.0); + PathCommandEnd(); + if (simplifier.PathCommandText2(L"", (const int*)unGid, unLen, m_pFontManager, dX, dY, 0, 0)) + { + DrawPath(c_nWindingFillMode); + PathCommandEnd(); + return true; + } + return false; +} +bool CAnnotRenderer::UpdateFont() +{ + /* + m_bNeedUpdateTextFont = false; + std::wstring wsFontPath = m_oFont.GetPath(); + LONG lFaceIndex = m_oFont.GetFaceIndex(); + if (L"" == wsFontPath) + { + if (!GetFontPath(m_oFont.GetName(), m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + { + m_pFont = NULL; + return false; + } + } + + m_oFont.SetNeedDoBold(false); + m_oFont.SetNeedDoItalic(false); + + m_pFont = NULL; + if (L"" != wsFontPath) + { + m_pFont = GetFont(wsFontPath, lFaceIndex); + if (m_pFont) + { + if (m_oFont.IsItalic() && !m_pFont->IsItalic()) + m_oFont.SetNeedDoItalic(true); + + if (m_oFont.IsBold() && !m_pFont->IsBold()) + m_oFont.SetNeedDoBold(true); + } + else + return false; + } + */ + return true; +} +void UpdateTransform() +{ + +} +unsigned char* CAnnotRenderer::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) +{ + if (m_bNeedUpdateTextFont) + { + if (!UpdateFont()) + return NULL; + } + + if (!m_pFont) + return NULL; + + unsigned char* pCodes = new unsigned char[2]; + if (!pCodes) + return NULL; + + unsigned short ushCode = m_pFont->EncodeGID(unGID, pUnicodes, unUnicodesCount); + pCodes[0] = (ushCode >> 8) & 0xFF; + pCodes[1] = ushCode & 0xFF; + return pCodes; +} +} diff --git a/PdfFile/SrcWriter/AnnotRenderer.h b/PdfFile/SrcWriter/AnnotRenderer.h new file mode 100644 index 00000000000..194111923b8 --- /dev/null +++ b/PdfFile/SrcWriter/AnnotRenderer.h @@ -0,0 +1,197 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_ANNOT_RENDERER_H +#define _PDF_WRITER_SRC_ANNOT_RENDERER_H + +#include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" + +#include "States.h" +#include "FontCidTT.h" + +namespace PdfWriter +{ +class CAnnotRenderer : public IRenderer +{ +public: + CAnnotRenderer(NSFonts::IApplicationFonts* pAppFonts); + virtual ~CAnnotRenderer(); + +public: + // тип рендерера----------------------------------------------------------------------------- + virtual HRESULT get_Type(LONG* lType); + //-------- Функции для работы со страницей -------------------------------------------------- + virtual HRESULT NewPage(); + virtual HRESULT get_Height(double* dHeight); + virtual HRESULT put_Height(const double& dHeight); + virtual HRESULT get_Width(double* dWidth); + virtual HRESULT put_Width(const double& dWidth); + virtual HRESULT get_DpiX(double* dDpiX); + virtual HRESULT get_DpiY(double* dDpiY); + + // pen -------------------------------------------------------------------------------------- + virtual HRESULT get_PenColor(LONG* lColor); + virtual HRESULT put_PenColor(const LONG& lColor); + virtual HRESULT get_PenAlpha(LONG* lAlpha); + virtual HRESULT put_PenAlpha(const LONG& lAlpha); + virtual HRESULT get_PenSize(double* dSize); + virtual HRESULT put_PenSize(const double& dSize); + virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); + virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); + virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); + virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); + virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); + virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); + virtual HRESULT get_PenDashOffset(double* dOffset); + virtual HRESULT put_PenDashOffset(const double& dOffset); + virtual HRESULT get_PenAlign(LONG* lAlign); + virtual HRESULT put_PenAlign(const LONG& lAlign); + virtual HRESULT get_PenMiterLimit(double* dMiter); + virtual HRESULT put_PenMiterLimit(const double& dMiter); + virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); + + // brush ------------------------------------------------------------------------------------ + virtual HRESULT get_BrushType(LONG* lType); + virtual HRESULT put_BrushType(const LONG& lType); + virtual HRESULT get_BrushColor1(LONG* lColor); + virtual HRESULT put_BrushColor1(const LONG& lColor); + virtual HRESULT get_BrushAlpha1(LONG* lAlpha); + virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); + virtual HRESULT get_BrushColor2(LONG* lColor); + virtual HRESULT put_BrushColor2(const LONG& lColor); + virtual HRESULT get_BrushAlpha2(LONG* lAlpha); + virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); + virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); + virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); + virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage); + virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage); + virtual HRESULT get_BrushTextureMode(LONG* lMode); + virtual HRESULT put_BrushTextureMode(const LONG& lMode); + virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); + virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); + virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix); + virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix); + virtual HRESULT get_BrushLinearAngle(double* dAngle); + virtual HRESULT put_BrushLinearAngle(const double& dAngle); + virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); + virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); + + // font ------------------------------------------------------------------------------------- + virtual HRESULT get_FontName(std::wstring* wsName); + virtual HRESULT put_FontName(const std::wstring& wsName); + virtual HRESULT get_FontPath(std::wstring* wsPath); + virtual HRESULT put_FontPath(const std::wstring& wsPath); + virtual HRESULT get_FontSize(double* dSize); + virtual HRESULT put_FontSize(const double& dSize); + virtual HRESULT get_FontStyle(LONG* lStyle); + virtual HRESULT put_FontStyle(const LONG& lStyle); + virtual HRESULT get_FontStringGID(INT* bGid); + virtual HRESULT put_FontStringGID(const INT& bGid); + virtual HRESULT get_FontCharSpace(double* dSpace); + virtual HRESULT put_FontCharSpace(const double& dSpace); + virtual HRESULT get_FontFaceIndex(int* lFaceIndex); + virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); + + //-------- Функции для вывода текста -------------------------------------------------------- + virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT CommandDrawTextCHAR2 (unsigned int* unUnicode, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH); + + //-------- Маркеры для команд --------------------------------------------------------------- + virtual HRESULT BeginCommand(const DWORD& lType); + virtual HRESULT EndCommand(const DWORD& lType); + + //-------- Функции для работы с Graphics Path ----------------------------------------------- + virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); + virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); + virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); + virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); + virtual HRESULT PathCommandClose(); + virtual HRESULT PathCommandEnd(); + virtual HRESULT DrawPath(const LONG& lType); + virtual HRESULT PathCommandStart(); + virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); + virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); + + //-------- Функции для вывода изображений --------------------------------------------------- + virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); + virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); + + // transform -------------------------------------------------------------------------------- + virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); + virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); + virtual HRESULT ResetTransform(); + + // clip ------------------------------------------------------------------------------------ + virtual HRESULT get_ClipMode(LONG* lMode); + virtual HRESULT put_ClipMode(const LONG& lMode); + + // additiaonal params ---------------------------------------------------------------------- + virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); + virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); + virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); + +private: + bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); + bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); + bool UpdateFont(); + void UpdateTransform(); + unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); + +private: + NSFonts::IApplicationFonts* m_pAppFonts; + NSFonts::IFontManager* m_pFontManager; + + CFontCidTrueType* m_pFont; + + CCommandManager m_oCommandManager; + CPenState m_oPen; + CBrushState m_oBrush; + CFontState m_oFont; + CPath m_oPath; + CTransform m_oTransform; + bool m_bNeedUpdateTextFont; + double m_dPageHeight; +}; +} + +#endif // _PDF_WRITER_SRC_ANNOT_RENDERER_H diff --git a/PdfFile/SrcWriter/States.h b/PdfFile/SrcWriter/States.h index d9b84243826..e197eabaf68 100644 --- a/PdfFile/SrcWriter/States.h +++ b/PdfFile/SrcWriter/States.h @@ -1500,6 +1500,7 @@ class CMultiLineTextManager CMultiLineTextManager() { m_pCodes = NULL; + m_pFontSizes = NULL; m_pWidths = NULL; m_unLen = 0; m_ushSpaceCode = 0; @@ -1518,9 +1519,19 @@ class CMultiLineTextManager m_nAscent = nAscent; m_nDescent = unLineHeight - nAscent; } + void Init(unsigned short* pCodes, double* pFontSizes, unsigned int* pWidths, const unsigned int& unLen, const unsigned short& ushSpaceCode, const unsigned short& ushNewLineCode) + { + m_pCodes = pCodes; + m_pFontSizes = pFontSizes; + m_pWidths = pWidths; + m_unLen = unLen; + m_ushSpaceCode = ushSpaceCode; + m_ushNewLineCode = ushNewLineCode; + } void Clear() { m_pCodes = NULL; + m_pFontSizes = NULL; m_pWidths = NULL; m_unLen = 0; m_ushSpaceCode = 0; @@ -1543,7 +1554,7 @@ class CMultiLineTextManager { if (IsSpace(unPos)) { - dX += dWordWidth + m_pWidths[unPos] * dKoef; + dX += dWordWidth + m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); bWord = false; dWordWidth = 0; bLineStart = false; @@ -1560,7 +1571,7 @@ class CMultiLineTextManager } else { - double dLetterWidth = m_pWidths[unPos] * dKoef; + double dLetterWidth = m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); if (dX + dWordWidth + dLetterWidth > dW) { if (bLineStart) @@ -1600,13 +1611,13 @@ class CMultiLineTextManager if (bWord) { - dWordWidth += m_pWidths[unPos] * dKoef; + dWordWidth += m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); } else { unWordStartPos = unPos; bWord = true; - dWordWidth = m_pWidths[unPos] * dKoef; + dWordWidth = m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); } bFirstItemOnLine = false; @@ -1615,7 +1626,7 @@ class CMultiLineTextManager unPos++; } } - double ProcessAutoFit(const double& dW, const double& dH) + double ProcessAutoFit(const double& dW, const double& dH) { double dGoodFontSize = 0; @@ -1676,7 +1687,11 @@ class CMultiLineTextManager return unLineEnd; } - double GetLineWidth(const int& nLineIndex, const double& dFontSize = 10.0) + double GetLineHeight(const double& dFontSize = 10.0) + { + return 0; + } + double GetLineWidth(const int& nLineIndex, const double& dFontSize = 10.0) { if (nLineIndex < 0 || nLineIndex > m_vBreaks.size()) return 0; @@ -1705,7 +1720,7 @@ class CMultiLineTextManager for (unsigned int unPos = unStart; unPos < unEnd; ++unPos) { - dWidth += m_pWidths[unPos] * dKoef; + dWidth += m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); } return dWidth; @@ -1728,6 +1743,7 @@ class CMultiLineTextManager private: unsigned short* m_pCodes; + double* m_pFontSizes; unsigned int* m_pWidths; unsigned int m_unLen; unsigned short m_ushSpaceCode; From d85b3dd7f046792ab0a11b3f31884017a11029ce Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Tue, 14 May 2024 21:43:21 +0300 Subject: [PATCH 646/794] Support images on recognize --- .../graphics/pro/js/drawingfile.json | 6 +++- .../pro/js/wasm/js/drawingfile_base.js | 24 ++++++++++++++ .../graphics/pro/js/wasm/src/drawingfile.cpp | 17 ++++++++++ .../graphics/pro/js/wasm/src/drawingfile.h | 7 ++++ DocxRenderer/src/logic/elements/Shape.cpp | 32 +++++++++++++++++++ .../src/logic/managers/ExternalImageStorage.h | 2 +- .../src/logic/managers/ImageManager.cpp | 23 +++++++++---- PdfFile/PdfFile.cpp | 1 + 8 files changed, 104 insertions(+), 8 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index f19239e88d7..1a5e6af8113 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -45,7 +45,11 @@ "_DestroyTextInfo", "_IsNeedCMap", "_SetCMapData", - "_ScanPage" + "_ScanPage", + "_GetImageBase64", + "_GetImageBase64Len", + "_GetImageBase64Ptr", + "_GetImageBase64Free" ], "include_path": [ "wasm/src/lib", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 88a03169d6a..37d8ed182a8 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -158,6 +158,8 @@ this.fontPageIndex = -1; this.fontPageUpdateType = UpdateFontsSource.Undefined; this.fontStreams = {}; + + this.scannedImages = {}; } CFile.prototype["loadFromData"] = function(arrayBuffer) @@ -1641,6 +1643,28 @@ return shapes; }; + CFile.prototype["getImageBase64"] = function(rId) + { + let strId = "" + rId; + if (this.scannedImages[strId]) + return this.scannedImages[strId]; + + let strPtr = Module["_GetImageBase64"](this.nativeFile, rId); + if (0 == strPtr) + { + this.scannedImages[strId] = "error"; + return this.scannedImages[strId]; + } + + let len = Module["_GetImageBase64Len"](strPtr); + let ptr = Module["_GetImageBase64Ptr"](strPtr); + + var buffer = new Uint8Array(Module["HEAP8"].buffer, ptr, len); + this.scannedImages[strId] = String.prototype.fromUtf8(buffer, 0, len); + Module["_GetImageBase64Free"](strPtr); + return this.scannedImages[strId]; + }; + CFile.prototype.memory = function() { return Module["HEAP8"]; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 2221c4c86e3..3801b96d6f6 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -267,6 +267,23 @@ WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex, int return pGraphics->GetPageShapes(nPageIndex, mode); } +WASM_EXPORT void* GetImageBase64(CGraphicsFileDrawing* pGraphics, int rId) +{ + return pGraphics->GetImageBase64(rId); +} +WASM_EXPORT int GetImageBase64Len(std::string* p) +{ + return (int)p->length(); +} +WASM_EXPORT char* GetImageBase64Ptr(std::string* p) +{ + return (char*)p->c_str(); +} +WASM_EXPORT void GetImageBase64Free(std::string* p) +{ + *p = ""; +} + #ifdef __cplusplus } #endif diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index 4a79910fb53..5fb3f8efc08 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -220,6 +220,13 @@ class CGraphicsFileDrawing oRes.ClearWithoutAttack(); return res; } + + std::string* GetImageBase64(int nRId) + { + if (NULL == pImageStorage) + return NULL; + return pImageStorage->GetBase64(nRId); + } }; #endif // _WASM_GRAPHICS_ diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 44137f4ebd4..77c6c8ff0d1 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -944,6 +944,38 @@ namespace NSDocxRenderer } void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const { + if (m_eType == eShapeType::stPicture) + { + // TODO: + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\" name=\"Picture "); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + oWriter.WriteString(L"m_nId); + oWriter.WriteString(L"\">"); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + + oWriter.WriteString(L""); + BuildForm(oWriter, true); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + oWriter.WriteString(L""); + return; + } + oWriter.WriteString(L""); oWriter.WriteString(L""); diff --git a/DocxRenderer/src/logic/managers/ExternalImageStorage.h b/DocxRenderer/src/logic/managers/ExternalImageStorage.h index 06926606fbf..1784da1a7b9 100644 --- a/DocxRenderer/src/logic/managers/ExternalImageStorage.h +++ b/DocxRenderer/src/logic/managers/ExternalImageStorage.h @@ -21,7 +21,7 @@ namespace NSDocxRenderer public: virtual std::shared_ptr GenerateImageID(Aggplus::CImage* pImage) = 0; - virtual std::map* GetImages() = 0; + virtual std::string* GetBase64(const int& nRId) = 0; }; DOCXRENDERER_DECL_EXPORT IImageStorage* CreateWasmImageStorage(); diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index f5c89bf1caf..ad08a20e491 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -1,5 +1,6 @@ #include "ImageManager.h" #include "../../../../DesktopEditor/common/Directory.h" +#include "../../resources/Constants.h" namespace NSDocxRenderer { @@ -10,7 +11,7 @@ namespace NSDocxRenderer { private: std::map> m_mapImageData; - std::map m_mapImages; + std::map m_mapImages; int m_lMaxSizeImage{1200}; int m_lNextIDImage{0}; @@ -87,21 +88,31 @@ namespace NSDocxRenderer oBgraFrame.put_Data(NULL); int nBase64DataSize = NSBase64::Base64EncodeGetRequiredLength(nEncodeBufferSize); - char* pBase64Data = new char[nBase64DataSize]; + int nHeaderSize = (pInfo->m_eType == CImageInfo::itPNG) ? 22 : 23; - NSBase64::Base64Encode(pEncodeBuffer, nEncodeBufferSize, (BYTE*)pBase64Data, &nBase64DataSize, NSBase64::B64_BASE64_FLAG_NOCRLF); + char* pBase64Data = new char[nBase64DataSize + nHeaderSize]; + if (pInfo->m_eType == CImageInfo::itPNG) + memcpy(pBase64Data, "data:image/png;base64,", nHeaderSize); + else + memcpy(pBase64Data, "data:image/jpeg;base64,", nHeaderSize); + + NSBase64::Base64Encode(pEncodeBuffer, nEncodeBufferSize, (BYTE*)pBase64Data + nHeaderSize, &nBase64DataSize, NSBase64::B64_BASE64_FLAG_NOCRLF); RELEASEARRAYOBJECTS(pEncodeBuffer); - m_mapImages.insert(std::pair(pInfo->m_strFileName, std::string(pBase64Data, nBase64DataSize))); + m_mapImages.insert(std::pair((int)pInfo->m_nId, std::string(pBase64Data, nHeaderSize + nBase64DataSize))); RELEASEARRAYOBJECTS(pBase64Data); m_mapImageData.insert(std::pair>(dwSum, pInfo)); return pInfo; } - virtual std::map* GetImages() + virtual std::string* GetBase64(const int& nRId) { - return &m_mapImages; + std::map::iterator iter = m_mapImages.find(nRId - c_iStartingIdForImages); + if (iter == m_mapImages.end()) + return NULL; + + return &iter->second; } }; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index c69218d3b14..a4bda134f0e 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -55,6 +55,7 @@ class CPdfEditor int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} bool IsEditPage() { return false; } + bool EditPage(int nPageIndex) { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} }; From 52555f4d9d56ce89cb24eb96c70620054b8de904 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 15 May 2024 09:24:08 +0300 Subject: [PATCH 647/794] fix bug #67963 --- .../OfficeArtBStoreContainerFileBlock.cpp | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp index bde4c2d8e55..2c56f582971 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp @@ -106,68 +106,68 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record) switch (rc_header.recType) { case OfficeArtRecord::BlipEMF: + { + pict_type = L".emf"; + if (rc_header.recInstance == 0x3D4) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".emf"; - if (rc_header.recInstance == 0x3D4) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipWMF: + { + pict_type = L".wmf"; + if (rc_header.recInstance == 0x216) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".wmf"; - if (rc_header.recInstance == 0x216) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipPICT: + { + pict_type = L".pcz"; + if (rc_header.recInstance == 0x542) + rgbUid1 = ReadMD4Digest(record); + else { - pict_type = L".pcz"; - if (rc_header.recInstance == 0x542) - rgbUid1 = ReadMD4Digest(record); - else - { - rgbUid1 = ReadMD4Digest(record); - rgbUid2 = ReadMD4Digest(record); - } + rgbUid1 = ReadMD4Digest(record); + rgbUid2 = ReadMD4Digest(record); + } - OfficeArtMetafileHeader metafileHeader; - record >> metafileHeader; + OfficeArtMetafileHeader metafileHeader; + record >> metafileHeader; - if (metafileHeader.compression == 0) - { - isCompressed = true; - readCompressedData(record, metafileHeader); - } + if (metafileHeader.compression == 0) + { + isCompressed = true; + readCompressedData(record, metafileHeader); } - break; + } + break; case OfficeArtRecord::BlipJPEG: pict_type = L".jpeg"; if ((rc_header.recInstance == 0x46A) || (rc_header.recInstance == 0x6E2)) @@ -233,7 +233,7 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record) } break; default: - record.RollRdPtrBack(rc_header.size()); + record.skipNunBytes(rc_header.recLen); return; } From ad1bd06bb373f47a32cbae7445a990f9e47dbb3e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 15 May 2024 09:55:58 +0300 Subject: [PATCH 648/794] fix bug #67968 --- .../PptFile/PPTXWriter/TableWriter.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp b/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp index 393d0504862..47245d0fe19 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp @@ -243,7 +243,15 @@ bool ProtoTable::fillCells(std::vector &arrCells) if (top == m_arrTop[posRow]) break; for (; posCol < countCol; posCol++) if (left == m_arrLeft[posCol]) break; - TCell* pParent = &m_table[posRow][posCol]; + TCell* pParent = NULL; + + if (posRow < m_table.size()) + { + if (posCol < m_table[posRow].size()) + { + pParent = &m_table[posRow][posCol]; + } + } UINT posRightCol = 0, posBottomRow = 0; for (; posBottomRow < countRow; posBottomRow++) @@ -263,9 +271,11 @@ bool ProtoTable::fillCells(std::vector &arrCells) if (posRow == cRow) tCell.setRowSpan(posBottomRow - cRow); } - pParent->setPParent(nullptr); - pParent->setPShape(ptrCell); - + if (pParent) + { + pParent->setPParent(nullptr); + pParent->setPShape(ptrCell); + } // pParent->setGridSpan(posRightCol - posCol); // pParent->setRowSpan(posBottomRow - posRow); } @@ -562,7 +572,7 @@ bool TCell::isRealCell() const return true; } -void TCell::FillTxBody(PPTX::Logic::TxBody &oTxBody, CTextCFRun* pLastCF) +void TCell::FillTxBody(PPTX::Logic::TxBody& oTxBody, CTextCFRun* pLastCF) { TxBodyConverter txBodyConverter(m_ptrSpElCell, m_pRels, pLastCF); txBodyConverter.FillTxBody(oTxBody); @@ -570,6 +580,8 @@ void TCell::FillTxBody(PPTX::Logic::TxBody &oTxBody, CTextCFRun* pLastCF) void TCell::FillTcPr(PPTX::Logic::TableCellProperties &oTcPr) { + if (!m_ptrSpElCell) return; + auto pShapeEl = static_cast(m_ptrSpElCell.get()); auto pShape = pShapeEl->m_pShape; //anchor From 8857d3daca061912846a577482d1a4f598d279a1 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 15 May 2024 11:00:27 +0300 Subject: [PATCH 649/794] fix bug #67972 --- .../XlsFile/Format/Logic/Biff_records/Label.cpp | 2 +- .../XlsFile/Format/Logic/Biff_records/Number.cpp | 15 +++++++++++++-- .../XlsFile/Format/Logic/Biff_structures/Cell.cpp | 3 ++- .../XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp index 937691a8da9..96200f2720d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp @@ -57,7 +57,7 @@ void Label::readFields(CFRecord& record) record >> cell; - if (global_info_->Version == 0x0200) + if (global_info_->Version == 0x0200 || global_info_->Version == 0x0400) { ShortXLAnsiString name; record >> name; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp index 18c975d9a26..3b7549da4d9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp @@ -94,7 +94,7 @@ int Number::serialize(std::wostream & stream) return 0; } //--------------------------------------------------------------------------------- -Integer_BIFF2::Integer_BIFF2() +Integer_BIFF2::Integer_BIFF2() : num(0) {} Integer_BIFF2::~Integer_BIFF2() {} @@ -106,7 +106,18 @@ void Integer_BIFF2::readFields(CFRecord& record) { global_info_ = record.getGlobalWorkbookInfo(); - record >> cell >> num; + record >> cell; + + if (record.getRdPtr() + 2 < record.getDataSize()) + { + record >> num; + } + else + { + _INT16 num_2byte = 0; + record >> num_2byte; + num = num_2byte; + } } const CellRef Integer_BIFF2::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp index b4cff4fc916..f8b19e0b4bd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp @@ -59,7 +59,8 @@ void Cell::load(CFRecord& record) { record >> rw >> col; - if (record.getGlobalWorkbookInfo()->Version == 0x0200) + if (record.getGlobalWorkbookInfo()->Version == 0x0200 || + record.getGlobalWorkbookInfo()->Version == 0x0400) { unsigned char flags1, flags2, flags3; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp index da94f8bf283..744f0a0a6e0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp @@ -68,6 +68,11 @@ const bool COLUMNS::loadContent(BinProcessor& proc) } int count = (global_info_->Version == 0x0200) ? proc.repeated(0, 255) : proc.repeated(0, 255); + if (count < 1) + {//version 0x0400 ???? ColWidth + count = (global_info_->Version == 0x0200) ? proc.repeated(0, 255) : proc.repeated(0, 255); + } + int last_add = 0; for (std::list::iterator it = elements_.begin(); it != elements_.end(); ++it) From c14856ac6fafcb277ec2f0f7687761d4c66b5207 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 15 May 2024 11:15:31 +0300 Subject: [PATCH 650/794] fix bug #68011 --- MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp index 067edc02759..f5623ebbef5 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfo.cpp @@ -144,6 +144,8 @@ bool CPPTDocumentInfo::LoadDocument() { m_arUsers[0]->ReadExtenalObjects(); // todooo ???? прочитать по всем (см 66864) m_arUsers[0]->FromDocument(); + + m_bMacroEnabled = m_arUsers[0]->m_bMacroEnabled; } catch(int) //error code { From 1e7611f3f9f6eb822c3e0f8025ef32c304a74e7e Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 15 May 2024 13:20:20 +0300 Subject: [PATCH 651/794] Add method for duplicate image links on recognize --- .../graphics/pro/js/wasm/js/drawingfile_base.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 37d8ed182a8..0590fe82d21 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1665,6 +1665,15 @@ return this.scannedImages[strId]; }; + CFile.prototype["changeImageUrl"] = function(baseUrl, resultUrl) + { + for (let i in this.scannedImages) + { + if (this.scannedImages[i] == baseUrl) + this.scannedImages[i] = resultUrl; + } + }; + CFile.prototype.memory = function() { return Module["HEAP8"]; From 5ea601cde97ab5d399a4587d05da8893d11f5314 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" Date: Wed, 15 May 2024 16:25:51 +0300 Subject: [PATCH 652/794] fix bug #67973 --- MsBinaryFile/PptFile/Main/PPTFormatLib.cpp | 2 +- .../XlsFile/Format/Logic/EncryptionStream.cpp | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp index 4a20e696f36..aebb08fd787 100644 --- a/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp +++ b/MsBinaryFile/PptFile/Main/PPTFormatLib.cpp @@ -109,7 +109,7 @@ bool COfficePPTFile::CloseFile() PPT::CPPTFileReader* r = (PPT::CPPTFileReader*)m_pReader; RELEASEOBJECT(r); m_pReader = NULL; - return S_OK; + return true; } _UINT32 COfficePPTFile::LoadFromFile(std::wstring sSrcFileName, std::wstring sDstPath, std::wstring password, bool &bMacros) diff --git a/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp b/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp index 396bd55deef..9290f225a52 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/EncryptionStream.cpp @@ -78,15 +78,28 @@ namespace XLS BYTE fStream = ((BYTE*)(buf2 + pos))[0]; pos += 1; pos += 4; - std::wstring name = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(buf2 + pos), NameSize); pos += NameSize * 2; + std::wstring name; + + if (pos + NameSize < StreamDescriptorArraySize) + { + name = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)(buf2 + pos), NameSize); + } + pos += NameSize * 2; + + if (pos + 1 < StreamDescriptorArraySize && buf2[pos] == 0 && buf2[pos + 1] == 0) + pos += 2; // padding??? std::pair, size_t> data; - data.first = boost::shared_array(new BYTE[StreamSize]); - data.second = StreamSize; - memcpy(data.first.get(), buf1 + StreamOffset - 8, StreamSize); // 8 = start stream offset + if (StreamSize + StreamOffset < StreamDescriptorArrayOffset) + { + data.first = boost::shared_array(new BYTE[StreamSize]); + data.second = StreamSize; + memcpy(data.first.get(), buf1 + StreamOffset - 8, StreamSize); // 8 = start stream offset + } streams.insert(std::make_pair(name, data)); + } delete[]buf1; From b6b99ee9f0861a30e47919578ebf13b433973fb8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 15 May 2024 17:43:59 +0300 Subject: [PATCH 653/794] Redirect to annotation rendering --- PdfFile/PdfEditor.cpp | 9 +++++ PdfFile/PdfFile.cpp | 5 ++- PdfFile/PdfReader.cpp | 4 +++ PdfFile/PdfReader.h | 1 + PdfFile/PdfWriter.cpp | 13 ++++++-- PdfFile/SrcReader/PdfAnnot.cpp | 51 +++++++++++++++++++---------- PdfFile/SrcReader/PdfAnnot.h | 1 + PdfFile/SrcWriter/AnnotRenderer.cpp | 16 --------- PdfFile/SrcWriter/AnnotRenderer.h | 1 - PdfFile/SrcWriter/Annotation.cpp | 38 +++++++++++++++++++++ PdfFile/SrcWriter/Annotation.h | 1 + PdfFile/SrcWriter/Document.cpp | 4 +++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Field.cpp | 15 +++++---- PdfFile/SrcWriter/Field.h | 4 +-- PdfFile/SrcWriter/Objects.cpp | 8 +++-- PdfFile/SrcWriter/Objects.h | 3 +- PdfFile/SrcWriter/Pages.cpp | 34 +++++++++---------- PdfFile/SrcWriter/Pages.h | 5 +-- 19 files changed, 146 insertions(+), 68 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 5b0dc80aaea..7c76618b9ba 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -886,6 +886,15 @@ bool CPdfEditor::EditPage(int nPageIndex) oAnnot.free(); oSubtype.free(); continue; } + else if (oSubtype.isName("FreeText")) + { + //TODO добавление шрифтов FreeText в общий m_pAppAplication чтобы writer мог использовать шрифты из reader + oAnnot.free(); oSubtype.free(); + oTemp.arrayGetNF(nIndex, &oAnnot); + pReader->AnnotFonts(&oAnnot); + DictToCDictObject(&oAnnot, pArray, false, ""); + oAnnot.free(); + } oAnnot.free(); oSubtype.free(); oTemp.arrayGetNF(nIndex, &oAnnot); DictToCDictObject(&oAnnot, pArray, false, ""); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index fd18d2a69cb..3c88584a8bd 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -881,7 +881,10 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->put_FontName(wsName); + std::wstring wsFontName = wsName; + if (m_pInternal->pEditor && wsFontName.find(L"Embedded: ") == 0) + wsFontName.erase(0, 10); + return m_pInternal->pWriter->put_FontName(wsFontName); } HRESULT CPdfFile::get_FontPath(std::wstring* wsPath) { diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 054f7ceb894..75543218beb 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -948,6 +948,10 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } +void CPdfReader::AnnotFonts(Object* pRefAnnot) +{ + PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, pRefAnnot, m_pFontManager, m_pFontList); +} BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 62b035c32eb..d30f562b5ff 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -82,6 +82,7 @@ class CPdfReader BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); + void AnnotFonts(Object* pRefAnnot); private: PDFDoc* m_pPDFDocument; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 64b76b3ac76..edeb0a6de6c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2065,13 +2065,22 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); if (nFlags & (1 << 22)) { + PdfWriter::CPage* pCurPage = m_pPage; + PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + m_pPage = pFakePage; + m_pDocument->SetCurPage(pFakePage); + LONG nLen = 0; BYTE* pRender = pFTPr->GetRender(nLen); - PdfWriter::CAnnotRenderer* pAnnotRenderer = new PdfWriter::CAnnotRenderer(pAppFonts); IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLen, pCorrector); RELEASEOBJECT(pCorrector); - RELEASEOBJECT(pAnnotRenderer); + + pFreeTextAnnot->APFromFakePage(pFakePage); + + m_pPage = pCurPage; + m_pDocument->SetCurPage(pCurPage); + RELEASEOBJECT(pFakePage); } } else if (oInfo.IsCaret()) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 4a601af8400..85b8a41a3c1 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -45,6 +45,7 @@ #include "../../DesktopEditor/common/StringExt.h" #include "../../DesktopEditor/xml/include/xmlutils.h" #include "../../DesktopEditor/fontengine/ApplicationFonts.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" namespace PdfReader { @@ -2353,31 +2354,28 @@ bool FindFonts(Object* oStream, int nDepth, Object* oResFonts) oXObject.free(); return false; } -std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector& arrRC, int nTypeFonts) +std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts) { - std::map mRes; - if (arrRC.empty()) - return mRes; - Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); + std::vector arrFontFreeText; Object oAP, oN, oR, oFonts; if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream()) { oAP.free(); oN.free(); oR.free(); oFonts.free(); - return mRes; + return arrFontFreeText; } if (!FindFonts(&oN, 0, &oFonts)) { oAP.free(); oN.free(); oR.free(); oFonts.free(); - return mRes; + return arrFontFreeText; } CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); - std::vector arrFontFreeText; + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); for (int i = 0, nFonts = oFonts.dictGetLength(); i < nFonts; ++i) { @@ -2396,9 +2394,13 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object oFontRef.free(); continue; } + oFontRef.free(); + + if (isBaseFont(sFontPath)) + continue; - CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); - if (pFontStream && !isBaseFont(sFontPath)) + NSFonts::IFontStream* pFontStream = pMemoryStorage ? (NSFonts::IFontStream*)pMemoryStorage->Get(sFontPath) : NULL; + if (pFontStream) { bool bNew = true; std::vector* arrFontList = pAppFontList->GetFonts(); @@ -2406,8 +2408,8 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object { if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && - (*arrFontList)[nIndex]->m_bBold == bBold && - (*arrFontList)[nIndex]->m_bItalic == bItalic) + (*arrFontList)[nIndex]->m_bBold == (bBold ? 1 : 0) && + (*arrFontList)[nIndex]->m_bItalic == (bItalic ? 1 : 0)) { bNew = false; break; @@ -2417,9 +2419,28 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object pAppFontList->Add(sFontPath, pFontStream); arrFontFreeText.push_back(sFontPath); } - oFontRef.free(); + else + { + pFontStream = NSFonts::NSStream::Create(); + if (pFontStream->CreateFromFile(sFontPath)) + pAppFontList->Add(sFontPath, pFontStream); + } } + oAP.free(); oN.free(); oR.free(); oFonts.free(); + + oAnnot.free(); + return arrFontFreeText; +} +std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector& arrRC, int nTypeFonts) +{ + std::map mRes; + if (arrRC.empty()) + return mRes; + + std::vector arrFontFreeText = SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, nTypeFonts); + + CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); for (int i = 0; i < arrRC.size(); ++i) { if (arrRC[i]->bFind) @@ -2532,10 +2553,6 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object } } - - oAP.free(); oN.free(); oR.free(); oFonts.free(); - - oAnnot.free(); return mRes; } CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 277493c33c7..ac235a991e3 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -364,6 +364,7 @@ class CAnnotMarkup : public CAnnot }; namespace AnnotMarkup { +std::vector SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts = 3); std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, std::vector& arrRC, int nTypeFonts = 3); std::vector ReadRC(const std::string& sRC); } diff --git a/PdfFile/SrcWriter/AnnotRenderer.cpp b/PdfFile/SrcWriter/AnnotRenderer.cpp index 8276c4b7995..1226af856f4 100644 --- a/PdfFile/SrcWriter/AnnotRenderer.cpp +++ b/PdfFile/SrcWriter/AnnotRenderer.cpp @@ -546,7 +546,6 @@ HRESULT CAnnotRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const // transform -------------------------------------------------------------------------------- HRESULT CAnnotRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) { - m_oCommandManager.Flush(); m_oTransform.Set(dM11, dM12, dM21, dM22, dX, dY); return S_OK; } @@ -586,21 +585,6 @@ HRESULT CAnnotRenderer::CommandString(const LONG& lType, const std::wstring& sCo // внутренние функции ---------------------------------------------------------------------- bool CAnnotRenderer::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { - if (!pCodes || !unLen) - return false; - - CTransform& t = m_oTransform; - m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); - - CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - pText->SetFont(m_pFont); - pText->SetSize(m_oFont.GetSize()); - pText->SetColor(m_oBrush.GetColor1()); - pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); - pText->SetCharSpace(MM_2_PT(m_oFont.GetCharSpace())); - pText->SetNeedDoBold(m_oFont.IsNeedDoBold()); - pText->SetNeedDoItalic(m_oFont.IsNeedDoItalic()); - return true; } bool CAnnotRenderer::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) diff --git a/PdfFile/SrcWriter/AnnotRenderer.h b/PdfFile/SrcWriter/AnnotRenderer.h index 194111923b8..7e74e949cb0 100644 --- a/PdfFile/SrcWriter/AnnotRenderer.h +++ b/PdfFile/SrcWriter/AnnotRenderer.h @@ -183,7 +183,6 @@ class CAnnotRenderer : public IRenderer CFontCidTrueType* m_pFont; - CCommandManager m_oCommandManager; CPenState m_oPen; CBrushState m_oBrush; CFontState m_oFont; diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index a621ad3c929..592daceb9a9 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1263,6 +1263,44 @@ namespace PdfWriter { SetC(arrIC); } + void CFreeTextAnnotation::APFromFakePage(CPage* pFakePage) + { + // xref NULL - тогда у CAnnotAppearanceObject не будет создан stream + m_pAppearance = new CAnnotAppearance(NULL, this); + if (!m_pAppearance) + return; + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal((CResourcesDict*)pFakePage->Get("Resources")); + m_pXref->Add(pNormal); + m_pAppearance->Add("N", pNormal); + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + pNormal->Add("BBox", pArray); + + pArray->Add(GetRect().fLeft); + pArray->Add(GetRect().fBottom); + pArray->Add(GetRect().fRight); + pArray->Add(GetRect().fTop); + + pArray = new CArrayObject(); + if (!pArray) + return; + + pNormal->Add("Matrix", pArray); + pArray->Add(1); + pArray->Add(0); + pArray->Add(0); + pArray->Add(1); + pArray->Add(-GetRect().fLeft); + pArray->Add(-GetRect().fBottom); + + CDictObject* pFPStream = pFakePage->GetContent(); + pNormal->SetStream(m_pXref, pFPStream->GetStream(), false, ((CNumberObject*)pFPStream->Get("Length"))->Get()); + pFPStream->SetStream(NULL); + // RELEASEOBJECT(pFPStream); Нельзя удалять - это объект стрима, он уже в xref + } //---------------------------------------------------------------------------------------- // CTextMarkupAnnotation //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 16df6efa6ee..e2bd4f7c08c 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -362,6 +362,7 @@ namespace PdfWriter return AnnotFreeText; } + void APFromFakePage(CPage* pFakePage); void StartAP(const std::vector& arrC); void EndAP(); void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index e77325707f7..7e7e983873f 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1492,6 +1492,10 @@ namespace PdfWriter return p->second; return NULL; } + CPage* CDocument::CreateFakePage() + { + return new CPage(this, m_pXref); + } bool CDocument::EditCO(const std::vector& arrCO) { if (arrCO.empty()) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 287d8676d5f..1949d27d8f7 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -200,6 +200,7 @@ namespace PdfWriter CDictObject* GetParent(int nID); CPage* GetCurPage() { return m_pCurPage; } void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } + CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index d9094c04c26..0aba1bda8fd 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1537,15 +1537,16 @@ namespace PdfWriter m_pRollover = NULL; m_pDown = NULL; } - CAnnotAppearanceObject* CAnnotAppearance::GetNormal() + CAnnotAppearanceObject* CAnnotAppearance::GetNormal(CResourcesDict* pResources) { if (!m_pNormal) { if (m_pField) m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot); - Add("N", m_pNormal); + m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); + if (m_pXref) + Add("N", m_pNormal); } return m_pNormal; @@ -1621,13 +1622,15 @@ namespace PdfWriter void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { m_pXref = pXref ? pXref : NULL; - m_pStream = new CMemoryStream(); m_pFont = NULL; m_dFontSize = 10.0; m_bStart = true; if (m_pXref) + { + m_pStream = new CMemoryStream(); SetStream(m_pXref, m_pStream); + } Add("Type", "XObject"); Add("Subtype", "Form"); @@ -1649,9 +1652,9 @@ namespace PdfWriter pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); } - CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot) + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) { - Init(pXRef, pAnnot->GetDocument()->GetFieldsResources()); + Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); m_pAnnot = pAnnot; m_pField = NULL; diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index ca7dd30d31e..1c74f9b9585 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -344,7 +344,7 @@ namespace PdfWriter CAnnotAppearance(CXref* pXRef, CFieldBase* pField); CAnnotAppearance(CXref* pXRef, CAnnotation* pAnnot); - CAnnotAppearanceObject* GetNormal(); + CAnnotAppearanceObject* GetNormal(CResourcesDict* pResources = NULL); CAnnotAppearanceObject* GetRollover(); CAnnotAppearanceObject* GetDown(); @@ -382,7 +382,7 @@ namespace PdfWriter { public: CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); - CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot); + CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources = NULL); void DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize = 10.0, double dX = 0.0, double dY = 0.0, double dR = 0.0, double dG = 0.0, double dB = 0.0, const char* sExtGrStateName = NULL, double dW = 1.0, double dH = 1.0, CFontCidTrueType** ppFonts = NULL, double* pShifts = NULL); void DrawPicture(const char* sImageName = NULL, const double& dX = 0.0, const double& dY = 0.0, const double& dW = 0.0, const double& dH = 0.0, const bool& bRespectBorder = false); void StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight); diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index d9018d560c8..a2989cab7bd 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -651,14 +651,18 @@ namespace PdfWriter } } } - void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis) + void CDictObject::SetStream(CStream* pStream) + { + m_pStream = pStream; + } + void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis, int nLength) { if (m_pStream) delete m_pStream; if (!Get("Length")) { - CNumberObject* pLength = new CNumberObject(0); + CNumberObject* pLength = new CNumberObject(nLength); // Только stream object добавляются в таблицу xref автоматически if (bThis) diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index 1852ca57c3c..e259ccd70cd 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -456,6 +456,7 @@ namespace PdfWriter { return m_pStream; } + void SetStream(CStream* pStream); unsigned int GetFilter() const { return m_unFilter; @@ -468,7 +469,7 @@ namespace PdfWriter { m_unFilter = unFiler; } - void SetStream(CXref* pXref, CStream* pStream, bool bThis = true); + void SetStream(CXref* pXref, CStream* pStream, bool bThis = true, int nLength = 0); virtual void BeforeWrite(){} virtual void Write(CStream* pStream){} diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index fb5aafb8515..ba961558976 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -41,6 +41,7 @@ #include "Pattern.h" #include "Document.h" #include "Field.h" +#include "ResourcesDictionary.h" #ifdef DrawText #undef DrawText @@ -310,9 +311,16 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CPage //---------------------------------------------------------------------------------------- - CPage::CPage(CDocument* pDocument) + CPage::CPage(CDocument* pDocument, CXref* pXref) { Init(pDocument); + if (pXref) + { + AddResource(pXref); + m_pContents = new CArrayObject(); + Add("Contents", m_pContents); + AddContents(pXref); + } } void CPage::Fix() { @@ -566,27 +574,13 @@ namespace PdfWriter { return Get("Rotate"); } - void CPage::AddResource() + void CPage::AddResource(CXref* pXref) { - // TODO: Переделать на ResourcesDict - CDictObject* pResource = new CDictObject(); + CResourcesDict* pResource = new CResourcesDict(pXref, !pXref, true); if (!pResource) return; - - // Не смотря на то, что ProcSet - устаревший объект, добавляем - // его для совместимости + Add("Resources", pResource); - - CArrayObject* pProcset = new CArrayObject(); - if (!pProcset) - return; - - pResource->Add("ProcSet", pProcset); - pProcset->Add(new CNameObject("PDF")); - pProcset->Add(new CNameObject("Text")); - pProcset->Add(new CNameObject("ImageB")); - pProcset->Add(new CNameObject("ImageC")); - pProcset->Add(new CNameObject("ImageI")); } void CPage::BeforeWrite() { @@ -1584,6 +1578,10 @@ namespace PdfWriter Add("Contents", m_pContents); AddContents(pXref); } + CDictObject* CPage::GetContent() const + { + return (CDictObject*)m_pContents->Remove(0); + } int CPage::GetRotate() { CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index b4656c5df0c..9455f197b11 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -90,7 +90,7 @@ namespace PdfWriter class CPage : public CDictObject { public: - CPage(CDocument* pDocument); + CPage(CDocument* pDocument, CXref* pXref = NULL); CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument); ~CPage(); @@ -165,6 +165,7 @@ namespace PdfWriter void SetRotate(int nRotate); int GetRotate(); void ClearContent(CXref* pXref); + CDictObject* GetContent() const; private: @@ -176,7 +177,7 @@ namespace PdfWriter CObjectBase* GetRotateItem(); TBox GetMediaBox(); void SetMediaBoxValue(unsigned int unIndex, double dValue); - void AddResource(); + void AddResource(CXref* pXref = NULL); void SetGrMode(EGrMode eMode); void CheckGrMode(EGrMode eMode); void WriteText(const BYTE* sText, unsigned int unLen); From a7501e370b91534a360c09a44fe5690cb3923c4a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 16 May 2024 19:06:13 +0600 Subject: [PATCH 654/794] Fix bug #66694 --- .../Logic/Biff_structures/Ftab_Cetab.cpp | 4 ++-- .../Format/Logic/Biff_structures/PtgArray.cpp | 4 ++-- .../Logic/Biff_structures/PtgExtraArray.cpp | 4 +++- .../Format/Logic/Biff_structures/SerBool.cpp | 12 ++++++++++- .../Format/Logic/Biff_structures/SerBool.h | 1 + .../Format/Logic/Biff_structures/SerErr.cpp | 15 ++++++++++++++ .../Format/Logic/Biff_structures/SerErr.h | 1 + .../Format/Logic/Biff_structures/SerNil.cpp | 6 ++++++ .../Format/Logic/Biff_structures/SerNil.h | 2 ++ .../Format/Logic/Biff_structures/SerNum.cpp | 10 ++++++++++ .../Format/Logic/Biff_structures/SerNum.h | 1 + .../Format/Logic/Biff_structures/SerStr.cpp | 20 +++++++++++++++++++ .../Format/Logic/Biff_structures/SerStr.h | 1 + 13 files changed, 75 insertions(+), 6 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp index c0927f95141..55e52f66773 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp @@ -521,9 +521,9 @@ Ftab_Cetab::ValuesDetermination::ValuesDetermination() params_fixed.insert(ParamsFixed(0x01D6, 4, L"ACCRINTM")); params_fixed.insert(ParamsFixed(0x01D7, 2, L"WORKDAY")); params_fixed.insert(ParamsFixed(0x01D8, 2, L"NETWORKDAYS")); - params_fixed.insert(ParamsFixed(0x01D9, 1, L"GCD")); + params_fixed.insert(ParamsFixed(0x01D9, -1, L"GCD")); params_fixed.insert(ParamsFixed(0x01DA, 1, L"MULTINOMIAL")); - params_fixed.insert(ParamsFixed(0x01DB, 1, L"LCM")); + params_fixed.insert(ParamsFixed(0x01DB, -1, L"LCM")); params_fixed.insert(ParamsFixed(0x01DC, 2, L"FVSCHEDULE")); params_fixed.insert(ParamsFixed(0x01DD, 3, L"CUBEKPIMEMBER")); params_fixed.insert(ParamsFixed(0x01DE, 1, L"CUBESET")); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp index 009c055daa5..32ab12c28a1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArray.cpp @@ -55,7 +55,7 @@ void PtgArray::loadFields(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.skipNunBytes(7); // unused else - record.skipNunBytes(16); // unused + record.skipNunBytes(14); // unused } void PtgArray::writeFields(CFRecord& record) @@ -63,7 +63,7 @@ void PtgArray::writeFields(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.reserveNunBytes(7); // unused else - record.reserveNunBytes(16); // unused + record.reserveNunBytes(14); // unused } void PtgArray::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp index 62fa36eff86..1caae069fa2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp @@ -99,7 +99,9 @@ void PtgExtraArray::save(CFRecord& record) } else { - record << cols << rows; + cols++; + rows++; + record << rows << cols; } for (auto& item : array_) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp index 43559b6b366..1e1dd8dd3a2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.cpp @@ -60,7 +60,17 @@ void SerBool::load(CFRecord& record) if (record.getGlobalWorkbookInfo()->Version < 0x0800) record.skipNunBytes(7); // unused } - +void SerBool::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 4; + else + serType = 2; + record <Version < 0x0800) + record.reserveNunBytes(7); +} const std::wstring SerBool::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h index 16c68e1296c..2e158cbb03a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerBool.h @@ -44,6 +44,7 @@ class SerBool : public SerAr SerBool(const std::wstring& word); // Accepts only "TRUE" or "FALSE" BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp index 3867e978274..89238584f60 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.cpp @@ -63,6 +63,21 @@ void SerErr::load(CFRecord& record) } +void SerErr::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 0x10; + else + serType = 4; + + record << serType << err; + + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + record.reserveNunBytes(7); + else + record.reserveNunBytes(3); +} const std::wstring SerErr::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h index 2354f7cd927..f68f474930c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerErr.h @@ -45,6 +45,7 @@ class SerErr : public SerAr SerErr(const std::wstring& word); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp index 5d3bc2481e9..2eb32157ca6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.cpp @@ -51,6 +51,12 @@ void SerNil::load(CFRecord& record) record.skipNunBytes(8); // reserved/unused } +void SerNil::save(CFRecord& record) +{ + record.reserveNunBytes(9); +} + + const std::wstring SerNil::toString() const { return L""; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h index 0f8870169f5..06dc4b95601 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNil.h @@ -43,6 +43,8 @@ class SerNil : public SerAr SerNil(); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); + virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp index 123dec8be10..f01548f273f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.cpp @@ -64,6 +64,16 @@ void SerNum::load(CFRecord& record) record >> xnum; } +void SerNum::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + serType = 1; + else + serType = 0; + + record << serType << xnum; +} const std::wstring SerNum::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h index da683eaad06..fb156eb2a06 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerNum.h @@ -44,6 +44,7 @@ class SerNum : public SerAr SerNum(const std::wstring& word); BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual const std::wstring toString() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp index d895801ec32..2ec84fb0066 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp @@ -71,6 +71,26 @@ void SerStr::load(CFRecord& record) } } +void SerStr::save(CFRecord& record) +{ + char serType; + if (record.getGlobalWorkbookInfo()->Version < 0x0800) + { + serType = 2; + record << serType << string_; + } + else + { + serType = 1; + rgch = string_; + cch = string_.getSize(); + record < Date: Thu, 16 May 2024 18:56:59 +0300 Subject: [PATCH 655/794] Write Base14 fonts to pdf --- PdfFile/PdfEditor.cpp | 18 +- PdfFile/PdfEditor.h | 2 + PdfFile/PdfFile.cpp | 17 + PdfFile/PdfFile.pro | 2 - PdfFile/PdfReader.cpp | 4 +- PdfFile/PdfReader.h | 2 +- PdfFile/PdfWriter.cpp | 91 +++- PdfFile/PdfWriter.h | 5 + PdfFile/SrcReader/PdfAnnot.cpp | 16 +- PdfFile/SrcReader/PdfAnnot.h | 2 +- PdfFile/SrcWriter/AnnotRenderer.cpp | 664 ---------------------------- PdfFile/SrcWriter/AnnotRenderer.h | 196 -------- PdfFile/SrcWriter/Font14.cpp | 3 +- PdfFile/SrcWriter/Font14.h | 2 +- 14 files changed, 139 insertions(+), 885 deletions(-) delete mode 100644 PdfFile/SrcWriter/AnnotRenderer.cpp delete mode 100644 PdfFile/SrcWriter/AnnotRenderer.h diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7c76618b9ba..c06269ab1da 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -891,7 +891,8 @@ bool CPdfEditor::EditPage(int nPageIndex) //TODO добавление шрифтов FreeText в общий m_pAppAplication чтобы writer мог использовать шрифты из reader oAnnot.free(); oSubtype.free(); oTemp.arrayGetNF(nIndex, &oAnnot); - pReader->AnnotFonts(&oAnnot); + std::map mapFont = pReader->AnnotFonts(&oAnnot); + m_mFonts.insert(mapFont.begin(), mapFont.end()); DictToCDictObject(&oAnnot, pArray, false, ""); oAnnot.free(); } @@ -1292,3 +1293,18 @@ void CPdfEditor::EndMarkedContent() { pWriter->GetPage()->EndMarkedContent(); } +bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) +{ + std::map::iterator it = m_mFonts.find(wsFontName); + if (it == m_mFonts.end()) + return false; + wsFontPath = it->second; + if (wsFontName == L"Courier-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Symbol") + return true; + return false; +} diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 1f3c6258385..8331d377c04 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -56,12 +56,14 @@ class CPdfEditor bool IsEditPage(); void AddShapeXML(const std::string& sXML); void EndMarkedContent(); + bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); private: void GetPageTree(XRef* xref, Object* pPagesRefObj); std::wstring wsSrcFile; std::wstring wsPassword; + std::map m_mFonts; CPdfReader* pReader; CPdfWriter* pWriter; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 3c88584a8bd..9a9c2c5ea73 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -883,7 +883,24 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) return S_FALSE; std::wstring wsFontName = wsName; if (m_pInternal->pEditor && wsFontName.find(L"Embedded: ") == 0) + { wsFontName.erase(0, 10); + bool bBold = false, bItalic = false; + std::wstring wsFontPath; + if (m_pInternal->pEditor->IsBase14(wsFontName, bBold, bItalic, wsFontPath)) + { + m_pInternal->pWriter->AddFont(wsFontName, bBold, bItalic, wsFontPath, 0); + if (bBold || bItalic) + { + LONG lStyle = 0; + if (bBold) + lStyle |= 1; + if (bItalic) + lStyle |= 2; + put_FontStyle(lStyle); + } + } + } return m_pInternal->pWriter->put_FontName(wsFontName); } HRESULT CPdfFile::get_FontPath(std::wstring* wsPath) diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index f1cc7223dd4..9de26c11ee4 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -170,7 +170,6 @@ HEADERS += \ SrcWriter/Utils.h \ SrcWriter/Metadata.h \ SrcWriter/ICCProfile.h \ - SrcWriter/AnnotRenderer.h \ SrcWriter/States.h SOURCES += \ @@ -199,7 +198,6 @@ SOURCES += \ SrcWriter/Streams.cpp \ SrcWriter/Utils.cpp \ SrcWriter/Metadata.cpp \ - SrcWriter/AnnotRenderer.cpp \ SrcWriter/States.cpp # PdfFile diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 75543218beb..f56cdedddde 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -948,9 +948,9 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } -void CPdfReader::AnnotFonts(Object* pRefAnnot) +std::map CPdfReader::AnnotFonts(Object* pRefAnnot) { - PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, pRefAnnot, m_pFontManager, m_pFontList); + return PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, pRefAnnot, m_pFontManager, m_pFontList, 3); } BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) { diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index d30f562b5ff..36d14ae5d4d 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -82,7 +82,7 @@ class CPdfReader BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); - void AnnotFonts(Object* pRefAnnot); + std::map AnnotFonts(Object* pRefAnnot); private: PDFDoc* m_pPDFDocument; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index edeb0a6de6c..1aa95b416b9 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -42,7 +42,6 @@ #include "SrcWriter/FontTT.h" #include "SrcWriter/Destination.h" #include "SrcWriter/Field.h" -#include "SrcWriter/AnnotRenderer.h" #include "../DesktopEditor/graphics/Image.h" #include "../DesktopEditor/graphics/structures.h" @@ -168,6 +167,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend m_dPageWidth = 210; m_pPage = NULL; m_pFont = NULL; + m_pFont14 = NULL; m_lClipMode = 0; m_unFieldsCounter = 0; @@ -740,6 +740,20 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned if (!IsPageValid()) return S_FALSE; + if (m_bNeedUpdateTextFont) + { + if (!UpdateFont()) + return NULL; + } + + if (m_pFont14) + { + unsigned char* pCodes = new unsigned char[2]; + pCodes[0] = 0; + pCodes[1] = *pUnicodes & 0xFF; + return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; + } + unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); if (!pCodes) return DrawTextToRenderer(&unGid, 1, dX, dY) ? S_OK : S_FALSE; @@ -2047,6 +2061,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetIT(pFTPr->GetIT()); if (nFlags & (1 << 21)) pFreeTextAnnot->SetIC(pFTPr->GetIC()); + /* std::vector arrRC = pPr->GetRC(); double dFontSize = 10.0; if (!arrRC.empty()) @@ -2063,6 +2078,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (m_bNeedUpdateTextFont) UpdateFont(); pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); + */ if (nFlags & (1 << 22)) { PdfWriter::CPage* pCurPage = m_pPage; @@ -2900,7 +2916,7 @@ bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, cons m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - pText->SetFont(m_pFont); + pText->SetFont(m_pFont14 ? m_pFont : m_pFont); pText->SetSize(m_oFont.GetSize()); pText->SetColor(m_oBrush.GetColor1()); pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); @@ -2934,14 +2950,62 @@ bool CPdfWriter::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen m_oPath.AddText(m_pFont, pCodes, unLen * 2, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), m_oFont.GetSize(), MM_2_PT(m_oFont.GetCharSpace())); return true; } +int CPdfWriter::IsBase14(const std::wstring& wsName) +{ + if (wsName == L"Helvetica") + return 0; + if (wsName == L"Helvetica-Bold") + return 1; + if (wsName == L"Helvetica-Oblique") + return 2; + if (wsName == L"Helvetice-BoldOblique") + return 3; + if (wsName == L"Courier") + return 4; + if (wsName == L"Courier-Bold") + return 5; + if (wsName == L"Courier-Oblique") + return 6; + if (wsName == L"Courier-BoldOblique") + return 7; + if (wsName == L"Times") + return 8; + if (wsName == L"Times-Bold") + return 9; + if (wsName == L"Times-Oblique") + return 10; + if (wsName == L"Times-BoldOblique") + return 11; + if (wsName == L"Symbol") + return 12; + if (wsName == L"ZapfDingbats") + return 13; + return -1; +} +bool CPdfWriter::GetBaseFont14(const std::wstring& wsFontName, int nBase14) +{ + std::wstring wsFontPath = m_oFont.GetPath(); + LONG lFaceIndex = m_oFont.GetFaceIndex(); + if (!FindFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + return false; + if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, m_oFont.GetSize(), 72, 72)) + return false; + m_pFont14 = m_pDocument->CreateFont14((PdfWriter::EStandard14Fonts)nBase14); + return !!m_pFont14; +} bool CPdfWriter::UpdateFont() { m_bNeedUpdateTextFont = false; + m_pFont14 = NULL; std::wstring wsFontPath = m_oFont.GetPath(); LONG lFaceIndex = m_oFont.GetFaceIndex(); if (L"" == wsFontPath) { - if (!GetFontPath(m_oFont.GetName(), m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + std::wstring wsFontName = m_oFont.GetName(); + int nBase14 = IsBase14(wsFontName); + if (nBase14 >= 0 && GetBaseFont14(wsFontName, nBase14)) + return true; + if (!GetFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) { m_pFont = NULL; return false; @@ -2968,9 +3032,16 @@ bool CPdfWriter::UpdateFont() } return true; } -bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, const bool &bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) +void CPdfWriter::AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex) +{ + std::wstring _wsFontPath; + LONG _lFaceIndex; + if (FindFontPath(wsFontName, bBold, bItalic, _wsFontPath, _lFaceIndex)) + return; + m_vFonts.push_back(TFontInfo(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex)); +} +bool CPdfWriter::FindFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) { - bool bFind = false; for (int nIndex = 0, nCount = m_vFonts.size(); nIndex < nCount; nIndex++) { TFontInfo& oInfo = m_vFonts.at(nIndex); @@ -2978,10 +3049,14 @@ bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, { wsFontPath = oInfo.wsFontPath; lFaceIndex = oInfo.lFaceIndex; - bFind = true; - break; + return true; } } + return false; +} +bool CPdfWriter::GetFontPath(const std::wstring &wsFontName, const bool &bBold, const bool &bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) +{ + bool bFind = FindFontPath(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex); if (!bFind) { @@ -3027,7 +3102,7 @@ PdfWriter::CFontCidTrueType* CPdfWriter::GetFont(const std::wstring& wsFontPath, } std::wstring wsFontType = m_pFontManager->GetFontType(); - if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType) + if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType || L"Type 1" == wsFontType) pFont = m_pDocument->CreateCidTrueTypeFont(wsFontPath, lFaceIndex); } diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index b25d7c29b95..89ae16d7d85 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -217,6 +217,7 @@ class CPdfWriter HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); PdfWriter::CDocument* GetDocument(); PdfWriter::CPage* GetPage(); + void AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex); private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); @@ -224,7 +225,10 @@ class CPdfWriter bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); + int IsBase14(const std::wstring& wsFontName); + bool GetBaseFont14(const std::wstring& wsFontName, int nBase14); bool UpdateFont(); + bool FindFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); bool GetFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontPath, const LONG& lFontIndex); PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic); @@ -252,6 +256,7 @@ class CPdfWriter PdfWriter::CDocument* m_pDocument; PdfWriter::CPage* m_pPage; PdfWriter::CFontCidTrueType* m_pFont; + PdfWriter::CFont14* m_pFont14; PdfWriter::CShading* m_pShading; PdfWriter::CExtGrState* m_pShadingExtGrState; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 85b8a41a3c1..44121b57c56 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2354,12 +2354,12 @@ bool FindFonts(Object* oStream, int nDepth, Object* oResFonts) oXObject.free(); return false; } -std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts) +std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts) { Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); oAnnotRef->fetch(pXref, &oAnnot); - std::vector arrFontFreeText; + std::map arrFontFreeText; Object oAP, oN, oR, oFonts; if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream()) @@ -2389,6 +2389,7 @@ std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef std::string sFontName, sActual; bool bBold = false, bItalic = false; std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); + std::wstring wsFontName = UTF8_TO_U(sFontName); if (sFontPath.empty()) { oFontRef.free(); @@ -2407,7 +2408,7 @@ std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) { if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || - (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && + (*arrFontList)[nIndex]->m_wsFontName == wsFontName) && (*arrFontList)[nIndex]->m_bBold == (bBold ? 1 : 0) && (*arrFontList)[nIndex]->m_bItalic == (bItalic ? 1 : 0)) { @@ -2417,7 +2418,6 @@ std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef } if (bNew) pAppFontList->Add(sFontPath, pFontStream); - arrFontFreeText.push_back(sFontPath); } else { @@ -2425,6 +2425,7 @@ std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef if (pFontStream->CreateFromFile(sFontPath)) pAppFontList->Add(sFontPath, pFontStream); } + arrFontFreeText[wsFontName] = sFontPath; } oAP.free(); oN.free(); oR.free(); oFonts.free(); @@ -2435,10 +2436,8 @@ std::vector AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector& arrRC, int nTypeFonts) { std::map mRes; - if (arrRC.empty()) - return mRes; - std::vector arrFontFreeText = SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, nTypeFonts); + std::map arrFontFreeText = SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, nTypeFonts); CFontList* pAppFontList = (CFontList*)pFontManager->GetApplication()->GetList(); for (int i = 0; i < arrRC.size(); ++i) @@ -2504,7 +2503,8 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { - bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); + std::wstring sFontPath = pFontInfo->m_wsFontPath; + bool bFreeText = std::find_if(arrFontFreeText.begin(), arrFontFreeText.end(), [&sFontPath](auto&& p) { return p.second == sFontPath; }) != arrFontFreeText.end(); std::wstring wsFontBaseName = pFontInfo->m_wsFontName; if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') { diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index ac235a991e3..283e320157a 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -364,7 +364,7 @@ class CAnnotMarkup : public CAnnot }; namespace AnnotMarkup { -std::vector SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts = 3); +std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts = 3); std::map SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, std::vector& arrRC, int nTypeFonts = 3); std::vector ReadRC(const std::string& sRC); } diff --git a/PdfFile/SrcWriter/AnnotRenderer.cpp b/PdfFile/SrcWriter/AnnotRenderer.cpp deleted file mode 100644 index 1226af856f4..00000000000 --- a/PdfFile/SrcWriter/AnnotRenderer.cpp +++ /dev/null @@ -1,664 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "AnnotRenderer.h" - -#include "../../DesktopEditor/graphics/GraphicsPath.h" - -#define MM_2_PT(X) ((X) * 72.0 / 25.4) -#define PT_2_MM(X) ((X) * 25.4 / 72.0) - -#define LONG_2_BOOL(X) ((X) ? true : false) - -namespace PdfWriter -{ -CAnnotRenderer::CAnnotRenderer(NSFonts::IApplicationFonts* pAppFonts) -{ - m_pAppFonts = pAppFonts; - m_bNeedUpdateTextFont = true; -} -CAnnotRenderer::~CAnnotRenderer() -{ - -} - -// тип рендерера----------------------------------------------------------------------------- -HRESULT CAnnotRenderer::get_Type(LONG* lType) -{ - return S_OK; -} -//-------- Функции для работы со страницей -------------------------------------------------- -HRESULT CAnnotRenderer::NewPage() -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_Height(double* dHeight) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_Height(const double& dHeight) -{ - m_dPageHeight = dHeight; - return S_OK; -} -HRESULT CAnnotRenderer::get_Width(double* dWidth) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_Width(const double& dWidth) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_DpiX(double* dDpiX) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_DpiY(double* dDpiY) -{ - return S_OK; -} - -// pen -------------------------------------------------------------------------------------- -HRESULT CAnnotRenderer::get_PenColor(LONG* lColor) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenColor(const LONG& lColor) -{ - m_oPen.SetColor(lColor); - return S_OK; -} -HRESULT CAnnotRenderer::get_PenAlpha(LONG* lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenAlpha(const LONG& lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenSize(double* dSize) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenSize(const double& dSize) -{ - m_oPen.SetSize(dSize); - return S_OK; -} -HRESULT CAnnotRenderer::get_PenDashStyle(BYTE* nDashStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenDashStyle(const BYTE& nDashStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenLineStartCap(BYTE* nCapStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenLineStartCap(const BYTE& nCapStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenLineEndCap(BYTE* nCapStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenLineEndCap(const BYTE& nCapStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenLineJoin(BYTE* nJoinStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenLineJoin(const BYTE& nJoinStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenDashOffset(double* dOffset) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenDashOffset(const double& dOffset) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenAlign(LONG* lAlign) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenAlign(const LONG& lAlign) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_PenMiterLimit(double* dMiter) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_PenMiterLimit(const double& dMiter) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PenDashPattern(double* pPattern, LONG lCount) -{ - return S_OK; -} - -// brush ------------------------------------------------------------------------------------ -HRESULT CAnnotRenderer::get_BrushType(LONG* lType) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushType(const LONG& lType) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushColor1(LONG* lColor) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushColor1(const LONG& lColor) -{ - if (lColor != m_oBrush.GetColor1()) - m_oBrush.SetColor1(lColor); - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushAlpha1(LONG* lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushAlpha1(const LONG& lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushColor2(LONG* lColor) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushColor2(const LONG& lColor) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushAlpha2(LONG* lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushAlpha2(const LONG& lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushTexturePath(std::wstring* wsPath) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushTexturePath(const std::wstring& wsPath) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushTextureMode(LONG* lMode) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushTextureMode(const LONG& lMode) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushTextureAlpha(LONG* lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushTextureAlpha(const LONG& lAlpha) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_BrushLinearAngle(double* dAngle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushLinearAngle(const double& dAngle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) -{ - return S_OK; -} -HRESULT CAnnotRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) -{ - return S_OK; -} - -// font ------------------------------------------------------------------------------------- -HRESULT CAnnotRenderer::get_FontName(std::wstring* wsName) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontName(const std::wstring& wsName) -{ - if (wsName != m_oFont.GetName()) - { - m_oFont.SetName(wsName); - m_bNeedUpdateTextFont = true; - } - return S_OK; -} -HRESULT CAnnotRenderer::get_FontPath(std::wstring* wsPath) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontPath(const std::wstring& wsPath) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_FontSize(double* dSize) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontSize(const double& dSize) -{ - if (fabs(dSize - m_oFont.GetSize()) > 0.001) - m_oFont.SetSize(dSize); - return S_OK; -} -HRESULT CAnnotRenderer::get_FontStyle(LONG* lStyle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontStyle(const LONG& lStyle) -{ - if (lStyle != m_oFont.GetStyle()) - { - m_oFont.SetStyle(lStyle); - m_bNeedUpdateTextFont = true; - } - return S_OK; -} -HRESULT CAnnotRenderer::get_FontStringGID(INT* bGid) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontStringGID(const INT& bGid) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_FontCharSpace(double* dSpace) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontCharSpace(const double& dSpace) -{ - return S_OK; -} -HRESULT CAnnotRenderer::get_FontFaceIndex(int* lFaceIndex) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_FontFaceIndex(const int& lFaceIndex) -{ - return S_OK; -} - -//-------- Функции для вывода текста -------------------------------------------------------- -HRESULT CAnnotRenderer::CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandDrawTextCHAR2 (unsigned int* pUnicodes, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); - if (!pCodes) - return DrawTextToRenderer(&unGid, 1, dX, dY) ? S_OK : S_FALSE; - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; -} - -//-------- Маркеры для команд --------------------------------------------------------------- -HRESULT CAnnotRenderer::BeginCommand(const DWORD& lType) -{ - return S_OK; -} -HRESULT CAnnotRenderer::EndCommand(const DWORD& dwType) -{ - /* - if (c_nClipType == dwType) - { - m_oCommandManager.Flush(); - m_pPage->GrSave(); - m_lClipDepth++; - UpdateTransform(); - - m_oPath.Clip(m_pPage, c_nClipRegionTypeEvenOdd & m_lClipMode); - } - else if (c_nResetClipType == dwType) - { - m_oCommandManager.Flush(); - while (m_lClipDepth) - { - m_pPage->GrRestore(); - m_lClipDepth--; - } - } - */ - return S_OK; -} - -//-------- Функции для работы с Graphics Path ----------------------------------------------- -HRESULT CAnnotRenderer::PathCommandMoveTo(const double& dX, const double& dY) -{ - m_oPath.MoveTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandLineTo(const double& dX, const double& dY) -{ - m_oPath.LineTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandLinesTo(double* pPoints, const int& nCount) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) -{ - m_oPath.CurveTo(MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dX2), MM_2_PT(m_dPageHeight - dY2), MM_2_PT(dXe), MM_2_PT(m_dPageHeight - dYe)); - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandClose() -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandEnd() -{ - m_oPath.Clear(); - return S_OK; -} -HRESULT CAnnotRenderer::DrawPath(const LONG& lType) -{ - /* - m_oCommandManager.Flush(); - - bool bStroke = LONG_2_BOOL(lType & c_nStroke); - bool bFill = LONG_2_BOOL(lType & c_nWindingFillMode); - bool bEoFill = LONG_2_BOOL(lType & c_nEvenOddFillMode); - - m_pPage->GrSave(); - UpdateTransform(); - - if (bStroke) - UpdatePen(); - - std::wstring sTextureOldPath = L""; - std::wstring sTextureTmpPath = L""; - - if (bFill || bEoFill) - { - if (c_BrushTypeTexture == m_oBrush.GetType()) - { - sTextureOldPath = m_oBrush.GetTexturePath(); - sTextureTmpPath = GetDownloadFile(sTextureOldPath, wsTempDirectory); - - if (!sTextureTmpPath.empty()) - m_oBrush.SetTexturePath(sTextureTmpPath); - } - - UpdateBrush(pAppFonts, wsTempDirectory); - } - - if (!m_pShading) - { - m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill); - } - else - { - if (bFill || bEoFill) - { - m_pPage->GrSave(); - m_oPath.Clip(m_pPage, bEoFill); - - if (NULL != m_pShadingExtGrState) - m_pPage->SetExtGrState(m_pShadingExtGrState); - - m_pPage->DrawShading(m_pShading); - m_pPage->GrRestore(); - } - - if (bStroke) - m_oPath.Draw(m_pPage, bStroke, false, false); - } - - m_pPage->GrRestore(); - - if (!sTextureTmpPath.empty()) - { - m_oBrush.SetTexturePath(sTextureOldPath); - - if (NSFile::CFileBinary::Exists(sTextureTmpPath)) - NSFile::CFileBinary::Remove(sTextureTmpPath); - } - - */ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandStart() -{ - m_oPath.Clear(); - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandGetCurrentPoint(double* dX, double* dY) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} - -//-------- Функции для вывода изображений --------------------------------------------------- -HRESULT CAnnotRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CAnnotRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) -{ - return S_OK; -} - -// transform -------------------------------------------------------------------------------- -HRESULT CAnnotRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) -{ - m_oTransform.Set(dM11, dM12, dM21, dM22, dX, dY); - return S_OK; -} -HRESULT CAnnotRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) -{ - return S_OK; -} -HRESULT CAnnotRenderer::ResetTransform() -{ - return S_OK; -} - -// clip ------------------------------------------------------------------------------------ -HRESULT CAnnotRenderer::get_ClipMode(LONG* lMode) -{ - return S_OK; -} -HRESULT CAnnotRenderer::put_ClipMode(const LONG& lMode) -{ - return S_OK; -} - -// additiaonal params ---------------------------------------------------------------------- -HRESULT CAnnotRenderer::CommandLong(const LONG& lType, const LONG& lCommand) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandDouble(const LONG& lType, const double& dCommand) -{ - return S_OK; -} -HRESULT CAnnotRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) -{ - return S_OK; -} - -// внутренние функции ---------------------------------------------------------------------- -bool CAnnotRenderer::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) -{ - return true; -} -bool CAnnotRenderer::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) -{ - Aggplus::CGraphicsPathSimpleConverter simplifier; - simplifier.SetRenderer(this); - m_pFontManager->LoadFontByName(m_oFont.GetName(), m_oFont.GetSize(), (int)m_oFont.GetStyle(), 72.0, 72.0); - PathCommandEnd(); - if (simplifier.PathCommandText2(L"", (const int*)unGid, unLen, m_pFontManager, dX, dY, 0, 0)) - { - DrawPath(c_nWindingFillMode); - PathCommandEnd(); - return true; - } - return false; -} -bool CAnnotRenderer::UpdateFont() -{ - /* - m_bNeedUpdateTextFont = false; - std::wstring wsFontPath = m_oFont.GetPath(); - LONG lFaceIndex = m_oFont.GetFaceIndex(); - if (L"" == wsFontPath) - { - if (!GetFontPath(m_oFont.GetName(), m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) - { - m_pFont = NULL; - return false; - } - } - - m_oFont.SetNeedDoBold(false); - m_oFont.SetNeedDoItalic(false); - - m_pFont = NULL; - if (L"" != wsFontPath) - { - m_pFont = GetFont(wsFontPath, lFaceIndex); - if (m_pFont) - { - if (m_oFont.IsItalic() && !m_pFont->IsItalic()) - m_oFont.SetNeedDoItalic(true); - - if (m_oFont.IsBold() && !m_pFont->IsBold()) - m_oFont.SetNeedDoBold(true); - } - else - return false; - } - */ - return true; -} -void UpdateTransform() -{ - -} -unsigned char* CAnnotRenderer::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) -{ - if (m_bNeedUpdateTextFont) - { - if (!UpdateFont()) - return NULL; - } - - if (!m_pFont) - return NULL; - - unsigned char* pCodes = new unsigned char[2]; - if (!pCodes) - return NULL; - - unsigned short ushCode = m_pFont->EncodeGID(unGID, pUnicodes, unUnicodesCount); - pCodes[0] = (ushCode >> 8) & 0xFF; - pCodes[1] = ushCode & 0xFF; - return pCodes; -} -} diff --git a/PdfFile/SrcWriter/AnnotRenderer.h b/PdfFile/SrcWriter/AnnotRenderer.h deleted file mode 100644 index 7e74e949cb0..00000000000 --- a/PdfFile/SrcWriter/AnnotRenderer.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2023 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_ANNOT_RENDERER_H -#define _PDF_WRITER_SRC_ANNOT_RENDERER_H - -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" - -#include "States.h" -#include "FontCidTT.h" - -namespace PdfWriter -{ -class CAnnotRenderer : public IRenderer -{ -public: - CAnnotRenderer(NSFonts::IApplicationFonts* pAppFonts); - virtual ~CAnnotRenderer(); - -public: - // тип рендерера----------------------------------------------------------------------------- - virtual HRESULT get_Type(LONG* lType); - //-------- Функции для работы со страницей -------------------------------------------------- - virtual HRESULT NewPage(); - virtual HRESULT get_Height(double* dHeight); - virtual HRESULT put_Height(const double& dHeight); - virtual HRESULT get_Width(double* dWidth); - virtual HRESULT put_Width(const double& dWidth); - virtual HRESULT get_DpiX(double* dDpiX); - virtual HRESULT get_DpiY(double* dDpiY); - - // pen -------------------------------------------------------------------------------------- - virtual HRESULT get_PenColor(LONG* lColor); - virtual HRESULT put_PenColor(const LONG& lColor); - virtual HRESULT get_PenAlpha(LONG* lAlpha); - virtual HRESULT put_PenAlpha(const LONG& lAlpha); - virtual HRESULT get_PenSize(double* dSize); - virtual HRESULT put_PenSize(const double& dSize); - virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); - virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); - virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); - virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); - virtual HRESULT get_PenDashOffset(double* dOffset); - virtual HRESULT put_PenDashOffset(const double& dOffset); - virtual HRESULT get_PenAlign(LONG* lAlign); - virtual HRESULT put_PenAlign(const LONG& lAlign); - virtual HRESULT get_PenMiterLimit(double* dMiter); - virtual HRESULT put_PenMiterLimit(const double& dMiter); - virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); - - // brush ------------------------------------------------------------------------------------ - virtual HRESULT get_BrushType(LONG* lType); - virtual HRESULT put_BrushType(const LONG& lType); - virtual HRESULT get_BrushColor1(LONG* lColor); - virtual HRESULT put_BrushColor1(const LONG& lColor); - virtual HRESULT get_BrushAlpha1(LONG* lAlpha); - virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); - virtual HRESULT get_BrushColor2(LONG* lColor); - virtual HRESULT put_BrushColor2(const LONG& lColor); - virtual HRESULT get_BrushAlpha2(LONG* lAlpha); - virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); - virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); - virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); - virtual HRESULT get_BrushTextureImage(Aggplus::CImage** pImage); - virtual HRESULT put_BrushTextureImage(Aggplus::CImage* pImage); - virtual HRESULT get_BrushTextureMode(LONG* lMode); - virtual HRESULT put_BrushTextureMode(const LONG& lMode); - virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); - virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); - virtual HRESULT get_BrushTransform(Aggplus::CMatrix& oMatrix); - virtual HRESULT put_BrushTransform(const Aggplus::CMatrix& oMatrix); - virtual HRESULT get_BrushLinearAngle(double* dAngle); - virtual HRESULT put_BrushLinearAngle(const double& dAngle); - virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); - - // font ------------------------------------------------------------------------------------- - virtual HRESULT get_FontName(std::wstring* wsName); - virtual HRESULT put_FontName(const std::wstring& wsName); - virtual HRESULT get_FontPath(std::wstring* wsPath); - virtual HRESULT put_FontPath(const std::wstring& wsPath); - virtual HRESULT get_FontSize(double* dSize); - virtual HRESULT put_FontSize(const double& dSize); - virtual HRESULT get_FontStyle(LONG* lStyle); - virtual HRESULT put_FontStyle(const LONG& lStyle); - virtual HRESULT get_FontStringGID(INT* bGid); - virtual HRESULT put_FontStringGID(const INT& bGid); - virtual HRESULT get_FontCharSpace(double* dSpace); - virtual HRESULT put_FontCharSpace(const double& dSpace); - virtual HRESULT get_FontFaceIndex(int* lFaceIndex); - virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); - - //-------- Функции для вывода текста -------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextCHAR2 (unsigned int* unUnicode, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH); - - //-------- Маркеры для команд --------------------------------------------------------------- - virtual HRESULT BeginCommand(const DWORD& lType); - virtual HRESULT EndCommand(const DWORD& lType); - - //-------- Функции для работы с Graphics Path ----------------------------------------------- - virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); - virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); - virtual HRESULT PathCommandClose(); - virtual HRESULT PathCommandEnd(); - virtual HRESULT DrawPath(const LONG& lType); - virtual HRESULT PathCommandStart(); - virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); - virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - - //-------- Функции для вывода изображений --------------------------------------------------- - virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); - - // transform -------------------------------------------------------------------------------- - virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); - virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); - virtual HRESULT ResetTransform(); - - // clip ------------------------------------------------------------------------------------ - virtual HRESULT get_ClipMode(LONG* lMode); - virtual HRESULT put_ClipMode(const LONG& lMode); - - // additiaonal params ---------------------------------------------------------------------- - virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); - virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - -private: - bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); - bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); - bool UpdateFont(); - void UpdateTransform(); - unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); - -private: - NSFonts::IApplicationFonts* m_pAppFonts; - NSFonts::IFontManager* m_pFontManager; - - CFontCidTrueType* m_pFont; - - CPenState m_oPen; - CBrushState m_oBrush; - CFontState m_oFont; - CPath m_oPath; - CTransform m_oTransform; - bool m_bNeedUpdateTextFont; - double m_dPageHeight; -}; -} - -#endif // _PDF_WRITER_SRC_ANNOT_RENDERER_H diff --git a/PdfFile/SrcWriter/Font14.cpp b/PdfFile/SrcWriter/Font14.cpp index f305a42f409..355d61490ab 100644 --- a/PdfFile/SrcWriter/Font14.cpp +++ b/PdfFile/SrcWriter/Font14.cpp @@ -30,6 +30,7 @@ * */ #include "Font14.h" +#include "Document.h" namespace PdfWriter { @@ -57,4 +58,4 @@ namespace PdfWriter Add("Subtype", "Type1"); Add("BaseFont", c_sStandardFontNames[(int)eType]); } -} \ No newline at end of file +} diff --git a/PdfFile/SrcWriter/Font14.h b/PdfFile/SrcWriter/Font14.h index e7992520cee..d8c0dbe27cc 100644 --- a/PdfFile/SrcWriter/Font14.h +++ b/PdfFile/SrcWriter/Font14.h @@ -50,4 +50,4 @@ namespace PdfWriter }; } -#endif // _PDF_WRITER_SRC_FONT14_H \ No newline at end of file +#endif // _PDF_WRITER_SRC_FONT14_H From 3d23e748182b0f61faa6b686f8f5614db82c0fa2 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 16 May 2024 21:48:26 +0500 Subject: [PATCH 656/794] Fix bug #61378 --- OdfFile/Reader/Converter/pptx_text_context.cpp | 2 +- OdfFile/Writer/Converter/ConvertDrawing.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OdfFile/Reader/Converter/pptx_text_context.cpp b/OdfFile/Reader/Converter/pptx_text_context.cpp index f3ee5fe6e2a..74d26af8092 100644 --- a/OdfFile/Reader/Converter/pptx_text_context.cpp +++ b/OdfFile/Reader/Converter/pptx_text_context.cpp @@ -701,7 +701,7 @@ void pptx_text_context::Impl::start_list_item(bool restart) void pptx_text_context::Impl::start_list(const std::wstring & StyleName, bool Continue) { - if (paragraphs_cout_ > 0 && ( in_paragraph || list_style_stack_.empty())) + if (paragraphs_cout_ > 0 && ( in_paragraph || !list_style_stack_.empty())) { dump_paragraph(); } diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 3965a23bd79..590eb17451e 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -2145,7 +2145,9 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T } else { - odf_context()->text_context()->start_span(true); + bool styled = oox_paragraph->endParaRPr.IsInit() && oox_paragraph->endParaRPr->sz.IsInit(); + + odf_context()->text_context()->start_span(styled); odf_context()->text_context()->end_span(); } From 140f9970f966a197369f3baa395bacf558ac9c91 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 12:07:22 +0400 Subject: [PATCH 657/794] Add wrapper library `docbuilder_functions.dll` and tests for it --- .../src/docbuilder_func_lib.pro | 28 ++ .../src/docbuilder_functions.cpp | 394 ++++++++++++++++++ .../src/docbuilder_functions.h | 134 ++++++ .../test/docbuilder_func_test.pro | 28 ++ .../docbuilder.python/test/main.cpp | 58 +++ 5 files changed, 642 insertions(+) create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro new file mode 100644 index 00000000000..f48067b5416 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro @@ -0,0 +1,28 @@ +QT -= core +QT -= gui + +TARGET = docbuilder_functions + +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(doctrenderer) + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +DEFINES += DOCBUILDER_FUNCTIONS_EXPORT + +SOURCES += \ + docbuilder_functions.cpp + +HEADERS += \ + docbuilder_functions.h diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp new file mode 100644 index 00000000000..e7310761817 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -0,0 +1,394 @@ +#include "docbuilder_functions.h" + +#include + +// ===== CDocBuilderValue ===== +CDocBuilderValue* CDocBuilderValue_Create() +{ + return new CDocBuilderValue(); +} + +CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other) +{ + return new CDocBuilderValue(*other); +} + +void CDocBuilderValue_Destroy(CDocBuilderValue* self) +{ + delete self; +} + +bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self) +{ + return self->IsEmpty(); +} + +void CDocBuilderValue_Clear(CDocBuilderValue* self) +{ + self->Clear(); +} + +bool CDocBuilderValue_IsNull(CDocBuilderValue* self) +{ + return self->IsNull(); +} + +bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self) +{ + return self->IsUndefined(); +} + +bool CDocBuilderValue_IsInt(CDocBuilderValue* self) +{ + return self->IsInt(); +} + +bool CDocBuilderValue_IsDouble(CDocBuilderValue* self) +{ + return self->IsDouble(); +} + +bool CDocBuilderValue_IsString(CDocBuilderValue* self) +{ + return self->IsString(); +} + +bool CDocBuilderValue_IsFunction(CDocBuilderValue* self) +{ + return self->IsFunction(); +} + +bool CDocBuilderValue_IsObject(CDocBuilderValue* self) +{ + return self->IsObject(); +} + +bool CDocBuilderValue_IsArray(CDocBuilderValue* self) +{ + return self->IsArray(); +} + +unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self) +{ + return self->GetLength(); +} + +bool CDocBuilderValue_ToBool(CDocBuilderValue* self) +{ + return self->ToBool(); +} + +int CDocBuilderValue_ToInt(CDocBuilderValue* self) +{ + return self->ToInt(); +} + +double CDocBuilderValue_ToDouble(CDocBuilderValue* self) +{ + return self->ToDouble(); +} + +const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self) +{ + // NOTE: User is responsible for calling DeleteWCharP() on returned pointer + CString strValue = self->ToString(); + size_t len = wcslen(strValue.c_str()); + wchar_t* strRes = new wchar_t[len + 1]; + memcpy(strRes, strValue.c_str(), (len + 1) + sizeof(wchar_t)); + return strRes; +} + +CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->GetProperty(name)); +} + +CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index) +{ + return new CDocBuilderValue(self->Get(index)); +} + +void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value) +{ + self->Set(name, *value); +} + +void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value) +{ + self->Set(index, *value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateUndefined() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderValue_CreateNull() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateNull()); +} + +CDocBuilderValue* CDocBuilderValue_CreateArray(int length) +{ + return new CDocBuilderValue(CDocBuilderValue::CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->Call(name)); +} + +CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1) +{ + return new CDocBuilderValue(self->Call(name, *p1)); +} + +CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2)); +} + +CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3)); +} + +CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4)); +} + +CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5)); +} + +CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5, *p6)); +} + +// ===== CDocBuilder ===== +CDocBuilder* CDocBuilder_Create() +{ + return new CDocBuilder(); +} + +void CDocBuilder_Destroy(CDocBuilder* self) +{ + delete self; +} + +int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params) +{ + return self->OpenFile(path, params); +} + +bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type) +{ + return self->CreateFile(type); +} + +bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension) +{ + return self->CreateFile(extension); +} + +void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder) +{ + self->SetTmpFolder(folder); +} + +int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path) +{ + return self->SaveFile(type, path); +} + +int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(type, path, params); +} + +int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path) +{ + return self->SaveFile(extension, path); +} + +int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(extension, path, params); +} + +void CDocBuilder_CloseFile(CDocBuilder* self) +{ + self->CloseFile(); +} + +bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command) +{ + return self->ExecuteCommand(command); +} + +bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue) +{ + return self->ExecuteCommand(command, retValue); +} + +bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path) +{ + return self->Run(path); +} + +bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands) +{ + return self->RunTextW(commands); +} + +void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value) +{ + self->SetPropertyW(param, value); +} + +void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append) +{ + self->WriteData(path, value, append); +} + +bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self) +{ + return self->IsSaveWithDoctrendererMode(); +} + +char* CDocBuilder_GetVersion(CDocBuilder* self) +{ + // NOTE: User is responsible for calling DeleteCharP() on returned pointer + return self->GetVersion(); +} + +CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self) +{ + return new CDocBuilderContext(self->GetContext()); +} + +void CDocBuilder_Initialize() +{ + CDocBuilder::Initialize(); +} + +void CDocBuilder_InitializeWithDirectory(const wchar_t* directory) +{ + CDocBuilder::Initialize(directory); +} + +void CDocBuilder_Dispose() +{ + CDocBuilder::Dispose(); +} + +// ===== CDocBuilderContextScope ===== +CDocBuilderContextScope* CDocBuilderContextScope_Create() +{ + return new CDocBuilderContextScope(); +} + +CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other) +{ + return new CDocBuilderContextScope(*other); +} + +void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self) +{ + delete self; +} + +void CDocBuilderContextScope_Close(CDocBuilderContextScope* self) +{ + self->Close(); +} + +// ===== CDocBuilderContext ===== +CDocBuilderContext* CDocBuilderContext_Create() +{ + return new CDocBuilderContext(); +} + +CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other) +{ + return new CDocBuilderContext(*other); +} + +void CDocBuilderContext_Destroy(CDocBuilderContext* self) +{ + delete self; +} + +CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateNull()); +} + +CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateObject()); +} + +CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length) +{ + return new CDocBuilderValue(self->CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->GetGlobal()); +} + +CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self) +{ + return new CDocBuilderContextScope(self->CreateScope()); +} + +bool CDocBuilderContext_IsError(CDocBuilderContext* self) +{ + return self->IsError(); +} + +// ===== Utility ===== +void DeleteWCharP(wchar_t* str) +{ + delete str; +} + +void DeleteCharP(char* str) +{ + delete str; +} diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h new file mode 100644 index 00000000000..a3acd2e02be --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h @@ -0,0 +1,134 @@ +#ifndef DOCBUILDER_FUNCTIONS_H +#define DOCBUILDER_FUNCTIONS_H + +#include "docbuilder.h" + +#include "../common/base_export.h" +#ifdef DOCBUILDER_FUNCTIONS_EXPORT +#define DOCBUILDER_FUNC_DECL Q_DECL_EXPORT +#else +#define DOCBUILDER_FUNC_DECL Q_DECL_IMPORT +#endif + +using namespace NSDoctRenderer; + +extern "C" +{ +// ===== CDocBuilderValue ===== +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Destroy(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Clear(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsNull(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsString(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsFunction(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsObject(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsArray(CDocBuilderValue* self); +// TODO: +// DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsTypedArray(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_ToBool(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL int CDocBuilderValue_ToInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL double CDocBuilderValue_ToDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index); + +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateUndefined(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateNull(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateArray(int length); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6); + +// ===== CDocBuilder ===== +DOCBUILDER_FUNC_DECL CDocBuilder* CDocBuilder_Create(); +DOCBUILDER_FUNC_DECL void CDocBuilder_Destroy(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder); + +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params); + +DOCBUILDER_FUNC_DECL void CDocBuilder_CloseFile(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command); +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path); +DOCBUILDER_FUNC_DECL bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value); + +DOCBUILDER_FUNC_DECL void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL char* CDocBuilder_GetVersion(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL void CDocBuilder_Initialize(); +DOCBUILDER_FUNC_DECL void CDocBuilder_InitializeWithDirectory(const wchar_t* directory); +DOCBUILDER_FUNC_DECL void CDocBuilder_Dispose(); + +// ===== CDocBuilderContextScope ===== +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self); + +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Close(CDocBuilderContextScope* self); + +// ===== CDocBuilderContext ===== +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContext_Destroy(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length); +// TODO: +// CDocBuilderContext_CreateTypedArray(CDocBuilderContext* self, unsigned char* buffer); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderContext_IsError(CDocBuilderContext* self); + +// ===== Utility ===== +DOCBUILDER_FUNC_DECL void DeleteWCharP(wchar_t* str); +DOCBUILDER_FUNC_DECL void DeleteCharP(char* str); +} + +#endif // DOCBUILDER_FUNCTIONS_H diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro new file mode 100644 index 00000000000..19cef476aec --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro @@ -0,0 +1,28 @@ +QT -= core +QT -= gui + +TARGET = test + +TEMPLATE = app + +CONFIG -= app_bundle +CONFIG += console + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +# !!! Set docbuilder path here !!! +DOCUMENT_BUILDER_INSTALL_PATH="C:/Program Files/ONLYOFFICE/DocumentBuilder" + +DEFINES += "DOCUMENT_BUILDER_INSTALL_PATH=\"$$DOCUMENT_BUILDER_INSTALL_PATH\"" +LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder_functions + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +SOURCES += \ + main.cpp + diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp new file mode 100644 index 00000000000..1e5491fd731 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp @@ -0,0 +1,58 @@ +#include "../src/docbuilder_functions.h" + +#include + +#include "app_builder_lib/utils.cpp" + +#define DECLARE_RAII_DOCBUILDER_FUNC_CLASS( CLASS_NAME ) \ +class CLASS_NAME ## F \ +{ \ +public: \ + CLASS_NAME ## F(CLASS_NAME* internal) { m_internal = internal; } \ + ~CLASS_NAME ## F() { CLASS_NAME ## _Destroy(m_internal); } \ + \ + CLASS_NAME* get() { return m_internal; } \ + \ +private: \ + CLASS_NAME* m_internal; \ +}; + +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilder) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderValue) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContext) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContextScope) + +int main() +{ + std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); + std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); + + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + + CDocBuilderF oBuilder = CDocBuilder_Create(); + CDocBuilder_SetProperty(oBuilder.get(), L"--work-directory", sWorkDirectory.c_str()); + + CDocBuilder_CreateFileByExtension(oBuilder.get(), L"docx"); + + CDocBuilderContextF oContext = CDocBuilder_GetContext(oBuilder.get()); + CDocBuilderContextScopeF oScope = CDocBuilderContext_CreateScope(oContext.get()); + + CDocBuilderValueF oGlobal = CDocBuilderContext_GetGlobal(oContext.get()); + + CDocBuilderValueF oApi = CDocBuilderValue_GetProperty(oGlobal.get(), L"Api"); + CDocBuilderValueF oDocument = CDocBuilderValue_Call0(oApi.get(), L"GetDocument"); + CDocBuilderValueF oParagraph = CDocBuilderValue_Call0(oApi.get(), L"CreateParagraph"); + CDocBuilderValue_Call2(oParagraph.get(), L"SetSpacingAfter", CDocBuilderValueF(CDocBuilderValue_CreateWithInt(1000)).get(), CDocBuilderValueF(CDocBuilderValue_CreateWithBool(false)).get()); + CDocBuilderValue_Call1(oParagraph.get(), L"AddText", CDocBuilderValueF(CDocBuilderValue_CreateWithString(L"Hello, world!")).get()); + CDocBuilderValueF oContent = CDocBuilderContext_CreateArray(oContext.get(), 1); + CDocBuilderValue_SetByIndex(oContent.get(), 0, oParagraph.get()); + CDocBuilderValue_Call1(oDocument.get(), L"InsertContent", oContent.get()); + + std::wstring sDstPath = sProcessDirectory + L"/result.docx"; + CDocBuilder_SaveFileByExtension(oBuilder.get(), L"docx", sDstPath.c_str()); + CDocBuilder_CloseFile(oBuilder.get()); + + CDocBuilder_Dispose(); + + return 0; +} From ebe045a83304bc1bed2eec064820d6a49b76110a Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Fri, 17 May 2024 11:56:18 +0300 Subject: [PATCH 658/794] fix bug #67995 --- MsBinaryFile/Common/Vba/StreamObjects.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/Common/Vba/StreamObjects.cpp b/MsBinaryFile/Common/Vba/StreamObjects.cpp index 44badb466b9..64ae0f1c4b9 100644 --- a/MsBinaryFile/Common/Vba/StreamObjects.cpp +++ b/MsBinaryFile/Common/Vba/StreamObjects.cpp @@ -41,6 +41,8 @@ namespace VBA bool DirStreamObject::loadContent() { + if (!reader) return false; + InformationRecord = boost::make_shared(reader); ReferencesRecord = boost::make_shared(reader); ModulesRecord = boost::make_shared(reader); @@ -50,12 +52,16 @@ bool DirStreamObject::loadContent() bool ModuleStreamObject::loadContent() { - SourceCode = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); + if (!reader) return false; + + SourceCode = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); return true; } bool ProjectStreamObject::loadContent() { + if (!reader) return false; + std::string strProps((char*)reader->getData(), reader->getDataSize()); std::vector arrProps; @@ -72,6 +78,8 @@ bool ProjectStreamObject::loadContent() } bool VBFrameObject::loadContent() { + if (!reader) return false; + std::wstring strProps = convert_string_icu((char*)reader->getData(), (unsigned int)reader->getDataSize(), reader->CodePage); std::vector arrProps; @@ -94,6 +102,8 @@ bool VBFrameObject::loadContent() bool FormControlStream::loadContent() { + if (!reader) return false; + unsigned char MinorVersion, MajorVersion; _UINT16 cbForm; From 28cd584393378a6a46256748648f5fe851ca2cc1 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 14:10:50 +0400 Subject: [PATCH 659/794] Fix delete functions and add simple c++ example --- .../src/docbuilder_functions.cpp | 4 ++-- .../docbuilder.python/test/main.cpp | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp index e7310761817..645b71811c5 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -385,10 +385,10 @@ bool CDocBuilderContext_IsError(CDocBuilderContext* self) // ===== Utility ===== void DeleteWCharP(wchar_t* str) { - delete str; + delete[] str; } void DeleteCharP(char* str) { - delete str; + delete[] str; } diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp index 1e5491fd731..71f06ba9a89 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp @@ -1,6 +1,7 @@ #include "../src/docbuilder_functions.h" #include +#include #include "app_builder_lib/utils.cpp" @@ -25,8 +26,21 @@ DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContextScope) int main() { std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); - std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); +#if 1 + // Simple test that shows builder version if everything is correct + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + CDocBuilder* pBuilder = CDocBuilder_Create(); + + char* sVersion = CDocBuilder_GetVersion(pBuilder); + std::cout << sVersion << std::endl; + DeleteCharP(sVersion); + + CDocBuilder_Dispose(); + CDocBuilder_Destroy(pBuilder); +#else + // Test is identical to app_builder_lib.pro + // The test uses RAII wrappers - classes with 'F' postfix, which are destroyed automatically CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); CDocBuilderF oBuilder = CDocBuilder_Create(); @@ -48,11 +62,13 @@ int main() CDocBuilderValue_SetByIndex(oContent.get(), 0, oParagraph.get()); CDocBuilderValue_Call1(oDocument.get(), L"InsertContent", oContent.get()); + std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); std::wstring sDstPath = sProcessDirectory + L"/result.docx"; CDocBuilder_SaveFileByExtension(oBuilder.get(), L"docx", sDstPath.c_str()); CDocBuilder_CloseFile(oBuilder.get()); CDocBuilder_Dispose(); +#endif return 0; } From 84d7eb03f2088c6ee253209c0285609955ec8148 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 14:11:22 +0400 Subject: [PATCH 660/794] Add example of python wrapper --- .../docbuilder.python/src/docbuilder.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py new file mode 100644 index 00000000000..959d1b82ee7 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -0,0 +1,59 @@ +import ctypes +import os +import platform +import sys + +DOCBUILDER_HANDLE = ctypes.c_void_p +STRING_HANDLE = ctypes.c_void_p + +_lib = None + +def loadLibrary(path): + if any(platform.win32_ver()): + os.environ['PATH'] += ';' + path + else: + os.environ['PATH'] += ':' + path + + global _lib + _lib = ctypes.CDLL('docbuilder_functions.dll') + + # init all function signatures + _lib.CDocBuilder_InitializeWithDirectory.argtypes = [ctypes.c_wchar_p] + _lib.CDocBuilder_InitializeWithDirectory.restype = None + + _lib.CDocBuilder_Create.argtypes = [] + _lib.CDocBuilder_Create.restype = DOCBUILDER_HANDLE + + _lib.CDocBuilder_GetVersion.argtypes = [DOCBUILDER_HANDLE] + _lib.CDocBuilder_GetVersion.restype = STRING_HANDLE + + _lib.CDocBuilder_Dispose.argtypes = [] + _lib.CDocBuilder_Dispose.restype = None + + _lib.CDocBuilder_Destroy.argtypes = [DOCBUILDER_HANDLE] + _lib.CDocBuilder_Destroy.restype = None + + _lib.DeleteCharP.argtypes = [ctypes.c_char_p] + _lib.DeleteCharP.restype = None + + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('Specify the folder with document builder and all dll-s') + exit(0) + + path = sys.argv[1] + + loadLibrary(path) + + # --------- + _lib.CDocBuilder_InitializeWithDirectory(path) + builder = _lib.CDocBuilder_Create() + + sVersion = _lib.CDocBuilder_GetVersion(builder) + version = ctypes.cast(sVersion, ctypes.c_char_p).value + print(version) + _lib.DeleteCharP(ctypes.cast(sVersion, ctypes.c_char_p)) + + _lib.CDocBuilder_Dispose() + _lib.CDocBuilder_Destroy(builder) From b8d54fb29523475f0187dfb06ea7a446dcd876d3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 17 May 2024 17:55:02 +0600 Subject: [PATCH 661/794] fix bug #65948 --- OOXML/DocxFormat/Media/ActiveX.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OOXML/DocxFormat/Media/ActiveX.cpp b/OOXML/DocxFormat/Media/ActiveX.cpp index c584a4583c1..b18dae358d3 100644 --- a/OOXML/DocxFormat/Media/ActiveX.cpp +++ b/OOXML/DocxFormat/Media/ActiveX.cpp @@ -484,6 +484,20 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); + if(m_oId.IsInit()) + { + smart_ptr pFileControlBin; + pFileControlBin = this->Find(OOX::RId(m_oId->GetValue())); + + smart_ptr pActiveX_bin = pFileControlBin.smart_dynamic_cast(); + + if (pActiveX_bin.IsInit()) + { + oContent.Registration(pActiveX_bin->type().OverrideType(), oDirectory, pActiveX_bin->filename().GetFilename()); + } + } + + IFileContainer::Write(oPath, oDirectory, oContent); } //--------------------------------------------------------------------------------------------------------- From 6ba40aba515b5b7d132796098b0b030e52897dfc Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 17 May 2024 16:57:40 +0500 Subject: [PATCH 662/794] Fix bug #67380 --- OdfFile/Reader/Format/draw_frame_docx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 0fbd1ed881f..0957ab9343e 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -886,7 +886,7 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm { drawing->behindDoc = L"1"; if (!drawing->styleWrap) - drawing->styleWrap = style_wrap(style_wrap::RunThrough); + drawing->styleWrap = style_wrap(style_wrap::Parallel); } if (!drawing->styleWrap) From d853d42090493c59a1f0be9147534432f7cbd0c1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 17 May 2024 16:00:23 +0300 Subject: [PATCH 663/794] Fix calculating glyph widths for Base14 fonts --- .../graphics/pro/js/wasm/src/pdfwriter.cpp | 1 + PdfFile/PdfEditor.cpp | 14 ++----- PdfFile/PdfFile.cpp | 1 + PdfFile/PdfWriter.cpp | 19 +++++++-- PdfFile/SrcWriter/Document.cpp | 20 ++++++++- PdfFile/SrcWriter/Document.h | 4 +- PdfFile/SrcWriter/Font.h | 4 ++ PdfFile/SrcWriter/Font14.cpp | 41 +++++++++++++++++++ PdfFile/SrcWriter/Font14.h | 10 +++++ PdfFile/SrcWriter/FontTT.h | 1 - PdfFile/SrcWriter/Pages.cpp | 9 ++++ PdfFile/SrcWriter/States.cpp | 2 +- 12 files changed, 108 insertions(+), 18 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index 76de8ff5f4d..dcefa78387a 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -149,6 +149,7 @@ void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, cons HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) { return 0; } PdfWriter::CDocument* CPdfWriter::GetDocument() { return NULL; } PdfWriter::CPage* CPdfWriter::GetPage() { return NULL; } +void CPdfWriter::AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex) {} PdfWriter::CImageDict* CPdfWriter::LoadImage(Aggplus::CImage* pImage, BYTE nAlpha) { return NULL; } PdfWriter::CImageDict* CPdfWriter::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) { return NULL; } bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) { return false; } diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index c06269ab1da..94fbfef4d39 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -886,16 +886,6 @@ bool CPdfEditor::EditPage(int nPageIndex) oAnnot.free(); oSubtype.free(); continue; } - else if (oSubtype.isName("FreeText")) - { - //TODO добавление шрифтов FreeText в общий m_pAppAplication чтобы writer мог использовать шрифты из reader - oAnnot.free(); oSubtype.free(); - oTemp.arrayGetNF(nIndex, &oAnnot); - std::map mapFont = pReader->AnnotFonts(&oAnnot); - m_mFonts.insert(mapFont.begin(), mapFont.end()); - DictToCDictObject(&oAnnot, pArray, false, ""); - oAnnot.free(); - } oAnnot.free(); oSubtype.free(); oTemp.arrayGetNF(nIndex, &oAnnot); DictToCDictObject(&oAnnot, pArray, false, ""); @@ -1027,7 +1017,11 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) else if (oType.isName("Polygon") || oType.isName("PolyLine")) pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); else if (oType.isName("FreeText")) + { + std::map mapFont = pReader->AnnotFonts(&oAnnotRef); + m_mFonts.insert(mapFont.begin(), mapFont.end()); pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); + } else if (oType.isName("Caret")) pAnnot = new PdfWriter::CCaretAnnotation(pXref); else if (oType.isName("Popup")) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 9a9c2c5ea73..1ee0dcf8065 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -58,6 +58,7 @@ class CPdfEditor bool IsEditPage() { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} + bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; } }; #endif // BUILDING_WASM_MODULE diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 1aa95b416b9..871259953e4 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -40,6 +40,7 @@ #include "SrcWriter/Font.h" #include "SrcWriter/FontCidTT.h" #include "SrcWriter/FontTT.h" +#include "SrcWriter/Font14.h" #include "SrcWriter/Destination.h" #include "SrcWriter/Field.h" @@ -748,8 +749,16 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned if (m_pFont14) { + bool bNew = false; + m_pFont14->EncodeUnicode(unGid, *pUnicodes, bNew); + if (bNew) + { + TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); + double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; + m_pFont14->AddWidth(dWidth); + } unsigned char* pCodes = new unsigned char[2]; - pCodes[0] = 0; + pCodes[0] = (*pUnicodes >> 8) & 0xFF; pCodes[1] = *pUnicodes & 0xFF; return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; } @@ -2916,7 +2925,10 @@ bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, cons m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - pText->SetFont(m_pFont14 ? m_pFont : m_pFont); + PdfWriter::CFontDict* pFont = m_pFont; + if (m_pFont14) + pFont = m_pFont14; + pText->SetFont(pFont); pText->SetSize(m_oFont.GetSize()); pText->SetColor(m_oBrush.GetColor1()); pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); @@ -2990,7 +3002,8 @@ bool CPdfWriter::GetBaseFont14(const std::wstring& wsFontName, int nBase14) return false; if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, m_oFont.GetSize(), 72, 72)) return false; - m_pFont14 = m_pDocument->CreateFont14((PdfWriter::EStandard14Fonts)nBase14); + PdfWriter::EStandard14Fonts nType = (PdfWriter::EStandard14Fonts)nBase14; + m_pFont14 = m_pDocument->CreateFont14(wsFontPath, lFaceIndex, nType); return !!m_pFont14; } bool CPdfWriter::UpdateFont() diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 7e7e983873f..6909e6d2736 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -785,9 +785,25 @@ namespace PdfWriter return pForm; } - CFont14* CDocument::CreateFont14(EStandard14Fonts eType) + CFont14* CDocument::CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType) { - return new CFont14(m_pXref, this, eType); + CFont14* pFont = FindFont14(wsFontPath, unIndex); + if (pFont) + return pFont; + pFont = new CFont14(m_pXref, this, eType); + m_vFonts14.push_back(TFontInfo(wsFontPath, unIndex, pFont)); + return pFont; + } + CFont14* CDocument::FindFont14(const std::wstring& wsFontPath, unsigned int unIndex) + { + for (int nIndex = 0, nCount = m_vFonts14.size(); nIndex < nCount; nIndex++) + { + TFontInfo& oInfo = m_vFonts14.at(nIndex); + if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) + return (CFont14*)oInfo.pFont; + } + + return NULL; } CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) { diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 1949d27d8f7..6d12ee0fc7c 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -157,7 +157,8 @@ namespace PdfWriter CImageDict* CreateImage(); CXObject* CreateForm(CImageDict* pImage, const std::string& sName); - CFont14* CreateFont14(EStandard14Fonts eType); + CFont14* CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType); + CFont14* FindFont14 (const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); CFontTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); @@ -291,6 +292,7 @@ namespace PdfWriter std::vector m_vShadings; std::vector m_vCidTTFonts; std::vector m_vTTFonts; + std::vector m_vFonts14; CFont14* m_pDefaultCheckBoxFont; CDictObject* m_pTransparencyGroup; std::vector m_vFreeTypeFonts; diff --git a/PdfFile/SrcWriter/Font.h b/PdfFile/SrcWriter/Font.h index 65abf3bd811..444880ad211 100644 --- a/PdfFile/SrcWriter/Font.h +++ b/PdfFile/SrcWriter/Font.h @@ -51,6 +51,10 @@ namespace PdfWriter { return fontUnknownType; } + virtual unsigned int GetWidth(unsigned short ushCode) + { + return 0; + } protected: diff --git a/PdfFile/SrcWriter/Font14.cpp b/PdfFile/SrcWriter/Font14.cpp index 355d61490ab..da847794fb7 100644 --- a/PdfFile/SrcWriter/Font14.cpp +++ b/PdfFile/SrcWriter/Font14.cpp @@ -57,5 +57,46 @@ namespace PdfWriter Add("Type", "Font"); Add("Subtype", "Type1"); Add("BaseFont", c_sStandardFontNames[(int)eType]); + m_ushCodesCount = 0; + } + unsigned int CFont14::GetWidth(unsigned short ushCode) + { + std::map::const_iterator oIter = m_mUnicodeToCode.find(ushCode); + if (oIter == m_mUnicodeToCode.end()) + return 0; + ushCode = oIter->second; + if (ushCode >= m_vWidths.size()) + return 0; + + return m_vWidths.at(ushCode); + } + void CFont14::AddWidth(unsigned int nWidth) + { + m_vWidths.push_back(nWidth); + } + unsigned short CFont14::EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew) + { + std::map::const_iterator oIter = m_mUnicodeToCode.find(unUnicode); + if (oIter != m_mUnicodeToCode.end()) + return oIter->second; + + unsigned short ushCode = EncodeGID(unGID, bNew); + m_mUnicodeToCode.insert(std::pair(unUnicode, ushCode)); + return ushCode; + } + unsigned short CFont14::EncodeGID(const unsigned int& unGID, bool& bNew) + { + for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) + { + if (unGID == m_vCodeToGid.at(ushCurCode)) + return ushCurCode; + } + + unsigned short ushCode = m_ushCodesCount++; + + m_vCodeToGid.push_back(unGID); + bNew = true; + + return ushCode; } } diff --git a/PdfFile/SrcWriter/Font14.h b/PdfFile/SrcWriter/Font14.h index d8c0dbe27cc..89c4a0ee036 100644 --- a/PdfFile/SrcWriter/Font14.h +++ b/PdfFile/SrcWriter/Font14.h @@ -46,6 +46,16 @@ namespace PdfWriter { return fontType1; } + unsigned int GetWidth(unsigned short ushCode); + void AddWidth(unsigned int nWidth); + unsigned short EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode, bool& bNew); + unsigned short EncodeGID(const unsigned int& unGID, bool& bNew); + + private: + unsigned short m_ushCodesCount; + std::map m_mUnicodeToCode; + std::vector m_vCodeToGid; + std::vector m_vWidths; }; } diff --git a/PdfFile/SrcWriter/FontTT.h b/PdfFile/SrcWriter/FontTT.h index 95a19f0cec7..37483c45710 100644 --- a/PdfFile/SrcWriter/FontTT.h +++ b/PdfFile/SrcWriter/FontTT.h @@ -58,7 +58,6 @@ namespace PdfWriter CFontTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex); ~CFontTrueType(); - unsigned int GetWidth(unsigned short ushCode); int GetLineHeight() const { return m_nLineHeight; diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index ba961558976..c347393d139 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1199,6 +1199,15 @@ namespace PdfWriter m_pStream->WriteBinary(sText, unLen, NULL); m_pStream->WriteChar('>'); } + else if (fontType1 == eType) + { + unLen = unLen / 2; + BYTE* sText2 = new BYTE[unLen]; + for (int i = 0; i < unLen; ++i) + sText2[i] = sText[i * 2 + 1]; + m_pStream->WriteEscapeText(sText2, unLen); + RELEASEARRAYOBJECTS(sText2); + } else { m_pStream->WriteEscapeText(sText, unLen); diff --git a/PdfFile/SrcWriter/States.cpp b/PdfFile/SrcWriter/States.cpp index 98d2f220934..a4ce71d84f7 100644 --- a/PdfFile/SrcWriter/States.cpp +++ b/PdfFile/SrcWriter/States.cpp @@ -177,7 +177,7 @@ void CCommandManager::Flush() double dX = pText->GetX(); double dY = pText->GetY(); double dTextSize = pText->GetSize(); - double dWidth = ((PdfWriter::CFontCidTrueType*)pText->GetFont())->GetWidth(ushCode) / 1000.0 * dTextSize; + double dWidth = pText->GetFont()->GetWidth(ushCode) / 1000.0 * dTextSize; if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize)) { From 05366635c14b23bd1ed785211149a2b5c13ab766 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 17 May 2024 18:10:30 +0300 Subject: [PATCH 664/794] Remove development --- DesktopEditor/graphics/commands/AnnotField.h | 3 - PdfFile/PdfEditor.cpp | 62 +++++- PdfFile/PdfFile.cpp | 24 +-- PdfFile/PdfWriter.cpp | 213 ++----------------- PdfFile/PdfWriter.h | 7 +- PdfFile/SrcReader/PdfAnnot.cpp | 11 +- PdfFile/SrcWriter/Annotation.cpp | 133 +----------- PdfFile/SrcWriter/Annotation.h | 7 - PdfFile/SrcWriter/Document.cpp | 1 - PdfFile/SrcWriter/Field.cpp | 19 +- PdfFile/SrcWriter/Field.h | 7 +- PdfFile/SrcWriter/Objects.cpp | 4 +- PdfFile/SrcWriter/Objects.h | 2 +- PdfFile/SrcWriter/States.cpp | 2 +- PdfFile/SrcWriter/States.h | 30 +-- 15 files changed, 117 insertions(+), 408 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 86c018b08f9..5043e1e15a0 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -385,9 +385,6 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector m_arrIC; LONG m_nRenderLen; BYTE* m_pRender; - std::wstring m_sMediaDirectory; - std::wstring m_sInternalMediaDirectory; - std::wstring m_sThemesDirectory; }; class GRAPHICS_DECL CCaretAnnotPr diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 94fbfef4d39..aeb5a9673ec 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -873,8 +873,7 @@ bool CPdfEditor::EditPage(int nPageIndex) else if (strcmp("Annots", chKey) == 0) { // ВРЕМЕНО удаление Link аннотаций при редактировании - pageObj.dictGetVal(nIndex, &oTemp); - if (oTemp.isArray()) + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); pPage->Add("Annots", pArray); @@ -894,11 +893,15 @@ bool CPdfEditor::EditPage(int nPageIndex) oTemp.free(); continue; } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } } else if (strcmp("Contents", chKey) == 0) { - pageObj.dictGetVal(nIndex, &oTemp); - if (oTemp.isArray()) + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) { DictToCDictObject(&oTemp, pPage, true, chKey); oTemp.free(); @@ -1293,12 +1296,63 @@ bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bIt if (it == m_mFonts.end()) return false; wsFontPath = it->second; + if (wsFontName == L"Helvetica") + return true; + if (wsFontName == L"Helvetica-Bold") + { + bBold = true; + return true; + } + if (wsFontName == L"Helvetica-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Helvetice-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } + if (wsFontName == L"Courier") + return true; + if (wsFontName == L"Courier-Bold") + { + bBold = true; + return true; + } if (wsFontName == L"Courier-Oblique") { bItalic = true; return true; } + if (wsFontName == L"Courier-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } + if (wsFontName == L"Times") + return true; + if (wsFontName == L"Times-Bold") + { + bBold = true; + return true; + } + if (wsFontName == L"Times-Oblique") + { + bItalic = true; + return true; + } + if (wsFontName == L"Times-BoldOblique") + { + bBold = true; + bItalic = true; + return true; + } if (wsFontName == L"Symbol") return true; + if (wsFontName == L"ZapfDingbats") + return true; return false; } diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 1ee0dcf8065..f8b19ca312a 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -47,14 +47,17 @@ class CPdfEditor { public: + int GetError() { return 0; } void Close() {} bool EditPage(int nPageIndex) { return false; } + bool DeletePage(int nPageIndex) { return false; } + bool AddPage(int nPageIndex) { return false; } bool EditAnnot(int nPageIndex, int nID) { return false; } bool DeleteAnnot(int nID) { return false; } bool EditWidgets(IAdvancedCommand* pCommand) { return false; } int GetPagesCount() { return 0; } - int GetRotate(int nPageIndex) { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} + int GetRotate(int nPageIndex) { return 0; } bool IsEditPage() { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} @@ -888,19 +891,16 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) wsFontName.erase(0, 10); bool bBold = false, bItalic = false; std::wstring wsFontPath; - if (m_pInternal->pEditor->IsBase14(wsFontName, bBold, bItalic, wsFontPath)) + if (m_pInternal->pEditor->IsBase14(wsFontName, bBold, bItalic, wsFontPath) && (bBold || bItalic)) { - m_pInternal->pWriter->AddFont(wsFontName, bBold, bItalic, wsFontPath, 0); - if (bBold || bItalic) - { - LONG lStyle = 0; - if (bBold) - lStyle |= 1; - if (bItalic) - lStyle |= 2; - put_FontStyle(lStyle); - } + LONG lStyle = 0; + if (bBold) + lStyle |= 1; + if (bItalic) + lStyle |= 2; + put_FontStyle(lStyle); } + m_pInternal->pWriter->AddFont(wsFontName, bBold, bItalic, wsFontPath, 0); } return m_pInternal->pWriter->put_FontName(wsFontName); } diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 871259953e4..6fe26dcc38c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -741,28 +741,6 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned if (!IsPageValid()) return S_FALSE; - if (m_bNeedUpdateTextFont) - { - if (!UpdateFont()) - return NULL; - } - - if (m_pFont14) - { - bool bNew = false; - m_pFont14->EncodeUnicode(unGid, *pUnicodes, bNew); - if (bNew) - { - TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); - double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; - m_pFont14->AddWidth(dWidth); - } - unsigned char* pCodes = new unsigned char[2]; - pCodes[0] = (*pUnicodes >> 8) & 0xFF; - pCodes[1] = *pUnicodes & 0xFF; - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; - } - unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); if (!pCodes) return DrawTextToRenderer(&unGid, 1, dX, dY) ? S_OK : S_FALSE; @@ -2070,24 +2048,6 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pFreeTextAnnot->SetIT(pFTPr->GetIT()); if (nFlags & (1 << 21)) pFreeTextAnnot->SetIC(pFTPr->GetIC()); - /* - std::vector arrRC = pPr->GetRC(); - double dFontSize = 10.0; - if (!arrRC.empty()) - { - dFontSize = arrRC[0]->dFontSise; - std::wstring wsFontName = arrRC[0]->sActualFont.empty() ? arrRC[0]->sFontFamily : arrRC[0]->sActualFont; - if (wsFontName == L"Times-Roman" || wsFontName == L"Times-Bold" || wsFontName == L"Times-BoldItalic" || wsFontName == L"Times-Italic") - wsFontName = L"Times New Roman"; - int nStyle = arrRC[0]->nFontFlag; - put_FontName(wsFontName); - put_FontStyle(nStyle); - put_FontSize(dFontSize); - } - if (m_bNeedUpdateTextFont) - UpdateFont(); - pFreeTextAnnot->SetDA(m_pFont, dFontSize, oInfo.GetC()); - */ if (nFlags & (1 << 22)) { PdfWriter::CPage* pCurPage = m_pPage; @@ -2107,6 +2067,10 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF m_pDocument->SetCurPage(pCurPage); RELEASEOBJECT(pFakePage); } + PdfWriter::CFontDict* pFont = m_pFont; + if (m_pFont14) + pFont = m_pFont14; + pFreeTextAnnot->SetDA(pFont, m_oFont.GetSize(), oInfo.GetC()); } else if (oInfo.IsCaret()) { @@ -3115,7 +3079,7 @@ PdfWriter::CFontCidTrueType* CPdfWriter::GetFont(const std::wstring& wsFontPath, } std::wstring wsFontType = m_pFontManager->GetFontType(); - if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType || L"Type 1" == wsFontType) + if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType) pFont = m_pDocument->CreateCidTrueTypeFont(wsFontPath, lFaceIndex); } @@ -3521,6 +3485,22 @@ unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned i return NULL; } + if (m_pFont14) + { + bool bNew = false; + m_pFont14->EncodeUnicode(unGID, *pUnicodes, bNew); + if (bNew) + { + TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); + double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; + m_pFont14->AddWidth(dWidth); + } + unsigned char* pCodes = new unsigned char[2]; + pCodes[0] = (*pUnicodes >> 8) & 0xFF; + pCodes[1] = *pUnicodes & 0xFF; + return pCodes; + } + if (!m_pFont) return NULL; @@ -3985,154 +3965,3 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit RELEASEARRAYOBJECTS(pCodes); RELEASEARRAYOBJECTS(ppFonts); } -void CPdfWriter::DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC) -{ - pFreeTextAnnot->StartAP(arrC); - - struct CGlypgs - { - unsigned int unLen; - unsigned int* pUnicodes; - unsigned short* pCodes; - PdfWriter::CFontCidTrueType** ppFonts; - double dFontSize; - BYTE nAlign; - unsigned int unStart; - PdfWriter::CFontTrueType* pFontTT; - double dR; - double dG; - double dB; - }; - - std::vector arrGlyphs; - - double dWidth = pFreeTextAnnot->GetRect().fRight - pFreeTextAnnot->GetRect().fLeft - pFreeTextAnnot->GetRD().fRight - pFreeTextAnnot->GetRD().fLeft; - double dHeight = pFreeTextAnnot->GetRect().fTop - pFreeTextAnnot->GetRect().fBottom - pFreeTextAnnot->GetRD().fTop - pFreeTextAnnot->GetRD().fBottom; - double dShiftBorder = pFreeTextAnnot->GetBorderWidth(); - - unsigned int unAllLen = 0; - for (int i = 0; i < arrRC.size(); ++i) - { - bool isBold = (arrRC[i]->nFontFlag >> 0) & 1; - bool isItalic = (arrRC[i]->nFontFlag >> 1) & 1; - PdfWriter::CFontCidTrueType* pFont = GetFont(arrRC[i]->sActualFont.empty() ? arrRC[i]->sFontFamily : arrRC[i]->sActualFont, isBold, isItalic); - if (!pFont) - continue; - - unsigned int unLen = 0; - unsigned int* pUnicodes = NULL; - unsigned short* pCodes = NULL; - PdfWriter::CFontCidTrueType** ppFonts = NULL; - bool bFont = GetFontData(pAppFonts, arrRC[i]->sText, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); - if (!bFont) - { - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); - continue; - } - - arrGlyphs.push_back({unLen, pUnicodes, pCodes, ppFonts, arrRC[i]->dFontSise, arrRC[i]->nAlignment, unAllLen, m_pDocument->CreateTrueTypeFont(pFont), - arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2]}); - unAllLen += unLen; - } - - unsigned short* pCodes2 = new unsigned short[unAllLen]; - unsigned int* pWidths = new unsigned int[unAllLen]; - double* pFontSizes = new double[unAllLen]; - - unsigned short ushSpaceCode = 0xFFFF; - unsigned short ushNewLineCode = 0xFFFE; - unsigned int unIndexI = 0; - - for (int i = 0; i < arrGlyphs.size(); ++i) - { - for (unsigned int unIndex = 0; unIndex < arrGlyphs[i].unLen; ++unIndex) - { - unsigned short ushCode = 0; - if (0x0020 == arrGlyphs[i].pUnicodes[unIndex]) - ushCode = ushSpaceCode; - else if (0x000D == arrGlyphs[i].pUnicodes[unIndex] || 0x000A == arrGlyphs[i].pUnicodes[unIndex]) - ushCode = ushNewLineCode; - - pCodes2[unIndexI] = ushCode; - pWidths[unIndexI] = arrGlyphs[i].ppFonts[unIndex]->GetWidth(arrGlyphs[i].pCodes[unIndex]); - pFontSizes[unIndexI] = arrGlyphs[i].dFontSize; - unIndexI++; - } - } - - m_oLinesManager.Init(pCodes2, pFontSizes, pWidths, unAllLen, ushSpaceCode, ushNewLineCode); - m_oLinesManager.CalculateLines(0, dWidth); - - unsigned int unLinesCount = m_oLinesManager.GetLinesCount(), unIndex = 0; - double _dLineShiftX = 0, dLineShiftY = dHeight + pFreeTextAnnot->GetRect().fBottom + pFreeTextAnnot->GetRD().fBottom - dShiftBorder * 2 - m_oLinesManager.GetLineHeight(0); - for (int i = 0; i < arrGlyphs.size(); ++i) - { - BYTE nAlign = arrGlyphs[i].nAlign; - dLineShiftY -= (arrGlyphs[i].pFontTT->m_dAscent + std::abs(arrGlyphs[i].pFontTT->m_dDescent)) * arrGlyphs[i].dFontSize / arrGlyphs[i].pFontTT->m_dUnitsPerEm; - // double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; - - double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - double dLineWidth = m_oLinesManager.GetLineWidth(unIndex); - if (2 == nAlign) - dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - else if (1 == nAlign) - dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - - int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); - if (nInLineCount > 0) - pFreeTextAnnot->AddTextToAP(arrGlyphs[i].dFontSize, dLineShiftX, dLineShiftY, arrGlyphs[i].pCodes, arrGlyphs[i].unLen, arrGlyphs[i].dR, arrGlyphs[i].dG, arrGlyphs[i].dB, arrGlyphs[i].ppFonts, NULL); - - unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); - while (unIndex < unLinesCount && unLineStart < arrGlyphs[i].unStart + arrGlyphs[i].unLen) - { - unLineStart = m_oLinesManager.GetLineStartPos(++unIndex); - dLineShiftY -= m_oLinesManager.GetLineHeight(unIndex); - } - } - - /* - for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) - { - unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); - BYTE nAlign = 0; - while (unPos < arrGlyphs.size() && unLineStart < arrGlyphs[unPos].unStart + arrGlyphs[unPos].unLen) - unPos++; - - //double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; - double dLineHeight = m_oLinesManager.GetLineHeight(unIndex); //(pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; - double dLineShiftY = _dLineShiftY - dLineHeight; - - double dLineShiftX = dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - double dLineWidth = m_oLinesManager.GetLineWidth(unIndex); - if (2 == nAlign) - dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - else if (1 == nAlign) - dLineShiftX = (dWidth - dLineWidth) / 2 + pFreeTextAnnot->GetRect().fLeft + pFreeTextAnnot->GetRD().fLeft; - - int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); - if (nInLineCount > 0) - pFreeTextAnnot->AddTextToAP(dFontSize, dLineShiftX, dLineShiftY, pCodes2 + unLineStart, nInLineCount, arrRC[i]->dColor[0], arrRC[i]->dColor[1], arrRC[i]->dColor[2], ppFonts + unLineStart, NULL); - - dLineShiftY -= dLineHeight; - - // TODO зачеркнутый, подчеркнутый текст, верхний и нижний регистр - } - */ - - m_oLinesManager.Clear(); - - RELEASEARRAYOBJECTS(pCodes2); - RELEASEARRAYOBJECTS(pWidths); - RELEASEARRAYOBJECTS(pFontSizes); - - for (int i = 0; i < arrGlyphs.size(); ++i) - { - RELEASEARRAYOBJECTS(arrGlyphs[i].pUnicodes); - RELEASEARRAYOBJECTS(arrGlyphs[i].pCodes); - RELEASEARRAYOBJECTS(arrGlyphs[i].ppFonts); - } - - pFreeTextAnnot->EndAP(); -} diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 89ae16d7d85..8cbe0301f7c 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -245,10 +245,9 @@ class CPdfWriter unsigned char* EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs = NULL); unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); - void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); - void DrawChoiceWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); - void DrawButtonWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); - void DrawFreeTextAnnot(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CFreeTextAnnotation* pFreeTextAnnot, const std::vector& arrRC, const std::vector& arrC); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); + void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm); private: NSFonts::IFontManager* m_pFontManager; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 44121b57c56..75a291d83fe 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2390,12 +2390,9 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object bool bBold = false, bItalic = false; std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); std::wstring wsFontName = UTF8_TO_U(sFontName); + oFontRef.free(); if (sFontPath.empty()) - { - oFontRef.free(); continue; - } - oFontRef.free(); if (isBaseFont(sFontPath)) continue; @@ -2419,12 +2416,6 @@ std::map AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object if (bNew) pAppFontList->Add(sFontPath, pFontStream); } - else - { - pFontStream = NSFonts::NSStream::Create(); - if (pFontStream->CreateFromFile(sFontPath)) - pAppFontList->Add(sFontPath, pFontStream); - } arrFontFreeText[wsFontName] = sFontPath; } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 592daceb9a9..dce678418e9 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -132,7 +132,6 @@ namespace PdfWriter sDA.append(bCaps ? "K" : "k"); else if (arr.size() == 1) sDA.append(bCaps ? "G" : "g"); - return sDA; } std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) @@ -917,7 +916,7 @@ namespace PdfWriter } } } - void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLX = 0, double dLY = 0, double dLL = 0, double dLLO = 0, double dLLE = 0) + void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) { double dDX = x2 - x1; double dDY = y2 - y1; @@ -971,8 +970,6 @@ namespace PdfWriter SreamWriteXYMove(pStream, tx1, ty1); SreamWriteXYLine(pStream, tx2, ty2); - if (dLX && dLY) - SreamWriteXYLine(pStream, dLX, dLY); pStream->WriteStr("S\012"); DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); @@ -1051,7 +1048,7 @@ namespace PdfWriter if (pObj && pObj->GetType() == object_type_REAL) dLLO = ((CRealObject*)pObj)->Get(); - DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, 0, 0, dLL, dLLE, dLLO); + DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); } //---------------------------------------------------------------------------------------- // CPopupAnnotation @@ -1072,123 +1069,6 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText) { - m_nIT = 0; - m_nLE = ELineEndType::None; - m_pAppearance = NULL; - } - void CFreeTextAnnotation::StartAP(const std::vector& arrC) - { - m_pAppearance = new CAnnotAppearance(m_pXref, this); - if (!m_pAppearance) - return; - Add("AP", m_pAppearance); - CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); - CStream* pStream = pNormal->GetStream(); - - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - pNormal->Add("BBox", pArray); - - pArray->Add(GetRect().fLeft); - pArray->Add(GetRect().fBottom); - pArray->Add(GetRect().fRight); - pArray->Add(GetRect().fTop); - - pArray = new CArrayObject(); - if (!pArray) - return; - - pNormal->Add("Matrix", pArray); - pArray->Add(1); - pArray->Add(0); - pArray->Add(0); - pArray->Add(1); - pArray->Add(-GetRect().fLeft); - pArray->Add(-GetRect().fBottom); - - if (GetBorderType() == EBorderType::Dashed) - pStream->WriteStr(GetBorderDash().c_str()); - - double dBorderSize = GetBorderWidth(); - pStream->WriteReal(dBorderSize); - pStream->WriteStr(" w\012"); - - CObjectBase* pObj = Get("C"); - if (pObj && pObj->GetType() == object_type_ARRAY) - { - pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); - pStream->WriteStr("\012"); - } - - pStream->WriteStr(GetColor(arrC, true).c_str()); - pStream->WriteStr("\012"); - - pObj = Get("CA"); - if (pObj && pObj->GetType() == object_type_REAL) - { - float dAlpha = ((CRealObject*)pObj)->Get(); - if (dAlpha != 1) - { - CExtGrState* pExtGrState = m_pDocument->GetExtGState(dAlpha, dAlpha); - const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); - if (sExtGrStateName) - { - pStream->WriteEscapeName(sExtGrStateName); - pStream->WriteStr(" gs\012"); - } - } - } - - // TODO Облачная граница - - pObj = Get("CL"); - if (m_nIT == 1 && pObj && pObj->GetType() == object_type_ARRAY) - { - CArrayObject* pArr = (CArrayObject*)pObj; - double dLX = 0, dLY = 0; - if (pArr->GetCount() == 6) - { - dLX = ((CRealObject*)(pArr->Get(4)))->Get(); - dLY = ((CRealObject*)(pArr->Get(5)))->Get(); - } - DrawLineArrow(pStream, dBorderSize, ((CRealObject*)(pArr->Get(0)))->Get(), ((CRealObject*)(pArr->Get(1)))->Get(), - ((CRealObject*)(pArr->Get(2)))->Get(), ((CRealObject*)(pArr->Get(3)))->Get(), m_nLE, ELineEndType::None, dLX, dLY); - } - - StreamWriteRect(pStream, GetRect().fLeft + m_oRD.fLeft + dBorderSize / 2, - GetRect().fBottom + m_oRD.fBottom + dBorderSize / 2, - GetRect().fRight - GetRect().fLeft - m_oRD.fRight - m_oRD.fLeft - dBorderSize, - GetRect().fTop - GetRect().fBottom - m_oRD.fBottom - m_oRD.fTop - dBorderSize); - pStream->WriteStr("B\012q\0121 0 0 1 0 0 cm\012"); - StreamWriteRect(pStream, GetRect().fLeft + m_oRD.fLeft + dBorderSize * 2, - GetRect().fBottom + m_oRD.fBottom + dBorderSize * 2, - GetRect().fRight - GetRect().fLeft - m_oRD.fRight - m_oRD.fLeft - dBorderSize * 4, - GetRect().fTop - GetRect().fBottom - m_oRD.fBottom - m_oRD.fTop - dBorderSize * 4); - pStream->WriteStr("W\012n\0120 g\0120 G\0121 w\012BT\012"); - } - void CFreeTextAnnotation::EndAP() - { - if (!m_pAppearance) - return; - CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); - pNormal->EndText(); - pNormal->EndDraw(); - } - void CFreeTextAnnotation::AddTextToAP(double dFontSize, const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, double dR, double dG, double dB, CFontCidTrueType** ppFonts, const double* pShifts) - { - if (!m_pAppearance) - return; - CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); - CStream* pStream = pNormal->GetStream(); - pNormal->SetFontSize(dFontSize); - pStream->WriteStr(std::to_string(dR).c_str()); - pStream->WriteChar(' '); - pStream->WriteStr(std::to_string(dG).c_str()); - pStream->WriteChar(' '); - pStream->WriteStr(std::to_string(dB).c_str()); - pStream->WriteStr(" rg\012"); - pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts); } void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC) { @@ -1208,10 +1088,6 @@ namespace PdfWriter Add("DA", new CStringObject(sDA.c_str())); } - TRect& CFreeTextAnnotation::GetRD() - { - return m_oRD; - } void CFreeTextAnnotation::SetQ(BYTE nQ) { Add("Q", (int)nQ); @@ -1231,12 +1107,10 @@ namespace PdfWriter } Add("IT", sValue.c_str()); - m_nIT = nIT; } void CFreeTextAnnotation::SetLE(BYTE nLE) { Add("LE", AddLE(nLE).c_str()); - m_nLE = ELineEndType(nLE); } void CFreeTextAnnotation::SetDS(const std::wstring& wsDS) { @@ -1246,7 +1120,6 @@ namespace PdfWriter void CFreeTextAnnotation::SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4) { AddRD(this, dRD1, dRD2, dRD3, dRD4); - m_oRD = { dRD1, dRD2, dRD3, dRD4 }; } void CFreeTextAnnotation::SetCL(const std::vector& arrCL) { @@ -1297,7 +1170,7 @@ namespace PdfWriter pArray->Add(-GetRect().fBottom); CDictObject* pFPStream = pFakePage->GetContent(); - pNormal->SetStream(m_pXref, pFPStream->GetStream(), false, ((CNumberObject*)pFPStream->Get("Length"))->Get()); + pNormal->SetStream(m_pXref, pFPStream->GetStream(), false); pFPStream->SetStream(NULL); // RELEASEOBJECT(pFPStream); Нельзя удалять - это объект стрима, он уже в xref } diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index e2bd4f7c08c..c91c89587a3 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -350,9 +350,6 @@ namespace PdfWriter class CFreeTextAnnotation : public CMarkupAnnotation { private: - BYTE m_nIT; - ELineEndType m_nLE; - TRect m_oRD; CAnnotAppearance* m_pAppearance; public: @@ -363,11 +360,7 @@ namespace PdfWriter } void APFromFakePage(CPage* pFakePage); - void StartAP(const std::vector& arrC); - void EndAP(); void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector& arrC); - void AddTextToAP(double dFontSize, const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, double dR, double dG, double dB, CFontCidTrueType** ppFonts = NULL, const double* pShifts = NULL); - TRect& GetRD(); void SetQ(BYTE nQ); void SetIT(BYTE nIT); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 6909e6d2736..08b1091e13c 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -802,7 +802,6 @@ namespace PdfWriter if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) return (CFont14*)oInfo.pFont; } - return NULL; } CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 0aba1bda8fd..768d63e4d8d 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1537,16 +1537,15 @@ namespace PdfWriter m_pRollover = NULL; m_pDown = NULL; } - CAnnotAppearanceObject* CAnnotAppearance::GetNormal(CResourcesDict* pResources) + CAnnotAppearanceObject* CAnnotAppearance::GetNormal() { if (!m_pNormal) { if (m_pField) m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); - if (m_pXref) - Add("N", m_pNormal); + m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot); + Add("N", m_pNormal); } return m_pNormal; @@ -1622,15 +1621,13 @@ namespace PdfWriter void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { m_pXref = pXref ? pXref : NULL; + m_pStream = new CMemoryStream(); m_pFont = NULL; m_dFontSize = 10.0; m_bStart = true; if (m_pXref) - { - m_pStream = new CMemoryStream(); SetStream(m_pXref, m_pStream); - } Add("Type", "XObject"); Add("Subtype", "Form"); @@ -1652,9 +1649,9 @@ namespace PdfWriter pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); } - CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot) { - Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); + Init(pXRef, pAnnot->GetDocument()->GetFieldsResources()); m_pAnnot = pAnnot; m_pField = NULL; @@ -2821,8 +2818,4 @@ namespace PdfWriter m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); } - void CAnnotAppearanceObject::StartDrawFreeText(const std::string& sColor) - { - - } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 1c74f9b9585..6280a8d038f 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -344,7 +344,7 @@ namespace PdfWriter CAnnotAppearance(CXref* pXRef, CFieldBase* pField); CAnnotAppearance(CXref* pXRef, CAnnotation* pAnnot); - CAnnotAppearanceObject* GetNormal(CResourcesDict* pResources = NULL); + CAnnotAppearanceObject* GetNormal(); CAnnotAppearanceObject* GetRollover(); CAnnotAppearanceObject* GetDown(); @@ -382,7 +382,7 @@ namespace PdfWriter { public: CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); - CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources = NULL); + CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot); void DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize = 10.0, double dX = 0.0, double dY = 0.0, double dR = 0.0, double dG = 0.0, double dB = 0.0, const char* sExtGrStateName = NULL, double dW = 1.0, double dH = 1.0, CFontCidTrueType** ppFonts = NULL, double* pShifts = NULL); void DrawPicture(const char* sImageName = NULL, const double& dX = 0.0, const double& dY = 0.0, const double& dW = 0.0, const double& dH = 0.0, const bool& bRespectBorder = false); void StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight); @@ -416,10 +416,7 @@ namespace PdfWriter void DrawTextUpArrow(const std::string& sColor); void DrawTextUpLeftArrow(const std::string& sColor); - void StartDrawFreeText(const std::string& sColor); - CStream* GetStream() { return m_pStream; } - void SetFontSize(double dFontSize) { m_dFontSize = dFontSize; } bool m_bStart; diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index a2989cab7bd..1522834b98f 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -655,14 +655,14 @@ namespace PdfWriter { m_pStream = pStream; } - void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis, int nLength) + void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis) { if (m_pStream) delete m_pStream; if (!Get("Length")) { - CNumberObject* pLength = new CNumberObject(nLength); + CNumberObject* pLength = new CNumberObject(0); // Только stream object добавляются в таблицу xref автоматически if (bThis) diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index e259ccd70cd..4a9a28a0abc 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -469,7 +469,7 @@ namespace PdfWriter { m_unFilter = unFiler; } - void SetStream(CXref* pXref, CStream* pStream, bool bThis = true, int nLength = 0); + void SetStream(CXref* pXref, CStream* pStream, bool bThis = true); virtual void BeforeWrite(){} virtual void Write(CStream* pStream){} diff --git a/PdfFile/SrcWriter/States.cpp b/PdfFile/SrcWriter/States.cpp index a4ce71d84f7..2e8d5363122 100644 --- a/PdfFile/SrcWriter/States.cpp +++ b/PdfFile/SrcWriter/States.cpp @@ -177,7 +177,7 @@ void CCommandManager::Flush() double dX = pText->GetX(); double dY = pText->GetY(); double dTextSize = pText->GetSize(); - double dWidth = pText->GetFont()->GetWidth(ushCode) / 1000.0 * dTextSize; + double dWidth = pText->GetFont()->GetWidth(ushCode) / 1000.0 * dTextSize; if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize)) { diff --git a/PdfFile/SrcWriter/States.h b/PdfFile/SrcWriter/States.h index e197eabaf68..d9b84243826 100644 --- a/PdfFile/SrcWriter/States.h +++ b/PdfFile/SrcWriter/States.h @@ -1500,7 +1500,6 @@ class CMultiLineTextManager CMultiLineTextManager() { m_pCodes = NULL; - m_pFontSizes = NULL; m_pWidths = NULL; m_unLen = 0; m_ushSpaceCode = 0; @@ -1519,19 +1518,9 @@ class CMultiLineTextManager m_nAscent = nAscent; m_nDescent = unLineHeight - nAscent; } - void Init(unsigned short* pCodes, double* pFontSizes, unsigned int* pWidths, const unsigned int& unLen, const unsigned short& ushSpaceCode, const unsigned short& ushNewLineCode) - { - m_pCodes = pCodes; - m_pFontSizes = pFontSizes; - m_pWidths = pWidths; - m_unLen = unLen; - m_ushSpaceCode = ushSpaceCode; - m_ushNewLineCode = ushNewLineCode; - } void Clear() { m_pCodes = NULL; - m_pFontSizes = NULL; m_pWidths = NULL; m_unLen = 0; m_ushSpaceCode = 0; @@ -1554,7 +1543,7 @@ class CMultiLineTextManager { if (IsSpace(unPos)) { - dX += dWordWidth + m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); + dX += dWordWidth + m_pWidths[unPos] * dKoef; bWord = false; dWordWidth = 0; bLineStart = false; @@ -1571,7 +1560,7 @@ class CMultiLineTextManager } else { - double dLetterWidth = m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); + double dLetterWidth = m_pWidths[unPos] * dKoef; if (dX + dWordWidth + dLetterWidth > dW) { if (bLineStart) @@ -1611,13 +1600,13 @@ class CMultiLineTextManager if (bWord) { - dWordWidth += m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); + dWordWidth += m_pWidths[unPos] * dKoef; } else { unWordStartPos = unPos; bWord = true; - dWordWidth = m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); + dWordWidth = m_pWidths[unPos] * dKoef; } bFirstItemOnLine = false; @@ -1626,7 +1615,7 @@ class CMultiLineTextManager unPos++; } } - double ProcessAutoFit(const double& dW, const double& dH) + double ProcessAutoFit(const double& dW, const double& dH) { double dGoodFontSize = 0; @@ -1687,11 +1676,7 @@ class CMultiLineTextManager return unLineEnd; } - double GetLineHeight(const double& dFontSize = 10.0) - { - return 0; - } - double GetLineWidth(const int& nLineIndex, const double& dFontSize = 10.0) + double GetLineWidth(const int& nLineIndex, const double& dFontSize = 10.0) { if (nLineIndex < 0 || nLineIndex > m_vBreaks.size()) return 0; @@ -1720,7 +1705,7 @@ class CMultiLineTextManager for (unsigned int unPos = unStart; unPos < unEnd; ++unPos) { - dWidth += m_pWidths[unPos] * (m_pFontSizes ? m_pFontSizes[unPos] / 1000.0 : dKoef); + dWidth += m_pWidths[unPos] * dKoef; } return dWidth; @@ -1743,7 +1728,6 @@ class CMultiLineTextManager private: unsigned short* m_pCodes; - double* m_pFontSizes; unsigned int* m_pWidths; unsigned int m_unLen; unsigned short m_ushSpaceCode; From 4c101b21d0e37afc480ed3470241da94dd2d6e03 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 22:07:17 +0400 Subject: [PATCH 665/794] Changed lines ending for consistency --- .../src/docbuilder_func_lib.pro | 56 +- .../src/docbuilder_functions.cpp | 788 +++++++++--------- .../src/docbuilder_functions.h | 268 +++--- .../test/docbuilder_func_test.pro | 55 +- .../docbuilder.python/test/main.cpp | 148 ++-- 5 files changed, 657 insertions(+), 658 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro index f48067b5416..03fdfc203ab 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro @@ -1,28 +1,28 @@ -QT -= core -QT -= gui - -TARGET = docbuilder_functions - -TEMPLATE = lib - -CONFIG += shared -CONFIG += plugin - -CORE_ROOT_DIR = $$PWD/../../../.. -PWD_ROOT_DIR = $$PWD - -include($$CORE_ROOT_DIR/Common/base.pri) - -ADD_DEPENDENCY(doctrenderer) - -DESTDIR = $$PWD/build - -INCLUDEPATH += ../.. - -DEFINES += DOCBUILDER_FUNCTIONS_EXPORT - -SOURCES += \ - docbuilder_functions.cpp - -HEADERS += \ - docbuilder_functions.h +QT -= core +QT -= gui + +TARGET = docbuilder_functions + +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(doctrenderer) + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +DEFINES += DOCBUILDER_FUNCTIONS_EXPORT + +SOURCES += \ + docbuilder_functions.cpp + +HEADERS += \ + docbuilder_functions.h diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp index 645b71811c5..b9aab0f4178 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -1,394 +1,394 @@ -#include "docbuilder_functions.h" - -#include - -// ===== CDocBuilderValue ===== -CDocBuilderValue* CDocBuilderValue_Create() -{ - return new CDocBuilderValue(); -} - -CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other) -{ - return new CDocBuilderValue(*other); -} - -void CDocBuilderValue_Destroy(CDocBuilderValue* self) -{ - delete self; -} - -bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self) -{ - return self->IsEmpty(); -} - -void CDocBuilderValue_Clear(CDocBuilderValue* self) -{ - self->Clear(); -} - -bool CDocBuilderValue_IsNull(CDocBuilderValue* self) -{ - return self->IsNull(); -} - -bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self) -{ - return self->IsUndefined(); -} - -bool CDocBuilderValue_IsInt(CDocBuilderValue* self) -{ - return self->IsInt(); -} - -bool CDocBuilderValue_IsDouble(CDocBuilderValue* self) -{ - return self->IsDouble(); -} - -bool CDocBuilderValue_IsString(CDocBuilderValue* self) -{ - return self->IsString(); -} - -bool CDocBuilderValue_IsFunction(CDocBuilderValue* self) -{ - return self->IsFunction(); -} - -bool CDocBuilderValue_IsObject(CDocBuilderValue* self) -{ - return self->IsObject(); -} - -bool CDocBuilderValue_IsArray(CDocBuilderValue* self) -{ - return self->IsArray(); -} - -unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self) -{ - return self->GetLength(); -} - -bool CDocBuilderValue_ToBool(CDocBuilderValue* self) -{ - return self->ToBool(); -} - -int CDocBuilderValue_ToInt(CDocBuilderValue* self) -{ - return self->ToInt(); -} - -double CDocBuilderValue_ToDouble(CDocBuilderValue* self) -{ - return self->ToDouble(); -} - -const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self) -{ - // NOTE: User is responsible for calling DeleteWCharP() on returned pointer - CString strValue = self->ToString(); - size_t len = wcslen(strValue.c_str()); - wchar_t* strRes = new wchar_t[len + 1]; - memcpy(strRes, strValue.c_str(), (len + 1) + sizeof(wchar_t)); - return strRes; -} - -CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name) -{ - return new CDocBuilderValue(self->GetProperty(name)); -} - -CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index) -{ - return new CDocBuilderValue(self->Get(index)); -} - -void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value) -{ - self->Set(name, *value); -} - -void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value) -{ - self->Set(index, *value); -} - -CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value) -{ - return new CDocBuilderValue(value); -} - -CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value) -{ - return new CDocBuilderValue(value); -} - -CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value) -{ - return new CDocBuilderValue(value); -} - -CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value) -{ - return new CDocBuilderValue(value); -} - -CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value) -{ - return new CDocBuilderValue(value); -} - -CDocBuilderValue* CDocBuilderValue_CreateUndefined() -{ - return new CDocBuilderValue(CDocBuilderValue::CreateUndefined()); -} - -CDocBuilderValue* CDocBuilderValue_CreateNull() -{ - return new CDocBuilderValue(CDocBuilderValue::CreateNull()); -} - -CDocBuilderValue* CDocBuilderValue_CreateArray(int length) -{ - return new CDocBuilderValue(CDocBuilderValue::CreateArray(length)); -} - -CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name) -{ - return new CDocBuilderValue(self->Call(name)); -} - -CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1) -{ - return new CDocBuilderValue(self->Call(name, *p1)); -} - -CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2) -{ - return new CDocBuilderValue(self->Call(name, *p1, *p2)); -} - -CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3) -{ - return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3)); -} - -CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4) -{ - return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4)); -} - -CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5) -{ - return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5)); -} - -CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6) -{ - return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5, *p6)); -} - -// ===== CDocBuilder ===== -CDocBuilder* CDocBuilder_Create() -{ - return new CDocBuilder(); -} - -void CDocBuilder_Destroy(CDocBuilder* self) -{ - delete self; -} - -int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params) -{ - return self->OpenFile(path, params); -} - -bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type) -{ - return self->CreateFile(type); -} - -bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension) -{ - return self->CreateFile(extension); -} - -void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder) -{ - self->SetTmpFolder(folder); -} - -int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path) -{ - return self->SaveFile(type, path); -} - -int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params) -{ - return self->SaveFile(type, path, params); -} - -int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path) -{ - return self->SaveFile(extension, path); -} - -int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params) -{ - return self->SaveFile(extension, path, params); -} - -void CDocBuilder_CloseFile(CDocBuilder* self) -{ - self->CloseFile(); -} - -bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command) -{ - return self->ExecuteCommand(command); -} - -bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue) -{ - return self->ExecuteCommand(command, retValue); -} - -bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path) -{ - return self->Run(path); -} - -bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands) -{ - return self->RunTextW(commands); -} - -void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value) -{ - self->SetPropertyW(param, value); -} - -void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append) -{ - self->WriteData(path, value, append); -} - -bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self) -{ - return self->IsSaveWithDoctrendererMode(); -} - -char* CDocBuilder_GetVersion(CDocBuilder* self) -{ - // NOTE: User is responsible for calling DeleteCharP() on returned pointer - return self->GetVersion(); -} - -CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self) -{ - return new CDocBuilderContext(self->GetContext()); -} - -void CDocBuilder_Initialize() -{ - CDocBuilder::Initialize(); -} - -void CDocBuilder_InitializeWithDirectory(const wchar_t* directory) -{ - CDocBuilder::Initialize(directory); -} - -void CDocBuilder_Dispose() -{ - CDocBuilder::Dispose(); -} - -// ===== CDocBuilderContextScope ===== -CDocBuilderContextScope* CDocBuilderContextScope_Create() -{ - return new CDocBuilderContextScope(); -} - -CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other) -{ - return new CDocBuilderContextScope(*other); -} - -void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self) -{ - delete self; -} - -void CDocBuilderContextScope_Close(CDocBuilderContextScope* self) -{ - self->Close(); -} - -// ===== CDocBuilderContext ===== -CDocBuilderContext* CDocBuilderContext_Create() -{ - return new CDocBuilderContext(); -} - -CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other) -{ - return new CDocBuilderContext(*other); -} - -void CDocBuilderContext_Destroy(CDocBuilderContext* self) -{ - delete self; -} - -CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self) -{ - return new CDocBuilderValue(self->CreateUndefined()); -} - -CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self) -{ - return new CDocBuilderValue(self->CreateNull()); -} - -CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self) -{ - return new CDocBuilderValue(self->CreateObject()); -} - -CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length) -{ - return new CDocBuilderValue(self->CreateArray(length)); -} - -CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self) -{ - return new CDocBuilderValue(self->GetGlobal()); -} - -CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self) -{ - return new CDocBuilderContextScope(self->CreateScope()); -} - -bool CDocBuilderContext_IsError(CDocBuilderContext* self) -{ - return self->IsError(); -} - -// ===== Utility ===== -void DeleteWCharP(wchar_t* str) -{ - delete[] str; -} - -void DeleteCharP(char* str) -{ - delete[] str; -} +#include "docbuilder_functions.h" + +#include + +// ===== CDocBuilderValue ===== +CDocBuilderValue* CDocBuilderValue_Create() +{ + return new CDocBuilderValue(); +} + +CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other) +{ + return new CDocBuilderValue(*other); +} + +void CDocBuilderValue_Destroy(CDocBuilderValue* self) +{ + delete self; +} + +bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self) +{ + return self->IsEmpty(); +} + +void CDocBuilderValue_Clear(CDocBuilderValue* self) +{ + self->Clear(); +} + +bool CDocBuilderValue_IsNull(CDocBuilderValue* self) +{ + return self->IsNull(); +} + +bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self) +{ + return self->IsUndefined(); +} + +bool CDocBuilderValue_IsInt(CDocBuilderValue* self) +{ + return self->IsInt(); +} + +bool CDocBuilderValue_IsDouble(CDocBuilderValue* self) +{ + return self->IsDouble(); +} + +bool CDocBuilderValue_IsString(CDocBuilderValue* self) +{ + return self->IsString(); +} + +bool CDocBuilderValue_IsFunction(CDocBuilderValue* self) +{ + return self->IsFunction(); +} + +bool CDocBuilderValue_IsObject(CDocBuilderValue* self) +{ + return self->IsObject(); +} + +bool CDocBuilderValue_IsArray(CDocBuilderValue* self) +{ + return self->IsArray(); +} + +unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self) +{ + return self->GetLength(); +} + +bool CDocBuilderValue_ToBool(CDocBuilderValue* self) +{ + return self->ToBool(); +} + +int CDocBuilderValue_ToInt(CDocBuilderValue* self) +{ + return self->ToInt(); +} + +double CDocBuilderValue_ToDouble(CDocBuilderValue* self) +{ + return self->ToDouble(); +} + +const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self) +{ + // NOTE: User is responsible for calling DeleteWCharP() on returned pointer + CString strValue = self->ToString(); + size_t len = wcslen(strValue.c_str()); + wchar_t* strRes = new wchar_t[len + 1]; + memcpy(strRes, strValue.c_str(), (len + 1) + sizeof(wchar_t)); + return strRes; +} + +CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->GetProperty(name)); +} + +CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index) +{ + return new CDocBuilderValue(self->Get(index)); +} + +void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value) +{ + self->Set(name, *value); +} + +void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value) +{ + self->Set(index, *value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value) +{ + return new CDocBuilderValue(value); +} + +CDocBuilderValue* CDocBuilderValue_CreateUndefined() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderValue_CreateNull() +{ + return new CDocBuilderValue(CDocBuilderValue::CreateNull()); +} + +CDocBuilderValue* CDocBuilderValue_CreateArray(int length) +{ + return new CDocBuilderValue(CDocBuilderValue::CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name) +{ + return new CDocBuilderValue(self->Call(name)); +} + +CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1) +{ + return new CDocBuilderValue(self->Call(name, *p1)); +} + +CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2)); +} + +CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3)); +} + +CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4)); +} + +CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5)); +} + +CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6) +{ + return new CDocBuilderValue(self->Call(name, *p1, *p2, *p3, *p4, *p5, *p6)); +} + +// ===== CDocBuilder ===== +CDocBuilder* CDocBuilder_Create() +{ + return new CDocBuilder(); +} + +void CDocBuilder_Destroy(CDocBuilder* self) +{ + delete self; +} + +int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params) +{ + return self->OpenFile(path, params); +} + +bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type) +{ + return self->CreateFile(type); +} + +bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension) +{ + return self->CreateFile(extension); +} + +void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder) +{ + self->SetTmpFolder(folder); +} + +int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path) +{ + return self->SaveFile(type, path); +} + +int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(type, path, params); +} + +int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path) +{ + return self->SaveFile(extension, path); +} + +int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params) +{ + return self->SaveFile(extension, path, params); +} + +void CDocBuilder_CloseFile(CDocBuilder* self) +{ + self->CloseFile(); +} + +bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command) +{ + return self->ExecuteCommand(command); +} + +bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue) +{ + return self->ExecuteCommand(command, retValue); +} + +bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path) +{ + return self->Run(path); +} + +bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands) +{ + return self->RunTextW(commands); +} + +void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value) +{ + self->SetPropertyW(param, value); +} + +void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append) +{ + self->WriteData(path, value, append); +} + +bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self) +{ + return self->IsSaveWithDoctrendererMode(); +} + +char* CDocBuilder_GetVersion(CDocBuilder* self) +{ + // NOTE: User is responsible for calling DeleteCharP() on returned pointer + return self->GetVersion(); +} + +CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self) +{ + return new CDocBuilderContext(self->GetContext()); +} + +void CDocBuilder_Initialize() +{ + CDocBuilder::Initialize(); +} + +void CDocBuilder_InitializeWithDirectory(const wchar_t* directory) +{ + CDocBuilder::Initialize(directory); +} + +void CDocBuilder_Dispose() +{ + CDocBuilder::Dispose(); +} + +// ===== CDocBuilderContextScope ===== +CDocBuilderContextScope* CDocBuilderContextScope_Create() +{ + return new CDocBuilderContextScope(); +} + +CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other) +{ + return new CDocBuilderContextScope(*other); +} + +void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self) +{ + delete self; +} + +void CDocBuilderContextScope_Close(CDocBuilderContextScope* self) +{ + self->Close(); +} + +// ===== CDocBuilderContext ===== +CDocBuilderContext* CDocBuilderContext_Create() +{ + return new CDocBuilderContext(); +} + +CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other) +{ + return new CDocBuilderContext(*other); +} + +void CDocBuilderContext_Destroy(CDocBuilderContext* self) +{ + delete self; +} + +CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateUndefined()); +} + +CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateNull()); +} + +CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->CreateObject()); +} + +CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length) +{ + return new CDocBuilderValue(self->CreateArray(length)); +} + +CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self) +{ + return new CDocBuilderValue(self->GetGlobal()); +} + +CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self) +{ + return new CDocBuilderContextScope(self->CreateScope()); +} + +bool CDocBuilderContext_IsError(CDocBuilderContext* self) +{ + return self->IsError(); +} + +// ===== Utility ===== +void DeleteWCharP(wchar_t* str) +{ + delete[] str; +} + +void DeleteCharP(char* str) +{ + delete[] str; +} diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h index a3acd2e02be..64b94140b3d 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h @@ -1,134 +1,134 @@ -#ifndef DOCBUILDER_FUNCTIONS_H -#define DOCBUILDER_FUNCTIONS_H - -#include "docbuilder.h" - -#include "../common/base_export.h" -#ifdef DOCBUILDER_FUNCTIONS_EXPORT -#define DOCBUILDER_FUNC_DECL Q_DECL_EXPORT -#else -#define DOCBUILDER_FUNC_DECL Q_DECL_IMPORT -#endif - -using namespace NSDoctRenderer; - -extern "C" -{ -// ===== CDocBuilderValue ===== -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Create(); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other); -DOCBUILDER_FUNC_DECL void CDocBuilderValue_Destroy(CDocBuilderValue* self); - -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL void CDocBuilderValue_Clear(CDocBuilderValue* self); - -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsNull(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsInt(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsDouble(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsString(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsFunction(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsObject(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsArray(CDocBuilderValue* self); -// TODO: -// DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsTypedArray(CDocBuilderValue* self); - -DOCBUILDER_FUNC_DECL unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self); - -DOCBUILDER_FUNC_DECL bool CDocBuilderValue_ToBool(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL int CDocBuilderValue_ToInt(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL double CDocBuilderValue_ToDouble(CDocBuilderValue* self); -DOCBUILDER_FUNC_DECL const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index); - -DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value); -DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateUndefined(); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateNull(); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateArray(int length); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6); - -// ===== CDocBuilder ===== -DOCBUILDER_FUNC_DECL CDocBuilder* CDocBuilder_Create(); -DOCBUILDER_FUNC_DECL void CDocBuilder_Destroy(CDocBuilder* self); - -DOCBUILDER_FUNC_DECL int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params); -DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type); -DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension); - -DOCBUILDER_FUNC_DECL void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder); - -DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path); -DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params); -DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path); -DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params); - -DOCBUILDER_FUNC_DECL void CDocBuilder_CloseFile(CDocBuilder* self); - -DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command); -DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue); - -DOCBUILDER_FUNC_DECL bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path); -DOCBUILDER_FUNC_DECL bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands); - -DOCBUILDER_FUNC_DECL void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value); - -DOCBUILDER_FUNC_DECL void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append); - -DOCBUILDER_FUNC_DECL bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self); - -DOCBUILDER_FUNC_DECL char* CDocBuilder_GetVersion(CDocBuilder* self); - -DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self); - -DOCBUILDER_FUNC_DECL void CDocBuilder_Initialize(); -DOCBUILDER_FUNC_DECL void CDocBuilder_InitializeWithDirectory(const wchar_t* directory); -DOCBUILDER_FUNC_DECL void CDocBuilder_Dispose(); - -// ===== CDocBuilderContextScope ===== -DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Create(); -DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other); -DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self); - -DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Close(CDocBuilderContextScope* self); - -// ===== CDocBuilderContext ===== -DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Create(); -DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other); -DOCBUILDER_FUNC_DECL void CDocBuilderContext_Destroy(CDocBuilderContext* self); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self); -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length); -// TODO: -// CDocBuilderContext_CreateTypedArray(CDocBuilderContext* self, unsigned char* buffer); - -DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self); - -DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self); - -DOCBUILDER_FUNC_DECL bool CDocBuilderContext_IsError(CDocBuilderContext* self); - -// ===== Utility ===== -DOCBUILDER_FUNC_DECL void DeleteWCharP(wchar_t* str); -DOCBUILDER_FUNC_DECL void DeleteCharP(char* str); -} - -#endif // DOCBUILDER_FUNCTIONS_H +#ifndef DOCBUILDER_FUNCTIONS_H +#define DOCBUILDER_FUNCTIONS_H + +#include "docbuilder.h" + +#include "../common/base_export.h" +#ifdef DOCBUILDER_FUNCTIONS_EXPORT +#define DOCBUILDER_FUNC_DECL Q_DECL_EXPORT +#else +#define DOCBUILDER_FUNC_DECL Q_DECL_IMPORT +#endif + +using namespace NSDoctRenderer; + +extern "C" +{ +// ===== CDocBuilderValue ===== +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Copy(CDocBuilderValue* other); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Destroy(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsEmpty(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_Clear(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsNull(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsUndefined(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsString(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsFunction(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsObject(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsArray(CDocBuilderValue* self); +// TODO: +// DOCBUILDER_FUNC_DECL bool CDocBuilderValue_IsTypedArray(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL unsigned int CDocBuilderValue_GetLength(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderValue_ToBool(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL int CDocBuilderValue_ToInt(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL double CDocBuilderValue_ToDouble(CDocBuilderValue* self); +DOCBUILDER_FUNC_DECL const wchar_t* CDocBuilderValue_ToString(CDocBuilderValue* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetProperty(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_GetByIndex(CDocBuilderValue* self, int index); + +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetProperty(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* value); +DOCBUILDER_FUNC_DECL void CDocBuilderValue_SetByIndex(CDocBuilderValue* self, int index, CDocBuilderValue* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithBool(bool value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithInt(int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithUInt(unsigned int value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithDouble(double value); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateWithString(const wchar_t* value); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateUndefined(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateNull(); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_CreateArray(int length); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call0(CDocBuilderValue* self, const wchar_t* name); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call1(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call2(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call3(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call4(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call5(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderValue_Call6(CDocBuilderValue* self, const wchar_t* name, CDocBuilderValue* p1, CDocBuilderValue* p2, CDocBuilderValue* p3, CDocBuilderValue* p4, CDocBuilderValue* p5, CDocBuilderValue* p6); + +// ===== CDocBuilder ===== +DOCBUILDER_FUNC_DECL CDocBuilder* CDocBuilder_Create(); +DOCBUILDER_FUNC_DECL void CDocBuilder_Destroy(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL int CDocBuilder_OpenFile(CDocBuilder* self, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByType(CDocBuilder* self, int type); +DOCBUILDER_FUNC_DECL bool CDocBuilder_CreateFileByExtension(CDocBuilder* self, const wchar_t* extension); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetTmpFolder(CDocBuilder* self, const wchar_t* folder); + +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByType(CDocBuilder* self, int type, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByTypeWithParams(CDocBuilder* self, int type, const wchar_t* path, const wchar_t* params); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtension(CDocBuilder* self, const wchar_t* extension, const wchar_t* path); +DOCBUILDER_FUNC_DECL int CDocBuilder_SaveFileByExtensionWithParams(CDocBuilder* self, const wchar_t* extension, const wchar_t* path, const wchar_t* params); + +DOCBUILDER_FUNC_DECL void CDocBuilder_CloseFile(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommand(CDocBuilder* self, const wchar_t* command); +DOCBUILDER_FUNC_DECL bool CDocBuilder_ExecuteCommandWithRetValue(CDocBuilder* self, const wchar_t* command, CDocBuilderValue* retValue); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_Run(CDocBuilder* self, const wchar_t* path); +DOCBUILDER_FUNC_DECL bool CDocBuilder_RunText(CDocBuilder* self, const wchar_t* commands); + +DOCBUILDER_FUNC_DECL void CDocBuilder_SetProperty(CDocBuilder* self, const wchar_t* param, const wchar_t* value); + +DOCBUILDER_FUNC_DECL void CDocBuilder_WriteData(CDocBuilder* self, const wchar_t* path, const wchar_t* value, bool append); + +DOCBUILDER_FUNC_DECL bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL char* CDocBuilder_GetVersion(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self); + +DOCBUILDER_FUNC_DECL void CDocBuilder_Initialize(); +DOCBUILDER_FUNC_DECL void CDocBuilder_InitializeWithDirectory(const wchar_t* directory); +DOCBUILDER_FUNC_DECL void CDocBuilder_Dispose(); + +// ===== CDocBuilderContextScope ===== +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContextScope_Copy(CDocBuilderContextScope* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Destroy(CDocBuilderContextScope* self); + +DOCBUILDER_FUNC_DECL void CDocBuilderContextScope_Close(CDocBuilderContextScope* self); + +// ===== CDocBuilderContext ===== +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Create(); +DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilderContext_Copy(CDocBuilderContext* other); +DOCBUILDER_FUNC_DECL void CDocBuilderContext_Destroy(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateUndefined(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateNull(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateObject(CDocBuilderContext* self); +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_CreateArray(CDocBuilderContext* self, int length); +// TODO: +// CDocBuilderContext_CreateTypedArray(CDocBuilderContext* self, unsigned char* buffer); + +DOCBUILDER_FUNC_DECL CDocBuilderValue* CDocBuilderContext_GetGlobal(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL CDocBuilderContextScope* CDocBuilderContext_CreateScope(CDocBuilderContext* self); + +DOCBUILDER_FUNC_DECL bool CDocBuilderContext_IsError(CDocBuilderContext* self); + +// ===== Utility ===== +DOCBUILDER_FUNC_DECL void DeleteWCharP(wchar_t* str); +DOCBUILDER_FUNC_DECL void DeleteCharP(char* str); +} + +#endif // DOCBUILDER_FUNCTIONS_H diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro index 19cef476aec..0af73a0782e 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro @@ -1,28 +1,27 @@ -QT -= core -QT -= gui - -TARGET = test - -TEMPLATE = app - -CONFIG -= app_bundle -CONFIG += console - -CORE_ROOT_DIR = $$PWD/../../../.. -PWD_ROOT_DIR = $$PWD - -include($$CORE_ROOT_DIR/Common/base.pri) - -# !!! Set docbuilder path here !!! -DOCUMENT_BUILDER_INSTALL_PATH="C:/Program Files/ONLYOFFICE/DocumentBuilder" - -DEFINES += "DOCUMENT_BUILDER_INSTALL_PATH=\"$$DOCUMENT_BUILDER_INSTALL_PATH\"" -LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder_functions - -DESTDIR = $$PWD/build - -INCLUDEPATH += ../.. - -SOURCES += \ - main.cpp - +QT -= core +QT -= gui + +TARGET = test + +TEMPLATE = app + +CONFIG -= app_bundle +CONFIG += console + +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +# !!! Set docbuilder path here !!! +DOCUMENT_BUILDER_INSTALL_PATH="C:/Program Files/ONLYOFFICE/DocumentBuilder" + +DEFINES += "DOCUMENT_BUILDER_INSTALL_PATH=\"$$DOCUMENT_BUILDER_INSTALL_PATH\"" +LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder_functions + +DESTDIR = $$PWD/build + +INCLUDEPATH += ../.. + +SOURCES += \ + main.cpp diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp index 71f06ba9a89..9dc6874ea4f 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp @@ -1,74 +1,74 @@ -#include "../src/docbuilder_functions.h" - -#include -#include - -#include "app_builder_lib/utils.cpp" - -#define DECLARE_RAII_DOCBUILDER_FUNC_CLASS( CLASS_NAME ) \ -class CLASS_NAME ## F \ -{ \ -public: \ - CLASS_NAME ## F(CLASS_NAME* internal) { m_internal = internal; } \ - ~CLASS_NAME ## F() { CLASS_NAME ## _Destroy(m_internal); } \ - \ - CLASS_NAME* get() { return m_internal; } \ - \ -private: \ - CLASS_NAME* m_internal; \ -}; - -DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilder) -DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderValue) -DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContext) -DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContextScope) - -int main() -{ - std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); - -#if 1 - // Simple test that shows builder version if everything is correct - CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); - CDocBuilder* pBuilder = CDocBuilder_Create(); - - char* sVersion = CDocBuilder_GetVersion(pBuilder); - std::cout << sVersion << std::endl; - DeleteCharP(sVersion); - - CDocBuilder_Dispose(); - CDocBuilder_Destroy(pBuilder); -#else - // Test is identical to app_builder_lib.pro - // The test uses RAII wrappers - classes with 'F' postfix, which are destroyed automatically - CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); - - CDocBuilderF oBuilder = CDocBuilder_Create(); - CDocBuilder_SetProperty(oBuilder.get(), L"--work-directory", sWorkDirectory.c_str()); - - CDocBuilder_CreateFileByExtension(oBuilder.get(), L"docx"); - - CDocBuilderContextF oContext = CDocBuilder_GetContext(oBuilder.get()); - CDocBuilderContextScopeF oScope = CDocBuilderContext_CreateScope(oContext.get()); - - CDocBuilderValueF oGlobal = CDocBuilderContext_GetGlobal(oContext.get()); - - CDocBuilderValueF oApi = CDocBuilderValue_GetProperty(oGlobal.get(), L"Api"); - CDocBuilderValueF oDocument = CDocBuilderValue_Call0(oApi.get(), L"GetDocument"); - CDocBuilderValueF oParagraph = CDocBuilderValue_Call0(oApi.get(), L"CreateParagraph"); - CDocBuilderValue_Call2(oParagraph.get(), L"SetSpacingAfter", CDocBuilderValueF(CDocBuilderValue_CreateWithInt(1000)).get(), CDocBuilderValueF(CDocBuilderValue_CreateWithBool(false)).get()); - CDocBuilderValue_Call1(oParagraph.get(), L"AddText", CDocBuilderValueF(CDocBuilderValue_CreateWithString(L"Hello, world!")).get()); - CDocBuilderValueF oContent = CDocBuilderContext_CreateArray(oContext.get(), 1); - CDocBuilderValue_SetByIndex(oContent.get(), 0, oParagraph.get()); - CDocBuilderValue_Call1(oDocument.get(), L"InsertContent", oContent.get()); - - std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); - std::wstring sDstPath = sProcessDirectory + L"/result.docx"; - CDocBuilder_SaveFileByExtension(oBuilder.get(), L"docx", sDstPath.c_str()); - CDocBuilder_CloseFile(oBuilder.get()); - - CDocBuilder_Dispose(); -#endif - - return 0; -} +#include "../src/docbuilder_functions.h" + +#include +#include + +#include "app_builder_lib/utils.cpp" + +#define DECLARE_RAII_DOCBUILDER_FUNC_CLASS( CLASS_NAME ) \ +class CLASS_NAME ## F \ +{ \ +public: \ + CLASS_NAME ## F(CLASS_NAME* internal) { m_internal = internal; } \ + ~CLASS_NAME ## F() { CLASS_NAME ## _Destroy(m_internal); } \ + \ + CLASS_NAME* get() { return m_internal; } \ + \ +private: \ + CLASS_NAME* m_internal; \ +}; + +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilder) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderValue) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContext) +DECLARE_RAII_DOCBUILDER_FUNC_CLASS(CDocBuilderContextScope) + +int main() +{ + std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); + +#if 1 + // Simple test that shows builder version if everything is correct + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + CDocBuilder* pBuilder = CDocBuilder_Create(); + + char* sVersion = CDocBuilder_GetVersion(pBuilder); + std::cout << sVersion << std::endl; + DeleteCharP(sVersion); + + CDocBuilder_Dispose(); + CDocBuilder_Destroy(pBuilder); +#else + // Test is identical to app_builder_lib.pro + // The test uses RAII wrappers - classes with 'F' postfix, which are destroyed automatically + CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); + + CDocBuilderF oBuilder = CDocBuilder_Create(); + CDocBuilder_SetProperty(oBuilder.get(), L"--work-directory", sWorkDirectory.c_str()); + + CDocBuilder_CreateFileByExtension(oBuilder.get(), L"docx"); + + CDocBuilderContextF oContext = CDocBuilder_GetContext(oBuilder.get()); + CDocBuilderContextScopeF oScope = CDocBuilderContext_CreateScope(oContext.get()); + + CDocBuilderValueF oGlobal = CDocBuilderContext_GetGlobal(oContext.get()); + + CDocBuilderValueF oApi = CDocBuilderValue_GetProperty(oGlobal.get(), L"Api"); + CDocBuilderValueF oDocument = CDocBuilderValue_Call0(oApi.get(), L"GetDocument"); + CDocBuilderValueF oParagraph = CDocBuilderValue_Call0(oApi.get(), L"CreateParagraph"); + CDocBuilderValue_Call2(oParagraph.get(), L"SetSpacingAfter", CDocBuilderValueF(CDocBuilderValue_CreateWithInt(1000)).get(), CDocBuilderValueF(CDocBuilderValue_CreateWithBool(false)).get()); + CDocBuilderValue_Call1(oParagraph.get(), L"AddText", CDocBuilderValueF(CDocBuilderValue_CreateWithString(L"Hello, world!")).get()); + CDocBuilderValueF oContent = CDocBuilderContext_CreateArray(oContext.get(), 1); + CDocBuilderValue_SetByIndex(oContent.get(), 0, oParagraph.get()); + CDocBuilderValue_Call1(oDocument.get(), L"InsertContent", oContent.get()); + + std::wstring sProcessDirectory = NSUtils::GetProcessDirectory(); + std::wstring sDstPath = sProcessDirectory + L"/result.docx"; + CDocBuilder_SaveFileByExtension(oBuilder.get(), L"docx", sDstPath.c_str()); + CDocBuilder_CloseFile(oBuilder.get()); + + CDocBuilder_Dispose(); +#endif + + return 0; +} From 93d77ee945a447377e5eb02756380045e87a8df4 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 22:09:38 +0400 Subject: [PATCH 666/794] Added all classes to `docbuilder.py` --- .../docbuilder.python/src/docbuilder.py | 513 +++++++++++++++++- 1 file changed, 505 insertions(+), 8 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 959d1b82ee7..3f6c89f9a4a 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -3,7 +3,7 @@ import platform import sys -DOCBUILDER_HANDLE = ctypes.c_void_p +OBJECT_HANDLE = ctypes.c_void_p STRING_HANDLE = ctypes.c_void_p _lib = None @@ -15,27 +15,514 @@ def loadLibrary(path): os.environ['PATH'] += ':' + path global _lib - _lib = ctypes.CDLL('docbuilder_functions.dll') + _lib = ctypes.CDLL(path + '/docbuilder_functions.dll') # init all function signatures - _lib.CDocBuilder_InitializeWithDirectory.argtypes = [ctypes.c_wchar_p] - _lib.CDocBuilder_InitializeWithDirectory.restype = None + # ===== CDocBuilderValue ===== + _lib.CDocBuilderValue_Create.argtypes = [] + _lib.CDocBuilderValue_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Destroy.restype = None + + _lib.CDocBuilderValue_IsEmpty.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsEmpty.restype = ctypes.c_bool + + _lib.CDocBuilderValue_Clear.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_Clear.restype = None + + _lib.CDocBuilderValue_IsNull.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsNull.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsUndefined.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsUndefined.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsInt.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsInt.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsDouble.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsDouble.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsString.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsString.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsFunction.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsFunction.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsObject.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsObject.restype = ctypes.c_bool + + _lib.CDocBuilderValue_IsArray.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_IsArray.restype = ctypes.c_bool + + _lib.CDocBuilderValue_GetLength.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_GetLength.restype = ctypes.c_uint + + _lib.CDocBuilderValue_ToBool.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToBool.restype = ctypes.c_bool + + _lib.CDocBuilderValue_ToInt.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToInt.restype = ctypes.c_int + + _lib.CDocBuilderValue_ToDouble.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToDouble.restype = ctypes.c_double + + _lib.CDocBuilderValue_ToString.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderValue_ToString.restype = STRING_HANDLE + + _lib.CDocBuilderValue_GetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilderValue_GetProperty.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_GetByIndex.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilderValue_GetByIndex.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_SetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilderValue_SetProperty.restype = None + + _lib.CDocBuilderValue_SetByIndex.argtypes = [OBJECT_HANDLE, ctypes.c_int, OBJECT_HANDLE] + _lib.CDocBuilderValue_SetByIndex.restype = None + + _lib.CDocBuilderValue_CreateWithBool.argtypes = [ctypes.c_bool] + _lib.CDocBuilderValue_CreateWithBool.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithInt.argtypes = [ctypes.c_int] + _lib.CDocBuilderValue_CreateWithInt.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithUInt.argtypes = [ctypes.c_uint] + _lib.CDocBuilderValue_CreateWithUInt.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithDouble.argtypes = [ctypes.c_double] + _lib.CDocBuilderValue_CreateWithDouble.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateWithString.argtypes = [ctypes.c_wchar_p] + _lib.CDocBuilderValue_CreateWithString.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateUndefined.argtypes = [] + _lib.CDocBuilderValue_CreateUndefined.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateNull.argtypes = [] + _lib.CDocBuilderValue_CreateNull.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_CreateArray.argtypes = [ctypes.c_int] + _lib.CDocBuilderValue_CreateArray.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call0.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilderValue_Call0.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call1.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call1.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call2.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call2.restype = OBJECT_HANDLE + _lib.CDocBuilderValue_Call3.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call3.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call4.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call4.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call5.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call5.restype = OBJECT_HANDLE + + _lib.CDocBuilderValue_Call6.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE, OBJECT_HANDLE] + _lib.CDocBuilderValue_Call6.restype = OBJECT_HANDLE + + # ===== CDocBuilder ===== _lib.CDocBuilder_Create.argtypes = [] - _lib.CDocBuilder_Create.restype = DOCBUILDER_HANDLE + _lib.CDocBuilder_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilder_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_Destroy.restype = None + + _lib.CDocBuilder_OpenFile.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_OpenFile.restype = ctypes.c_int + + _lib.CDocBuilder_CreateFileByType.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilder_CreateFileByType.restype = ctypes.c_bool + + _lib.CDocBuilder_CreateFileByExtension.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_CreateFileByExtension.restype = ctypes.c_bool + + _lib.CDocBuilder_SetTmpFolder.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_SetTmpFolder.restype = None + + _lib.CDocBuilder_SaveFileByType.argtypes = [OBJECT_HANDLE, ctypes.c_int, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByType.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByTypeWithParams.argtypes = [OBJECT_HANDLE, ctypes.c_int, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByTypeWithParams.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByExtension.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByExtension.restype = ctypes.c_int + + _lib.CDocBuilder_SaveFileByExtensionWithParams.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SaveFileByExtensionWithParams.restype = ctypes.c_int + + _lib.CDocBuilder_CloseFile.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_CloseFile.restype = None + + _lib.CDocBuilder_ExecuteCommand.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_ExecuteCommand.restype = ctypes.c_bool + + _lib.CDocBuilder_ExecuteCommandWithRetValue.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, OBJECT_HANDLE] + _lib.CDocBuilder_ExecuteCommandWithRetValue.restype = ctypes.c_bool - _lib.CDocBuilder_GetVersion.argtypes = [DOCBUILDER_HANDLE] + _lib.CDocBuilder_Run.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_Run.restype = ctypes.c_bool + + _lib.CDocBuilder_RunText.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p] + _lib.CDocBuilder_RunText.restype = ctypes.c_bool + + _lib.CDocBuilder_SetProperty.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p] + _lib.CDocBuilder_SetProperty.restype = None + + _lib.CDocBuilder_WriteData.argtypes = [OBJECT_HANDLE, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_bool] + _lib.CDocBuilder_WriteData.restype = None + + _lib.CDocBuilder_IsSaveWithDoctrendererMode.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_IsSaveWithDoctrendererMode.restype = ctypes.c_bool + + _lib.CDocBuilder_GetVersion.argtypes = [OBJECT_HANDLE] _lib.CDocBuilder_GetVersion.restype = STRING_HANDLE + _lib.CDocBuilder_GetContext.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilder_GetContext.restype = OBJECT_HANDLE + + _lib.CDocBuilder_Initialize.argtypes = [] + _lib.CDocBuilder_Initialize.restype = None + + _lib.CDocBuilder_InitializeWithDirectory.argtypes = [ctypes.c_wchar_p] + _lib.CDocBuilder_InitializeWithDirectory.restype = None + _lib.CDocBuilder_Dispose.argtypes = [] _lib.CDocBuilder_Dispose.restype = None - _lib.CDocBuilder_Destroy.argtypes = [DOCBUILDER_HANDLE] - _lib.CDocBuilder_Destroy.restype = None + # ===== CDocBuilderContextScope ===== + _lib.CDocBuilderContextScope_Create.argtypes = [] + _lib.CDocBuilderContextScope_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderContextScope_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderContextScope_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Destroy.restype = None + + _lib.CDocBuilderContextScope_Close.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContextScope_Close.restype = None + + # ===== CDocBuilderContext ===== + _lib.CDocBuilderContext_Create.argtypes = [] + _lib.CDocBuilderContext_Create.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_Copy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_Copy.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_Destroy.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_Destroy.restype = None + + _lib.CDocBuilderContext_CreateUndefined.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateUndefined.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateNull.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateNull.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateObject.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateObject.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateArray.argtypes = [OBJECT_HANDLE, ctypes.c_int] + _lib.CDocBuilderContext_CreateArray.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_GetGlobal.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_GetGlobal.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_CreateScope.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_CreateScope.restype = OBJECT_HANDLE + + _lib.CDocBuilderContext_IsError.argtypes = [OBJECT_HANDLE] + _lib.CDocBuilderContext_IsError.restype = ctypes.c_bool + + # ===== Utility ===== + _lib.DeleteWCharP.argtypes = [ctypes.c_wchar_p] + _lib.DeleteWCharP.restype = None _lib.DeleteCharP.argtypes = [ctypes.c_char_p] _lib.DeleteCharP.restype = None +class CDocBuilderValue: + def __init__(self, value=None): + if value is None: + self._internal = _lib.CDocBuilderValue_Create() + elif isinstance(value, bool): + self._internal = _lib.CDocBuilderValue_CreateWithBool(ctypes.c_bool(value)) + elif isinstance(value, int): + self._internal = _lib.CDocBuilderValue_CreateWithInt(ctypes.c_int(value)) + elif isinstance(value, float): + self._internal = _lib.CDocBuilderValue_CreateWithDouble(ctypes.c_double(value)) + elif isinstance(value, str): + self._internal = _lib.CDocBuilderValue_CreateWithString(ctypes.c_wchar_p(value)) + elif isinstance(value, CDocBuilderValue): + self._internal = _lib.CDocBuilderValue_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + raise TypeError("Unsupported type for CDocBuilderValue constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderValue_Destroy(self._internal) + + def IsEmpty(self): + return _lib.CDocBuilderValue_IsEmpty(self._internal).value + + def Clear(self): + _lib.CDocBuilderValue_Clear(self._internal) + + def IsNull(self): + return _lib.CDocBuilderValue_IsNull(self._internal).value + + def IsUndefined(self): + return _lib.CDocBuilderValue_IsUndefined(self._internal).value + + def IsInt(self): + return _lib.CDocBuilderValue_IsInt(self._internal).value + + def IsDouble(self): + return _lib.CDocBuilderValue_IsDouble(self._internal).value + + def IsString(self): + return _lib.CDocBuilderValue_IsString(self._internal).value + + def IsFunction(self): + return _lib.CDocBuilderValue_IsFunction(self._internal).value + + def IsObject(self): + return _lib.CDocBuilderValue_IsObject(self._internal).value + + def IsArray(self): + return _lib.CDocBuilderValue_IsArray(self._internal).value + + def GetLength(self): + return _lib.CDocBuilderValue_GetLength(self._internal).value + + def ToBool(self): + return _lib.CDocBuilderValue_ToBool(self._internal).value + + def ToInt(self): + return _lib.CDocBuilderValue_ToInt(self._internal).value + + def ToDouble(self): + return _lib.CDocBuilderValue_ToDouble(self._internal).value + + def ToString(self): + strRes = _lib.CDocBuilderValue_ToString(self._internal) + res = ctypes.cast(strRes, ctypes.c_wchar_p).value + _lib.DeleteWCharP(ctypes.cast(strRes, ctypes.c_wchar_p)) + return res + + def GetProperty(self, name): + return CDocBuilderValue(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(name))) + + def Get(self, key): + if isinstance(key, int): + return CDocBuilderValue(_lib.CDocBuilderValue_GetByIndex(self._internal, ctypes.c_int(key))) + elif isinstance(key, str): + return CDocBuilderValue(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(key))) + else: + return None + + def SetProperty(self, name, value): + _lib.CDocBuilderValue_SetProperty(self._internal, ctypes.c_wchar_p(name), value._internal) + + def Set(self, key, value): + if isinstance(key, int): + _lib.CDocBuilderValue_SetByIndex(self._internal, ctypes.c_int(key), value._internal) + elif isinstance(key, str): + _lib.CDocBuilderValue_SetProperty(self._internal, ctypes.c_wchar_p(key), value._internal) + + def __getitem__(self, key): + return self.Get(key) + + def __setitem__(self, key): + self.Set(key) + + @staticmethod + def CreateUndefined(): + return CDocBuilderValue(_lib.CDocBuilderValue_CreateUndefined()) + + @staticmethod + def CreateNull(): + return CDocBuilderValue(_lib.CDocBuilderValue_CreateNull()) + + @staticmethod + def CreateArray(length): + return CDocBuilderValue(_lib.CDocBuilderValue_CreateArray(length)) + + def Call(self, name, *args): + if len(args) == 0: + return CDocBuilderValue(_lib.CDocBuilderValue_Call0(self._internal, ctypes.c_wchar_p(name))) + elif len(args) < 7: + values = [] + for i in range(len(args)): + p = args[i] + if not isinstance(p, CDocBuilderValue): + p = CDocBuilderValue(p) + values.append(p) + if len(args) == 1: + return CDocBuilderValue(_lib.CDocBuilderValue_Call1(self._internal, ctypes.c_wchar_p(name), values[0]._internal)) + elif len(args) == 2: + return CDocBuilderValue(_lib.CDocBuilderValue_Call2(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal)) + elif len(args) == 3: + return CDocBuilderValue(_lib.CDocBuilderValue_Call3(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal)) + elif len(args) == 4: + return CDocBuilderValue(_lib.CDocBuilderValue_Call4(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal)) + elif len(args) == 5: + return CDocBuilderValue(_lib.CDocBuilderValue_Call5(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal)) + elif len(args) == 6: + return CDocBuilderValue(_lib.CDocBuilderValue_Call6(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal, values[5]._internal)) + else: + raise TypeError("Call() expects at most 6 arguments") + +class CDocBuilder: + def __init__(self): + self._internal = _lib.CDocBuilder_Create() + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilder_Destroy(self._internal) + + def OpenFile(self, path, params): + return _lib.CDocBuilder_OpenFile(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + + def CreateFile(self, type): + if isinstance(type, int): + return _lib.CDocBuilder_CreateFileByType(self._internal, ctypes.c_int(type)).value + elif isinstance(type, str): + return _lib.CDocBuilder_CreateFileByExtension(self._internal, ctypes.c_wchar_p(type)).value + else: + return False + + def SetTmpFolder(self, folder): + _lib.CDocBuilder_SetTmpFolder(self._internal, ctypes.c_wchar_p(folder)) + + def SaveFile(self, type, path, params=None): + if isinstance(type, int): + if params is None: + return _lib.CDocBuilder_SaveFileByType(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path)).value + else: + return _lib.CDocBuilder_SaveFileByTypeWithParams(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + elif isinstance(type, str): + if params is None: + return _lib.CDocBuilder_SaveFileByExtension(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path)).value + else: + return _lib.CDocBuilder_SaveFileByExtensionWithParams(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + else: + return -1 + + def CloseFile(self): + _lib.CDocBuilder_CloseFile(self._internal) + + def ExecuteCommand(self, command, retValue=None): + if retValue is None: + return _lib.CDocBuilder_ExecuteCommand(self._internal, ctypes.c_wchar_p(command)).value + else: + return _lib.CDocBuilder_ExecuteCommandWithRetValue(self._internal, ctypes.c_wchar_p(command), retValue._internal).value + + def Run(self, path): + return _lib.CDocBuilder_Run(self._internal, ctypes.c_wchar_p(path)).value + + def RunText(self, commands): + return _lib.CDocBuilder_RunText(self._internal, ctypes.c_wchar_p(commands)).value + + def SetProperty(self, param, value): + _lib.CDocBuilder_SetProperty(self._internal, ctypes.c_wchar_p(param), ctypes.c_wchar_p(value)) + + def WriteData(self, path, value, append): + _lib.CDocBuilder_WriteData(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(value), ctypes.c_bool(append)) + + def IsSaveWithDoctrendererMode(self): + return _lib.CDocBuilder_IsSaveWithDoctrendererMode(self._internal).value + + def GetVersion(self): + strVersion = _lib.CDocBuilder_GetVersion(self._internal) + version = ctypes.cast(strVersion, ctypes.c_char_p).value + _lib.DeleteCharP(ctypes.cast(strVersion, ctypes.c_char_p)) + return version + + def GetContext(self): + return CDocBuilderContext(_lib.CDocBuilder_GetContext(self._internal)) + + @staticmethod + def Initialize(directory=None): + if directory is None: + _lib.CDocBuilder_Initialize() + else: + _lib.CDocBuilder_InitializeWithDirectory(ctypes.c_wchar_p(directory)) + + @staticmethod + def Dispose(): + _lib.CDocBuilder_Dispose() + +class CDocBuilderContextScope: + def __init__(self, value=None): + self._lib = _lib + if value is None: + self._internal = _lib.CDocBuilderContextScope_Create() + elif isinstance(value, CDocBuilderContextScope): + self._internal = _lib.CDocBuilderContextScope_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + TypeError("Unsupported type for CDocBuilderContextScope constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderContextScope_Destroy(self._internal) + + def Close(self): + _lib.CDocBuilderContextScope_Close(self._internal) + +class CDocBuilderContext: + def __init__(self, value=None): + if value is None: + self._internal = _lib.CDocBuilderContext_Create() + elif isinstance(value, CDocBuilderContext): + self._internal = _lib.CDocBuilderContext_Copy(value._internal) + elif isinstance(value, OBJECT_HANDLE): + self._internal = value + else: + TypeError("Unsupported type for CDocBuilderContext constructor") + self._lib = _lib + + def __del__(self): + # using self._lib instead of global _lib because it might be already garbage collected during this function call + self._lib.CDocBuilderContext_Destroy(self._internal) + + def CreateUndefined(self): + return CDocBuilderValue(_lib.CDocBuilderContext_CreateUndefined(self._internal)) + + def CreateNull(self): + return CDocBuilderValue(_lib.CDocBuilderContext_CreateNull(self._internal)) + + def CreateObject(self): + return CDocBuilderValue(_lib.CDocBuilderContext_CreateObject(self._internal)) + + def CreateArray(self, length): + return CDocBuilderValue(_lib.CDocBuilderContext_CreateArray(self._internal, ctypes.c_int(length))) + + def GetGlobal(self): + return CDocBuilderValue(_lib.CDocBuilderContext_GetGlobal(self._internal)) + + def CreateScope(self): + return CDocBuilderContextScope(_lib.CDocBuilderContext_CreateScope(self._internal)) + + def IsError(self): + return _lib.CDocBuilderContext_IsError(self._internal).value if __name__ == '__main__': if len(sys.argv) < 2: @@ -47,6 +534,7 @@ def loadLibrary(path): loadLibrary(path) # --------- + ''' _lib.CDocBuilder_InitializeWithDirectory(path) builder = _lib.CDocBuilder_Create() @@ -57,3 +545,12 @@ def loadLibrary(path): _lib.CDocBuilder_Dispose() _lib.CDocBuilder_Destroy(builder) + ''' + # --------- + CDocBuilder.Initialize(path) + builder = CDocBuilder() + + version = builder.GetVersion() + print(version) + + CDocBuilder.Dispose() From c802944d3b619d43ef392464f789de796637a727 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Fri, 17 May 2024 23:16:02 +0400 Subject: [PATCH 667/794] Fixes in `docbuilder.py` + Add more complex example + Add .gitignore --- .../doctrenderer/docbuilder.python/.gitignore | 2 + .../docbuilder.python/src/docbuilder.py | 127 +++++++++++------- 2 files changed, 79 insertions(+), 50 deletions(-) create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/.gitignore diff --git a/DesktopEditor/doctrenderer/docbuilder.python/.gitignore b/DesktopEditor/doctrenderer/docbuilder.python/.gitignore new file mode 100644 index 00000000000..71ac840d032 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/.gitignore @@ -0,0 +1,2 @@ +result.docx +*.pyc diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 3f6c89f9a4a..0a8f9b7ccea 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -276,46 +276,46 @@ def __del__(self): self._lib.CDocBuilderValue_Destroy(self._internal) def IsEmpty(self): - return _lib.CDocBuilderValue_IsEmpty(self._internal).value + return _lib.CDocBuilderValue_IsEmpty(self._internal) def Clear(self): _lib.CDocBuilderValue_Clear(self._internal) def IsNull(self): - return _lib.CDocBuilderValue_IsNull(self._internal).value + return _lib.CDocBuilderValue_IsNull(self._internal) def IsUndefined(self): - return _lib.CDocBuilderValue_IsUndefined(self._internal).value + return _lib.CDocBuilderValue_IsUndefined(self._internal) def IsInt(self): - return _lib.CDocBuilderValue_IsInt(self._internal).value + return _lib.CDocBuilderValue_IsInt(self._internal) def IsDouble(self): - return _lib.CDocBuilderValue_IsDouble(self._internal).value + return _lib.CDocBuilderValue_IsDouble(self._internal) def IsString(self): - return _lib.CDocBuilderValue_IsString(self._internal).value + return _lib.CDocBuilderValue_IsString(self._internal) def IsFunction(self): - return _lib.CDocBuilderValue_IsFunction(self._internal).value + return _lib.CDocBuilderValue_IsFunction(self._internal) def IsObject(self): - return _lib.CDocBuilderValue_IsObject(self._internal).value + return _lib.CDocBuilderValue_IsObject(self._internal) def IsArray(self): - return _lib.CDocBuilderValue_IsArray(self._internal).value + return _lib.CDocBuilderValue_IsArray(self._internal) def GetLength(self): - return _lib.CDocBuilderValue_GetLength(self._internal).value + return _lib.CDocBuilderValue_GetLength(self._internal) def ToBool(self): - return _lib.CDocBuilderValue_ToBool(self._internal).value + return _lib.CDocBuilderValue_ToBool(self._internal) def ToInt(self): - return _lib.CDocBuilderValue_ToInt(self._internal).value + return _lib.CDocBuilderValue_ToInt(self._internal) def ToDouble(self): - return _lib.CDocBuilderValue_ToDouble(self._internal).value + return _lib.CDocBuilderValue_ToDouble(self._internal) def ToString(self): strRes = _lib.CDocBuilderValue_ToString(self._internal) @@ -324,13 +324,13 @@ def ToString(self): return res def GetProperty(self, name): - return CDocBuilderValue(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(name))) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(name)))) def Get(self, key): if isinstance(key, int): - return CDocBuilderValue(_lib.CDocBuilderValue_GetByIndex(self._internal, ctypes.c_int(key))) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetByIndex(self._internal, ctypes.c_int(key)))) elif isinstance(key, str): - return CDocBuilderValue(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(key))) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_GetProperty(self._internal, ctypes.c_wchar_p(key)))) else: return None @@ -346,24 +346,24 @@ def Set(self, key, value): def __getitem__(self, key): return self.Get(key) - def __setitem__(self, key): - self.Set(key) + def __setitem__(self, key, value): + self.Set(key, value) @staticmethod def CreateUndefined(): - return CDocBuilderValue(_lib.CDocBuilderValue_CreateUndefined()) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateUndefined())) @staticmethod def CreateNull(): - return CDocBuilderValue(_lib.CDocBuilderValue_CreateNull()) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateNull())) @staticmethod def CreateArray(length): - return CDocBuilderValue(_lib.CDocBuilderValue_CreateArray(length)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_CreateArray(length))) def Call(self, name, *args): if len(args) == 0: - return CDocBuilderValue(_lib.CDocBuilderValue_Call0(self._internal, ctypes.c_wchar_p(name))) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call0(self._internal, ctypes.c_wchar_p(name)))) elif len(args) < 7: values = [] for i in range(len(args)): @@ -372,17 +372,17 @@ def Call(self, name, *args): p = CDocBuilderValue(p) values.append(p) if len(args) == 1: - return CDocBuilderValue(_lib.CDocBuilderValue_Call1(self._internal, ctypes.c_wchar_p(name), values[0]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call1(self._internal, ctypes.c_wchar_p(name), values[0]._internal))) elif len(args) == 2: - return CDocBuilderValue(_lib.CDocBuilderValue_Call2(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call2(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal))) elif len(args) == 3: - return CDocBuilderValue(_lib.CDocBuilderValue_Call3(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call3(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal))) elif len(args) == 4: - return CDocBuilderValue(_lib.CDocBuilderValue_Call4(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call4(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal))) elif len(args) == 5: - return CDocBuilderValue(_lib.CDocBuilderValue_Call5(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call5(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal))) elif len(args) == 6: - return CDocBuilderValue(_lib.CDocBuilderValue_Call6(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal, values[5]._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderValue_Call6(self._internal, ctypes.c_wchar_p(name), values[0]._internal, values[1]._internal, values[2]._internal, values[3]._internal, values[4]._internal, values[5]._internal))) else: raise TypeError("Call() expects at most 6 arguments") @@ -396,13 +396,13 @@ def __del__(self): self._lib.CDocBuilder_Destroy(self._internal) def OpenFile(self, path, params): - return _lib.CDocBuilder_OpenFile(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + return _lib.CDocBuilder_OpenFile(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) def CreateFile(self, type): if isinstance(type, int): - return _lib.CDocBuilder_CreateFileByType(self._internal, ctypes.c_int(type)).value + return _lib.CDocBuilder_CreateFileByType(self._internal, ctypes.c_int(type)) elif isinstance(type, str): - return _lib.CDocBuilder_CreateFileByExtension(self._internal, ctypes.c_wchar_p(type)).value + return _lib.CDocBuilder_CreateFileByExtension(self._internal, ctypes.c_wchar_p(type)) else: return False @@ -412,14 +412,14 @@ def SetTmpFolder(self, folder): def SaveFile(self, type, path, params=None): if isinstance(type, int): if params is None: - return _lib.CDocBuilder_SaveFileByType(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path)).value + return _lib.CDocBuilder_SaveFileByType(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path)) else: - return _lib.CDocBuilder_SaveFileByTypeWithParams(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + return _lib.CDocBuilder_SaveFileByTypeWithParams(self._internal, ctypes.c_int(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) elif isinstance(type, str): if params is None: - return _lib.CDocBuilder_SaveFileByExtension(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path)).value + return _lib.CDocBuilder_SaveFileByExtension(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path)) else: - return _lib.CDocBuilder_SaveFileByExtensionWithParams(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)).value + return _lib.CDocBuilder_SaveFileByExtensionWithParams(self._internal, ctypes.c_wchar_p(type), ctypes.c_wchar_p(path), ctypes.c_wchar_p(params)) else: return -1 @@ -428,15 +428,15 @@ def CloseFile(self): def ExecuteCommand(self, command, retValue=None): if retValue is None: - return _lib.CDocBuilder_ExecuteCommand(self._internal, ctypes.c_wchar_p(command)).value + return _lib.CDocBuilder_ExecuteCommand(self._internal, ctypes.c_wchar_p(command)) else: - return _lib.CDocBuilder_ExecuteCommandWithRetValue(self._internal, ctypes.c_wchar_p(command), retValue._internal).value + return _lib.CDocBuilder_ExecuteCommandWithRetValue(self._internal, ctypes.c_wchar_p(command), retValue._internal) def Run(self, path): - return _lib.CDocBuilder_Run(self._internal, ctypes.c_wchar_p(path)).value + return _lib.CDocBuilder_Run(self._internal, ctypes.c_wchar_p(path)) def RunText(self, commands): - return _lib.CDocBuilder_RunText(self._internal, ctypes.c_wchar_p(commands)).value + return _lib.CDocBuilder_RunText(self._internal, ctypes.c_wchar_p(commands)) def SetProperty(self, param, value): _lib.CDocBuilder_SetProperty(self._internal, ctypes.c_wchar_p(param), ctypes.c_wchar_p(value)) @@ -445,7 +445,7 @@ def WriteData(self, path, value, append): _lib.CDocBuilder_WriteData(self._internal, ctypes.c_wchar_p(path), ctypes.c_wchar_p(value), ctypes.c_bool(append)) def IsSaveWithDoctrendererMode(self): - return _lib.CDocBuilder_IsSaveWithDoctrendererMode(self._internal).value + return _lib.CDocBuilder_IsSaveWithDoctrendererMode(self._internal) def GetVersion(self): strVersion = _lib.CDocBuilder_GetVersion(self._internal) @@ -454,7 +454,7 @@ def GetVersion(self): return version def GetContext(self): - return CDocBuilderContext(_lib.CDocBuilder_GetContext(self._internal)) + return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal))) @staticmethod def Initialize(directory=None): @@ -477,7 +477,7 @@ def __init__(self, value=None): elif isinstance(value, OBJECT_HANDLE): self._internal = value else: - TypeError("Unsupported type for CDocBuilderContextScope constructor") + raise TypeError("Unsupported type for CDocBuilderContextScope constructor") self._lib = _lib def __del__(self): @@ -496,7 +496,7 @@ def __init__(self, value=None): elif isinstance(value, OBJECT_HANDLE): self._internal = value else: - TypeError("Unsupported type for CDocBuilderContext constructor") + raise TypeError("Unsupported type for CDocBuilderContext constructor") self._lib = _lib def __del__(self): @@ -504,25 +504,25 @@ def __del__(self): self._lib.CDocBuilderContext_Destroy(self._internal) def CreateUndefined(self): - return CDocBuilderValue(_lib.CDocBuilderContext_CreateUndefined(self._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateUndefined(self._internal))) def CreateNull(self): - return CDocBuilderValue(_lib.CDocBuilderContext_CreateNull(self._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateNull(self._internal))) def CreateObject(self): - return CDocBuilderValue(_lib.CDocBuilderContext_CreateObject(self._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateObject(self._internal))) def CreateArray(self, length): - return CDocBuilderValue(_lib.CDocBuilderContext_CreateArray(self._internal, ctypes.c_int(length))) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateArray(self._internal, ctypes.c_int(length)))) def GetGlobal(self): - return CDocBuilderValue(_lib.CDocBuilderContext_GetGlobal(self._internal)) + return CDocBuilderValue(OBJECT_HANDLE(_lib.CDocBuilderContext_GetGlobal(self._internal))) def CreateScope(self): - return CDocBuilderContextScope(_lib.CDocBuilderContext_CreateScope(self._internal)) + return CDocBuilderContextScope(OBJECT_HANDLE(_lib.CDocBuilderContext_CreateScope(self._internal))) def IsError(self): - return _lib.CDocBuilderContext_IsError(self._internal).value + return _lib.CDocBuilderContext_IsError(self._internal) if __name__ == '__main__': if len(sys.argv) < 2: @@ -547,6 +547,7 @@ def IsError(self): _lib.CDocBuilder_Destroy(builder) ''' # --------- + ''' CDocBuilder.Initialize(path) builder = CDocBuilder() @@ -554,3 +555,29 @@ def IsError(self): print(version) CDocBuilder.Dispose() + ''' + # --------- + CDocBuilder.Initialize(path) + builder = CDocBuilder() + + builder.CreateFile('docx') + + context = builder.GetContext() + scope = context.CreateScope() + + globalObj = context.GetGlobal() + + api = globalObj['Api'] + document = api.Call('GetDocument') + paragraph = api.Call('CreateParagraph') + paragraph.Call('SetSpacingAfter', 1000, False) + paragraph.Call('AddText', 'Hello, World!') + content = context.CreateArray(1) + content[0] = paragraph + document.Call('InsertContent', content) + + dstPath = os.getcwd() + '/result.docx' + builder.SaveFile('docx', dstPath) + builder.CloseFile() + + CDocBuilder.Dispose() From 5227a593ed83b91aaae52a00575acc3c125fd295 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sat, 18 May 2024 13:05:34 +0300 Subject: [PATCH 668/794] Fix bug #68034 --- Common/3dParty/html/htmltoxhtml.h | 39 +----- HtmlFile2/htmlfile2.cpp | 204 +++++++++++++++++++----------- HtmlFile2/src/StringFinder.h | 24 ++++ 3 files changed, 159 insertions(+), 108 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index b417716bcff..1e544477841 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -59,39 +59,12 @@ static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) if (boost::regex_search(sFileContent, oResult, oRegex)) sFileContent.erase(0, oResult.position()); - // Избавление от
- size_t posA = sFileContent.find("", posA); - if(nEnd < nBegin) - sFileContent.replace(nEnd, 2, ">"); - posA = sFileContent.find(" - posA = sFileContent.find(""); - while (posA != std::string::npos) - { - sFileContent.replace(posA, 8, "<title>"); - posA = sFileContent.find("", posA); - } - // Избавление от <script/> - posA = sFileContent.find("<script"); - while (posA != std::string::npos) - { - size_t nEnd = 0; - size_t nEnd1 = sFileContent.find("/>", posA); - size_t nEnd2 = sFileContent.find("</script>", posA); - if (nEnd1 != std::string::npos) - nEnd = nEnd1 + 2; - if (nEnd2 != std::string::npos && (nEnd == 0 || (nEnd > 0 && nEnd2 < nEnd))) - nEnd = nEnd2 + 9; - - sFileContent.erase(posA, nEnd - posA); - - posA = sFileContent.find("<script", posA); - } + //Избавление от <a ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "a")); + //Избавление от <title ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "title")); + //Избавление от <script ... /> + while (NSStringFinder::RemoveEmptyTag(sFileContent, "script")); // Gumbo GumboOptions options = kGumboDefaultOptions; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 077447b99f6..cbea0ad966b 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -85,6 +85,18 @@ struct CTextSettings CTextSettings(const CTextSettings& oTS) : bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} + + void AddRStyle(const std::wstring& wsStyle) + { + if (std::wstring::npos == sRStyle.find(wsStyle)) + sRStyle += wsStyle; + } + + void AddPStyle(const std::wstring& wsStyle) + { + if (std::wstring::npos == sPStyle.find(wsStyle)) + sPStyle += wsStyle; + } }; std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL) @@ -922,8 +934,8 @@ class CHtmlFile2_Private private: int m_nFootnoteId; // ID сноски int m_nHyperlinkId; // ID ссылки - int m_nCrossId; // ID перекрестной ссылки int m_nNumberingId; // ID списка + int m_nId; // ID остальные элементы NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml NSStringUtils::CStringBuilder m_oDocXmlRels; // document.xml.rels @@ -932,19 +944,21 @@ class CHtmlFile2_Private NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml - bool m_bInP; // <w:p> открыт? - bool m_bInR; // <w:r> открыт? - bool m_bInT; // <w:t> открыт? - bool m_bWasPStyle; // <w:pStyle> записан? - bool m_bWasSpace; // Был пробел? + bool m_bInP; // <w:p> открыт? + bool m_bInR; // <w:r> открыт? + bool m_bInT; // <w:t> открыт? + bool m_bWasPStyle; // <w:pStyle> записан? + bool m_bWasSpace; // Был пробел? + bool m_bInHyperlink; // <w:hyperlink> открыт? std::vector<std::wstring> m_arrImages; // Картинки std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски + std::map<std::wstring, UINT> m_mBookmarks; // Закладки public: CHtmlFile2_Private() - : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), - m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true) + : m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), + m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false) { m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); @@ -1137,6 +1151,8 @@ class CHtmlFile2_Private m_oNoteXml += L"<w:footnote w:type=\"separator\" w:id=\"-1\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type=\"continuationSeparator\" w:id=\"0\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>"; m_oStylesXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" mc:Ignorable=\"w14 w15\">"; + m_nId += 7; + // docDefaults по умолчанию if(oParams && !oParams->m_sdocDefaults.empty()) m_oStylesXml += oParams->m_sdocDefaults; @@ -1590,6 +1606,15 @@ class CHtmlFile2_Private CloseT(pXml); CloseR(pXml); + if (m_bInHyperlink) + { + if (arSelectors.rend() != std::find_if(arSelectors.rbegin(), arSelectors.rend(), [](const NSCSS::CNode& oNode) { return L"a" == oNode.m_wsName; })) + { + pXml->WriteString(L"</w:hyperlink>"); + m_bInHyperlink = false; + } + } + pXml->WriteString(L"</w:p>"); m_bInP = false; } @@ -1787,7 +1812,7 @@ class CHtmlFile2_Private else if(sName == L"b" || sName == L"strong") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:b/><w:bCs/>"; + oTSR.AddRStyle(L"<w:b/><w:bCs/>"); readStream(oXml, sSelectors, oTSR); } // Направление текста @@ -1814,7 +1839,7 @@ class CHtmlFile2_Private else if(sName == L"big") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:sz w:val=\"26\"/>"; + oTSR.AddRStyle(L"<w:sz w:val=\"26\"/>"); readStream(oXml, sSelectors, oTSR); } // Перенос строки @@ -1836,7 +1861,7 @@ class CHtmlFile2_Private else if(sName == L"center") { CTextSettings oTSP(oTS); - oTSP.sPStyle += L"<w:jc w:val=\"center\"/>"; + oTSP.AddPStyle(L"<w:jc w:val=\"center\"/>"); readStream(oXml, sSelectors, oTSP); } // Цитата, обычно выделяется курсивом @@ -1847,7 +1872,7 @@ class CHtmlFile2_Private else if(sName == L"cite" || sName == L"dfn" || sName == L"em" || sName == L"i" || sName == L"var") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); readStream(oXml, sSelectors, oTSR); } // Код @@ -1856,14 +1881,14 @@ class CHtmlFile2_Private else if(sName == L"code" || sName == L"kbd" || sName == L"samp" || sName == L"tt") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"; + oTSR.AddRStyle(L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"); readStream(oXml, sSelectors, oTSR); } // Зачеркнутый текст else if(sName == L"del" || sName == L"s") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:strike/>"; + oTSR.AddRStyle(L"<w:strike/>"); readStream(oXml, sSelectors, oTSR); } else if(sName == L"font") @@ -1914,14 +1939,14 @@ class CHtmlFile2_Private else if(sName == L"ins" || sName == L"u") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:u w:val=\"single\"/>"; + oTSR.AddRStyle(L"<w:u w:val=\"single\"/>"); readStream(oXml, sSelectors, oTSR); } // Выделенный текст, обычно выделяется желтым else if(sName == L"mark") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:highlight w:val=\"yellow\"/>"; + oTSR.AddRStyle(L"<w:highlight w:val=\"yellow\"/>"); readStream(oXml, sSelectors, oTSR); } // Цитата, выделенная кавычками, обычно выделяется курсивом @@ -1933,7 +1958,7 @@ class CHtmlFile2_Private oXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t></w:r>"); CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); readStream(oXml, sSelectors, oTSR); wrP(oXml, sSelectors, oTS); @@ -1952,21 +1977,21 @@ class CHtmlFile2_Private else if(sName == L"rt" || sName == L"sup") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:vertAlign w:val=\"superscript\"/>"; + oTSR.AddRStyle(L"<w:vertAlign w:val=\"superscript\"/>"); readStream(oXml, sSelectors, oTSR); } // Уменьшает размер шрифта else if(sName == L"small") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:sz w:val=\"18\"/>"; + oTSR.AddRStyle(L"<w:sz w:val=\"18\"/>"); readStream(oXml, sSelectors, oTSR); } // Текст нижнего регистра else if(sName == L"sub") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:vertAlign w:val=\"subscript\"/>"; + oTSR.AddRStyle(L"<w:vertAlign w:val=\"subscript\"/>"); readStream(oXml, sSelectors, oTSR); } // Векторная картинка @@ -2016,7 +2041,7 @@ class CHtmlFile2_Private if(sName == L"address") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); readStream(oXml, sSelectors, oTSR); } // Определение термина, отступ от левого края @@ -2107,7 +2132,7 @@ class CHtmlFile2_Private else if(sName == L"textarea" || sName == L"fieldset") { CTextSettings oTSP(oTS); - oTSP.sPStyle += L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"; + oTSP.AddPStyle(L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"); readStream(oXml, sSelectors, oTSP); } else if (sName == L"xml") @@ -2264,7 +2289,7 @@ class CHtmlFile2_Private if (pCell->GetStyles()->m_wsHAlign.empty()) oTSR.sPStyle += L"<w:jc w:val=\"center\"/>"; - oTSR.sRStyle += L"<w:b/><w:bCs/>"; + oTSR.AddRStyle(L"<w:b/><w:bCs/>"); readStream(pCell->GetData(), sSelectors, oTSR, true); } // Читаем td. Ячейка таблицы @@ -2526,36 +2551,14 @@ class CHtmlFile2_Private if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); - const bool bInP{m_bInP}, bWasPStyle{m_bWasPStyle}; - - NSStringUtils::CStringBuilder oInsideData; - m_bInP = true; - m_bWasPStyle = true; - - if(!readStream(&oInsideData, sSelectors, oTS)) - { - oInsideData.WriteString(L"<w:r>"); - wrRPr(&oInsideData, sSelectors, oTS); - oInsideData.WriteString(L"<w:t xml:space=\"preserve\">"); - oInsideData.WriteEncodeXmlString(sAlt); - oInsideData.WriteString(L"</w:t></w:r>"); - } - - if (0 != oInsideData.GetCurSize() && L"</w:p>" == oInsideData.GetSubData(0, 6)) - { - CloseP(oXml, sSelectors); - oXml->WriteString(oInsideData.GetSubData(6, oInsideData.GetCurSize() - 6)); - sNote.clear(); - return; - } - - m_bInP = bInP; - m_bWasPStyle = bWasPStyle; + const bool bInP(m_bInP); wrP(oXml, sSelectors, oTS); + // Перекрестная ссылка внутри файла if(bCross) { + m_bInHyperlink = true; oXml->WriteString(L"<w:hyperlink w:tooltip=\"Current Document\" w:anchor=\""); size_t nSharp = sRef.find('#'); if(nSharp == std::wstring::npos) @@ -2576,6 +2579,7 @@ class CHtmlFile2_Private oRelationshipXml->WriteEncodeXmlString(sRef); oRelationshipXml->WriteString(L"\" TargetMode=\"External\"/>"); + m_bInHyperlink = true; // Пишем в document.xml oXml->WriteString(L"<w:hyperlink w:tooltip=\""); oXml->WriteEncodeXmlString(sNote); @@ -2584,11 +2588,22 @@ class CHtmlFile2_Private } oXml->WriteString(L"\">"); - oXml->WriteString(oInsideData.GetData()); + if(!readStream(oXml, sSelectors, oTS)) + { + oXml->WriteString(L"<w:r>"); + wrRPr(oXml, sSelectors, oTS); + oXml->WriteString(L"<w:t xml:space=\"preserve\">"); + oXml->WriteEncodeXmlString(sAlt); + oXml->WriteString(L"</w:t></w:r>"); + } if (m_bInP) { - oXml->WriteString(L"</w:hyperlink>"); + if (m_bInHyperlink) + { + oXml->WriteString(L"</w:hyperlink>"); + m_bInHyperlink = false; + } bool bFootnote = false; if (sSelectors.size() > 1) @@ -2611,9 +2626,12 @@ class CHtmlFile2_Private else oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteRef/></w:r>"); } + + if (!bInP) + CloseP(oXml, sSelectors); } - sNote = L""; + sNote.clear(); } bool readBase64 (const std::wstring& sSrcM, std::wstring& sExtention) @@ -2692,12 +2710,28 @@ class CHtmlFile2_Private sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz"; } - void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt) + void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc) { if (wsAlt.empty()) { //TODO:: реализовать отображение того, что картинку не удалось получить - WriteEmptyParagraph(oXml, false, m_bInP); + if (wsSrc.empty()) + WriteEmptyParagraph(oXml, false, m_bInP); + else + { + m_oDocXmlRels.WriteString(L"<Relationship Id=\"rId"); + m_oDocXmlRels.WriteString(std::to_wstring(m_nId)); + m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\""); + m_oDocXmlRels.WriteEncodeXmlString(wsSrc); + m_oDocXmlRels.WriteString(L"\" TargetMode=\"External\"/>"); + + const bool bOpenedP{OpenP(oXml)}; + + WriteEmptyImage(oXml, 304800, 304800); + + if (bOpenedP) + CloseP(oXml, sSelectors); + } return; } @@ -2725,7 +2759,7 @@ class CHtmlFile2_Private if (sSrcM.empty()) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); return; } @@ -2735,11 +2769,13 @@ class CHtmlFile2_Private if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos) bIsBase64 = true; - if (!bIsBase64) + if (!bIsBase64 && (sSrcM.length() <= 7 || L"http" != sSrcM.substr(0, 4))) + { sSrcM = NSSystemPath::ShortenPath(sSrcM); - if (!CanUseThisPath(sSrcM, bIsAllowExternalLocalFiles)) - return; + if (!CanUseThisPath(sSrcM, bIsAllowExternalLocalFiles)) + return; + } int nImageId = -1; std::wstring sImageSrc, sExtention; @@ -2754,7 +2790,7 @@ class CHtmlFile2_Private std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); if (NotValidExtension(sExtention)) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); return; } @@ -2800,7 +2836,7 @@ class CHtmlFile2_Private } if (!bRes) - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); else { wrP(oXml, sSelectors, oTS); @@ -2872,6 +2908,7 @@ class CHtmlFile2_Private oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); oXml->WriteNodeEnd(L"w:pPr"); m_bWasPStyle = true; + return sPStyle; } @@ -2907,6 +2944,38 @@ class CHtmlFile2_Private return sRStyle; } + void WriteImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight, const std::wstring& wsId) + { + // Пишем в document.xml + pXml->WriteString(L"<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\""); + pXml->WriteString(std::to_wstring(nWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(nHeight)); + pXml->WriteString(L"\"/><wp:docPr id=\""); + pXml->WriteString(wsId); + pXml->WriteString(L"\" name=\"\"/><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\""); + pXml->WriteString(wsId); + pXml->WriteString(L"\" name=\"\"/><pic:cNvPicPr></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rPic"); + pXml->WriteString(wsId); + pXml->WriteString(L"\"/><a:stretch/></pic:blipFill><pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\""); + pXml->WriteString(std::to_wstring(nWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(nHeight)); + pXml->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + } + + void WriteEmptyImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight) + { + pXml->WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"); + pXml->WriteString(L"<wp:docPr id=\"" + std::to_wstring(m_nId - 7) + L"\" name=\"\"/>"); + pXml->WriteString(L"<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>"); + pXml->WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); + pXml->WriteString(L"<pic:nvPicPr><pic:cNvPr id=\"0\" name=\"\"/><pic:cNvPicPr><a:picLocks noChangeAspect=\"1\" noChangeArrowheads=\"1\"/></pic:cNvPicPr></pic:nvPicPr>"); + pXml->WriteString(L"<pic:blipFill><a:blip r:link=\"rId" + std::to_wstring(m_nId++) + L"\"><a:extLst><a:ext uri=\"{28A0092B-C50C-407E-A947-70E740481C1C}\"><a14:useLocalDpi xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"0\"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>"); + pXml->WriteString(L"<pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr>"); + pXml->WriteString(L"</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + } + void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention) { bool bNew = nImageId < 0; @@ -2958,22 +3027,7 @@ class CHtmlFile2_Private nWx = nW; } - // Пишем в document.xml - oXml->WriteString(L"<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\""); - oXml->WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/><wp:docPr id=\""); - oXml->WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\""); - oXml->WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/><pic:cNvPicPr></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rPic"); - oXml->WriteString(sImageId); - oXml->WriteString(L"\"/><a:stretch/></pic:blipFill><pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\""); - oXml->WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + WriteImage(oXml, nWx, nHy, sImageId); } void readNote (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const std::wstring& sNote) diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index 01479d37255..5f565aeb877 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -135,6 +135,30 @@ namespace NSStringFinder return FindPropetyTemplate<wchar_t>(wsString, wsProperty, arDelimiters, arEndings, unStarting); } + template<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> + bool RemoveEmptyTagTemplate(StringType& sValue, const StringType& sTagName, size_t unStart) + { + boost::wregex oRegex(L"<\\s*(?i)" + std::wstring(sTagName.begin(), sTagName.end()) + L"\\s*[^>]*/>"); + boost::match_results<typename StringType::const_iterator> oResult; + + if (unStart >= sValue.length() || !boost::regex_search(sValue.cbegin() + unStart, sValue.cend(), oResult, oRegex)) + return false; + + sValue.erase(unStart + oResult.position(), oResult.length()); + + return true; + } + + bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0) + { + return RemoveEmptyTagTemplate<char>(sValue, sTagName, unStart); + } + + bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0) + { + return RemoveEmptyTagTemplate<wchar_t>(sValue, sTagName, unStart); + } + template <typename StringType, typename StringEndgeType> void CutInside(StringType& sString, const StringEndgeType& sLeftEdge, const StringEndgeType& sRightEdge) { From ff3b94a23a4b92ecd9c4e5b2ae5c724b8ae19dad Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Sat, 18 May 2024 13:05:58 +0300 Subject: [PATCH 669/794] Fix bug #68036 --- HtmlFile2/htmlfile2.cpp | 56 ++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index cbea0ad966b..b6172cab19f 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -151,6 +151,11 @@ void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = fal pXml->WriteString(L"</w:pPr></w:p>"); } +bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors) +{ + return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; }); +} + typedef enum { ParseModeHeader, @@ -1619,6 +1624,31 @@ class CHtmlFile2_Private m_bInP = false; } + void WriteBookmark(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsId) + { + if (NULL == pXml) + return; + + const std::wstring sCrossId = std::to_wstring(m_mBookmarks.size() + 1); + std::wstring sName; + + if (m_mBookmarks.end() != m_mBookmarks.find(wsId)) + sName = wsId + L"_" + std::to_wstring(++m_mBookmarks[wsId]); + else + { + sName = wsId; + m_mBookmarks.insert({wsId, 1}); + } + + pXml->WriteString(L"<w:bookmarkStart w:id=\""); + pXml->WriteString(sCrossId); + pXml->WriteString(L"\" w:name=\""); + pXml->WriteEncodeXmlString(sName); + pXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); + pXml->WriteString(sCrossId); + pXml->WriteString(L"\"/>"); + } + std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors) { NSCSS::CNode oNode; @@ -1630,17 +1660,10 @@ class CHtmlFile2_Private std::wstring sName = m_oLightReader.GetName(); if(sName == L"class") oNode.m_wsClass = m_oLightReader.GetText(); - else if(sName == L"id" && NULL != oXml) + else if(sName == L"id") { oNode.m_wsId = m_oLightReader.GetText(); - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - oXml->WriteString(L"<w:bookmarkStart w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteEncodeXmlString(oNode.m_wsId); - oXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\"/>"); + WriteBookmark(oXml, oNode.m_wsId); } else if(sName == L"style") oNode.m_wsStyle += m_oLightReader.GetText(); @@ -2009,6 +2032,7 @@ class CHtmlFile2_Private sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" || sName == L"comment" || sName == L"title" || sName == L"style") { + WriteEmptyParagraph(oXml); sSelectors.pop_back(); return; } @@ -2421,7 +2445,8 @@ class CHtmlFile2_Private oXml->WriteEncodeXmlString(sValue + L' '); oXml->WriteString(L"</w:t></w:r>"); } - readStream(oXml, sSelectors, oTS); + + readStream(oXml, sSelectors, oTS, ElementInTable(sSelectors)); } void readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, bool bType) @@ -2527,16 +2552,7 @@ class CHtmlFile2_Private bCross = true; } else if(sName == L"name") - { - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - oXml->WriteString(L"<w:bookmarkStart w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteString(sText); - oXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\"/>"); - } + WriteBookmark(oXml, sText); else if(sName == L"alt") sAlt = sText; else if (sName == L"style" && sText.find(L"mso-footnote-id") != std::wstring::npos) From 6ad319554d1cf7760fe44e95cde13299b1d2ce6f Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Sat, 18 May 2024 13:42:32 +0300 Subject: [PATCH 670/794] Fix bug with font-size --- Common/3dParty/html/css/src/StyleProperties.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c2ffb22901c..c05c7338939 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -2212,16 +2212,16 @@ namespace NSCSS bool CFont::SetSize(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - const std::map<std::wstring, std::wstring> arAbsoluteFontValues = - {{L"xx-small", L"7.5pt"}, {L"x-small", L"10pt" }, + const std::vector<std::pair<std::wstring, std::wstring>> arAbsoluteFontValues = + {{L"xx-small", L"7.5pt"}, {L"xx-large", L"36pt" }, + {L"x-small", L"10pt" }, {L"x-large", L"24pt" }, {L"small", L"12pt" }, {L"medium", L"13.5pt"}, - {L"large", L"18pt" }, {L"x-large", L"24pt" }, - {L"xx-large", L"36pt" }}; + {L"large", L"18pt" }}; size_t unFoundPos = std::wstring::npos; std::wstring wsNewValue(wsValue); - for (const std::pair<std::wstring, std::wstring> oAbsValue : arAbsoluteFontValues) + for (const std::pair<std::wstring, std::wstring>& oAbsValue : arAbsoluteFontValues) { unFoundPos = wsNewValue.find(oAbsValue.first); if (std::wstring::npos != unFoundPos) From d82b2dc6ef8ae207856cb76fb1262dae3098401f Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Sat, 18 May 2024 14:14:05 +0300 Subject: [PATCH 671/794] Fix bug #68073 --- HtmlFile2/htmlfile2.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index b6172cab19f..0744984eed9 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1509,7 +1509,13 @@ class CHtmlFile2_Private void PageBreakBefore() { - m_oDocXml.WriteString(L"<w:p><w:pPr><w:pageBreakBefore/></w:pPr></w:p>"); + if (!m_bInP) + m_oDocXml.WriteString(L"<w:p>"); + + m_oDocXml.WriteString(L"<w:pPr><w:pageBreakBefore/></w:pPr>"); + + if (!m_bInP) + m_oDocXml.WriteString(L"</w:p>"); } private: @@ -1994,7 +2000,7 @@ class CHtmlFile2_Private oXml->WriteString(oTS.sRStyle); oXml->WriteString(L"</w:rPr>"); } - oXml->WriteString(L"</w:rPr><w:t xml:space=\"preserve\">"</w:t></w:r>"); + oXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t></w:r>"); } // Текст верхнего регистра else if(sName == L"rt" || sName == L"sup") From 7a73d3288cf114770ad001e0bd4877510343bed3 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Sun, 19 May 2024 11:21:18 +0300 Subject: [PATCH 672/794] Refactoring --- .../docbuilder.python/src/docbuilder.py | 76 ++++--------------- .../src/docbuilder_func_lib.pro | 7 +- .../docbuilder.python/src/docbuilder_test.py | 28 +++++++ 3 files changed, 44 insertions(+), 67 deletions(-) create mode 100644 DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 0a8f9b7ccea..cff5b44a935 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -9,13 +9,17 @@ _lib = None def loadLibrary(path): - if any(platform.win32_ver()): - os.environ['PATH'] += ';' + path - else: - os.environ['PATH'] += ':' + path - + os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] + + os_name = platform.system().lower() + library_ext = "dll" + if ("linux" == os_name): + library_ext = "so" + elif ("darwin" == os_name): + library_ext = "dylib" + global _lib - _lib = ctypes.CDLL(path + '/docbuilder_functions.dll') + _lib = ctypes.CDLL(path + '/docbuilder_functions.' + library_ext) # init all function signatures # ===== CDocBuilderValue ===== @@ -524,60 +528,6 @@ def CreateScope(self): def IsError(self): return _lib.CDocBuilderContext_IsError(self._internal) -if __name__ == '__main__': - if len(sys.argv) < 2: - print('Specify the folder with document builder and all dll-s') - exit(0) - - path = sys.argv[1] - - loadLibrary(path) - - # --------- - ''' - _lib.CDocBuilder_InitializeWithDirectory(path) - builder = _lib.CDocBuilder_Create() - - sVersion = _lib.CDocBuilder_GetVersion(builder) - version = ctypes.cast(sVersion, ctypes.c_char_p).value - print(version) - _lib.DeleteCharP(ctypes.cast(sVersion, ctypes.c_char_p)) - - _lib.CDocBuilder_Dispose() - _lib.CDocBuilder_Destroy(builder) - ''' - # --------- - ''' - CDocBuilder.Initialize(path) - builder = CDocBuilder() - - version = builder.GetVersion() - print(version) - - CDocBuilder.Dispose() - ''' - # --------- - CDocBuilder.Initialize(path) - builder = CDocBuilder() - - builder.CreateFile('docx') - - context = builder.GetContext() - scope = context.CreateScope() - - globalObj = context.GetGlobal() - - api = globalObj['Api'] - document = api.Call('GetDocument') - paragraph = api.Call('CreateParagraph') - paragraph.Call('SetSpacingAfter', 1000, False) - paragraph.Call('AddText', 'Hello, World!') - content = context.CreateArray(1) - content[0] = paragraph - document.Call('InsertContent', content) - - dstPath = os.getcwd() + '/result.docx' - builder.SaveFile('docx', dstPath) - builder.CloseFile() - - CDocBuilder.Dispose() +builder_path = os.path.dirname(os.path.realpath(__file__)) +loadLibrary(builder_path) +CDocBuilder.Initialize(builder_path) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro index 03fdfc203ab..9bfc8f16485 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_func_lib.pro @@ -1,7 +1,7 @@ QT -= core QT -= gui -TARGET = docbuilder_functions +TARGET = docbuilder.c TEMPLATE = lib @@ -12,10 +12,9 @@ CORE_ROOT_DIR = $$PWD/../../../.. PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -ADD_DEPENDENCY(doctrenderer) - -DESTDIR = $$PWD/build +ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer) INCLUDEPATH += ../.. diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py new file mode 100644 index 00000000000..265c5f9ee42 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py @@ -0,0 +1,28 @@ +import os +import sys +sys.path.append('directory_installed_docbuilder/docbuilder.py') +import docbuilder + +builder = docbuilder.CDocBuilder() + +builder.CreateFile('docx') + +context = builder.GetContext() +scope = context.CreateScope() + +globalObj = context.GetGlobal() + +api = globalObj['Api'] +document = api.Call('GetDocument') +paragraph = api.Call('CreateParagraph') +paragraph.Call('SetSpacingAfter', 1000, False) +paragraph.Call('AddText', 'Hello, World!') +content = context.CreateArray(1) +content[0] = paragraph +document.Call('InsertContent', content) + +dstPath = os.getcwd() + '/result.docx' +builder.SaveFile('docx', dstPath) +builder.CloseFile() + +docbuilder.CDocBuilder.Dispose() From 5a04f9033b0f4f74ffa670b956b434ea03190003 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Sun, 19 May 2024 11:33:45 +0300 Subject: [PATCH 673/794] Fix build --- .../doctrenderer/docbuilder.python/src/docbuilder_functions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp index b9aab0f4178..24bb38523fc 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -1,6 +1,7 @@ #include "docbuilder_functions.h" #include <cstring> +#include <wchar.h> // ===== CDocBuilderValue ===== CDocBuilderValue* CDocBuilderValue_Create() From 58980e61b7defd1ecc30542a81189aa02ad6e93e Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Sun, 19 May 2024 12:02:37 +0300 Subject: [PATCH 674/794] Fix typo and create folder for tests --- DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py | 2 +- .../docbuilder.python/src/{ => test}/docbuilder_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename DesktopEditor/doctrenderer/docbuilder.python/src/{ => test}/docbuilder_test.py (90%) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index cff5b44a935..4ef45854acf 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -19,7 +19,7 @@ def loadLibrary(path): library_ext = "dylib" global _lib - _lib = ctypes.CDLL(path + '/docbuilder_functions.' + library_ext) + _lib = ctypes.CDLL(path + '/docbuilder.c.' + library_ext) # init all function signatures # ===== CDocBuilderValue ===== diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/src/test/docbuilder_test.py similarity index 90% rename from DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py rename to DesktopEditor/doctrenderer/docbuilder.python/src/test/docbuilder_test.py index 265c5f9ee42..d1d7aec51ae 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_test.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/test/docbuilder_test.py @@ -1,6 +1,6 @@ import os import sys -sys.path.append('directory_installed_docbuilder/docbuilder.py') +sys.path.append('path_to_docbuilder') import docbuilder builder = docbuilder.CDocBuilder() From d0a82d71eecc5110b1673c4ba1b2cb3df5820ac3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Mon, 20 May 2024 12:29:00 +0300 Subject: [PATCH 675/794] Fix build --- PdfFile/PdfFile.cpp | 1 - PdfFile/SrcWriter/Field.cpp | 23 +++++++++++++---------- PdfFile/SrcWriter/Field.h | 8 ++++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index a5e86ab8262..f8b19ca312a 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -59,7 +59,6 @@ class CPdfEditor void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} int GetRotate(int nPageIndex) { return 0; } bool IsEditPage() { return false; } - bool EditPage(int nPageIndex) { return false; } void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; } diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 768d63e4d8d..4c769c1a0e7 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1537,40 +1537,41 @@ namespace PdfWriter m_pRollover = NULL; m_pDown = NULL; } - CAnnotAppearanceObject* CAnnotAppearance::GetNormal() + CAnnotAppearanceObject* CAnnotAppearance::GetNormal(CResourcesDict* pResources) { if (!m_pNormal) { if (m_pField) m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot); - Add("N", m_pNormal); + m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); + if (m_pXref) + Add("N", m_pNormal); } return m_pNormal; } - CAnnotAppearanceObject* CAnnotAppearance::GetRollover() + CAnnotAppearanceObject* CAnnotAppearance::GetRollover(CResourcesDict* pResources) { if (!m_pRollover) { if (m_pField) m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pAnnot); + m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("R", m_pRollover); } return m_pRollover; } - CAnnotAppearanceObject* CAnnotAppearance::GetDown() + CAnnotAppearanceObject* CAnnotAppearance::GetDown(CResourcesDict* pResources) { if (!m_pDown) { if (m_pField) m_pDown = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot); + m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("D", m_pDown); } @@ -1621,13 +1622,15 @@ namespace PdfWriter void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { m_pXref = pXref ? pXref : NULL; - m_pStream = new CMemoryStream(); m_pFont = NULL; m_dFontSize = 10.0; m_bStart = true; if (m_pXref) + { + m_pStream = new CMemoryStream(); SetStream(m_pXref, m_pStream); + } Add("Type", "XObject"); Add("Subtype", "Form"); @@ -1649,9 +1652,9 @@ namespace PdfWriter pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); } - CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot) + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) { - Init(pXRef, pAnnot->GetDocument()->GetFieldsResources()); + Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); m_pAnnot = pAnnot; m_pField = NULL; diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 6280a8d038f..0fb7548e7de 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -344,9 +344,9 @@ namespace PdfWriter CAnnotAppearance(CXref* pXRef, CFieldBase* pField); CAnnotAppearance(CXref* pXRef, CAnnotation* pAnnot); - CAnnotAppearanceObject* GetNormal(); - CAnnotAppearanceObject* GetRollover(); - CAnnotAppearanceObject* GetDown(); + CAnnotAppearanceObject* GetNormal(CResourcesDict* pResources = NULL); + CAnnotAppearanceObject* GetRollover(CResourcesDict* pResources = NULL); + CAnnotAppearanceObject* GetDown(CResourcesDict* pResources = NULL); private: @@ -382,7 +382,7 @@ namespace PdfWriter { public: CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); - CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot); + CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources = NULL); void DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize = 10.0, double dX = 0.0, double dY = 0.0, double dR = 0.0, double dG = 0.0, double dB = 0.0, const char* sExtGrStateName = NULL, double dW = 1.0, double dH = 1.0, CFontCidTrueType** ppFonts = NULL, double* pShifts = NULL); void DrawPicture(const char* sImageName = NULL, const double& dX = 0.0, const double& dY = 0.0, const double& dW = 0.0, const double& dH = 0.0, const bool& bRespectBorder = false); void StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight); From 0e5b95f1d80100b85e7b35c05e6a5ffa91e4a3be Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <Mikhail.Lobotskiy@onlyoffice.com> Date: Mon, 20 May 2024 13:21:01 +0400 Subject: [PATCH 676/794] Refactoring --- .../{ => docbuilder_func_lib}/docbuilder_func_test.pro | 10 +++++----- .../test/{ => docbuilder_func_lib}/main.cpp | 4 ++-- .../{src => }/test/docbuilder_test.py | 0 3 files changed, 7 insertions(+), 7 deletions(-) rename DesktopEditor/doctrenderer/docbuilder.python/test/{ => docbuilder_func_lib}/docbuilder_func_test.pro (55%) rename DesktopEditor/doctrenderer/docbuilder.python/test/{ => docbuilder_func_lib}/main.cpp (98%) rename DesktopEditor/doctrenderer/docbuilder.python/{src => }/test/docbuilder_test.py (100%) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro similarity index 55% rename from DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro rename to DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro index 0af73a0782e..9624461e5ec 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_test.pro +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/docbuilder_func_test.pro @@ -8,20 +8,20 @@ TEMPLATE = app CONFIG -= app_bundle CONFIG += console -CORE_ROOT_DIR = $$PWD/../../../.. +CORE_ROOT_DIR = $$PWD/../../../../.. PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) -# !!! Set docbuilder path here !!! -DOCUMENT_BUILDER_INSTALL_PATH="C:/Program Files/ONLYOFFICE/DocumentBuilder" +# Set docbuilder path here +DOCUMENT_BUILDER_INSTALL_PATH=C:/Program Files/ONLYOFFICE/DocumentBuilder DEFINES += "DOCUMENT_BUILDER_INSTALL_PATH=\"$$DOCUMENT_BUILDER_INSTALL_PATH\"" -LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder_functions +LIBS += -L'$$DOCUMENT_BUILDER_INSTALL_PATH' -ldocbuilder.c DESTDIR = $$PWD/build -INCLUDEPATH += ../.. +INCLUDEPATH += ../../.. SOURCES += \ main.cpp diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp similarity index 98% rename from DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp rename to DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp index 9dc6874ea4f..cde089b7aa9 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/main.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_func_lib/main.cpp @@ -1,4 +1,4 @@ -#include "../src/docbuilder_functions.h" +#include "docbuilder.python/src/docbuilder_functions.h" #include <string> #include <iostream> @@ -27,7 +27,7 @@ int main() { std::wstring sWorkDirectory = NSUtils::GetBuilderDirectory(); -#if 1 +#if 0 // Simple test that shows builder version if everything is correct CDocBuilder_InitializeWithDirectory(sWorkDirectory.c_str()); CDocBuilder* pBuilder = CDocBuilder_Create(); diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/test/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py similarity index 100% rename from DesktopEditor/doctrenderer/docbuilder.python/src/test/docbuilder_test.py rename to DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py From 788620079d2e1dbab339dab414de245e83301d16 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <Mikhail.Lobotskiy@onlyoffice.com> Date: Mon, 20 May 2024 14:33:43 +0400 Subject: [PATCH 677/794] Add `loadLibrary()` check and automatic `Dispose()` --- .../docbuilder.python/src/docbuilder.py | 32 ++++++++++++------- .../docbuilder.python/test/docbuilder_test.py | 2 -- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 4ef45854acf..9d23fb898b1 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -1,24 +1,27 @@ import ctypes import os import platform -import sys +import atexit OBJECT_HANDLE = ctypes.c_void_p STRING_HANDLE = ctypes.c_void_p _lib = None -def loadLibrary(path): +def _loadLibrary(path): + global _lib + if _lib is not None: + return + os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] - + os_name = platform.system().lower() library_ext = "dll" if ("linux" == os_name): library_ext = "so" elif ("darwin" == os_name): library_ext = "dylib" - - global _lib + _lib = ctypes.CDLL(path + '/docbuilder.c.' + library_ext) # init all function signatures @@ -391,6 +394,8 @@ def Call(self, name, *args): raise TypeError("Call() expects at most 6 arguments") class CDocBuilder: + _initialized = False + def __init__(self): self._internal = _lib.CDocBuilder_Create() self._lib = _lib @@ -460,16 +465,19 @@ def GetVersion(self): def GetContext(self): return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal))) - @staticmethod - def Initialize(directory=None): + @classmethod + def Initialize(cls, directory=None): if directory is None: _lib.CDocBuilder_Initialize() else: _lib.CDocBuilder_InitializeWithDirectory(ctypes.c_wchar_p(directory)) + cls._initialized = True - @staticmethod - def Dispose(): - _lib.CDocBuilder_Dispose() + @classmethod + def Dispose(cls): + if (cls._initialized): + _lib.CDocBuilder_Dispose() + cls._initialized = False class CDocBuilderContextScope: def __init__(self, value=None): @@ -529,5 +537,7 @@ def IsError(self): return _lib.CDocBuilderContext_IsError(self._internal) builder_path = os.path.dirname(os.path.realpath(__file__)) -loadLibrary(builder_path) +_loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) + +atexit.register(CDocBuilder.Dispose) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py index d1d7aec51ae..8fd73b26fd5 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py @@ -24,5 +24,3 @@ dstPath = os.getcwd() + '/result.docx' builder.SaveFile('docx', dstPath) builder.CloseFile() - -docbuilder.CDocBuilder.Dispose() From fac976a22e6183fc12dc541e99ca91d6d6f5ed7f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Mon, 20 May 2024 17:52:22 +0300 Subject: [PATCH 678/794] Read and write image ref for OShapes --- DesktopEditor/graphics/commands/DocInfo.cpp | 18 ++++++++- DesktopEditor/graphics/commands/DocInfo.h | 7 +++- PdfFile/PdfEditor.cpp | 2 +- PdfFile/PdfReader.cpp | 2 +- PdfFile/SrcReader/RendererOutputDev.cpp | 35 ++++++++++++++++++ PdfFile/SrcReader/RendererOutputDev.h | 1 + PdfFile/SrcWriter/Document.cpp | 41 ++++++++++++++++++--- PdfFile/SrcWriter/Document.h | 4 ++ PdfFile/lib/xpdf/Gfx.cc | 28 ++++++++------ PdfFile/lib/xpdf/OutputDev.h | 1 + 10 files changed, 119 insertions(+), 20 deletions(-) diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index 6ebbaf74e83..e82ba62bfdb 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -129,9 +129,25 @@ bool CDocInfoCommand::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta return true; } -CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) {} +CShapeStart::CShapeStart() : IAdvancedCommand(AdvancedCommandType::ShapeStart) +{ + m_pImage = NULL; +} +CShapeStart::~CShapeStart() +{ + RELEASEINTERFACE(m_pImage); +} void CShapeStart::SetShapeXML(const std::string& sShapeXML) { m_sShapeXML = sShapeXML; } +void CShapeStart::SetShapeImage(BYTE* pImgData, int nWidth, int nHeight) +{ + if (pImgData) + { + m_pImage = new Aggplus::CImage(); + m_pImage->Create(pImgData, nWidth, nHeight, -4 * nWidth); + } +} const std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } +Aggplus::CImage* CShapeStart::GetShapeImage() { return m_pImage; } bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { m_sShapeXML = pReader->ReadStringA(); diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index 9690ffd14fb..f17ed97b332 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -136,14 +136,19 @@ class GRAPHICS_DECL CShapeStart : public IAdvancedCommand { public: CShapeStart(); + ~CShapeStart(); - void SetShapeXML(const std::string& sShapeXML); const std::string& GetShapeXML(); + Aggplus::CImage* GetShapeImage(); + + void SetShapeXML(const std::string& sShapeXML); + void SetShapeImage(BYTE* pImgData, int nWidth, int nHeight); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); private: std::string m_sShapeXML; + Aggplus::CImage* m_pImage; }; class GRAPHICS_DECL CEmptyComand : public IAdvancedCommand diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index aeb5a9673ec..909f6f5bd0e 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1288,7 +1288,7 @@ void CPdfEditor::AddShapeXML(const std::string& sXML) } void CPdfEditor::EndMarkedContent() { - pWriter->GetPage()->EndMarkedContent(); + pWriter->GetDocument()->EndShapeXML(); } bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index f56cdedddde..283f444e486 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1656,7 +1656,7 @@ BYTE* CPdfReader::GetShapes(int nPageIndex) Object oProperties, oMetaOForm, oID; XRef* xref = m_pPDFDocument->getXRef(); - if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("MetaOForm", &oMetaOForm)->isDict("MetaOForm") || !oMetaOForm.dictLookup("ID", &oID)->isString()) + if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("OShapes", &oMetaOForm)->isDict("OShapes") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { oProperties.free(); oMetaOForm.free(); oID.free(); return NULL; diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 29ebe5029b0..4b5c6cdd200 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -4195,12 +4195,47 @@ namespace PdfReader return; } GBool RendererOutputDev::beginMarkedContent(GfxState *state, GString* s) + { + return gFalse; + } + GBool RendererOutputDev::beginMCOShapes(GfxState *state, GString *s, Object *ref) { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) { CShapeStart* pCommand = new CShapeStart(); pCommand->SetShapeXML(s->getCString()); + + Object oIm; + if (ref && ref->isRef() && ref->fetch(m_pXref, &oIm)->isStream()) + { + Dict *oImDict = oIm.streamGetDict(); + + int nLength = 0; + Object oLength; + if (oImDict->lookup("Length", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + if (oImDict->lookup("DL", &oLength)->isInt()) + nLength = oLength.getInt(); + oLength.free(); + + Stream* pImage = oIm.getStream()->getUndecodedStream(); + pImage->reset(); + + BYTE* pBuffer = new BYTE[nLength]; + BYTE* pBufferPtr = pBuffer; + for (int nI = 0; nI < nLength; ++nI) + *pBufferPtr++ = (BYTE)pImage->getChar(); + + CBgraFrame oFrame; + if (oFrame.Decode(pBuffer, nLength)) + { + pCommand->SetShapeImage(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height()); + oFrame.ClearNoAttack(); + } + } + oIm.free(); bool bRes = m_pRenderer->AdvancedCommand(pCommand) == S_OK; RELEASEOBJECT(pCommand); if (bRes) diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index 24b698b15fd..b8fa2c3d0fa 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -260,6 +260,7 @@ namespace PdfReader void Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy); //----- Дополнительные функции virtual GBool beginMarkedContent(GfxState *state, GString *s) override; + virtual GBool beginMCOShapes(GfxState *state, GString *s, Object *ref) override; virtual void endMarkedContent(GfxState *state) override; //----- Вывод картинок virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 08b1091e13c..c49b098da1a 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -80,6 +80,7 @@ namespace PdfWriter m_pPageTree = NULL; m_pCurPage = NULL; m_nCurPageNum = -1; + m_pCurImage = NULL; m_unFormFields = 0; m_pInfo = NULL; m_pTrailer = NULL; @@ -192,6 +193,7 @@ namespace PdfWriter m_pPageTree = NULL; m_pCurPage = NULL; m_nCurPageNum = 0; + m_pCurImage = NULL; m_unFormFields = 0; m_bEncrypt = false; m_pEncryptDict = NULL; @@ -1271,7 +1273,10 @@ namespace PdfWriter for (size_t i = 0, nSize = m_vImages.size(); i < nSize; ++i) { if (m_vImages[i].wsImagePath == wsImagePath && m_vImages[i].nAlpha == nAlpha) + { + m_pCurImage = m_vImages[i].pImage; return m_vImages[i].pImage; + } } return NULL; } @@ -1279,6 +1284,7 @@ namespace PdfWriter { if (!pImage) return; + m_pCurImage = pImage; m_vImages.push_back({wsImagePath, nAlpha, pImage}); } bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) @@ -1782,10 +1788,10 @@ namespace PdfWriter pProperties = new CDictObject(); pResources->Add("Properties", pProperties); } - CObjectBase* pObj = pProperties->Get("MetaOForm"); + CObjectBase* pObj = pProperties->Get("OShapes"); if (pObj && pObj->GetType() != object_type_DICT) { - pProperties->Remove("MetaOForm"); + pProperties->Remove("OShapes"); pObj = NULL; } CDictObject* pMetaOForm = (CDictObject*)pObj; @@ -1793,8 +1799,8 @@ namespace PdfWriter { pMetaOForm = new CDictObject(); m_pXref->Add(pMetaOForm); - pMetaOForm->Add("Type", "MetaOForm"); - pProperties->Add("MetaOForm", pMetaOForm); + pMetaOForm->Add("Type", "OShapes"); + pProperties->Add("OShapes", pMetaOForm); m_vMetaOForms.push_back(pMetaOForm); CBinaryObject* sID = NULL; @@ -1821,14 +1827,39 @@ namespace PdfWriter { pArrayMeta = new CArrayObject(); pMetaOForm->Add("Metadata", pArrayMeta); + CArrayObject* pArrayImage = new CArrayObject(); + pMetaOForm->Add("Image", pArrayImage); } pArrayMeta->Add(new CStringObject(sXML.c_str())); CDictObject* pBDC = new CDictObject(); pBDC->Add("MCID", pArrayMeta->GetCount() - 1); - m_pCurPage->BeginMarkedContentDict("MetaOForm", pBDC); + m_pCurPage->BeginMarkedContentDict("OShapes", pBDC); RELEASEOBJECT(pBDC); } + void CDocument::EndShapeXML() + { + CDictObject* pResources = (CDictObject*)m_pCurPage->Get("Resources"); + if (!pResources) + return; + CDictObject* pProperties = (CDictObject*)pResources->Get("Properties"); + if (!pProperties) + return; + CObjectBase* pObj = pProperties->Get("OShapes"); + if (!pObj || pObj->GetType() != object_type_DICT) + return; + CDictObject* pMetaOForm = (CDictObject*)pObj; + CArrayObject* pArrayImage = (CArrayObject*)pMetaOForm->Get("Image"); + if (!pArrayImage) + return; + + pObj = m_pCurImage; + if (!pObj) + pObj = new PdfWriter::CNullObject(); + pArrayImage->Add(pObj); + + m_pCurPage->EndMarkedContent(); + } void CDocument::ClearPage() { m_pCurPage->ClearContent(m_pXref); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 6d12ee0fc7c..a9553518ec7 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -183,6 +183,8 @@ namespace PdfWriter bool HasImage(const std::wstring& wsImagePath, BYTE nAlpha); CImageDict* GetImage(const std::wstring& wsImagePath, BYTE nAlpha); void AddImage(const std::wstring& wsImagePath, BYTE nAlpha, CImageDict* pImage); + CImageDict* GetCurImage() { return m_pCurImage; } + void SetCurImage(CImageDict* pImage) { m_pCurImage = pImage; } bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); @@ -205,6 +207,7 @@ namespace PdfWriter bool EditCO(const std::vector<int>& arrCO); const std::map<int, CAnnotation*>& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); + void EndShapeXML(); void ClearPage(); private: @@ -274,6 +277,7 @@ namespace PdfWriter CPageTree* m_pPageTree; CPage* m_pCurPage; int m_nCurPageNum; + CImageDict* m_pCurImage; CInfoDict* m_pInfo; CDictObject* m_pTrailer; CDictObject* m_pResources; diff --git a/PdfFile/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 8879323061e..4a66ee81a3d 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,21 +5053,27 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { mcKind = gfxMCActualText; } obj.free(); - } else if (args[0].isName("MetaOForm") && numArgs == 2 && args[1].isDict() && res->lookupPropertiesNF("MetaOForm", &obj)) { + } else if (args[0].isName("OShapes") && numArgs == 2 && args[1].isDict() && res->lookupPropertiesNF("OShapes", &obj)) { Object oMetaOForm, oID, oTID, oID2, oMCID, oMetadata, oMetadataCur; - if (obj.fetch(xref, &oMetaOForm)->isDict("MetaOForm") && oMetaOForm.dictLookup("ID", &oID)->isString() && xref->getTrailerDict()->dictLookup("ID", &oTID)->isArray() && + if (obj.fetch(xref, &oMetaOForm)->isDict("OShapes") && oMetaOForm.dictLookup("ID", &oID)->isString() && xref->getTrailerDict()->dictLookup("ID", &oTID)->isArray() && oTID.arrayGet(1, &oID2)->isString() && oID2.getString()->cmp(oID.getString()) == 0 && args[1].dictLookup("MCID", &oMCID)->isInt() && - oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray() && oMetadata.arrayGet(oMCID.getInt(), &oMetadataCur)->isString() && - out->beginMarkedContent(state, oMetadataCur.getString())) { - oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); - getContentObj(&obj); - while (!obj.isEOF() && !obj.isCmd("EMC")) { - obj.free(); + oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray() && oMetadata.arrayGet(oMCID.getInt(), &oMetadataCur)->isString()) { + oID.free(); oTID.free(); oID2.free(); oMCID.free(); oMetadata.free(); obj.free(); + Object oImRef, oArrImage; + if (!oMetaOForm.dictLookup("Image", &oArrImage)->isArray() || !oArrImage.arrayGetNF(oMCID.getInt(), &oImRef)->isRef()) + oImRef.free(); + if (out->beginMCOShapes(state, oMetadataCur.getString(), &oImRef)) { getContentObj(&obj); + while (!obj.isEOF() && !obj.isCmd("EMC")) { + obj.free(); + getContentObj(&obj); + } + out->endMarkedContent(state); + oImRef.free(); oArrImage.free(); + oMetaOForm.free(); oMetadataCur.free(); obj.free(); + return; } - obj.free(); - out->endMarkedContent(state); - return; + oImRef.free(); oArrImage.free(); } oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); } diff --git a/PdfFile/lib/xpdf/OutputDev.h b/PdfFile/lib/xpdf/OutputDev.h index a770dfd6ff7..540c2900715 100644 --- a/PdfFile/lib/xpdf/OutputDev.h +++ b/PdfFile/lib/xpdf/OutputDev.h @@ -188,6 +188,7 @@ class OutputDev { //----- additional virtual GBool beginMarkedContent(GfxState *state, GString *s) { return gFalse; } + virtual GBool beginMCOShapes(GfxState *state, GString *s, Object *ref) { return gFalse; } virtual void endMarkedContent(GfxState *state) {} //----- image drawing From 9d8e75a957341625ec38ce58cf7ac53ef2b0e5da Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <Mikhail.Lobotskiy@onlyoffice.com> Date: Mon, 20 May 2024 19:40:40 +0400 Subject: [PATCH 679/794] Fix library names for linux and mac --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 9d23fb898b1..62ab28ca242 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -16,13 +16,13 @@ def _loadLibrary(path): os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] os_name = platform.system().lower() - library_ext = "dll" + library_name = 'docbuilder.c.dll' if ("linux" == os_name): - library_ext = "so" + library_name = 'libdocbuilder.c.so' elif ("darwin" == os_name): - library_ext = "dylib" + library_name = 'libdocbuilder.c.dylib' - _lib = ctypes.CDLL(path + '/docbuilder.c.' + library_ext) + _lib = ctypes.CDLL(path + '/' + library_name) # init all function signatures # ===== CDocBuilderValue ===== From 5f8b557eb5fb0a4332defaa52ee283be99eda87e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 21 May 2024 10:18:18 +0300 Subject: [PATCH 680/794] Fix pdf build --- PdfFile/SrcReader/PdfAnnot.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 75a291d83fe..fd718ef6e09 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -47,6 +47,8 @@ #include "../../DesktopEditor/fontengine/ApplicationFonts.h" #include "../../DesktopEditor/graphics/pro/Fonts.h" +#include <map> + namespace PdfReader { @@ -2495,7 +2497,9 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { std::wstring sFontPath = pFontInfo->m_wsFontPath; - bool bFreeText = std::find_if(arrFontFreeText.begin(), arrFontFreeText.end(), [&sFontPath](auto&& p) { return p.second == sFontPath; }) != arrFontFreeText.end(); + bool bFreeText = false; + for (std::map<std::wstring, std::wstring>::iterator it = arrFontFreeText.begin(); it != arrFontFreeText.end(); it++) + bFreeText = it->second == sFontPath; std::wstring wsFontBaseName = pFontInfo->m_wsFontName; if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') { From 1602fb21062900bcdd0c2f5bbc98fca54e1a94e1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 21 May 2024 10:49:49 +0300 Subject: [PATCH 681/794] Fix FreeText renderer length --- DesktopEditor/graphics/commands/AnnotField.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 155dc2e6f66..00f91e72f95 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -601,9 +601,9 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead } if (nFlags & (1 << 22)) { - m_nRenderLen = pReader->ReadInt(); + m_nRenderLen = pReader->ReadInt() - 4; m_pRender = pReader->GetCurrentBuffer(); - pReader->Skip(m_nRenderLen - 4); + pReader->Skip(m_nRenderLen); } } From 8f711f607ff04ba50a9ca0c0735562c446e1d3d5 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 21 May 2024 11:25:57 +0300 Subject: [PATCH 682/794] fix bug #67989 --- OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 8830027dfcd..3fc6ffa9124 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1614,7 +1614,7 @@ bool CConditionalFormattingRule::isValid () const } bool CConditionalFormattingRule::isExtended() { - //if (m_oDxf.IsInit()) return true; + if (m_oDxf.IsInit()) return true; if (m_oDataBar.IsInit()) return m_oDataBar->isExtended(); if (m_oIconSet.IsInit()) return m_oIconSet->isExtended(); From ab52ee7486be36946a7e816ba7fa897819264011 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <mikhail.lobotskiy@onlyoffice.com> Date: Tue, 21 May 2024 17:37:34 +0400 Subject: [PATCH 683/794] Move PATH modify to windows-only section --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index 62ab28ca242..b6aaf81e731 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -13,13 +13,15 @@ def _loadLibrary(path): if _lib is not None: return - os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] - os_name = platform.system().lower() - library_name = 'docbuilder.c.dll' - if ("linux" == os_name): + library_name = '' + if 'windows' == os_name: + # modify PATH to load all DLLs + os.environ['PATH'] = path + os.pathsep + os.environ['PATH'] + library_name = 'docbuilder.c.dll' + elif 'linux' == os_name: library_name = 'libdocbuilder.c.so' - elif ("darwin" == os_name): + elif 'darwin' == os_name: library_name = 'libdocbuilder.c.dylib' _lib = ctypes.CDLL(path + '/' + library_name) From 5dede9304b955cb8c832014463cef73e4c56cec5 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Tue, 21 May 2024 16:52:54 +0300 Subject: [PATCH 684/794] Add support added images on recognize --- DesktopEditor/graphics/commands/DocInfo.cpp | 2 +- DesktopEditor/graphics/commands/DocInfo.h | 4 ++-- DocxRenderer/DocxRenderer.cpp | 9 ++++++++- DocxRenderer/src/logic/managers/ImageManager.h | 3 +-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index e82ba62bfdb..f098bf6b01d 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -146,7 +146,7 @@ void CShapeStart::SetShapeImage(BYTE* pImgData, int nWidth, int nHeight) m_pImage->Create(pImgData, nWidth, nHeight, -4 * nWidth); } } -const std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } +std::string& CShapeStart::GetShapeXML() { return m_sShapeXML; } Aggplus::CImage* CShapeStart::GetShapeImage() { return m_pImage; } bool CShapeStart::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index f17ed97b332..c691a86ecb4 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -138,8 +138,8 @@ class GRAPHICS_DECL CShapeStart : public IAdvancedCommand CShapeStart(); ~CShapeStart(); - const std::string& GetShapeXML(); - Aggplus::CImage* GetShapeImage(); + std::string& GetShapeXML(); + Aggplus::CImage* GetShapeImage(); void SetShapeXML(const std::string& sShapeXML); void SetShapeImage(BYTE* pImgData, int nWidth, int nHeight); diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 85bc381dcdf..befcdad7d2f 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -237,7 +237,14 @@ HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::ShapeStart: { CShapeStart* pShape = (CShapeStart*)command; - const std::string& sUtf8Shape = pShape->GetShapeXML(); + std::string& sUtf8Shape = pShape->GetShapeXML(); + Aggplus::CImage* pImage = pShape->GetShapeImage(); + if (pImage) + { + std::shared_ptr<NSDocxRenderer::CImageInfo> pInfo = m_pInternal->m_oDocument.m_oImageManager.GenerateImageID(pImage); + std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\""; + NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId); + } m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml.push_back(UTF8_TO_U(sUtf8Shape)); return S_OK; } diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index 357b4c9d709..67a9119df56 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -37,8 +37,6 @@ namespace NSDocxRenderer void SaveImage(Aggplus::CImage* pImage, std::shared_ptr<CImageInfo> pInfo); - std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage); - std::shared_ptr<CImageInfo> GenerateImageID(const std::wstring& strFileName); void FlipY(Aggplus::CImage* pImage); @@ -47,5 +45,6 @@ namespace NSDocxRenderer public: static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); + std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage); }; } From a2b04952549a2c59b42d4c7dfa888aad7f3d9864 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Tue, 21 May 2024 21:11:57 +0600 Subject: [PATCH 685/794] Fix bug #66675 --- .../XlsFile/Format/Binary/CFRecord.cpp | 24 ++++++++++- MsBinaryFile/XlsFile/Format/Binary/CFRecord.h | 11 ++++- .../Logic/Biff_structures/DVParsedFormula.cpp | 2 +- .../Logic/Biff_structures/Ftab_Cetab.cpp | 2 +- .../Logic/Biff_structures/StringPtgParser.cpp | 13 ++++++ OOXML/XlsxFormat/Pivot/Pivots.cpp | 22 ++++++++-- OOXML/XlsxFormat/Slicer/SlicerCache.cpp | 41 ++++++++++++++----- .../XlsxFormat/Worksheets/DataValidation.cpp | 19 +++++++-- .../Worksheets/WorksheetChildOther.cpp | 7 ++-- 9 files changed, 114 insertions(+), 27 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp index eff534e0173..2015a5dd947 100644 --- a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp +++ b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp @@ -37,7 +37,7 @@ namespace XLS { -char CFRecord::intData[MAX_RECORD_SIZE]; +char CFRecord::intData[MAX_RECORD_SIZE_XLSB]; // Create a record and read its data from the stream CFRecord::CFRecord(CFStreamPtr stream, GlobalWorkbookInfoPtr global_info) @@ -262,6 +262,10 @@ const BYTE CFRecord::getSizeOfRecordTypeRecordLength() const const size_t CFRecord::getMaxRecordSize() const { + if(global_info_ && (global_info_.get()->Version == 0x0800)) + { + return MAX_RECORD_SIZE_XLSB; + } return MAX_RECORD_SIZE; } @@ -302,6 +306,11 @@ void CFRecord::appendRawDataToStatic(const unsigned char *raw_data, const size_t memcpy(&intData[rdPtr], raw_data, size); rdPtr += size; } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (MAX_RECORD_SIZE_XLSB - rdPtr > size)) + { + memcpy(&intData[rdPtr], raw_data, size); + rdPtr += size; + } } void CFRecord::appendRawDataToStatic(const wchar_t *raw_data, const size_t size) @@ -311,6 +320,11 @@ void CFRecord::appendRawDataToStatic(const wchar_t *raw_data, const size_t size) for(int i = 0; i < size; ++i) storeAnyData(raw_data[i]); } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (MAX_RECORD_SIZE_XLSB - rdPtr > size)) + { + for(int i = 0; i < size; ++i) + storeAnyData(raw_data[i]); + } } @@ -387,6 +401,8 @@ const bool CFRecord::checkFitReadSafe(const size_t size) const const bool CFRecord::checkFitWriteSafe(const size_t size) const { + if(global_info_ && (global_info_.get()->Version == 0x0800)) + return (rdPtr + size <= MAX_RECORD_SIZE_XLSB); return (rdPtr + size <= MAX_RECORD_SIZE); } @@ -432,6 +448,12 @@ void CFRecord::reserveNunBytes(const size_t n) if (rdPtr + n < MAX_RECORD_SIZE) for (size_t i = 0; i < n; ++i) intData[rdPtr++] = 0; + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (rdPtr + n < MAX_RECORD_SIZE_XLSB)) + { + for (size_t i = 0; i < n; ++i) + intData[rdPtr++] = 0; + } + } diff --git a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h index c01e4bd6a5f..8ad0ee56f3a 100644 --- a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h +++ b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.h @@ -131,6 +131,12 @@ class CFRecord rdPtr += sizeof(T); return true; } + else if(global_info_ && (global_info_.get()->Version == 0x0800) && (rdPtr + sizeof(T) < MAX_RECORD_SIZE_XLSB)) + { + memcpy(&intData[rdPtr], &val, sizeof(T)); + rdPtr += sizeof(T); + return true; + } return false; } @@ -161,7 +167,8 @@ class CFRecord CFRecord& operator << (bool& val); private: - static const size_t MAX_RECORD_SIZE = 8224; + static const size_t MAX_RECORD_SIZE = 8224; + static const size_t MAX_RECORD_SIZE_XLSB = 0xFFFFFFF; CFStream::ReceiverItems receiver_items; CFStream::SourceItems source_items; @@ -172,7 +179,7 @@ class CFRecord char* data_; BYTE sizeOfRecordTypeRecordLength; //размер RecordType и RecordLength size_t rdPtr; - static char intData[MAX_RECORD_SIZE]; + static char intData[MAX_RECORD_SIZE_XLSB]; GlobalWorkbookInfoPtr global_info_; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp index 447b0e0b833..7d0cb4d56e1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DVParsedFormula.cpp @@ -93,7 +93,7 @@ void DVParsedFormula::save(CFRecord& record, bool bSave) else { cce = 0; - auto cb = 0; + _UINT32 cb = 0; record << cce << cb; } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp index c0927f95141..52e9b358649 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Ftab_Cetab.cpp @@ -529,7 +529,7 @@ Ftab_Cetab::ValuesDetermination::ValuesDetermination() params_fixed.insert(ParamsFixed(0x01DE, 1, L"CUBESET")); params_fixed.insert(ParamsFixed(0x01DF, 1, L"CUBESETCOUNT")); params_fixed.insert(ParamsFixed(0x01E0, 2, L"IFERROR")); - params_fixed.insert(ParamsFixed(0x01E1, 2, L"COUNTIFS")); + params_fixed.insert(ParamsFixed(0x01E1, -1, L"COUNTIFS")); params_fixed.insert(ParamsFixed(0x01E2, 3, L"SUMIFS")); params_fixed.insert(ParamsFixed(0x01E3, 2, L"AVERAGEIF")); params_fixed.insert(ParamsFixed(0x01E4, 3, L"AVERAGEIFS")); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 980924d3fc1..c0dffe80b04 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -70,6 +70,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { PtgPtr last_ptg; bool operand_expected = true; // This would help distinguish unary and binary and determine if an argument to a function is missed. + bool union_expected = false; for(std::wstring::const_iterator it = assembled_formula.begin(), itEnd = assembled_formula.end(); it != itEnd;) { @@ -266,6 +267,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R if(!ptg_stack.size() || !left_p) { operand_expected = true; + union_expected = true; continue;// EXCEPT::RT::WrongParenthesisSequence(assembled_formula); } left_p->incrementParametersNum(); // The count of parameters will be transferred to PtgFuncVar @@ -416,6 +418,11 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R } last_ptg = found_operand; operand_expected = false; + if(union_expected) + { + rgce.addPtg(PtgPtr(new PtgUnion)); + union_expected = false; + } } #pragma endregion } @@ -597,6 +604,12 @@ std::vector<bool> StringPtgParser::PosValArgs(const unsigned int &index) const argVector.push_back(false); argVector.push_back(true); break; + case 0x01E1: + for(auto i = 0; i < 127; i++) + { + argVector.push_back(false); + argVector.push_back(true); + } default: break; } diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index b9a3d456c75..ce15188289e 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -200,7 +200,7 @@ namespace Spreadsheet void CPivotTableFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); - if ((xlsb) && (xlsb->m_bWriteToXlsb)) + if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotTableDefinition.IsInit()) { XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); @@ -3550,9 +3550,12 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } XLS::BaseObjectPtr CPivotCacheDefinitionFile::WriteBin() const { - auto pivotCacheDefStream = m_oPivotCashDefinition->toBin(); - return pivotCacheDefStream; + if(m_oPivotCashDefinition.IsInit()) + { + auto pivotCacheDefStream = m_oPivotCashDefinition->toBin(); + return pivotCacheDefStream; + } } void CPivotCacheDefinitionFile::read(const CPath& oRootPath, const CPath& oPath) { @@ -3583,7 +3586,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" bIsWritten = true; CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); - if ((xlsb) && (xlsb->m_bWriteToXlsb)) + if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotCashDefinition.IsInit()) { XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); @@ -5039,12 +5042,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr1(new XLSB::PCDIA); ptr1->m_source = XLS::BaseObjectPtr{ptr1}; XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + else + ptr->st.setSize(0); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); + else + { + ptr->info.stCaption.setSize(0xFFFF); + ptr->info.fCaption = false; + } if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); for(auto i:m_arrItems) diff --git a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp index 34ec92e7273..7dbeec3ea36 100644 --- a/OOXML/XlsxFormat/Slicer/SlicerCache.cpp +++ b/OOXML/XlsxFormat/Slicer/SlicerCache.cpp @@ -87,9 +87,11 @@ XLS::BaseObjectPtr COlapSlicerCacheItem::toBin() if(m_oN.IsInit()) ptr->stName = m_oN.get(); else - ptr->stName = 0xFFFFFFFF; + ptr->stName.setSize(0xFFFFFFFF); if(m_oC.IsInit()) ptr->stTitle = m_oC.get(); + else + ptr->stTitle.setSize(0xFFFFFFFF); for(auto i:m_oP) if(i.m_oN.IsInit()) ptr->parents.push_back(i.m_oN.get()); @@ -281,7 +283,10 @@ XLS::BaseObjectPtr COlapSlicerCacheRange::toBin() if(m_oStartItem.IsInit()) { auto ptr1(new XLSB::BeginSlicerCacheSiRange); - ptr1->iitemstart = m_oStartItem.get(); + if(m_oStartItem.IsInit()) + ptr1->iitemstart = m_oStartItem.get(); + else + ptr1->iitemstart = 0; } for(auto i:m_oI) ptr->m_arBrtSlicerCacheOlapItem.push_back(i.toBin()); @@ -519,6 +524,16 @@ XLS::BaseObjectPtr COlapSlicerCacheSelection::toBin() { auto ptr(new XLSB::SlicerCacheSelection); XLS::BaseObjectPtr objectPtr(ptr); + if(m_oN.IsInit()) + ptr->stUniqueName = m_oN.get(); + else + ptr->stUniqueName = L""; + + for(auto i:m_oP) + { + if(i.m_oN.IsInit()) + ptr->parents.push_back(i.m_oN.get()); + } return objectPtr; } @@ -647,28 +662,32 @@ XLS::BaseObjectPtr COlapSlicerCacheLevelData::toBin() ptr->m_BrtBeginSlicerCacheLevelData = XLS::BaseObjectPtr{ptr1}; if(m_oCount.IsInit()) - ptr1->citem = m_oCount.get(); + ptr1->citem = m_oCount.get(); + else + ptr1->citem = 0; if(m_oSortOrder.IsInit()) ptr1->fSortOrder = m_oSortOrder->GetValue(); + else + ptr1->fSortOrder = false; if(m_oUniqueName.IsInit()) ptr1->stUniqueName = m_oUniqueName.get(); else - ptr1->stUniqueName = 0xFFFFFFFF; + ptr1->stUniqueName.setSize(0xFFFFFFFF); if(m_oSourceCaption.IsInit()) ptr1->stSourceCaption = m_oSourceCaption.get(); else - ptr1->stSourceCaption = 0xFFFFFFFF; + ptr1->stSourceCaption.setSize(0xFFFFFFFF); if(m_oCrossFilter.IsInit()) ptr1->fCrossFilter = m_oCrossFilter->GetValue(); - if(!m_oRanges.empty()) - { + else + ptr1->fCrossFilter = false; + auto ptr2(new XLSB::SLICERCACHESIRANGES); ptr->m_SLICERCACHESIRANGES = XLS::BaseObjectPtr{ptr2}; for(auto i:m_oRanges) { ptr2->m_arSLICERCACHESIRANGE.push_back(i.toBin()); } - } return objectPtr; } void COlapSlicerCacheLevelData::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -1363,10 +1382,10 @@ XLS::BaseObjectPtr COlapSlicerCache::toBin() { auto ptr(new XLSB::SLICERCACHEOLAPIMPL); XLS::BaseObjectPtr objectPtr(ptr); - if(m_oPivotCacheId.IsInit()) + if(m_oPivotCacheId.IsInit()) { auto ptr1(new XLSB::BeginSlicerCacheOlapImpl); - ptr->m_BrtBeginSlicerCacheOlapImpl = XLS::BaseObjectPtr{ptr1}; + ptr->m_BrtBeginSlicerCacheOlapImpl = XLS::BaseObjectPtr{ptr1}; ptr1->ipivotcacheid = m_oPivotCacheId.get(); } if(m_oLevels.IsInit()) @@ -1717,7 +1736,7 @@ XLS::BaseObjectPtr CSlicerCacheDefinition::toBin() { XLSB::SlicerCachePivotTable table; i.toBin(&table); - ptr2->pivotTables.push_back(table); + ptr2->pivotTables.push_back(table); } } if(m_oData.IsInit()) diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index c5b4acd5c6d..5fe0cff9ebd 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -239,18 +239,29 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); } else ptr->valType = XLS::typeDvNone; - ptr->fAllowBlank = m_oAllowBlank->GetValue(); + if(m_oAllowBlank.IsInit()) + ptr->fAllowBlank = m_oAllowBlank->GetValue(); + else + ptr->fAllowBlank = false; if(m_oError.IsInit()) ptr->Error = m_oError.get(); + else + ptr->Error = L""; if (m_oErrorTitle.IsInit()) ptr->ErrorTitle = m_oErrorTitle.get(); + else + ptr->ErrorTitle = L""; if (m_oPrompt.IsInit()) ptr->Prompt = m_oPrompt.get(); + else + ptr->Prompt = L""; if (m_oPromptTitle.IsInit()) ptr->PromptTitle = m_oPromptTitle.get(); + else + ptr->PromptTitle = L""; if(m_oErrorStyle.IsInit()) ptr->errStyle = m_oErrorStyle->GetValue(); else @@ -312,9 +323,9 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); ptr->sqrfx.strValue = m_oSqRef.get(); if(m_oFormula1.IsInit()) - ptr->formula1 = m_oFormula1->m_sText; + ptr->formula1 = m_oFormula1->m_sText; if(m_oFormula2.IsInit()) - ptr->formula2 = m_oFormula2->m_sText; + ptr->formula2 = m_oFormula2->m_sText; return objectPtr; } @@ -630,7 +641,6 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); auto beginPtr(new XLSB::BeginDVals); ptr->m_BrtBeginDVals = XLS::BaseObjectPtr{beginPtr}; - beginPtr->dVals.idvMac = m_arrItems.size(); if(m_oDisablePrompts.IsInit()) beginPtr->dVals.fWnClosed = m_oDisablePrompts->GetValue(); else @@ -648,6 +658,7 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); { ptr->m_arBrtDVal.push_back(i->toBin()); } + beginPtr->dVals.idvMac = ptr->m_arBrtDVal.size(); return objectPtr; } diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index e5c54f10d44..3bed8485396 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1109,7 +1109,8 @@ namespace OOX else if(m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) ptr->pnnAcct_xlsb = 3; } - + ptr->fFrozen = false; + ptr->fFrozenNoSplit = false; if(m_oState.IsInit()) { if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozenSplit) @@ -1391,7 +1392,7 @@ namespace OOX if (m_oShowFormulas.IsInit()) pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; else - pWsView->fDspFmlaRt = false; + pWsView->fDspFmlaRt = true; if (m_oShowGridLines.IsInit()) pWsView->fDspGridRt = m_oShowGridLines->m_eValue; else @@ -1457,7 +1458,7 @@ namespace OOX for(auto i:m_arrItems) { - ptr->m_arBrtSel.push_back(i->toBin()); + ptr->m_arBrtSel.push_back(i->toBin()); } return castedPtr; From f28119e6461450a051236d7bcd786fbcb0b0078e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 21 May 2024 20:47:23 +0300 Subject: [PATCH 686/794] fix bug #68010 --- Common/OfficeFileFormatChecker2.cpp | 12 +++-- Common/OfficeFileFormats.h | 1 + MsBinaryFile/DocFile/OleObject.cpp | 3 +- .../XlsFile/Format/Logic/Biff_records/BOF.cpp | 2 + OOXML/PPTXFormat/Logic/GraphicFrame.cpp | 3 +- OOXML/PPTXFormat/Logic/Pic.cpp | 46 ++++++++++++++++++- RtfFile/Format/DestinationCommand.cpp | 3 +- 7 files changed, 62 insertions(+), 8 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 9d9caba1306..d4aa195f15b 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -326,27 +326,33 @@ bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) if (sz_obj > 4) Program = ReadStringFromOle(&streamCompObject, sz_obj); } - if (std::string::npos != Program.find("Excel") || std::string::npos != UserType.find("Excel")) + POLE::Stream streamPackage(storage, L"Package"); + if (false == streamPackage.fail()) + { + nFileType = AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE; + } + else if (std::string::npos != Program.find("Excel") || std::string::npos != UserType.find("Excel")) { if (isXlsFormatFile(storage)) { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS; } } - if (std::string::npos != Program.find("Word") || std::string::npos != UserType.find("Word")) + else if (std::string::npos != Program.find("Word") || std::string::npos != UserType.find("Word")) { if (isDocFormatFile(storage)) { //nFileType inside } } - if (std::string::npos != Program.find("PowerPoint") || std::string::npos != UserType.find("PowerPoint")) + else if (std::string::npos != Program.find("PowerPoint") || std::string::npos != UserType.find("PowerPoint")) { if (isPptFormatFile(storage)) { nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT; } } + return true; } else diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index fc98dc017a0..2221abef9a7 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -127,6 +127,7 @@ #define AVS_OFFICESTUDIO_FILE_OTHER_ODF AVS_OFFICESTUDIO_FILE_OTHER + 0x000a #define AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO AVS_OFFICESTUDIO_FILE_OTHER + 0x000b #define AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT AVS_OFFICESTUDIO_FILE_OTHER + 0x000c +#define AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE AVS_OFFICESTUDIO_FILE_OTHER + 0x000d #define AVS_OFFICESTUDIO_FILE_TEAMLAB 0x1000 #define AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001 diff --git a/MsBinaryFile/DocFile/OleObject.cpp b/MsBinaryFile/DocFile/OleObject.cpp index ce936581044..dbc6de5aa8f 100644 --- a/MsBinaryFile/DocFile/OleObject.cpp +++ b/MsBinaryFile/DocFile/OleObject.cpp @@ -171,7 +171,8 @@ bool OleObject::processPackageStream(const std::wstring& packageStream) POLE::Stream* pPackageStream = new POLE::Stream(oleStorage, packageStream); if ((pPackageStream) && (false == pPackageStream->fail())) - { + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE VirtualStreamReader reader(pPackageStream, 0, false); size_t sz = reader.GetSize(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp index 777ab4d89c0..57fb2d8a772 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp @@ -74,6 +74,8 @@ void BOF::readFields(CFRecord& record) if (type_id_ == rt_BOF_BIFF8) { + if (vers > 0x0700) vers = 0x0600; + record >> rupBuild >> rupYear; // biff 5 - 8 if ( record.checkFitReadSafe(8)) // biff 8 diff --git a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp index 4b34dc8e6f6..4d3cebf7aa6 100644 --- a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp +++ b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp @@ -904,7 +904,8 @@ namespace PPTX } void GraphicFrame::ChartToOlePackageInStorage(OOX::IFileContainer* pRels, const std::wstring &sTempDirectory, int nCurrentGenerateId) - { + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE if (!chartRec.IsInit()) return; if (olePic.IsInit()) return; diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index a57e12c544f..c6f76fcc982 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -282,7 +282,9 @@ namespace PPTX ooxml_file = ole_file->filename().GetPath() + (bMacro ? L".docm" : L".docx"); } - + else if (checker.nFileType == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT) + {//todooo + } if (0 == nRes) { COfficeUtils oCOfficeUtils(NULL); @@ -296,6 +298,46 @@ namespace PPTX ole_file->set_filename(ooxml_file, false); } } + else if (checker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE) + { + POLE::Storage* storageIn = new POLE::Storage(ole_file->filename().GetPath().c_str()); + if ((storageIn) && (storageIn->open(false, false))) //storage in storage + { + POLE::Stream stream(storageIn, L"Package"); + if (false == stream.fail()) + {//test package stream??? xls ole -> xlsx ole + + POLE::uint64 size = stream.size(); + unsigned char* data = new unsigned char[size]; + stream.read(data, size); + storageIn->close(); + + std::wstring package = ole_file->filename().GetPath() + L".temp"; + + NSFile::CFileBinary file; + + file.CreateFileW(package); + file.WriteFile(data, (DWORD)size); + file.CloseFile(); + + COfficeFileFormatChecker checker2; + checker2.isOfficeFile(package); + if (checker2.nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) + { + std::wstring package2 = package + checker2.GetExtensionByType(checker2.nFileType); + + file.CreateFileW(package2); + file.WriteFile(data, (DWORD)size); + file.CloseFile(); + + ole_file->set_MsPackage(true); + ole_file->set_filename(package2, false); + } + delete[]data; + } + } + delete storageIn; + } } if (ole_file.IsInit() && 0 == sProgID.find(L"asc.")) @@ -419,7 +461,7 @@ namespace PPTX delete pXlsxEmbedded; } //else if (office_checker.nFileType == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX) - //{ + //{ todooo //} else {//unknown ms package diff --git a/RtfFile/Format/DestinationCommand.cpp b/RtfFile/Format/DestinationCommand.cpp index 6d14a90bd70..3fb24dd7b69 100644 --- a/RtfFile/Format/DestinationCommand.cpp +++ b/RtfFile/Format/DestinationCommand.cpp @@ -68,7 +68,8 @@ void ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name) { POLE::Stream stream(storageIn, L"Package"); if (false == stream.fail()) - {//test package stream??? xls ole -> xlsx ole + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE POLE::uint64 size = stream.size(); unsigned char* data = new unsigned char[size]; From 5fbed3db1cdccc3dbcc56e7d7069a7fd045ed3e9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 22 May 2024 10:30:09 +0300 Subject: [PATCH 687/794] Fix double hashtag for color in RC --- PdfFile/PdfWriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 6fe26dcc38c..dd5b3412df2 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1673,7 +1673,7 @@ void GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData, NSStr oRC += L"line-through"; } - oRC += L";color:#"; + oRC += L";color:"; oRC.WriteHexColor3((unsigned char)(pFontData->dColor[0] * 255.0), (unsigned char)(pFontData->dColor[1] * 255.0), (unsigned char)(pFontData->dColor[2] * 255.0)); @@ -1899,6 +1899,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } oRC += L"</p></body>"; pMarkupAnnot->SetRC(oRC.GetData()); + // std::wcout << oRC.GetData() << std::endl; } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); From 3cd89354bcb14f3d661528072390555ccd860a19 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 22 May 2024 11:08:12 +0300 Subject: [PATCH 688/794] Fix pdf rotate for drawingfile --- PdfFile/PdfReader.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 283f444e486..538b6503ae0 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -429,7 +429,7 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, if (!m_pPDFDocument) return; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); #else @@ -496,7 +496,7 @@ void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* oRendererOut.NewPDF(m_pPDFDocument->getXRef()); oRendererOut.SetBreak(pbBreak); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(_nPageIndex + 1); #endif m_pPDFDocument->displayPage(&oRendererOut, _nPageIndex + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); @@ -744,11 +744,13 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, double dy = 0; double dTop = pLinkDest->getTop(); double dHeight = pdfDoc->getPageCropHeight(pg); + /* if (pdfDoc->getPageRotate(pg) % 180 != 0) { dHeight = pdfDoc->getPageCropWidth(pg); dTop = pLinkDest->getLeft(); } + */ if (dTop > 0 && dTop < dHeight) dy = dHeight - dTop; @@ -891,7 +893,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) RELEASEOBJECT(pLinks); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); #endif From 7758da7173492760a1fbeed4f333ad072a46ccbe Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <Mikhail.Lobotskiy@onlyoffice.com> Date: Wed, 22 May 2024 15:55:39 +0400 Subject: [PATCH 689/794] Add number constants for file types --- .../docbuilder.python/src/docbuilder.py | 41 +++++++++++++++++++ .../docbuilder.python/test/docbuilder_test.py | 4 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index b6aaf81e731..bf4d13d78d8 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -538,6 +538,47 @@ def CreateScope(self): def IsError(self): return _lib.CDocBuilderContext_IsError(self._internal) +# Constants +class FileTypes: + class Document: + _MASK = 0x0040 + DOCX = _MASK + 0x0001 + DOC = _MASK + 0x0002 + ODT = _MASK + 0x0003 + RTF = _MASK + 0x0004 + TXT = _MASK + 0x0005 + DOTX = _MASK + 0x000c + OTT = _MASK + 0x000f + HTML = _MASK + 0x0012 + + class Presentation: + _MASK = 0x0080 + PPTX = _MASK + 0x0001 + PPT = _MASK + 0x0002 + ODP = _MASK + 0x0003 + PPSX = _MASK + 0x0004 + POTX = _MASK + 0x0007 + OTP = _MASK + 0x000a + + class Spreadsheet: + _MASK = 0x0100 + XLSX = _MASK + 0x0001 + XLS = _MASK + 0x0002 + ODS = _MASK + 0x0003 + CSV = _MASK + 0x0004 + XLTX = _MASK + 0x0006 + OTS = _MASK + 0x0009 + + class Graphics: + _PDF_MASK = 0x0200 + PDF = _PDF_MASK + 0x0001 + PDFA = _PDF_MASK + 0x0009 + + _IMAGE_MASK = 0x0400 + JPG = _IMAGE_MASK + 0x0001 + PNG = _IMAGE_MASK + 0x0005 + BMP = _IMAGE_MASK + 0x0008 + builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py index 8fd73b26fd5..733c459e26c 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py @@ -5,7 +5,7 @@ builder = docbuilder.CDocBuilder() -builder.CreateFile('docx') +builder.CreateFile(docbuilder.FileTypes.Document.DOCX) context = builder.GetContext() scope = context.CreateScope() @@ -22,5 +22,5 @@ document.Call('InsertContent', content) dstPath = os.getcwd() + '/result.docx' -builder.SaveFile('docx', dstPath) +builder.SaveFile(docbuilder.FileTypes.Document.DOCX, dstPath) builder.CloseFile() From 1cdb2b0f1537ef0a403db0acf3160b7fbc2fb34d Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <Mikhail.Lobotskiy@onlyoffice.com> Date: Wed, 22 May 2024 16:52:13 +0400 Subject: [PATCH 690/794] Add list constructor and automatic conversion to CValue in functions --- .../docbuilder.python/src/docbuilder.py | 9 +++++++++ .../docbuilder.python/test/docbuilder_test.py | 13 ++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index bf4d13d78d8..c71994853e9 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -272,6 +272,11 @@ def __init__(self, value=None): self._internal = _lib.CDocBuilderValue_CreateWithDouble(ctypes.c_double(value)) elif isinstance(value, str): self._internal = _lib.CDocBuilderValue_CreateWithString(ctypes.c_wchar_p(value)) + elif isinstance(value, list): + length = len(value) + self._internal = _lib.CDocBuilderValue_CreateArray(length) + for i in range(length): + self.Set(i, value[i]) elif isinstance(value, CDocBuilderValue): self._internal = _lib.CDocBuilderValue_Copy(value._internal) elif isinstance(value, OBJECT_HANDLE): @@ -344,9 +349,13 @@ def Get(self, key): return None def SetProperty(self, name, value): + if not isinstance(value, CDocBuilderValue): + value = CDocBuilderValue(value) _lib.CDocBuilderValue_SetProperty(self._internal, ctypes.c_wchar_p(name), value._internal) def Set(self, key, value): + if not isinstance(value, CDocBuilderValue): + value = CDocBuilderValue(value) if isinstance(key, int): _lib.CDocBuilderValue_SetByIndex(self._internal, ctypes.c_int(key), value._internal) elif isinstance(key, str): diff --git a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py index 733c459e26c..851847e024f 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/test/docbuilder_test.py @@ -14,11 +14,14 @@ api = globalObj['Api'] document = api.Call('GetDocument') -paragraph = api.Call('CreateParagraph') -paragraph.Call('SetSpacingAfter', 1000, False) -paragraph.Call('AddText', 'Hello, World!') -content = context.CreateArray(1) -content[0] = paragraph +paragraph1 = api.Call('CreateParagraph') +paragraph1.Call('SetSpacingAfter', 1000, False) +paragraph1.Call('AddText', 'Hello from Python!') + +paragraph2 = api.Call('CreateParagraph') +paragraph2.Call('AddText', 'Goodbye!') + +content = [paragraph1, paragraph2] document.Call('InsertContent', content) dstPath = os.getcwd() + '/result.docx' From 24b32a2ba783c4e5eec5c4e7b35829d5cefecd74 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov <kamil.kerimov@onlyoffice.com> Date: Wed, 22 May 2024 17:56:53 +0500 Subject: [PATCH 691/794] Fix bug #67380 --- OdfFile/Reader/Format/draw_frame_docx.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 0957ab9343e..d66a4a97da2 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -881,17 +881,17 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm drawing->relativeHeight = L"2"; drawing->behindDoc = L"0"; + if (!drawing->styleWrap) + drawing->styleWrap = style_wrap(style_wrap::Parallel);//у опен офис и мс разные дефолты + if (((drawing->styleWrap && drawing->styleWrap->get_type() == style_wrap::RunThrough) || !drawing->styleWrap) && ((styleRunThrough && styleRunThrough->get_type() == run_through::Background) || !styleRunThrough)) { drawing->behindDoc = L"1"; if (!drawing->styleWrap) - drawing->styleWrap = style_wrap(style_wrap::Parallel); - + drawing->styleWrap = style_wrap(style_wrap::RunThrough); } - if (!drawing->styleWrap) - drawing->styleWrap = style_wrap(style_wrap::Parallel);//у опен офис и мс разные дефолты - + _CP_OPT(unsigned int) zIndex = attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_z_index_; if (zIndex)//порядок отрисовки объектов From ca5201e70473a75edad228bee46cca38af3e9475 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 22 May 2024 16:49:19 +0300 Subject: [PATCH 692/794] FreeText has Rotate --- DesktopEditor/graphics/commands/AnnotField.cpp | 1 + DesktopEditor/graphics/commands/AnnotField.h | 2 ++ DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js | 1 + DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp | 4 ++++ PdfFile/PdfWriter.cpp | 1 + PdfFile/SrcReader/PdfAnnot.cpp | 6 ++++++ PdfFile/SrcReader/PdfAnnot.h | 1 + PdfFile/SrcWriter/Annotation.cpp | 4 ++++ PdfFile/SrcWriter/Annotation.h | 1 + 9 files changed, 21 insertions(+) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 00f91e72f95..c6532e542c4 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -574,6 +574,7 @@ BYTE* CAnnotFieldInfo::CFreeTextAnnotPr::GetRender(LONG& nLen) void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nQ = pReader->ReadByte(); + m_nRotate = pReader->ReadInt(); if (nFlags & (1 << 15)) { m_dRD[0] = pReader->ReadDouble(); diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 5043e1e15a0..2f1e86fe943 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -367,6 +367,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE GetQ() const; BYTE GetIT() const; BYTE GetLE() const; + int GetRotate(); const std::wstring& GetDS(); void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); const std::vector<double>& GetCL(); @@ -379,6 +380,7 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nQ; BYTE m_nIT; BYTE m_nLE; + int m_nRotate; std::wstring m_wsDS; double m_dRD[4]{}; std::vector<double> m_arrCL; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 0590fe82d21..ba1b0a1e319 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1347,6 +1347,7 @@ } // 0 - left-justified, 1 - centered, 2 - right-justified rec["alignment"] = reader.readByte(); + rec["Rotate"] = reader.readInt(); // Rect and RD differences if (flags & (1 << 15)) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index b098bb32bca..d3ddb7fc6ea 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1597,6 +1597,10 @@ int main(int argc, char* argv[]) i += 1; std::cout << "Q " << arrQ[nPathLength] << ", "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Rotate " << nPathLength << ", "; + if (nFlags & (1 << 15)) { std::cout << "RD"; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index dd5b3412df2..3af47625d1d 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2029,6 +2029,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot; pFreeTextAnnot->SetQ(pFTPr->GetQ()); + pFreeTextAnnot->SetRotate(pFTPr->GetRotate()); if (nFlags & (1 << 15)) { double dRD1, dRD2, dRD3, dRD4; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index fd718ef6e09..46b43b0fede 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1642,6 +1642,11 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex m_nQ = oObj.getInt(); oObj.free(); + m_nRotate = 0; + if (oAnnot.dictLookup("Rotate", &oObj)->isInt()) + m_nRotate = oObj.getInt(); + oObj.free(); + // 15 - Различия Rect и фактического размера - RD if (oAnnot.dictLookup("RD", &oObj)->isArray()) { @@ -3662,6 +3667,7 @@ void CAnnotFreeText::ToWASM(NSWasm::CData& oRes) CAnnotMarkup::ToWASM(oRes); oRes.WriteBYTE(m_nQ); + oRes.AddInt(m_nRotate); if (m_unFlags & (1 << 15)) { for (int i = 0; i < 4; ++i) diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 283e320157a..7e7012995d5 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -492,6 +492,7 @@ class CAnnotFreeText final : public CAnnotMarkup BYTE m_nQ; // Выравнивание текста - Q BYTE m_nIT; // Назначение аннотации BYTE m_nLE; // Стиль окончания линии + int m_nRotate; std::string m_sDS; // Строка стиля по умолчанию - DS double m_pRD[4]{}; // Различия Rect и фактического размера std::vector<double> m_arrCFromDA; // Цвет границы diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index dce678418e9..a294d1cdbcb 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1112,6 +1112,10 @@ namespace PdfWriter { Add("LE", AddLE(nLE).c_str()); } + void CFreeTextAnnotation::SetRotate(int nRotate) + { + Add("Rotate", nRotate); + } void CFreeTextAnnotation::SetDS(const std::wstring& wsDS) { std::string sValue = U_TO_UTF8(wsDS); diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index c91c89587a3..ac691002ca5 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -365,6 +365,7 @@ namespace PdfWriter void SetQ(BYTE nQ); void SetIT(BYTE nIT); void SetLE(BYTE nLE); + void SetRotate(int nRotate); void SetDS(const std::wstring& wsDS); void SetRD(const double& dRD1, const double& dRD2, const double& dRD3, const double& dRD4); void SetCL(const std::vector<double>& arrCL); From fbb7ab93d618e52363545c11a07244ad41a2144b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 22 May 2024 17:37:33 +0300 Subject: [PATCH 693/794] Fix bug 67740 --- PdfFile/PdfEditor.cpp | 83 +++++++++++++++++++++++++++++++++++++ PdfFile/SrcWriter/Pages.cpp | 9 ++++ PdfFile/SrcWriter/Pages.h | 1 + PdfFile/SrcWriter/Types.h | 2 +- PdfFile/test/test.cpp | 16 +++++++ 5 files changed, 110 insertions(+), 1 deletion(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 909f6f5bd0e..11b072449cc 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -386,6 +386,86 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo return bRes ? S_OK : S_FALSE; } +void StreamGetCTM(XRef* pXref, Object* oStream, double* dCTM) +{ + Parser* parser = new Parser(pXref, new Lexer(pXref, oStream), gFalse); + + int nNumArgs = 0; + Object oObj; + Object pArgs[maxArgs]; + + parser->getObj(&oObj); + while (!oObj.isEOF()) + { + if (oObj.isCmd()) + { + if (oObj.isCmd("q")) + { + Object obj; + parser->getObj(&obj); + while (!obj.isEOF() && !obj.isCmd("Q")) + { + obj.free(); + parser->getObj(&obj); + } + obj.free(); + } + else if (oObj.isCmd("cm") && nNumArgs > 5) + { + double a1 = dCTM[0]; + double b1 = dCTM[1]; + double c1 = dCTM[2]; + double d1 = dCTM[3]; + + dCTM[0] = pArgs[0].getNum() * a1 + pArgs[1].getNum() * c1; + dCTM[1] = pArgs[0].getNum() * b1 + pArgs[1].getNum() * d1; + dCTM[2] = pArgs[2].getNum() * a1 + pArgs[3].getNum() * c1; + dCTM[3] = pArgs[2].getNum() * b1 + pArgs[3].getNum() * d1; + dCTM[4] = pArgs[4].getNum() * a1 + pArgs[5].getNum() * c1 + dCTM[4]; + dCTM[5] = pArgs[4].getNum() * b1 + pArgs[5].getNum() * d1 + dCTM[5]; + } + oObj.free(); + for (int i = 0; i < nNumArgs; ++i) + pArgs[i].free(); + nNumArgs = 0; + } + else if (nNumArgs < maxArgs) + pArgs[nNumArgs++] = oObj; + + parser->getObj(&oObj); + } + oObj.free(); + for (int i = 0; i < nNumArgs; ++i) + pArgs[i].free(); + RELEASEOBJECT(parser); +} +void GetCTM(XRef* pXref, Object* oPage, double* dCTM) +{ + if (!oPage || !oPage->isDict()) + return; + + Object oContents; + if (!oPage->dictLookup("Contents", &oContents)) + { + oContents.free(); + return; + } + + if (oContents.isArray()) + { + for (int nIndex = 0; nIndex < oContents.arrayGetLength(); ++nIndex) + { + Object oTemp; + oContents.arrayGet(nIndex, &oTemp); + if (oTemp.isStream()) + StreamGetCTM(pXref, &oTemp, dCTM); + oTemp.free(); + } + } + else if (oContents.isStream()) + StreamGetCTM(pXref, &oContents, dCTM); + oContents.free(); +} CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) { @@ -919,12 +999,15 @@ bool CPdfEditor::EditPage(int nPageIndex) oTemp.free(); } pPage->Fix(); + double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + GetCTM(xref, &pageObj, dCTM); pageObj.free(); // Применение редактирования страницы для writer if (pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) { bEditPage = true; + pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); return true; } diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index c347393d139..991b3f9e31f 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1037,6 +1037,15 @@ namespace PdfWriter m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; } + void CPage::StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { + m_pGrState->m_oMatrix.m11 = dM11; + m_pGrState->m_oMatrix.m12 = dM12; + m_pGrState->m_oMatrix.m21 = dM21; + m_pGrState->m_oMatrix.m22 = dM22; + m_pGrState->m_oMatrix.x = dX; + m_pGrState->m_oMatrix.y = dY; + } void CPage::SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) { CMatrix oInverse = m_pGrState->m_oMatrix.Inverse(); diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 9455f197b11..1bcaa9e4f6b 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -131,6 +131,7 @@ namespace PdfWriter void SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB); void SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB); void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void StartTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); void SetExtGrState(CExtGrState* pExtGrState); void AddAnnotation(CDictObject* pAnnot); diff --git a/PdfFile/SrcWriter/Types.h b/PdfFile/SrcWriter/Types.h index 20a211ceb00..bfd04c1398a 100644 --- a/PdfFile/SrcWriter/Types.h +++ b/PdfFile/SrcWriter/Types.h @@ -136,7 +136,7 @@ namespace PdfWriter CMatrix oInverse; double dDet = m11 * m22 - m12 * m21; - if (dDet < 0.0001 && dDet > 0.0001) + if (dDet < 0.0001 && dDet > -0.0001) return oInverse; oInverse.m11 = m22 / dDet; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 19b3ce54a4b..6f6fa3b900a 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -205,6 +205,22 @@ TEST_F(CPdfFileTest, PdfFromBin) EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); } +TEST_F(CPdfFileTest, PdfToPdf) +{ + GTEST_SKIP(); + + LoadFromFile(); + pdfFile->CreatePdf(); + + for (int i = 0; i < pdfFile->GetPagesCount(); i++) + { + pdfFile->NewPage(); + pdfFile->DrawPageOnRenderer(pdfFile, i, NULL); + } + + pdfFile->SaveToFile(wsDstFile); +} + TEST_F(CPdfFileTest, SetMetaData) { GTEST_SKIP(); From 3780922610abfa529db1124609e4f701d21adbaf Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Wed, 22 May 2024 21:42:33 +0600 Subject: [PATCH 694/794] Fix bug #68111 --- .../Biff12_records/BeginSupBook.cpp | 2 +- .../Biff12_structures/ECTxtWizData.cpp | 1 + .../ExternalLinks/ExternalLinks.cpp | 198 +++++++++++++++++- .../XlsxFormat/ExternalLinks/ExternalLinks.h | 9 +- OOXML/XlsxFormat/Ole/OleObjects.cpp | 11 +- OOXML/XlsxFormat/SharedStrings/Si.cpp | 1 + OOXML/XlsxFormat/Table/Connections.cpp | 43 +++- .../Worksheets/ConditionalFormatting.cpp | 6 +- .../Worksheets/WorksheetChildOther.cpp | 2 +- 9 files changed, 256 insertions(+), 17 deletions(-) diff --git a/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp b/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp index 25e7d9dc887..632c2505499 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp @@ -97,7 +97,7 @@ namespace XLSB RelID relID; XLNullableWideString str; relID.value = string1; - str = string2; + str.setSize(0xFFFFFFFF); record << relID << str; break; } diff --git a/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp b/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp index f2fed5fd5e2..a41231ccd4d 100644 --- a/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp +++ b/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp @@ -88,6 +88,7 @@ namespace XLSB SETBIT(flags, 16, fSemiColon) SETBIT(flags, 17, fConsecutive) SETBITS(flags, 18, 19, fTextDelim) + SETBIT(flags, 20, 1) SETBIT(flags, 21, fPromptForFile) SETBIT(flags, 22, fCustom) diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index 81927d690c7..b17e9e43ad1 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -65,6 +65,7 @@ #include "../../XlsbFormat/Biff12_records/SupName.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include <string> @@ -182,6 +183,34 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CExternalDefinedName::toBin() + { + XLSB::ExternalReferenceType type; + type = XLSB::ExternalReferenceType::WORKBOOK; + auto ptr(new XLSB::EXTERNNAME(type)); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oName.IsInit()) + { + auto nameStart(new XLSB::SupNameStart); + nameStart->name = m_oName.get(); + ptr->m_BrtSupNameStart = XLS::BaseObjectPtr{nameStart}; + } + if(m_oRefersTo.IsInit()) + { + auto nameFmla(new XLSB::SupNameFmla); + ptr->m_BrtSupNameFmla = XLS::BaseObjectPtr{nameFmla}; + nameFmla->fmla = m_oRefersTo.get(); + } + if(m_oSheetId.IsInit()) + { + auto supBits(new XLSB::SupNameBits(type)); + ptr->m_BrtSupNameBits = XLS::BaseObjectPtr{supBits}; + supBits->contentsExtName.iSheet = m_oSheetId->GetValue(); + supBits->contentsExtName.fBuiltIn = false; + } + return objectPtr; + } void CExternalDefinedName::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::EXTERNNAME*>(obj.get()); @@ -274,7 +303,15 @@ namespace Spreadsheet m_arrItems.push_back(new CExternalDefinedName(item)); } } - + std::vector<XLS::BaseObjectPtr> CExternalDefinedNames::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i:m_arrItems) + { + objectVector.push_back(i->toBin()); + } + return objectVector; + } CExternalCell::CExternalCell() { } @@ -322,6 +359,98 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalCell::toBin() + { + + auto ptr(new XLSB::EXTERNVALUE(0)); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValueMetadata.IsInit()) + { + auto metaPtr(new XLSB::ExternValueMeta); + ptr->m_BrtExternValueMeta = XLS::BaseObjectPtr{metaPtr}; + metaPtr->ivmb = m_oValueMetadata.get(); + } + + auto valuePtr(new XLSB::EXTERNVALUEDATA(0)); + ptr->m_EXTERNVALUEDATA = XLS::BaseObjectPtr{valuePtr}; + XLSB::RgceLoc loc; + if(m_oRef.IsInit()) + loc = XLSB::RgceLoc(m_oRef.get()); + else + loc = XLSB::RgceLoc(L"A1"); + valuePtr->m_Col = loc.getColumn(); + if(!m_oValue.IsInit()) + { auto blanc(new XLSB::ExternCellBlank); + blanc->col = valuePtr->m_Col; + valuePtr->m_source = XLS::BaseObjectPtr{blanc}; + return objectPtr; + } + if(!m_oType.IsInit()) + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + } + switch(m_oType->GetValue()) + { + case SimpleTypes::Spreadsheet::celltypeStr: + { + auto str(new XLSB::ExternCellString); + str->col = valuePtr->m_Col; + str->value = m_oValue->m_sText; + valuePtr->m_source = XLS::BaseObjectPtr{str}; + break; + } + case SimpleTypes::Spreadsheet::celltypeBool: + { + auto boolVal(new XLSB::ExternCellBool); + boolVal->col = valuePtr->m_Col; + boolVal->value = m_oValue->m_sText == L"1" ? true : false; + valuePtr->m_source = XLS::BaseObjectPtr{boolVal}; + break; + } + case SimpleTypes::Spreadsheet::celltypeNumber: + { + auto doubleVal(new XLSB::ExternCellReal); + doubleVal->col = valuePtr->m_Col; + doubleVal->value.data.value = std::stod(m_oValue->m_sText); + valuePtr->m_source = XLS::BaseObjectPtr{doubleVal}; + break; + } + case SimpleTypes::Spreadsheet::celltypeError: + { + auto errVal(new XLSB::ExternCellError); + errVal->col = valuePtr->m_Col; + if(m_oValue->m_sText == L"#NULL!") + errVal->value = 0; + else if(m_oValue->m_sText == L"#DIV/0!") + errVal->value = 0x7; + else if(m_oValue->m_sText == L"#VALUE!") + errVal->value = 0xF; + else if(m_oValue->m_sText == L"#REF!") + errVal->value = 0x17; + else if(m_oValue->m_sText == L"#NAME?") + errVal->value = 0x1D; + else if(m_oValue->m_sText == L"#NUM!") + errVal->value = 0x24; + else if(m_oValue->m_sText == L"#N/A") + errVal->value = 0x2A; + else if(m_oValue->m_sText == L"#GETTING_DATA") + errVal->value = 0x2B; + else + errVal->value = 0x2A; + valuePtr->m_source = XLS::BaseObjectPtr{errVal}; + break; + } + default: + { + auto blanc(new XLSB::ExternCellBlank); + blanc->col = valuePtr->m_Col; + valuePtr->m_source = XLS::BaseObjectPtr{blanc}; + } + }; + + return objectPtr; + } void CExternalCell::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -467,6 +596,27 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalRow::toBin() + { + auto ptr(new XLSB::EXTERNROW); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::ExternRowHdr); + ptr->m_BrtExternRowHdr = XLS::BaseObjectPtr{ptr1}; + + if(m_oR.IsInit() && m_oR->GetValue() > 0) + { + ptr1->rw = m_oR->GetValue() - 1; + } + else + ptr1->rw = 0; + + for(auto i:m_arrItems) + { + ptr->m_arEXTERNVALUE.push_back(i->toBin()); + } + + return objectPtr; + } void CExternalRow::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -548,6 +698,29 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalSheetData::toBin() + { + auto ptr(new XLSB::EXTERNTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::ExternTableStart); + ptr->m_BrtExternTableStart = XLS::BaseObjectPtr{ptr1}; + + if(m_oSheetId.IsInit()) + ptr1->iTab = m_oSheetId->GetValue(); + else + ptr1->iTab = 0; + if(m_oRefreshError.IsInit()) + ptr1->fRefreshError = m_oRefreshError->GetValue(); + else + ptr1->fRefreshError = false; + + for(auto i:m_arrItems) + { + ptr->m_arEXTERNROW.push_back(i->toBin()); + } + + return objectPtr; + } void CExternalSheetData::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -631,7 +804,15 @@ namespace Spreadsheet m_arrItems.push_back(new CExternalSheetData(item)); } } - + std::vector<XLS::BaseObjectPtr> CExternalSheetDataSet::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i:m_arrItems) + { + objectVector.push_back(i->toBin()); + } + return objectVector; + } CExternalBook::CExternalBook() { } @@ -712,8 +893,15 @@ namespace Spreadsheet XLS::BaseObjectPtr CExternalBook::toBin() { XLSB::EXTERNALLINKPtr externalLINK(new XLSB::EXTERNALLINK()); - + auto beginSupbook(new XLSB::BeginSupBook); + if(m_oRid.IsInit()) + beginSupbook->string1 = m_oRid->GetValue(); + else + beginSupbook->string1 = L" "; + beginSupbook->sbt = 0; + externalLINK->m_BrtBeginSupBook = XLS::BaseObjectPtr{beginSupbook}; XLSB::ExternalReferenceType type; + type = XLSB::ExternalReferenceType::WORKBOOK; XLSB::EXTERNALBOOKPtr externalBOOK(new XLSB::EXTERNALBOOK(type)); externalLINK->m_EXTERNALBOOK = externalBOOK; @@ -721,6 +909,10 @@ namespace Spreadsheet { if (m_oSheetNames.IsInit()) externalBOOK->m_BrtSupTabs = m_oSheetNames->toBin(); + if(m_oDefinedNames.IsInit()) + externalBOOK->m_arEXTERNNAME = m_oDefinedNames->toBin(); + if(m_oSheetDataSet.IsInit()) + externalBOOK->m_arEXTERNTABLE = m_oSheetDataSet->toBin(); } return externalLINK; } diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index b9d635bf513..8099f9989ca 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -123,6 +123,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -146,6 +147,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType() const; }; @@ -163,7 +165,8 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); - + XLS::BaseObjectPtr toBin(); + virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -189,6 +192,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -211,6 +215,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -234,7 +239,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(std::vector<XLS::BaseObjectPtr>& obj); - + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType() const; }; diff --git a/OOXML/XlsxFormat/Ole/OleObjects.cpp b/OOXML/XlsxFormat/Ole/OleObjects.cpp index 0db040495ee..9406977c9b6 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.cpp +++ b/OOXML/XlsxFormat/Ole/OleObjects.cpp @@ -314,14 +314,19 @@ namespace OOX if(m_oShapeId.IsInit()) ptr->shapeId = m_oShapeId->GetValue(); - - ptr->fAutoLoad = m_oAutoLoad->GetValue(); + if(m_oAutoLoad.IsInit()) + ptr->fAutoLoad = m_oAutoLoad->GetValue(); + else + ptr->fAutoLoad = false; if(m_oProgId.IsInit()) - ptr->strProgID.value() = m_oProgId.get(); + ptr->strProgID = m_oProgId.get(); if(m_oLink.IsInit()) ptr->link = m_oLink.get(); + else + ptr->fLinked = false; + if(m_oRid.IsInit()) ptr->strRelID.value = m_oRid->GetValue(); diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index e008680be19..cfb2f424d72 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -164,6 +164,7 @@ namespace OOX if(phonPtr) { ptr->fExtStr = true; + ptr->phoneticStr = L""; XLSB::PhRun phRun; phonPtr->toBin(&phRun); if(i < m_arrItems.size() - 1) diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index fe144fc3485..1e3d32d8a91 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -92,8 +92,12 @@ namespace OOX auto ptr(new XLSB::BeginECTwFldInfo); if(m_oPosition.IsInit()) ptr->data.fieldStart = m_oPosition.get(); + else + ptr->data.fieldStart = 0; if(m_oType.IsInit()) ptr->data.fieldType = m_oType->GetValue(); + else + ptr->data.fieldType = 0; return XLS::BaseObjectPtr{ptr}; } EElementType CTextField::getType() const @@ -788,41 +792,72 @@ namespace OOX { auto ptr1(new XLSB::ECTXTWIZ); auto ptr(new XLSB::BeginECTxtWiz); + ptr1->m_BrtBeginECTxtWiz = XLS::BaseObjectPtr{ptr}; if(m_oSourceFile.IsInit()) ptr->stFile = m_oSourceFile.get(); + else + ptr->stFile.setSize(0); if(m_oFileType.IsInit()) { ptr->data.iCpid = m_oFileType->m_eValue; ptr->data.iCpidNew = m_oFileType->m_eValue; } + else + { + ptr->data.iCpid = 1; + ptr->data.iCpidNew = 0; + } if(m_oDecimal.IsInit()) - ptr->data.chDecimal = std::stoi(m_oDecimal.get()); + ptr->data.chDecimal = m_oDecimal.get()[0]; + else + ptr->data.chDecimal = '.'; if(m_oDelimiter.IsInit()) - ptr->data.chCustom = std::stoi(m_oDelimiter.get()); + ptr->data.chCustom = m_oDelimiter.get()[0]; + else + { + ptr->data.chCustom = 0; + ptr->data.fCustom = false; + } if(m_oThousands.IsInit()) - ptr->data.chThousSep = std::stoi(m_oThousands.get()); + ptr->data.chThousSep = m_oThousands.get()[0]; + else + ptr->data.chThousSep = ' '; if(m_oFirstRow.IsInit()) ptr->data.rowStartAt = m_oFirstRow.get(); if(m_oQualifier.IsInit()) ptr->data.fTextDelim = m_oQualifier->GetValue(); + else + ptr->data.fTextDelim = 0; if(m_oPrompt.IsInit()) ptr->data.fPromptForFile = m_oPrompt.get(); if(m_oDelimited.IsInit()) ptr->data.fDelimited = m_oDelimited.get(); + else + ptr->data.fDelimited = false; if(m_oTab.IsInit()) ptr->data.fTab = m_oTab.get(); + else + ptr->data.fTab = false; if(m_oSpace.IsInit()) ptr->data.fSpace = m_oSpace.get(); + else + ptr->data.fSpace = false; if(m_oComma.IsInit()) ptr->data.fComma = m_oComma.get(); + else + ptr->data.fComma = false; if(m_oSemicolon.IsInit()) ptr->data.fSemiColon = m_oSemicolon.get(); + else + ptr->data.fSemiColon = false; if(m_oConsecutive.IsInit()) ptr->data.fConsecutive = m_oConsecutive.get(); + else + ptr->data.fConsecutive = false; if(m_oTextFields.IsInit()) - ptr1->m_ECTWFLDINFOLST = m_oTextFields->toBin(); + ptr1->m_ECTWFLDINFOLST = m_oTextFields->toBin(); return XLS::BaseObjectPtr{ptr1}; } EElementType CTextPr::getType() const diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 3fc6ffa9124..70f2e68c21b 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -267,9 +267,9 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin(bool isIcon) else ptr1->iType = XLSB::CFVOtype::CFVONUM; - if(m_oVal.IsInit() && ptr1->iType != XLSB::CFVOtype::CFVOFMLA) - ptr1->numParam.data.value = std::stod(m_oVal.get()); - else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) + //if(m_oVal.IsInit() && ptr1->iType != XLSB::CFVOtype::CFVOFMLA) + //ptr1->numParam.data.value = std::stod(m_oVal.get()); + if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMIN) ptr1->numParam.data.value = 0; else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) ptr1->numParam.data.value = 0; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index e5c54f10d44..5618cb42d40 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2659,7 +2659,7 @@ namespace OOX XLS::BaseObjectPtr castedPtr(ptr); if (m_oPassword.IsInit()) - ptr->protpwd = std::stoul(m_oPassword.get()); + ptr->protpwd = std::stoul(m_oPassword.get(),nullptr, 16); else ptr->protpwd = 0; From a19b4a03b384b57d922fd489070b18b5b74f9513 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Thu, 23 May 2024 11:27:28 +0300 Subject: [PATCH 695/794] Fixed a bug with attributes of functions and indexes --- .../StarMath2OOXML/TestSMConverter/main.cpp | 60 +++++++++++++-- .../StarMath2OOXML/cstarmathpars.cpp | 73 +++++++++++++------ .../Converter/StarMath2OOXML/cstarmathpars.h | 3 + 3 files changed, 109 insertions(+), 27 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index c0db5e051b2..a336d152ced 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -940,7 +940,7 @@ TEST(SMConvectorTest,OperatorLllint) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2230\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"DC143C\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:sub><m:sup><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>+3</m:t></m:r></m:e></m:d></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>100</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2230\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"DC143C\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:sub><m:sup><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:e></m:d></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>100</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -950,7 +950,7 @@ TEST(SMConvectorTest,BracketLdlineAttribute) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:acc><m:accPr><m:chr m:val=\"\u0307\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:acc><m:accPr><m:chr m:val=\"\u0332\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:acc></m:e></m:acc></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>+3</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>10</m:t></m:r></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:acc><m:accPr><m:chr m:val=\"\u0307\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:acc><m:accPr><m:chr m:val=\"\u0332\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:acc></m:e></m:acc></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>3</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>10</m:t></m:r></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1040,7 +1040,7 @@ TEST(SMConvectorTest,Example9) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString =L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f'</m:t></m:r></m:e></m:nary><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>dx</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString =L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r></m:e></m:nary><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>dx</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1110,7 +1110,7 @@ TEST(SMConvectorTest,Example7) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t'</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r></m:num><m:den><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>v</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:den></m:f></m:e></m:rad></m:den></m:f></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r></m:num><m:den><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>v</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:den></m:f></m:e></m:rad></m:den></m:f></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1300,7 +1300,7 @@ TEST(SMConvectorTest,UnarySignWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"[\" /><m:endChr m:val=\"]\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>2</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>+10</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>\u2216</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>5</m:t></m:r></m:num><m:den><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:groupChr><m:groupChrPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:groupChrPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>9</m:t></m:r></m:e></m:groupChr></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>3</m:t></m:r></m:lim></m:limLow></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u005B\" /><m:endChr m:val=\"\u005D\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>2</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>10</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>\u2216</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>5</m:t></m:r></m:num><m:den><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:groupChr><m:groupChrPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:groupChrPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>9</m:t></m:r></m:e></m:groupChr></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>3</m:t></m:r></m:lim></m:limLow></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -1354,6 +1354,56 @@ TEST(SMConvectorTest,OperatorWithoutValue) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,MatrixWithDifferentValues) +{ + std::wstring wsString = L"matrix{2} matrix 2 matrix"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:e /></m:mr><m:mr><m:e /><m:e /></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e /><m:e /></m:mr><m:mr><m:e /><m:e /></m:mr></m:m></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,StackWithDifferentValues) +{ + std::wstring wsString = L"stack stack{2} stack 2"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr></m:mr></m:m></m:e></m:mr><m:mr><m:e /></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr><m:e /></m:mr></m:m></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,Partial) +{ + std::wstring wsString = L"{partial f(x)} over { partial x } = ln(x) + tan^-1(x^2)"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>ln</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>tan</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:sup></m:sSup></m:e></m:func><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:e></m:d></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,LimWithArrow) +{ + std::wstring wsString = L"lim from { x->1^-"" }{ {x^{2}-1 } over { x-1 }} = 2 "; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2794</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r></m:sup></m:sSup></m:lim></m:limLow></m:fName><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:den></m:f></m:e></m:func><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + +TEST(SMConvectorTest,FuctionWithAttributeAndIndex) +{ + std::wstring wsString = L"{%sigma' = %sigma color red bold func e ^ color blue frac 2 3 }"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C3</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>e</m:t></m:r></m:e><m:sup><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:sup></m:sSup></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index eaa0773af14..8fce79b2333 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -668,10 +668,28 @@ namespace StarMath if(m_unCount == 0) delete this; } + unsigned int CAttribute::GetCount() + { + return m_unCount; + } + void CAttribute::ComparingAttributes(CAttribute *pAttributeParent, CAttribute *pAttributeChild) + { + if(!pAttributeChild->GetBold() && pAttributeParent->GetBold()) + pAttributeChild->SetBold(); + if(!pAttributeChild->GetItal() && pAttributeParent->GetItal()) + pAttributeChild->SetItal(); + if(!pAttributeChild->GetPhantom() && pAttributeParent->GetPhantom()) + pAttributeChild->SetPhantom(); + if(!pAttributeChild->GetStrike() && pAttributeParent->GetStrike()) + pAttributeChild->SetStrike(); + if(pAttributeChild->EmptyColor() && !pAttributeParent->EmptyColor()) + pAttributeChild->SetColor(pAttributeParent->GetColor()); + if(pAttributeChild->GetSize() == 0 && pAttributeParent->GetSize() != 0) + pAttributeChild->SetSize(pAttributeParent->GetSize()); + } //class methods CElement CElement::~CElement() { -// delete m_pAttribute; if(m_pAttribute != nullptr) m_pAttribute->Release(); } @@ -750,20 +768,18 @@ namespace StarMath m_pAttribute = pAttribute; m_pAttribute->AddRef(); } - else if(pAttribute != nullptr && pAttribute != m_pAttribute) + else if(pAttribute != nullptr && m_pAttribute!=nullptr && pAttribute != m_pAttribute) { - if(!m_pAttribute->GetBold() && pAttribute->GetBold()) - m_pAttribute->SetBold(); - if(!m_pAttribute->GetItal() && pAttribute->GetItal()) - m_pAttribute->SetItal(); - if(!m_pAttribute->GetPhantom() && pAttribute->GetPhantom()) - m_pAttribute->SetPhantom(); - if(!m_pAttribute->GetStrike() && pAttribute->GetStrike()) - m_pAttribute->SetStrike(); - if(m_pAttribute->EmptyColor() && !pAttribute->EmptyColor()) - m_pAttribute->SetColor(pAttribute->GetColor()); - if(m_pAttribute->GetSize() == 0 && pAttribute->GetSize() != 0) - m_pAttribute->SetSize(pAttribute->GetSize()); + if(m_pAttribute->GetCount() <= 1) + CAttribute::ComparingAttributes(pAttribute,m_pAttribute); + else if(m_pAttribute->GetCount() > 1) + { + CAttribute* pTempAttribute = m_pAttribute; + m_pAttribute = new CAttribute; + m_pAttribute->AddRef(); + CAttribute::ComparingAttributes(pTempAttribute,m_pAttribute); + CAttribute::ComparingAttributes(pAttribute,m_pAttribute); + } } } CAttribute* CElement::GetAttribute() @@ -774,6 +790,11 @@ namespace StarMath { return m_enTypeConversion; } + void CElement::DeleteAttribute() + { + m_pAttribute->Release(); + m_pAttribute = nullptr; + } //class methods CElementString CElementString::CElementString(const std::wstring& wsTokenString,const TypeConversion &enTypeConversion) :CElement(TypeElement::String,enTypeConversion),m_wsString(wsTokenString) @@ -2198,7 +2219,7 @@ namespace StarMath if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() == nullptr && pAttribute != nullptr) m_pLeftArg->SetAttribute(pAttribute); if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() != nullptr) - SetBaseAttribute(m_pLeftArg->GetAttribute()); + this->SetBaseAttribute(m_pLeftArg->GetAttribute()); if(m_pValueIndex != nullptr) m_pValueIndex->SetAttribute(pAttribute); if(m_pLeftArg != nullptr) @@ -2367,7 +2388,18 @@ namespace StarMath if(CElementIndex::GetUpperIndex(pReader->GetLocalType()) || CElementIndex::GetLowerIndex(pReader->GetLocalType())) { m_pIndex = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(new CElementString(m_wsNameFunc,pReader->GetTypeConversion()),m_pIndex); + CElementString* pString = new CElementString(m_wsNameFunc,pReader->GetTypeConversion()); + if(this->GetAttribute() != nullptr && pReader->GetBaseAttribute()!=nullptr) + { + pString->SetAttribute(this->GetAttribute()); + pString->SetAttribute(pReader->GetBaseAttribute()); + } + else if(this->GetAttribute()!=nullptr) + pString->SetAttribute(this->GetAttribute()); + else if(pReader->GetBaseAttribute()!=nullptr) + pString->SetAttribute(pReader->GetBaseAttribute()); + + CParserStarMathString::AddLeftArgument(pString,m_pIndex); return ; } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -2991,6 +3023,7 @@ namespace StarMath case L'`': case L'~': case L'"': + case L'\'': return true; default: return false; @@ -3090,14 +3123,10 @@ namespace StarMath } CConversionSMtoOOXML::WriteCtrlPrNode(pXmlWrite,GetAttribute(),GetTypeConversion()); pXmlWrite->WriteNodeEnd(L"m:groupChrPr",false,false); - pXmlWrite->WriteNodeBegin(L"m:e",false); - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pLeftArg); - pXmlWrite->WriteNodeEnd(L"m:e",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pLeftArg,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:groupChr",false,false); pXmlWrite->WriteNodeEnd(L"m:e",false,false); - pXmlWrite->WriteNodeBegin(L"m:lim",false); - CConversionSMtoOOXML::ElementConversion(pXmlWrite,m_pValue); - pXmlWrite->WriteNodeEnd(L"m:lim",false,false); + CConversionSMtoOOXML::WriteNodeConversion(L"m:lim",m_pValue,pXmlWrite); pXmlWrite->WriteNodeEnd(wsNameNode,false,false); } TypeElement CElementBracketWithIndex::GetBracketWithIndex(const std::wstring &wsToken) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index d33a080839a..b4f6c640633 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -87,6 +87,8 @@ namespace StarMath bool SetFont(const TypeElement& enFont); void SetFontName(const std::wstring& wsNameFont); bool CheckAttribute(); + unsigned int GetCount(); + static void ComparingAttributes(CAttribute* pAttributeParent,CAttribute* pAttributeChild); //checking an element for a number from 1 to 9 or from the letter A to F static bool CheckHexPosition(const wchar_t& cToken); bool CheckingForEmptiness(); @@ -165,6 +167,7 @@ namespace StarMath CAttribute* GetAttribute(); const TypeElement& GetBaseType(); const TypeConversion& GetTypeConversion(); + void DeleteAttribute(); private: CAttribute* m_pAttribute; TypeElement m_enBaseType; From 84eebc69e12c3cf44efec3536b11f7350f1138e4 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 23 May 2024 12:03:14 +0300 Subject: [PATCH 696/794] fix bug #68135 --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 9888220ecb5..325fb23ffd6 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -6384,6 +6384,11 @@ void BinaryWorksheetTableWriter::WriteDrawings(const OOX::Spreadsheet::CWorkshee { //преобразуем ClientData в CellAnchor OOX::Vml::CClientData* pClientData = static_cast<OOX::Vml::CClientData*>(pElemShape); + + if (pClientData->m_oObjectType.IsInit() && pClientData->m_oObjectType->GetValue() == SimpleTypes::Vml::vmlclientdataobjecttypeNote) + { + continue; + } SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); From 3bfb3ee045951b98b68cfed6ec78d96484a81328 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 23 May 2024 15:17:23 +0600 Subject: [PATCH 697/794] Fix bug #68113 --- OOXML/XlsxFormat/Controls/Controls.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Controls/Controls.cpp b/OOXML/XlsxFormat/Controls/Controls.cpp index 9e48da5966a..c0dc716b6d0 100644 --- a/OOXML/XlsxFormat/Controls/Controls.cpp +++ b/OOXML/XlsxFormat/Controls/Controls.cpp @@ -208,12 +208,17 @@ namespace OOX XLS::BaseObjectPtr objectPtr(ptr); if (m_oShapeId.IsInit()) ptr->shapeId = m_oShapeId->GetValue(); - + else + ptr->shapeId = 1; if (!m_oName.IsInit()) ptr->strName = m_oName.get(); + else + ptr->strName = L""; if (!m_oRid.IsInit()) ptr->strRelID.value = m_oRid->GetValue(); + else + ptr->strRelID.value = L""; return objectPtr; } void CControl::fromBin(XLS::BaseObjectPtr& obj) From 4ca9a94609ee7ed448e48d08fd50d9c9f8c62be3 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Thu, 23 May 2024 13:00:50 +0300 Subject: [PATCH 698/794] Fix bugs in html --- .../3dParty/html/css/src/StyleProperties.cpp | 11 ++++-- Common/3dParty/html/css/src/StyleProperties.h | 1 + Common/3dParty/html/htmltoxhtml.h | 34 +++++++++++++------ HtmlFile2/htmlfile2.cpp | 25 +++++++++++--- HtmlFile2/src/StringFinder.h | 5 +++ 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c05c7338939..c380779c338 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -604,6 +604,11 @@ namespace NSCSS return m_oValue.Empty(); } + bool CColor::None() const + { + return ColorNone == m_oValue.m_enType; + } + void CColor::Clear() { m_oValue.Clear(); @@ -621,10 +626,10 @@ namespace NSCSS if (m_oOpacity.Empty()) return 1.; - if (Percent == m_oOpacity.GetUnitMeasure()) + if (UnitMeasure::Percent == m_oOpacity.GetUnitMeasure()) return m_oOpacity.ToDouble() / 100.; - if (None == m_oOpacity.GetUnitMeasure() && m_oOpacity.ToDouble() <= 1.) + if (UnitMeasure::None == m_oOpacity.GetUnitMeasure() && m_oOpacity.ToDouble() <= 1.) return m_oOpacity.ToDouble(); return 1.; @@ -1476,7 +1481,7 @@ namespace NSCSS bool CBorderSide::Empty() const { - return m_oWidth.Empty(); + return m_oWidth.Empty() || m_oColor.None(); } bool CBorderSide::Zero() const diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index cfe494a916d..066bcb68c89 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -229,6 +229,7 @@ namespace NSCSS bool SetOpacity(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true); bool Empty() const override; + bool None() const; void Clear() override; ColorType GetType() const; diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 1e544477841..b7fb19d4340 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -204,15 +204,20 @@ static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::s // Content-Location oData = NSStringFinder::FindPropety(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"}); std::string sContentLocation{oData.m_sValue}; - unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); - unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + + if (!oData.Empty()) + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); // Content-ID oData = NSStringFinder::FindPropety(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"}); std::string sContentID{oData.m_sValue}; - unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); - unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); - NSStringFinder::CutInside<std::string>(sContentID, "<", ">"); + + if (!oData.Empty()) + { + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + NSStringFinder::CutInside<std::string>(sContentID, "<", ">"); + } if (sContentLocation.empty() && !sContentID.empty()) sContentLocation = "cid:" + sContentID; @@ -220,13 +225,17 @@ static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::s // Content-Transfer-Encoding oData = NSStringFinder::FindPropety(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"}); const std::string sContentEncoding{oData.m_sValue}; - unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); - unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + + if (!oData.Empty()) + { + unContentPosition = std::max(unContentPosition, oData.m_unEndPosition); + unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition); + } // charset std::string sCharset = "utf-8"; - if (unCharsetBegin < unCharsetEnd) + if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd) { sCharset = NSStringFinder::FindPropety(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue; NSStringFinder::CutInside<std::string>(sCharset, "\""); @@ -250,7 +259,7 @@ static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::s oRes.WriteString("<style>"); if (NSStringFinder::Equals(sContentEncoding, "base64")) - oRes.WriteString(Base64ToString(sContent, sCharset)); + sContent = Base64ToString(sContent, sCharset); else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty()) { if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty()) @@ -258,7 +267,6 @@ static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::s NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); } - oRes.WriteString(sContent); } else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable")) { @@ -268,9 +276,13 @@ static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::s NSUnicodeConverter::CUnicodeConverter oConverter; sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data())); } - oRes.WriteString(sContent); } + if (NSStringFinder::Equals(sContentType, "text/html")) + sContent = U_TO_UTF8(htmlToXhtml(sContent, false)); + + oRes.WriteString(sContent); + if(bAddTagStyle) oRes.WriteString("</style>"); } diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 0744984eed9..1d51ff07e7d 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -140,17 +140,24 @@ void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = fal if (!bInP) pXml->WriteString(L"<w:p><w:pPr>"); - pXml->WriteString(L"<w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/>"); + pXml->WriteString(L"<w:r><w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/>"); if (bVahish) pXml->WriteString(L"<w:vanish/>"); - pXml->WriteString(L"</w:rPr>"); + pXml->WriteString(L"</w:rPr></w:r>"); if (!bInP) pXml->WriteString(L"</w:pPr></w:p>"); } +void WriteLine(NSStringUtils::CStringBuilder* pXml, double dHeight, const std::wstring& wsColor) +{ + pXml->WriteNodeBegin(L"w:pict"); + pXml->WriteString(L"<v:rect style=\"width:0;height:" + std::to_wstring(dHeight) + L"pt\" o:hralign=\"center\" o:hrstd=\"t\" o:hr=\"t\" fillcolor=\"#" + wsColor + L"\" stroked=\"f\"/>"); + pXml->WriteNodeEnd(L"w:pict"); +} + bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors) { return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; }); @@ -1883,7 +1890,7 @@ class CHtmlFile2_Private oXml->WriteString(L"<w:br/></w:r>"); } else - WriteEmptyParagraph(oXml); + WriteEmptyParagraph(oXml, false, m_bInP); m_bWasSpace = true; } @@ -2038,7 +2045,7 @@ class CHtmlFile2_Private sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" || sName == L"comment" || sName == L"title" || sName == L"style") { - WriteEmptyParagraph(oXml); + WriteEmptyParagraph(oXml, false, m_bInP); sSelectors.pop_back(); return; } @@ -2138,7 +2145,15 @@ class CHtmlFile2_Private } } if (bPrint) - oXml->WriteString(L"<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr></w:pPr></w:p>"); + { + const bool bOpenedP = OpenP(oXml); + OpenR(oXml); + WriteLine(oXml, 1.5, L"a0a0a0"); + CloseR(oXml); + if (bOpenedP) + CloseP(oXml, sSelectors); + } +// oXml->WriteString(L"<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr></w:pPr></w:p>"); } // Меню // Маркированный список diff --git a/HtmlFile2/src/StringFinder.h b/HtmlFile2/src/StringFinder.h index 5f565aeb877..3b4fd572bb9 100644 --- a/HtmlFile2/src/StringFinder.h +++ b/HtmlFile2/src/StringFinder.h @@ -23,6 +23,11 @@ namespace NSStringFinder TFoundedData() : m_unBeginPosition(0), m_unEndPosition(0) {} + + bool Empty() const + { + return 0 == m_unEndPosition || StringType::npos == m_unEndPosition; + } }; template<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> From 105a193742585c1e176d80b9e9d4bcb450ad6440 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 23 May 2024 14:00:28 +0300 Subject: [PATCH 699/794] fix bug #68143 --- .../ODRAW/OfficeArtBStoreContainerFileBlock.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp index 2c56f582971..f942807ce30 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.cpp @@ -232,9 +232,14 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record) record.RollRdPtrBack(32); } break; - default: + case 0xf018: + { record.skipNunBytes(rc_header.recLen); return; + }break; + default: //0xf007 + record.RollRdPtrBack(rc_header.size()); + return; } From a70f50206d3cb0af6d60957eebf051b7e1468e7e Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 23 May 2024 14:36:14 +0300 Subject: [PATCH 700/794] fix bug #67917 --- MsBinaryFile/DocFile/SettingsMapping.cpp | 32 +++++++++---- .../test/win32Test/X2tConverter_win_test.sln | 46 ------------------- X2tConverter/test/win32Test/X2tTest.cpp | 12 +++-- X2tConverter/test/win32Test/X2tTest.vcxproj | 6 --- 4 files changed, 32 insertions(+), 64 deletions(-) diff --git a/MsBinaryFile/DocFile/SettingsMapping.cpp b/MsBinaryFile/DocFile/SettingsMapping.cpp index 9458f5d3e13..bba5b52cfdd 100644 --- a/MsBinaryFile/DocFile/SettingsMapping.cpp +++ b/MsBinaryFile/DocFile/SettingsMapping.cpp @@ -83,32 +83,48 @@ namespace DocFileFormat if (_ctx->_doc->FIB->m_FibBase.fWriteReservation) { - m_oXmlWriter.WriteNodeBegin( L"w:writeProtection", TRUE ); - WideString* passw = static_cast<WideString*>(_ctx->_doc->AssocNames->operator[]( 17 )); + CRYPT::_ecmaWriteProtectData data; + + WideString* passw = static_cast<WideString*>(_ctx->_doc->AssocNames->operator[]( 17 )); if (passw && false == passw->empty()) { - CRYPT::_ecmaWriteProtectData data; - CRYPT::ECMAWriteProtect protect; protect.SetCryptData(data); protect.SetPassword(*passw); protect.Generate(); protect.GetCryptData(data); + } + m_oXmlWriter.WriteNodeBegin(L"w:writeProtection", TRUE); + if (false == data.saltValue.empty()) + { //m_oXmlWriter.WriteAttribute ( L"w:cryptProviderType", L"rsaAES"); //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmSid", 14); //sha-512 //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmType", L"typeAny"); //m_oXmlWriter.WriteAttribute ( L"w:cryptAlgorithmClass", L"hash"); - //m_oXmlWriter.WriteAttribute ( L"w:cryptSpinCount", data.spinCount); - //m_oXmlWriter.WriteAttribute ( L"w:hash", EncodeBase64(data.hashValue)); - //m_oXmlWriter.WriteAttribute ( L"w:salt", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteAttribute ( L"w:algorithmName", L"SHA-512"); m_oXmlWriter.WriteAttribute ( L"w:spinCount", data.spinCount); m_oXmlWriter.WriteAttribute ( L"w:hashValue", EncodeBase64(data.hashValue)); - m_oXmlWriter.WriteAttribute ( L"w:saltValue", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteAttribute ( L"w:saltValue", EncodeBase64(data.saltValue)); } m_oXmlWriter.WriteNodeEnd( L"", TRUE, TRUE ); + if (false == data.saltValue.empty()) + { + m_oXmlWriter.WriteNodeBegin(L"w:documentProtection", TRUE); + m_oXmlWriter.WriteAttribute(L"w:edit", L"readOnly"); + m_oXmlWriter.WriteAttribute(L"w:enforcement", L"1"); + m_oXmlWriter.WriteAttribute(L"w:cryptProviderType", L"rsaAES"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmClass", L"hash"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmType", L"typeAny"); + m_oXmlWriter.WriteAttribute(L"w:cryptAlgorithmSid", 14); //sha-512 + m_oXmlWriter.WriteAttribute(L"w:cryptSpinCount", data.spinCount); + m_oXmlWriter.WriteAttribute(L"w:spinCount", data.spinCount); + m_oXmlWriter.WriteAttribute(L"w:hash", EncodeBase64(data.hashValue)); + m_oXmlWriter.WriteAttribute(L"w:salt", EncodeBase64(data.saltValue)); + m_oXmlWriter.WriteNodeEnd(L"", TRUE, TRUE); + } } //zoom m_oXmlWriter.WriteNodeBegin ( L"w:zoom", TRUE ); diff --git a/X2tConverter/test/win32Test/X2tConverter_win_test.sln b/X2tConverter/test/win32Test/X2tConverter_win_test.sln index 3c1f5659759..c59cbaa4208 100644 --- a/X2tConverter/test/win32Test/X2tConverter_win_test.sln +++ b/X2tConverter/test/win32Test/X2tConverter_win_test.sln @@ -7,9 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X2tTest", "X2tTest.vcxproj" ProjectSection(ProjectDependencies) = postProject {41BED424-4EAF-4053-8A5F-1E2A387D53D1} = {41BED424-4EAF-4053-8A5F-1E2A387D53D1} {609ED938-3CA8-4BED-B363-25096D4C4812} = {609ED938-3CA8-4BED-B363-25096D4C4812} - {C39F4B46-6E89-4074-902E-CA57073044D2} = {C39F4B46-6E89-4074-902E-CA57073044D2} {94954A67-A853-43B1-A727-6EF2774C5A6A} = {94954A67-A853-43B1-A727-6EF2774C5A6A} - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C} = {C27E9A9F-3A17-4482-9C5F-BF15C01E747C} {FA22BAB4-E93E-459D-8A5F-16764FBBED40} = {FA22BAB4-E93E-459D-8A5F-16764FBBED40} {DACBE6CA-E089-47D1-8CE7-C7DB59C15417} = {DACBE6CA-E089-47D1-8CE7-C7DB59C15417} EndProjectSection @@ -43,10 +41,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OdfFormatWriterLib", "..\.. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Oox2OdfConverter", "..\..\..\OdfFile\Projects\Windows\Oox2OdfConverter.vcxproj", "{BEE01B53-244A-44E6-8947-ED9342D9247E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "..\..\..\Common\3dParty\cryptopp\vs2019\cryptlib.vcxproj", "{C39F4B46-6E89-4074-902E-CA57073044D2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OfficeFileCrypt", "..\..\..\OfficeCryptReader\win32\ECMACryptReader.vcxproj", "{C27E9A9F-3A17-4482-9C5F-BF15C01E747C}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OdfCommon", "..\..\..\OdfFile\Projects\Windows\cpcommon.vcxproj", "{609ED938-3CA8-4BED-B363-25096D4C4812}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml_wrapper", "..\..\..\OdfFile\Projects\Windows\cpxml.vcxproj", "{41BED424-4EAF-4053-8A5F-1E2A387D53D1}" @@ -350,46 +344,6 @@ Global {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 {BEE01B53-244A-44E6-8947-ED9342D9247E}.ReleaseOpenSource|x64.Build.0 = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|Win32.ActiveCfg = Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|Win32.Build.0 = Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.ActiveCfg = Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Debug|x64.Build.0 = Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|Win32.ActiveCfg = DLL-Import Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|Win32.Build.0 = DLL-Import Debug|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|x64.ActiveCfg = DLL-Import Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Debug|x64.Build.0 = DLL-Import Debug|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|Win32.ActiveCfg = DLL-Import Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|Win32.Build.0 = DLL-Import Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|x64.ActiveCfg = DLL-Import Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.DLL-Import Release|x64.Build.0 = DLL-Import Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|Win32.ActiveCfg = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|Win32.Build.0 = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.ActiveCfg = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.Release|x64.Build.0 = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|Win32.ActiveCfg = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 - {C39F4B46-6E89-4074-902E-CA57073044D2}.ReleaseOpenSource|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|Win32.Build.0 = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|x64.ActiveCfg = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Debug|x64.Build.0 = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|Win32.ActiveCfg = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|Win32.Build.0 = Debug|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|x64.ActiveCfg = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Debug|x64.Build.0 = Debug|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.DLL-Import Release|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.Release|x64.Build.0 = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|Win32.ActiveCfg = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|Win32.Build.0 = Release|Win32 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|x64.ActiveCfg = Release|x64 - {C27E9A9F-3A17-4482-9C5F-BF15C01E747C}.ReleaseOpenSource|x64.Build.0 = Release|x64 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|Win32.ActiveCfg = Debug|Win32 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|Win32.Build.0 = Debug|Win32 {609ED938-3CA8-4BED-B363-25096D4C4812}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/X2tConverter/test/win32Test/X2tTest.cpp b/X2tConverter/test/win32Test/X2tTest.cpp index 132efa395b5..0609df7d328 100644 --- a/X2tConverter/test/win32Test/X2tTest.cpp +++ b/X2tConverter/test/win32Test/X2tTest.cpp @@ -45,7 +45,8 @@ #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/UnicodeConverter.lib") - #else + #pragma comment(lib, "../../../build/lib/win_64/DEBUG/CryptoPPLib.lib") +#else #pragma comment(lib, "../../../build/lib/win_64/doctrenderer.lib") #pragma comment(lib, "../../../build/lib/win_64/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_64/PdfFile.lib") @@ -58,7 +59,8 @@ #pragma comment(lib, "../../../build/lib/win_64/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/UnicodeConverter.lib") - #endif + #pragma comment(lib, "../../../build/lib/win_64/CryptoPPLib.lib") +#endif #pragma comment(lib, "../../../Common/3dParty/icu/win_64/build//icuuc.lib") #elif defined (_WIN32) #if defined(_DEBUG) @@ -75,7 +77,8 @@ #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/UnicodeConverter.lib") - #else + #pragma comment(lib, "../../../build/lib/win_32/DEBUG/CryptoPPLib.lib") +#else #pragma comment(lib, "../../../build/lib/win_32/doctrenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/HtmlRenderer.lib") #pragma comment(lib, "../../../build/lib/win_32/DocxRenderer.lib") @@ -89,7 +92,8 @@ #pragma comment(lib, "../../../build/lib/win_32/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/UnicodeConverter.lib") - #endif + #pragma comment(lib, "../../../build/lib/win_32/CryptoPPLib.lib") +#endif #pragma comment(lib, "../../../Common/3dParty/icu/win_32/build/icuuc.lib") #endif diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj b/X2tConverter/test/win32Test/X2tTest.vcxproj index 4f3cfd2abb1..8223bda761e 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -194,9 +194,6 @@ <ClInclude Include="..\..\src\lib\xlsx.h" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\..\..\Common\3dParty\cryptopp\vs2019\cryptlib.vcxproj"> - <Project>{c39f4b46-6e89-4074-902e-ca57073044d2}</Project> - </ProjectReference> <ProjectReference Include="..\..\..\Common\cfcpp\CompoundFileLib.vcxproj"> <Project>{fa22bab4-e93e-459d-8a5f-16764fbbed40}</Project> </ProjectReference> @@ -233,9 +230,6 @@ <ProjectReference Include="..\..\..\OdfFile\Projects\Windows\Oox2OdfConverter.vcxproj"> <Project>{bee01b53-244a-44e6-8947-ed9342d9247e}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\OfficeCryptReader\win32\ECMACryptReader.vcxproj"> - <Project>{c27e9a9f-3a17-4482-9c5f-bf15c01e747c}</Project> - </ProjectReference> <ProjectReference Include="..\..\..\OOXML\Projects\Windows\BinaryFormatLib\BinaryFormatLib.vcxproj"> <Project>{cd359215-e183-4ea7-b986-42868b10d8b8}</Project> </ProjectReference> From 40b6178a0da3609b20e5d3b5829e6907d89ac338 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 23 May 2024 16:22:52 +0300 Subject: [PATCH 701/794] Fix c_nPenWidth0As1px for annot/field renderer --- DesktopEditor/graphics/commands/AnnotField.cpp | 1 + PdfFile/SrcReader/PdfAnnot.cpp | 1 + PdfFile/SrcReader/RendererOutputDev.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index c6532e542c4..fd8fe60ff5f 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -562,6 +562,7 @@ void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferR BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetQ() const { return m_nQ; } BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetIT() const { return m_nIT; } BYTE CAnnotFieldInfo::CFreeTextAnnotPr::GetLE() const { return m_nLE; } +int CAnnotFieldInfo::CFreeTextAnnotPr::GetRotate() { return m_nRotate; } const std::wstring& CAnnotFieldInfo::CFreeTextAnnotPr::GetDS() { return m_wsDS; } void CAnnotFieldInfo::CFreeTextAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; } const std::vector<double>& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 46b43b0fede..fa5dcceabe3 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2987,6 +2987,7 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFon m_pRenderer->put_Height((m_dy2 - m_dy1 + (2 + m_dHTale) * dHeight / (double)nRasterH) * 25.4 / 72.0); if (nBackgroundColor != 0xFFFFFF) m_pRenderer->CommandLong(c_nDarkMode, 1); + m_pRenderer->CommandLong(c_nPenWidth0As1px, 1); m_pRendererOut = new RendererOutputDev(m_pRenderer, pFontManager, pFontList); m_pRendererOut->NewPDF(pdfDoc->getXRef()); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 4b5c6cdd200..c1d8e473ec4 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3094,6 +3094,7 @@ namespace PdfReader pRenderer->CreateFromBgraFrame(pFrame); pRenderer->put_Width (nWidth * 25.4 / 72.0); pRenderer->put_Height(nHeight * 25.4 / 72.0); + pRenderer->CommandLong(c_nPenWidth0As1px, 1); PDFRectangle box; box.x1 = pBBox[0]; From 55a009713e41dc06caf0e36d3cb3402335005226 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 23 May 2024 16:56:40 +0300 Subject: [PATCH 702/794] Fix bug 54371 --- PdfFile/SrcWriter/Image.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/PdfFile/SrcWriter/Image.cpp b/PdfFile/SrcWriter/Image.cpp index 77ae89b1a13..75fabbae3e7 100644 --- a/PdfFile/SrcWriter/Image.cpp +++ b/PdfFile/SrcWriter/Image.cpp @@ -53,8 +53,8 @@ namespace NSImageReSaver return; int nSize = oFile.GetFileSize(); - if (nSize > 1000) - nSize = 1000; + if (nSize > 10000) + nSize = 10000; BYTE* data = new BYTE[nSize]; DWORD dwRead = 0; @@ -68,22 +68,22 @@ namespace NSImageReSaver oFile.CloseFile(); RELEASEARRAYOBJECTS(data); - if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) - return; + if (std::string::npos != sFind.find("Photoshop") || std::string::npos != sFind.find("photoshop")) + { + CBgraFrame oFrame; + if (!oFrame.OpenFile(wsFileName)) + return; - CBgraFrame oFrame; - if (!oFrame.OpenFile(wsFileName)) - return; + oFrame.SetJpegQuality(85.0); + if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) + return; - oFrame.SetJpegQuality(85.0); - if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) - return; + if (!pBuffer || !nBufferSize) + return; - if (!pBuffer || !nBufferSize) - return; - - unWidth = (unsigned int)oFrame.get_Width(); - unHeight = (unsigned int)oFrame.get_Height(); + unWidth = (unsigned int)oFrame.get_Width(); + unHeight = (unsigned int)oFrame.get_Height(); + } } } From dcb4364410107815eca962eed74cbab60e491a24 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 23 May 2024 17:23:06 +0300 Subject: [PATCH 703/794] Fix bug 67641 --- PdfFile/SrcReader/RendererOutputDev.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index c1d8e473ec4..27876b4651a 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -672,7 +672,7 @@ namespace PdfReader m_bTransparentGroupSoftMaskEnd = false; if (c_nHtmlRendrerer2 == m_lRendererType) - m_bDrawOnlyText = (S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0)) ? true : false; + m_bDrawOnlyText = S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0); else if (c_nHtmlRendrererText == m_lRendererType) m_bDrawOnlyText = true; else @@ -3942,7 +3942,7 @@ namespace PdfReader int nRenderMode = pGState->getRender(); - if (3 == nRenderMode) // Невидимый текст + if (3 == nRenderMode && !m_bDrawOnlyText) // Невидимый текст { return; } @@ -4053,7 +4053,7 @@ namespace PdfReader } } - if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || (m_bDrawOnlyText && nRenderMode == 2)) + if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || m_bDrawOnlyText) { bool bReplace = false; std::wstring sFontPath; From 1286b7f458dc5497f3b930ca155a7694b4921245 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 23 May 2024 17:27:42 +0300 Subject: [PATCH 704/794] fix bug #68122 --- MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index a13e0b41a9a..3f8de98f722 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -178,8 +178,7 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring& strInput, const st if (strExts == L".video" || strExts == L".audio") { std::wstring strInput1 = strInput.substr(0, nIndexExt); - nIndexExt = strInput1.rfind(wchar_t('.')); - strExts = nIndexExt < 0 ? L"" : strInput1.substr(nIndexExt); + strExts.clear(); } if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; From 08111e8fdebd2c7521259e41554867b69f3c066b Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 23 May 2024 17:46:02 +0300 Subject: [PATCH 705/794] fix bug #67992 --- OOXML/XlsxFormat/Workbook/Sheets.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index e4309a7c55a..97c6c4068f6 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -99,13 +99,12 @@ namespace OOX } void CSheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { - WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_Read_if ( oReader, (L"r:id"), m_oRid ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"relationships:id"), m_oRid ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"name"), m_oName ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"sheetId"), m_oSheetId ) - WritingElement_ReadAttributes_Read_else_if( oReader, (L"state"), m_oState ) - WritingElement_ReadAttributes_End( oReader ) + WritingElement_ReadAttributes_Start_No_NS( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"id", m_oRid ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"name", m_oName ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"sheetId", m_oSheetId ) + WritingElement_ReadAttributes_Read_else_if( oReader, L"state", m_oState ) + WritingElement_ReadAttributes_End_No_NS( oReader ) } void CSheet::ReadAttributes(XLS::BaseObjectPtr& obj) { From a1fed79a78fa8ae142e836c280b6a919449ef5b2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 23 May 2024 16:56:40 +0300 Subject: [PATCH 706/794] Fix bug 54371 --- PdfFile/SrcWriter/Image.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/PdfFile/SrcWriter/Image.cpp b/PdfFile/SrcWriter/Image.cpp index 77ae89b1a13..75fabbae3e7 100644 --- a/PdfFile/SrcWriter/Image.cpp +++ b/PdfFile/SrcWriter/Image.cpp @@ -53,8 +53,8 @@ namespace NSImageReSaver return; int nSize = oFile.GetFileSize(); - if (nSize > 1000) - nSize = 1000; + if (nSize > 10000) + nSize = 10000; BYTE* data = new BYTE[nSize]; DWORD dwRead = 0; @@ -68,22 +68,22 @@ namespace NSImageReSaver oFile.CloseFile(); RELEASEARRAYOBJECTS(data); - if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) - return; + if (std::string::npos != sFind.find("Photoshop") || std::string::npos != sFind.find("photoshop")) + { + CBgraFrame oFrame; + if (!oFrame.OpenFile(wsFileName)) + return; - CBgraFrame oFrame; - if (!oFrame.OpenFile(wsFileName)) - return; + oFrame.SetJpegQuality(85.0); + if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) + return; - oFrame.SetJpegQuality(85.0); - if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) - return; + if (!pBuffer || !nBufferSize) + return; - if (!pBuffer || !nBufferSize) - return; - - unWidth = (unsigned int)oFrame.get_Width(); - unHeight = (unsigned int)oFrame.get_Height(); + unWidth = (unsigned int)oFrame.get_Width(); + unHeight = (unsigned int)oFrame.get_Height(); + } } } From ba87df6b9de2800d7c8ae07e73360e0707cfcbcc Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 23 May 2024 17:23:06 +0300 Subject: [PATCH 707/794] Fix bug 67641 --- PdfFile/SrcReader/RendererOutputDev.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 4b5c6cdd200..f34d588f669 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -672,7 +672,7 @@ namespace PdfReader m_bTransparentGroupSoftMaskEnd = false; if (c_nHtmlRendrerer2 == m_lRendererType) - m_bDrawOnlyText = (S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0)) ? true : false; + m_bDrawOnlyText = S_OK == m_pRenderer->CommandLong(c_nCommandLongTypeOnlyText, 0); else if (c_nHtmlRendrererText == m_lRendererType) m_bDrawOnlyText = true; else @@ -3941,7 +3941,7 @@ namespace PdfReader int nRenderMode = pGState->getRender(); - if (3 == nRenderMode) // Невидимый текст + if (3 == nRenderMode && !m_bDrawOnlyText) // Невидимый текст { return; } @@ -4052,7 +4052,7 @@ namespace PdfReader } } - if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || (m_bDrawOnlyText && nRenderMode == 2)) + if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || m_bDrawOnlyText) { bool bReplace = false; std::wstring sFontPath; From d01681bb1e8b2c75cf92a6a7d2c29f4cf0f1dec7 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Fri, 24 May 2024 12:02:18 +0300 Subject: [PATCH 708/794] Fix bug #66549 --- Common/3dParty/html/htmltoxhtml.h | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index b7fb19d4340..ff28c84dc7c 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -22,6 +22,23 @@ static std::string special_handling = "|html|body|"; static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; +static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6", + "ul", "ol", "li","table","tr","td","th","br","form","input", + "button","section","nav","header","footer","main","figure", + "figcaption","strong","em","i", "b", "u","pre","code","blockquote", + "hr","script","link","meta","style","title","head","body","html", + "legend","optgroup","option","select","dl","dt","dd","time", + "data","abbr","address","area","base","bdi","bdo","cite","col", + "iframe","video","source","track","textarea","label","fieldset", + "colgroup","del","ins","details","summary","dialog","embed", + "kbd","map","mark","menu","meter","object","output","param", + "progress","q","samp","small","sub","sup","var","wbr","acronym", + "applet","article","aside","audio","basefont","bgsound","big", + "blink","canvas","caption","center","command","comment","datalist", + "dfn","dir","font","frame","frameset","hgroup","isindex","keygen", + "marquee","nobr","noembed","noframes","noscript","plaintext","rp", + "rt","ruby","s","strike","tt","tfoot","thead","xmp"}; + static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder); static std::string mhtTohtml(const std::string &sFileContent); @@ -566,13 +583,20 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde return; } + std::string tagname = get_tag_name(node); + + if (html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname)) + { + prettyprint_contents(node, oBuilder); + return; + } + std::string close = ""; std::string closeTag = ""; - std::string tagname = get_tag_name(node); std::string key = "|" + tagname + "|"; bool is_empty_tag = empty_tags.find(key) != std::string::npos; bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; - + // determine closing tag type if (is_empty_tag) close = "/"; From d51f03556130490f3cde732c60108d848ef39eab Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 24 May 2024 14:32:29 +0300 Subject: [PATCH 709/794] Fix AddShape for NewPage --- PdfFile/PdfFile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index f8b19ca312a..de42f8f7e55 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1244,13 +1244,13 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::ShapeStart: { CShapeStart* pCommand = (CShapeStart*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + if (m_pInternal->pEditor) m_pInternal->pEditor->AddShapeXML(pCommand->GetShapeXML()); return S_OK; } case IAdvancedCommand::AdvancedCommandType::ShapeEnd: { - if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + if (m_pInternal->pEditor) m_pInternal->pEditor->EndMarkedContent(); return S_OK; } @@ -1263,7 +1263,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::PageRotate: { CPageRotate* pCommand = (CPageRotate*)command; - if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + if (m_pInternal->pEditor) m_pInternal->pWriter->PageRotate(pCommand->GetPageRotate()); return S_OK; } From af12226bfa5bd71ad9eb012bcdad94d27b16d17e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 24 May 2024 14:51:30 +0300 Subject: [PATCH 710/794] Fix FlateDecode for annot view --- PdfFile/SrcWriter/Annotation.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index a294d1cdbcb..7c6f2ba1847 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1175,6 +1175,10 @@ namespace PdfWriter CDictObject* pFPStream = pFakePage->GetContent(); pNormal->SetStream(m_pXref, pFPStream->GetStream(), false); +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_pDocument->GetCompressionMode() & COMP_TEXT) + pNormal->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif pFPStream->SetStream(NULL); // RELEASEOBJECT(pFPStream); Нельзя удалять - это объект стрима, он уже в xref } From 0be217ba0510520a001ee3dfef8c00ae63dd5a13 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Fri, 24 May 2024 18:23:17 +0600 Subject: [PATCH 711/794] Fix bug #68109 --- .../Biff12_structures/PCDIDateTime_bs.cpp | 57 ++- OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 4 +- OOXML/XlsxFormat/Pivot/Pivots.cpp | 442 ++++++++++++------ 3 files changed, 343 insertions(+), 160 deletions(-) diff --git a/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp b/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp index 73c6196d2e7..f01dd92287e 100644 --- a/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp +++ b/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp @@ -87,15 +87,54 @@ namespace XLSB void PCDIDateTime::fromString(const std::wstring& str) { std::string ts(str.begin(), str.end()); - boost::posix_time::ptime pt(boost::posix_time::time_from_string(ts)); - tm pt_tm = boost::posix_time::to_tm(pt); - - yr = pt_tm.tm_year; - mon = pt_tm.tm_mon; - dom = pt_tm.tm_mday; - hr = pt_tm.tm_hour; - min = pt_tm.tm_min; - sec = pt_tm.tm_sec; + boost::posix_time::ptime pt; + bool timeValid = false; + try + { + pt = (boost::posix_time::time_from_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + if(!timeValid) + { + try + { + pt = (boost::posix_time::from_iso_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + } + if(!timeValid) + { + try + { + pt = (boost::posix_time::from_iso_extended_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + } + if(timeValid) + { + tm pt_tm = boost::posix_time::to_tm(pt); + yr = pt_tm.tm_year; + mon = pt_tm.tm_mon; + dom = pt_tm.tm_mday; + hr = pt_tm.tm_hour; + min = pt_tm.tm_min; + sec = pt_tm.tm_sec; + } + else + { + yr = 0; + mon = 0; + dom = 0; + hr = 0; + min = 0; + sec = 0; + } } diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 114093b2c8f..ee42561c090 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -75,7 +75,7 @@ namespace OOX } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - XLS::BaseObjectPtr writeAttributes(); + XLS::BaseObjectPtr writeAttributes(const UINT8 flags); nullable_bool m_oContainsBlank; nullable_bool m_oContainsDate; @@ -825,7 +825,7 @@ namespace OOX XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { - return et_x_PivotBooleanValue; + return et_x_PivotDateTimeValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index ce15188289e..b65bcb076af 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -445,16 +445,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oApplyBorderFormats.IsInit()) ptr->ibitAtrBdr = m_oApplyBorderFormats.get(); + else + ptr->ibitAtrBdr = false; if (m_oApplyFontFormats.IsInit()) ptr->ibitAtrFnt = m_oApplyFontFormats.get(); + else + ptr->ibitAtrFnt = false; if (m_oApplyNumberFormats.IsInit()) ptr->ibitAtrNum = m_oApplyNumberFormats.get(); + else + ptr->ibitAtrNum = false; if (m_oApplyPatternFormats.IsInit()) ptr->ibitAtrPat = m_oApplyPatternFormats.get(); + else + ptr->ibitAtrPat = false; if (m_oApplyWidthHeightFormats.IsInit()) ptr->ibitAtrProt = m_oApplyWidthHeightFormats.get(); + else + ptr->ibitAtrProt = false; if (m_oApplyAlignmentFormats.IsInit()) ptr->ibitAtrAlc = m_oApplyAlignmentFormats.get(); + else + ptr->ibitAtrAlc = false; if (m_oAsteriskTotals.IsInit()) ptr->fHideTotAnnotation = m_oAsteriskTotals.get(); @@ -480,105 +492,202 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (m_oColHeaderCaption.IsInit()) ptr->irstColHdrName = m_oColHeaderCaption.get(); else ptr->fUseColHdrName = false; - if (m_oCompact.IsInit()) ptr->fDefaultCompact = m_oCompact.get(); - if (m_oCompactData.IsInit()) ptr->fCompactData = m_oCompactData.get(); - if (m_oCreatedVersion.IsInit()) ptr->bVerSxMacro = m_oCreatedVersion->GetValue(); - if (m_oCustomListSort.IsInit()) ptr->fDontUseCustomLists = !m_oCustomListSort.get(); - else ptr->fDontUseCustomLists = false; - if (m_oDataCaption.IsInit()) ptr->irstData = m_oDataCaption.get(); + if (m_oCompact.IsInit()) + ptr->fDefaultCompact = m_oCompact.get(); + else + ptr->fDefaultCompact = false; + if (m_oCompactData.IsInit()) + ptr->fCompactData = m_oCompactData.get(); + else + ptr->fCompactData = false; + if (m_oCreatedVersion.IsInit()) + ptr->bVerSxMacro = m_oCreatedVersion->GetValue(); + else + ptr->bVerSxMacro = false; + if (m_oCustomListSort.IsInit()) + ptr->fDontUseCustomLists = !m_oCustomListSort.get(); + else + ptr->fDontUseCustomLists = false; + if (m_oDataCaption.IsInit()) + ptr->irstData = m_oDataCaption.get(); else ptr->irstData = 0xFFFFFFFF; - if (m_oDataOnRows.IsInit()) ptr->fDefaultCompact = m_oDataOnRows.get(); - if (m_oDataPosition.IsInit()) ptr->ipos4Data = m_oDataPosition->GetValue(); - else ptr->ipos4Data = -1; - if (m_oDisableFieldList.IsInit()) ptr->fDisableFList = m_oDisableFieldList.get(); - else ptr->fDisableFList = false; - if (m_oEditData.IsInit()) ptr->fEnableDataEd = m_oEditData.get(); - else - ptr->fEnableDataEd = false; - if (m_oEnableDrill.IsInit()) ptr->fEnableDrilldown = m_oEnableDrill.get(); - if (m_oEnableFieldProperties.IsInit()) ptr->fEnableFieldDialog = m_oEnableFieldProperties.get(); - if (m_oEnableWizard.IsInit()) ptr->fEnableWizard = m_oEnableWizard.get(); - if (m_oErrorCaption.IsInit()) ptr->irstErrorString = m_oErrorCaption.get(); + if (m_oDataOnRows.IsInit()) + ptr->fDefaultCompact = m_oDataOnRows.get(); + else + ptr->fDefaultCompact = false; + if (m_oDataPosition.IsInit()) + ptr->ipos4Data = m_oDataPosition->GetValue(); + else + ptr->ipos4Data = -1; + if (m_oDisableFieldList.IsInit()) + ptr->fDisableFList = m_oDisableFieldList.get(); + else + ptr->fDisableFList = false; + if (m_oEditData.IsInit()) + ptr->fEnableDataEd = m_oEditData.get(); + else + ptr->fEnableDataEd = false; + if (m_oEnableDrill.IsInit()) + ptr->fEnableDrilldown = m_oEnableDrill.get(); + else + ptr->fEnableDrilldown = false; + if (m_oEnableFieldProperties.IsInit()) + ptr->fEnableFieldDialog = m_oEnableFieldProperties.get(); + else + ptr->fEnableFieldDialog = false; + if (m_oEnableWizard.IsInit()) + ptr->fEnableWizard = m_oEnableWizard.get(); + else + ptr->fEnableWizard = false; + if (m_oErrorCaption.IsInit()) + ptr->irstErrorString = m_oErrorCaption.get(); else { ptr->fEmptyDisplayErrorString = true; ptr->fDisplayErrorString = false; } - if (m_oFieldListSortAscending.IsInit()) ptr->fNonDefaultSortInFlist = m_oFieldListSortAscending.get(); - else ptr->fNonDefaultSortInFlist = false; - if (m_oFieldPrintTitles.IsInit()) ptr->fPrintTitles = m_oFieldPrintTitles.get(); - else ptr->fPrintTitles = false; - if (m_oGrandTotalCaption.IsInit()) ptr->irstGrand = m_oGrandTotalCaption.get(); + if (m_oFieldListSortAscending.IsInit()) + ptr->fNonDefaultSortInFlist = m_oFieldListSortAscending.get(); + else + ptr->fNonDefaultSortInFlist = false; + if (m_oFieldPrintTitles.IsInit()) + ptr->fPrintTitles = m_oFieldPrintTitles.get(); + else + ptr->fPrintTitles = false; + if (m_oGrandTotalCaption.IsInit()) + ptr->irstGrand = m_oGrandTotalCaption.get(); else ptr->fDisplayGrand = false; - if (m_oGridDropZones.IsInit()) ptr->fNewDropZones = !m_oGridDropZones.get(); - if (m_oImmersive.IsInit()) ptr->fTurnOffImmersive = m_oImmersive.get(); - else ptr->fTurnOffImmersive = false; - if (m_oIndent.IsInit()) ptr->cIndentInc = m_oIndent->GetValue(); - if (m_oItemPrintTitles.IsInit()) ptr->fRepeatItemsOnEachPrintedPage = m_oItemPrintTitles.get(); - if (m_oMdxSubqueries.IsInit()) ptr->fDefaultCompact = m_oMdxSubqueries.get(); - if (m_oMergeItem.IsInit()) ptr->fMergeLabels = m_oMergeItem.get(); - else ptr->fMergeLabels = false; - if (m_oMinRefreshableVersion.IsInit()) ptr->bVerSxUpdateableMin = m_oMinRefreshableVersion->GetValue(); - if (m_oMissingCaption.IsInit()) ptr->irstNullString = m_oMissingCaption.get(); + if (m_oGridDropZones.IsInit()) + ptr->fNewDropZones = !m_oGridDropZones.get(); + else + ptr->fNewDropZones = false; + if (m_oImmersive.IsInit()) + ptr->fTurnOffImmersive = m_oImmersive.get(); + else + ptr->fTurnOffImmersive = false; + if (m_oIndent.IsInit()) + ptr->cIndentInc = m_oIndent->GetValue(); + else + ptr->cIndentInc = false; + if (m_oItemPrintTitles.IsInit()) + ptr->fRepeatItemsOnEachPrintedPage = m_oItemPrintTitles.get(); + else + ptr->fRepeatItemsOnEachPrintedPage = false; + if (m_oMdxSubqueries.IsInit()) + ptr->fDefaultCompact = m_oMdxSubqueries.get(); + else + ptr->fDefaultCompact = false; + if (m_oMergeItem.IsInit()) + ptr->fMergeLabels = m_oMergeItem.get(); + else + ptr->fMergeLabels = false; + if (m_oMinRefreshableVersion.IsInit()) + ptr->bVerSxUpdateableMin = m_oMinRefreshableVersion->GetValue(); + if (m_oMissingCaption.IsInit()) + ptr->irstNullString = m_oMissingCaption.get(); else ptr->fEmptyDisplayNullString = true; - if (m_oMultipleFieldFilters.IsInit()) ptr->fSingleFilterPerField = !m_oMultipleFieldFilters.get(); + if (m_oMultipleFieldFilters.IsInit()) + ptr->fSingleFilterPerField = !m_oMultipleFieldFilters.get(); if (m_oName.IsInit()) ptr->irstName = m_oName.get(); else ptr->irstName = 0xFFFFFFFF; - if (m_oOutline.IsInit()) ptr->fDefaultOutline = m_oOutline.get(); - if (m_oOutlineData.IsInit()) ptr->fOutlineData = m_oOutlineData.get(); - if (m_oPageOverThenDown.IsInit()) ptr->fAcrossPageLay = m_oPageOverThenDown.get(); - else ptr->fAcrossPageLay = false; - if (m_oPageStyle.IsInit()) ptr->irstPageFieldStyle = m_oPageStyle.get(); + if (m_oOutline.IsInit()) + ptr->fDefaultOutline = m_oOutline.get(); + if (m_oOutlineData.IsInit()) + ptr->fOutlineData = m_oOutlineData.get(); + else + ptr->fOutlineData = false; + if (m_oPageOverThenDown.IsInit()) + ptr->fAcrossPageLay = m_oPageOverThenDown.get(); + else + ptr->fAcrossPageLay = false; + if (m_oPageStyle.IsInit()) + ptr->irstPageFieldStyle = m_oPageStyle.get(); else ptr->fDisplayPageFieldStyle = false; - if (m_oPageWrap.IsInit()) ptr->cWrapPage = m_oPageWrap->GetValue(); + if (m_oPageWrap.IsInit()) + ptr->cWrapPage = m_oPageWrap->GetValue(); else ptr->cWrapPage = 0; - if (m_oPivotTableStyle.IsInit()) ptr->irstTableStyle = m_oPivotTableStyle.get(); + if (m_oPivotTableStyle.IsInit()) + ptr->irstTableStyle = m_oPivotTableStyle.get(); else ptr->fDisplayTableStyle = false; - if (m_oPreserveFormatting.IsInit()) ptr->fPreserveFormatting = m_oPreserveFormatting.get(); - if (m_oPrintDrill.IsInit()) ptr->fPrintDrillIndicators = m_oPrintDrill.get(); - else ptr->fPrintDrillIndicators = false; - if (m_oPublished.IsInit()) ptr->fPublished = m_oPublished.get(); - else ptr->fPublished = false; - if (m_oRowGrandTotals.IsInit()) ptr->fRwGrand = m_oRowGrandTotals.get(); - if (m_oRowHeaderCaption.IsInit()) ptr->irstRwHdrName = m_oRowHeaderCaption.get(); + if (m_oPreserveFormatting.IsInit()) + ptr->fPreserveFormatting = m_oPreserveFormatting.get(); + if (m_oPrintDrill.IsInit()) + ptr->fPrintDrillIndicators = m_oPrintDrill.get(); + else + ptr->fPrintDrillIndicators = false; + if (m_oPublished.IsInit()) + ptr->fPublished = m_oPublished.get(); + else + ptr->fPublished = false; + if (m_oRowGrandTotals.IsInit()) + ptr->fRwGrand = m_oRowGrandTotals.get(); + if (m_oRowHeaderCaption.IsInit()) + ptr->irstRwHdrName = m_oRowHeaderCaption.get(); else ptr->fUseRwHdrName = false; - if (m_oShowCalcMbrs.IsInit()) ptr->fNotViewCalculatedMembers = !m_oShowCalcMbrs.get(); - else ptr->fNotViewCalculatedMembers = false; - if (m_oShowDataDropDown.IsInit()) ptr->fHideDDData = !m_oShowDataDropDown.get(); - else ptr->fHideDDData = false; - if (m_oShowDataTips.IsInit()) ptr->fNoPivotTips = !m_oShowDataTips.get(); - else ptr->fNoPivotTips = false; - if (m_oShowDrill.IsInit()) ptr->fHideDrillIndicators = !m_oShowDrill.get(); - else ptr->fHideDrillIndicators = false; - if (m_oShowDropZones.IsInit()) ptr->fNoStencil = !m_oShowDropZones.get(); - else ptr->fNoStencil = false; - if (m_oShowEmptyCol.IsInit()) ptr->fIncludeEmptyCol = m_oShowEmptyCol.get(); - else ptr->fIncludeEmptyCol = false; - if (m_oShowEmptyRow.IsInit()) ptr->fIncludeEmptyRw = m_oShowEmptyRow.get(); - else ptr->fIncludeEmptyRw = false; - if (m_oShowError.IsInit()) ptr->fDisplayErrorString = m_oShowError.get(); - if (m_oShowHeaders.IsInit()) ptr->fNoHeaders = !m_oShowHeaders.get(); - else ptr->fNoHeaders = false; - if (m_oShowItems.IsInit()) ptr->fDisplayImmediateItems = m_oShowItems.get(); - if (m_oShowMemberPropertyTips.IsInit()) ptr->fMemPropsInTips = m_oShowMemberPropertyTips.get(); - if (m_oShowMissing.IsInit()) ptr->fDisplayNullString = m_oShowMissing.get(); - if (m_oShowMultipleLabel.IsInit()) ptr->fPageMultipleItemLabel = m_oShowMultipleLabel.get(); - if (m_oSubtotalHiddenItems.IsInit()) ptr->fSubtotalHiddenPageItems = m_oSubtotalHiddenItems.get(); - else ptr->fSubtotalHiddenPageItems = false; - if (m_oTag.IsInit()) ptr->irstTag = m_oTag.get(); + if (m_oShowCalcMbrs.IsInit()) + ptr->fNotViewCalculatedMembers = !m_oShowCalcMbrs.get(); + else + ptr->fNotViewCalculatedMembers = false; + if (m_oShowDataDropDown.IsInit()) + ptr->fHideDDData = !m_oShowDataDropDown.get(); + else + ptr->fHideDDData = false; + if (m_oShowDataTips.IsInit()) + ptr->fNoPivotTips = !m_oShowDataTips.get(); + else + ptr->fNoPivotTips = false; + if (m_oShowDrill.IsInit()) + ptr->fHideDrillIndicators = !m_oShowDrill.get(); + else + ptr->fHideDrillIndicators = false; + if (m_oShowDropZones.IsInit()) + ptr->fNoStencil = !m_oShowDropZones.get(); + else + ptr->fNoStencil = false; + if (m_oShowEmptyCol.IsInit()) + ptr->fIncludeEmptyCol = m_oShowEmptyCol.get(); + else + ptr->fIncludeEmptyCol = false; + if (m_oShowEmptyRow.IsInit()) + ptr->fIncludeEmptyRw = m_oShowEmptyRow.get(); + else + ptr->fIncludeEmptyRw = false; + if (m_oShowError.IsInit()) + ptr->fDisplayErrorString = m_oShowError.get(); + if (m_oShowHeaders.IsInit()) + ptr->fNoHeaders = !m_oShowHeaders.get(); + else + ptr->fNoHeaders = false; + if (m_oShowItems.IsInit()) + ptr->fDisplayImmediateItems = m_oShowItems.get(); + if (m_oShowMemberPropertyTips.IsInit()) + ptr->fMemPropsInTips = m_oShowMemberPropertyTips.get(); + if (m_oShowMissing.IsInit()) + ptr->fDisplayNullString = m_oShowMissing.get(); + if (m_oShowMultipleLabel.IsInit()) + ptr->fPageMultipleItemLabel = m_oShowMultipleLabel.get(); + if (m_oSubtotalHiddenItems.IsInit()) + ptr->fSubtotalHiddenPageItems = m_oSubtotalHiddenItems.get(); + else + ptr->fSubtotalHiddenPageItems = false; + if (m_oTag.IsInit()) + ptr->irstTag = m_oTag.get(); else ptr->fDisplayTag = false; - if (m_oUpdatedVersion.IsInit()) ptr->bVerSxLastUpdated = m_oUpdatedVersion->GetValue(); - if (m_oUseAutoFormatting.IsInit()) ptr->fAutoFormat = m_oUseAutoFormatting.get(); - if (m_oVacatedStyle.IsInit()) ptr->irstVacateStyle = m_oVacatedStyle.get(); + if (m_oUpdatedVersion.IsInit()) + ptr->bVerSxLastUpdated = m_oUpdatedVersion->GetValue(); + if (m_oUseAutoFormatting.IsInit()) + ptr->fAutoFormat = m_oUseAutoFormatting.get(); + if (m_oVacatedStyle.IsInit()) + ptr->irstVacateStyle = m_oVacatedStyle.get(); else ptr->fDisplayVacateStyle = false; ptr->sxaxis4Data = 2; @@ -2831,8 +2940,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr(new XLSB::PRFILTER); XLS::BaseObjectPtr objectPtr(ptr); ptr->m_BrtBeginPRFilter = writeAttributes(); - ///@todo дописать конветрацию - ptr->m_arPRFITEM.push_back(m_oX->toBinPrfItem()); + if(m_oX.IsInit()) + ptr->m_arPRFITEM.push_back(m_oX->toBinPrfItem()); return objectPtr; } XLS::BaseObjectPtr CReference::writeAttributes() @@ -3919,9 +4028,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptr(new XLSB::PCDFIELDS); XLS::BaseObjectPtr objectPtr(ptr); - auto ptr1(new XLSB::BeginPCDFields); - ptr1->cFields = m_arrItems.size(); - ptr->m_BrtBeginPCDFields = XLS::BaseObjectPtr{ptr1}; for(auto i:m_arrItems) ptr->m_arPCDFIELD.push_back(i->toBin()); return objectPtr; @@ -4273,7 +4379,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { auto ptr(new XLSB::PCDFATBL); XLS::BaseObjectPtr objectPtr(ptr); - ptr->m_BrtBeginPCDFAtbl = writeAttributes(); + bool hasBolean = false; + bool hasStr = false; + bool hasDate = false; + bool hasMissing = false; + bool hasNumber = false; + bool hasError = false; + for(auto i:m_arrItems) { @@ -4282,6 +4394,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto valueBool = static_cast<CPivotBooleanValue*>(i); XLS::BaseObjectPtr element = valueBool->toBin(); ptr->m_arSource.push_back(element); + hasBolean = true; continue; } else if(i->getType() == et_x_PivotNoValue) @@ -4289,6 +4402,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto noVal = static_cast<CPivotNoValue*>(i); XLS::BaseObjectPtr element = noVal->toBin(); ptr->m_arSource.push_back(element); + hasMissing = true; continue; } else if(i->getType() == et_x_PivotNumericValue) @@ -4296,6 +4410,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto numVal = static_cast<CPivotNumericValue*>(i); XLS::BaseObjectPtr element = numVal->toBin(); ptr->m_arSource.push_back(element); + hasNumber = true; continue; } else if(i->getType() == et_x_PivotCharacterValue) @@ -4303,6 +4418,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto charVal = static_cast<CPivotCharacterValue*>(i); XLS::BaseObjectPtr element = charVal->toBin(); ptr->m_arSource.push_back(element); + hasStr = true; continue; } else if(i->getType() == et_x_PivotDateTimeValue) @@ -4310,6 +4426,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto dateValue = static_cast<CPivotDateTimeValue*>(i); XLS::BaseObjectPtr element = dateValue->toBin(); ptr->m_arSource.push_back(element); + hasDate = true; continue; } else if(i->getType() == et_x_PivotErrorValue) @@ -4317,13 +4434,30 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto errorVal = static_cast<CPivotErrorValue*>(i); XLS::BaseObjectPtr element = errorVal->toBin(); ptr->m_arSource.push_back(element); + hasError = true; + continue; + } + else + { + auto missingVal(new XLSB::PCDIMissing); + XLS::BaseObjectPtr element(missingVal); + ptr->m_arSource.push_back(element); + hasMissing = true; continue; } } + UINT8 flags = 0; + SETBIT(flags,0, hasBolean); + SETBIT(flags,1, hasStr); + SETBIT(flags,2, hasDate); + SETBIT(flags,3, hasMissing); + SETBIT(flags,4, hasNumber); + SETBIT(flags,5, hasError); + ptr->m_BrtBeginPCDFAtbl = writeAttributes(flags); return objectPtr; } - XLS::BaseObjectPtr CSharedItems::writeAttributes() + XLS::BaseObjectPtr CSharedItems::writeAttributes(const UINT8 flags) { auto ptr(new XLSB::BeginPCDFAtbl); XLS::BaseObjectPtr objectPtr(ptr); @@ -4373,14 +4507,41 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->xnumMin.data.value = std::stod(m_oMinDate->GetValue()); ptr->xnumMax.data.value =std::stod(m_oMaxDate->GetValue()); } - else + else if(m_oMinValue.IsInit() && m_oMaxValue.IsInit()) { if(m_oMinValue.IsInit()) ptr->xnumMin.data.value = m_oMinValue.get(); if(m_oMaxValue.IsInit()) ptr->xnumMax.data.value = m_oMaxValue.get(); } - + else + { + ptr->fNumMinMaxValid = false; + } + bool hasBolean = GETBIT(flags,0); + bool hasStr = GETBIT(flags,1); + bool hasDate = GETBIT(flags,2); + bool hasMissing = GETBIT(flags,3); + bool hasNumber = GETBIT(flags,4); + bool hasError = GETBIT(flags,5); + if(!hasDate) + ptr->fNonDates = true; + if(!hasDate && hasNumber) + ptr->fNumField = true; + if(hasStr || hasError || hasBolean) + { + ptr->fTextEtcField = true; + ptr->fHasTextItem = true; + } + if(hasMissing) + { + ptr->fHasBlankItem = true; + ptr->fTextEtcField = true; + } + if(hasDate && hasNumber || hasNumber && ptr->fHasTextItem ||hasDate && ptr->fHasTextItem) + { + ptr->fMixedTypesIgnoringBlanks = true; + } return objectPtr; } void CSharedItems::fromBin(XLS::BaseObjectPtr& obj) @@ -5049,18 +5210,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); else - { - ptr->info.stCaption.setSize(0xFFFF); ptr->info.fCaption = false; - } if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); else ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + if(m_oValue.IsInit()) + ptr->st = m_oValue.get(); + else + ptr->st.setSize(0); for(auto i:m_arrItems) ptr->info.rgIMemProps.push_back(i->m_oV.get()); return objectPtr; @@ -5073,20 +5239,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->st = m_oValue.get(); - if(m_oBold.IsInit()) - ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); - if(m_oItalic.IsInit()) - ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); - if(m_oStrike.IsInit()) - ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); - if(m_oUnderline.IsInit()) - ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); - if(m_oFormatIndex.IsInit()) - ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); - if(m_oBackColor.IsInit()) - ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); - if(m_oForeColor.IsInit()) - ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); return objectPtr; } } @@ -5238,12 +5390,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); for(auto i:m_arrItems) ptr->info.rgIMemProps.push_back(i->m_oV.get()); return objectPtr; @@ -5265,20 +5425,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (m_oValue == L"#N/A") ptr->err = 0x2A; else if (m_oValue == L"#GETTING_DATA") ptr->err = 0x2B; } - if(m_oBold.IsInit()) - ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); - if(m_oItalic.IsInit()) - ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); - if(m_oStrike.IsInit()) - ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); - if(m_oUnderline.IsInit()) - ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); - if(m_oFormatIndex.IsInit()) - ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); - if(m_oBackColor.IsInit()) - ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); - if(m_oForeColor.IsInit()) - ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); return objectPtr; } } @@ -5441,12 +5587,22 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr1); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); + if(m_oValue.IsInit()) + ptr->xnum.data.value = m_oValue.get(); for(auto i:m_arrItems) ptr->info.rgIMemProps.push_back(i->m_oV.get()); return objectPtr; @@ -5459,25 +5615,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr1); if(m_oValue.IsInit()) ptr->xnum.data.value = m_oValue.get(); - if(m_oBold.IsInit() || m_oItalic.IsInit() || m_oStrike.IsInit() - || m_oUnderline.IsInit() || m_oFormatIndex.IsInit() || m_oForeColor.IsInit() ||m_oBackColor.IsInit()) - { - ptr->sxvcellextra.reset(new XLSB::PCDISrvFmt); - if(m_oBold.IsInit()) - ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); - if(m_oItalic.IsInit()) - ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); - if(m_oStrike.IsInit()) - ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); - if(m_oUnderline.IsInit()) - ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); - if(m_oFormatIndex.IsInit()) - ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); - if(m_oBackColor.IsInit()) - ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); - if(m_oForeColor.IsInit()) - ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); - } return objectPtr; } } @@ -5600,12 +5737,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" XLS::BaseObjectPtr objectPtr(ptr1); if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); + if(m_oValue.IsInit()) + ptr->datetime.fromString(m_oValue->GetValue()); for(auto i:m_arrItems) ptr->info.rgIMemProps.push_back(i->m_oV.get()); return objectPtr; @@ -5722,12 +5867,20 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->f = m_oValue.get(); if(m_oCalculated.IsInit()) ptr->info.fFmla = m_oCalculated.get(); + else + ptr->info.fFmla = false; if(m_oCaption.IsInit()) ptr->info.stCaption = m_oCaption.get(); + else + ptr->info.fCaption = false; if(m_oUnused.IsInit()) ptr->info.fGhost = m_oUnused.get(); + else + ptr->info.fGhost = false; if(m_oCount.IsInit()) ptr->info.cIMemProps = m_oCount->GetValue(); + else + ptr->info.cIMemProps = m_arrItems.size(); for(auto i:m_arrItems) ptr->info.rgIMemProps.push_back(i->m_oV.get()); return objectPtr; @@ -5738,8 +5891,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr1(new XLSB::PCDI); ptr1->m_source = XLS::BaseObjectPtr{ptr}; XLS::BaseObjectPtr objectPtr(ptr1); + nullable_bool boolVal; if(m_oValue.IsInit()) - ptr->f = m_oValue.get(); + boolVal = m_oValue.get(); + if(boolVal.IsInit()) + ptr->f = boolVal.get(); + else + ptr->f = false; return objectPtr; } } @@ -5856,20 +6014,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto ptr1(new XLSB::PCDI); ptr1->m_source = XLS::BaseObjectPtr{ptr}; XLS::BaseObjectPtr objectPtr(ptr1); - if(m_oBold.IsInit()) - ptr->sxvcellextra->fSrvFmtBold = m_oBold.get(); - if(m_oItalic.IsInit()) - ptr->sxvcellextra->fSrvFmtItalic = m_oItalic.get(); - if(m_oStrike.IsInit()) - ptr->sxvcellextra->fSrvFmtStrikethrough = m_oStrike.get(); - if(m_oUnderline.IsInit()) - ptr->sxvcellextra->fSrvFmtUnderline = m_oUnderline.get(); - if(m_oFormatIndex.IsInit()) - ptr->sxvcellextra->isfci = m_oFormatIndex->GetValue(); - if(m_oBackColor.IsInit()) - ptr->sxvcellextra->cvBack.fromHex(m_oBackColor->GetValue()); - if(m_oForeColor.IsInit()) - ptr->sxvcellextra->cvFore.fromHex(m_oForeColor->GetValue()); return objectPtr; } else From f55d822c4fb8a9c4aa88c643f880f52274049939 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Sun, 26 May 2024 20:17:44 +0300 Subject: [PATCH 712/794] fix build --- OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index ee42561c090..4e3ed890fc4 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -75,7 +75,7 @@ namespace OOX } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - XLS::BaseObjectPtr writeAttributes(const UINT8 flags); + XLS::BaseObjectPtr writeAttributes(const unsigned char flags); nullable_bool m_oContainsBlank; nullable_bool m_oContainsDate; From 499810dbae17bdab7c04c875e0f260f1d1fc6b55 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Mon, 27 May 2024 08:01:06 +0300 Subject: [PATCH 713/794] . --- OOXML/XlsxFormat/Pivot/Pivots.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index b65bcb076af..79d86ae7d58 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -4446,7 +4446,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" continue; } } - UINT8 flags = 0; + unsigned char flags = 0; SETBIT(flags,0, hasBolean); SETBIT(flags,1, hasStr); SETBIT(flags,2, hasDate); @@ -4457,7 +4457,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" return objectPtr; } - XLS::BaseObjectPtr CSharedItems::writeAttributes(const UINT8 flags) + XLS::BaseObjectPtr CSharedItems::writeAttributes(const unsigned char flags) { auto ptr(new XLSB::BeginPCDFAtbl); XLS::BaseObjectPtr objectPtr(ptr); From 63003a5e7654035c36ce55b30a294618aad5da6f Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Mon, 27 May 2024 11:57:54 +0300 Subject: [PATCH 714/794] fix bug 68094 --- .../StarMath2OOXML/TestSMConverter/main.cpp | 2 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 4 +- .../StarMath2OOXML/cconversionsmtoooxml.h | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 50 ++++++++++++------- .../Converter/StarMath2OOXML/cstarmathpars.h | 10 ++-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index a336d152ced..d7c371117a1 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1190,7 +1190,7 @@ TEST(SMConvectorTest,IndexWithColor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sPrePr><m:sub /><m:sup><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>5</m:t></m:r></m:e><m:lim><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr></m:ctrlPr></m:sPrePr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>8</m:t></m:r></m:sub><m:sup /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>6</m:t></m:r></m:e></m:sPre></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>7</m:t></m:r></m:lim></m:limUpp></m:lim></m:limLow></m:sup><m:e><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>4</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:sup></m:sSubSup></m:e></m:sPre></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sPrePr><m:sub /><m:sup><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>5</m:t></m:r></m:e><m:lim><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sPrePr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>8</m:t></m:r></m:sub><m:sup /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>6</m:t></m:r></m:e></m:sPre></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>7</m:t></m:r></m:lim></m:limUpp></m:lim></m:limLow></m:sup><m:e><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>4</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:sup></m:sSubSup></m:e></m:sPre></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 7fc55240c14..8d24c1c2993 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -50,10 +50,10 @@ namespace StarMath { switch(iAlignment) { case 0: - wsAlignment = L"center"; + wsAlignment = L"left"; break; case 1: - wsAlignment = L"left"; + wsAlignment = L"center"; break; case 2: wsAlignment = L"right"; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index 9ec88401478..c054c8ef362 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -42,7 +42,7 @@ namespace StarMath { public: CConversionSMtoOOXML(); ~CConversionSMtoOOXML(); - void StartConversion(std::vector<CElement*> arPars, const unsigned int& iAlignment = 0); + void StartConversion(std::vector<CElement*> arPars, const unsigned int& iAlignment = 1); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 8fce79b2333..7d73d57196a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -36,7 +36,7 @@ namespace StarMath { //class methods CParsStarMath - CParserStarMathString::CParserStarMathString():m_iAlignment(0){} + CParserStarMathString::CParserStarMathString():m_iAlignment(1){} CParserStarMathString::~CParserStarMathString() { for(CElement* pElement:m_arEquation) @@ -55,7 +55,7 @@ namespace StarMath if(!m_arEquation.empty()) CElementBinOperator::UnaryCheck(pReader,m_arEquation.back()); CElement* pTempElement = ParseElement(pReader); - AddingAnElementToAnArray(m_arEquation,pTempElement); + AddingAnElementToAnArray(m_arEquation,pTempElement,pReader); } if(!pReader->EmptyString()) { @@ -114,7 +114,7 @@ namespace StarMath else return false; } - bool CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd) + bool CParserStarMathString::AddLeftArgument(CElement *pLeftArg, CElement *pElementWhichAdd, CStarMathReader *pReader) { if(pElementWhichAdd!=nullptr) { @@ -123,7 +123,7 @@ namespace StarMath case TypeElement::BinOperator: { CElementBinOperator* pBinOp = dynamic_cast<CElementBinOperator*>(pElementWhichAdd); - if(pBinOp->GetType() == TypeElement::neg || (pBinOp->GetAttribute()!= nullptr && pBinOp->MixedOperators(pBinOp->GetType()))) + if(pBinOp->GetType() == TypeElement::neg || (pBinOp->GetAttribute() != nullptr && pBinOp->GetAttribute() != pReader->GetBaseAttribute() && pBinOp->MixedOperators(pBinOp->GetType()))) return false; else return SetLeft<CElementBinOperator>(pLeftArg, pElementWhichAdd); @@ -191,13 +191,13 @@ namespace StarMath else return false; } - void CParserStarMathString::AddingAnElementToAnArray(std::vector<CElement *> &arrEquation, CElement *pAddElement) + void CParserStarMathString::AddingAnElementToAnArray(std::vector<CElement *> &arrEquation, CElement *pAddElement, CStarMathReader *pReader) { if(pAddElement !=nullptr) { if(!arrEquation.empty() && CheckForLeftArgument(pAddElement->GetBaseType())) { - if(AddLeftArgument(arrEquation.back(),pAddElement)) + if(AddLeftArgument(arrEquation.back(),pAddElement,pReader)) arrEquation.pop_back(); } arrEquation.push_back(pAddElement); @@ -207,14 +207,14 @@ namespace StarMath { CElement* pNextElement = ParseElement(pReader); if(pLeftElement != nullptr) - AddLeftArgument(pLeftElement,pNextElement); + AddLeftArgument(pLeftElement,pNextElement,pReader); pLeftElement = pNextElement; pReader->ReadingTheNextToken(); } void CParserStarMathString::ReadingElementsWithAttributes(CStarMathReader *pReader, CElement*& pSavingElement) { CElement* pElement = CParserStarMathString::ParseElement(pReader); - if(pElement->GetAttribute() != nullptr) + if(pElement->GetAttribute() != pReader->GetBaseAttribute()) { pReader->ReadingTheNextToken(); if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) @@ -222,7 +222,7 @@ namespace StarMath CElement* pIndex = new CElementIndex(pReader->GetLocalType(),pReader->GetTypeConversion()); pReader->ClearReader(); pIndex->Parse(pReader); - AddLeftArgument(pElement,pIndex); + AddLeftArgument(pElement,pIndex,pReader); pSavingElement = pIndex; } else @@ -246,11 +246,11 @@ namespace StarMath void CParserStarMathString::SetBaseSize(const unsigned int &iSize) { if(iSize < 130) - m_stBaseAttribute.base_font_size = iSize; + m_stBaseAttribute.base_font_size = iSize*2; } void CParserStarMathString::SetBaseAlignment(const unsigned int &iAlignment) { - if(iAlignment > 0 && iAlignment < 3) + if(iAlignment >= 0 && iAlignment < 3) m_stBaseAttribute.base_alignment = iAlignment; } void CParserStarMathString::SetBaseBold(const bool &bBold) @@ -274,7 +274,7 @@ namespace StarMath return wsLowerCase; } //class methods CAttribute - CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_iSize(0),m_iAlignment(0),m_unCount(0) + CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_bParent(false),m_iSize(0),m_iAlignment(0),m_unCount(0) { } CAttribute::~CAttribute() @@ -452,6 +452,14 @@ namespace StarMath { return m_wsColor.empty(); } + void CAttribute::SetParent() + { + m_bParent = true; + } + bool CAttribute::GetParent() + { + return m_bParent; + } //hex current bool CAttribute::ParseColorAttribute(const std::wstring &wsToken,CStarMathReader* pReader) { @@ -770,9 +778,9 @@ namespace StarMath } else if(pAttribute != nullptr && m_pAttribute!=nullptr && pAttribute != m_pAttribute) { - if(m_pAttribute->GetCount() <= 1) + if(m_pAttribute->GetCount() <= 1 && !m_pAttribute->GetParent()) CAttribute::ComparingAttributes(pAttribute,m_pAttribute); - else if(m_pAttribute->GetCount() > 1) + else if(m_pAttribute->GetCount() > 1 || m_pAttribute->GetParent()) { CAttribute* pTempAttribute = m_pAttribute; m_pAttribute = new CAttribute; @@ -1141,7 +1149,7 @@ namespace StarMath if(!m_arBrecketValue.empty()) CElementBinOperator::UnaryCheck(pReader,m_arBrecketValue.back()); CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddingAnElementToAnArray(m_arBrecketValue,pTempElement); + CParserStarMathString::AddingAnElementToAnArray(m_arBrecketValue,pTempElement,pReader); } if(!pReader->EmptyString()) { @@ -2085,7 +2093,7 @@ namespace StarMath if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(m_pLeftArg,pElement); + CParserStarMathString::AddLeftArgument(m_pLeftArg,pElement,pReader); m_pLeftArg = pElement; } m_pValueIndex = CParserStarMathString::ParseElement(pReader); @@ -2093,7 +2101,7 @@ namespace StarMath if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement,pReader); m_pValueIndex = pElement; } } @@ -2104,7 +2112,7 @@ namespace StarMath if(CElementIndex::GetLowerIndex(pReader->GetLocalType()) || CElementIndex::GetUpperIndex(pReader->GetLocalType())) { CElement* pElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement); + CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement,pReader); m_pValueIndex = pElement; } // m_pLeftArg = m_pValueIndex; @@ -2219,7 +2227,10 @@ namespace StarMath if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() == nullptr && pAttribute != nullptr) m_pLeftArg->SetAttribute(pAttribute); if(m_pLeftArg != nullptr && m_pLeftArg->GetAttribute() != nullptr) + { + m_pLeftArg->SetBaseAttribute(pAttribute); this->SetBaseAttribute(m_pLeftArg->GetAttribute()); + } if(m_pValueIndex != nullptr) m_pValueIndex->SetAttribute(pAttribute); if(m_pLeftArg != nullptr) @@ -2399,7 +2410,7 @@ namespace StarMath else if(pReader->GetBaseAttribute()!=nullptr) pString->SetAttribute(pReader->GetBaseAttribute()); - CParserStarMathString::AddLeftArgument(pString,m_pIndex); + CParserStarMathString::AddLeftArgument(pString,m_pIndex,pReader); return ; } CElement* pTempElement = CParserStarMathString::ParseElement(pReader); @@ -2866,6 +2877,7 @@ namespace StarMath m_pBaseAttribute->SetAlignment(pAttribute.base_alignment); if(!m_pBaseAttribute->CheckingForEmptiness()) m_pBaseAttribute = nullptr; + m_pBaseAttribute->SetParent(); } CAttribute* CStarMathReader::GetBaseAttribute() { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index b4f6c640633..f3bd2c3cdc8 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -50,7 +50,7 @@ namespace StarMath struct TBaseAttribute { - TBaseAttribute():base_font_size(0),base_alignment(0),base_font_bold(false),base_font_italic(false){}; + TBaseAttribute():base_font_size(0),base_alignment(1),base_font_bold(false),base_font_italic(false){}; unsigned int base_font_size; std::wstring base_font_name; unsigned int base_alignment; @@ -86,6 +86,8 @@ namespace StarMath void SetColor(const std::wstring& wsColor); bool SetFont(const TypeElement& enFont); void SetFontName(const std::wstring& wsNameFont); + void SetParent(); + bool GetParent(); bool CheckAttribute(); unsigned int GetCount(); static void ComparingAttributes(CAttribute* pAttributeParent,CAttribute* pAttributeChild); @@ -97,7 +99,7 @@ namespace StarMath private: void RefundOfTheAmountRGB(CStarMathReader* pReader,const int& iRed, const int& iGreen, const int& iBlue); std::wstring m_wsColor,m_wsNameFont; - bool m_bBold,m_bItal,m_bPhantom,m_bStrike; + bool m_bBold,m_bItal,m_bPhantom,m_bStrike,m_bParent; unsigned int m_iSize,m_iAlignment; unsigned int m_unCount; }; @@ -446,13 +448,13 @@ namespace StarMath std::vector<CElement*> Parse(std::wstring& wsParseString,int iTypeConversion = 0); static CElement* ParseElement(CStarMathReader* pReader); //Function for adding a left argument (receives the argument itself and the element to which it needs to be added as input. Works with classes:CElementBinOperator,CElementConnection,CElementSetOperation). - static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd); + static bool AddLeftArgument(CElement* pLeftArg,CElement* pElementWhichAdd,CStarMathReader* pReader); static bool CheckForLeftArgument(const TypeElement& enType, const bool& bConnection = true); static CElement* ReadingWithoutBracket(CStarMathReader* pReader,const bool& bConnection = true); //checking the element (true if it is newline) static bool CheckNewline(CElement* pElement); //adding an element to the array, checking that it is not empty and adding the left element, if there is one. - static void AddingAnElementToAnArray(std::vector<CElement*>& arrEquation,CElement* pAddElement); + static void AddingAnElementToAnArray(std::vector<CElement*>& arrEquation,CElement* pAddElement,CStarMathReader* pReader); //Receives the left element as input, reads the next one, if the next element has a higher priority and contains the left element, the element received at the input is passed to it. The entire structure is saved and returned. static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); //method for parsing indexes with attributes. If there is an attribute present when indexes are read, then all subsequent indexes are applied to the index with the attribute. From bc56de19c119df871ae87f24ba1d3894ba104a74 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Mon, 27 May 2024 20:11:30 +0600 Subject: [PATCH 715/794] Fix bug #66009 --- .../XlsFile/Format/Logic/Biff_records/Pane.cpp | 2 +- .../XlsFile/Format/Logic/Biff_records/Selection.cpp | 4 ++-- .../XlsFile/Format/Logic/Biff_records/Window2.cpp | 2 +- .../Format/Logic/Biff_structures/CellRef.cpp | 2 +- .../XlsFile/Format/Logic/Biff_structures/PtgStr.cpp | 2 +- OOXML/XlsxFormat/Comments/XlsxComments.cpp | 2 +- OOXML/XlsxFormat/Pivot/Pivots.cpp | 10 +++++----- OOXML/XlsxFormat/Table/Autofilter.cpp | 6 +++--- OOXML/XlsxFormat/Table/Connections.cpp | 9 ++++++++- OOXML/XlsxFormat/Table/Tables.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 13 ++++++++++--- OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 2 +- 12 files changed, 35 insertions(+), 21 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp index c179c24269a..1974a6fcd3e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.cpp @@ -69,7 +69,7 @@ void Pane::readFields(CFRecord& record) else { record >> xnumXSplit >> xnumYSplit >> rwTop >> colLeft >> pnnAcct_xlsb; - topLeftCell = static_cast<std::wstring >(CellRef(rwTop, colLeft, true, true)); + topLeftCell = CellRef(rwTop, colLeft, true, true).toString(true); unsigned char flags; record >> flags; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp index 73068028fdc..356bc7b5701 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Selection.cpp @@ -80,12 +80,12 @@ void Selection::readFields(CFRecord& record) { XLSB::UncheckedSqRfX sqrfx; record >> pnn_xlsb >> rwAct >> colAct >> irefAct >> sqrfx; - activeCell = static_cast<std::wstring >(CellRef(rwAct, colAct, true, true)); + activeCell = CellRef(rwAct, colAct, true, true).toString(true); std::wstring sqref_str; int i = 0, cref = sqrfx.rgrfx.size(); std::for_each(sqrfx.rgrfx.begin(), sqrfx.rgrfx.end(), [&](XLSB::UncheckedRfX &refu) { - sqref_str += std::wstring (refu.toString(false).c_str()) + ((i == cref - 1) ? L"" : L" "); + sqref_str += std::wstring (refu.toString(false, true).c_str()) + ((i == cref - 1) ? L"" : L" "); }); sqref = sqref_str; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp index 1e71f16379e..bc278788964 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp @@ -152,7 +152,7 @@ void Window2::readFields(CFRecord& record) record >> xlView >> rwTop >> colLeft; - topLeftCell = static_cast<std::wstring >(CellRef(rwTop, colLeft, true, true)); + topLeftCell = CellRef(rwTop, colLeft, true, true).toString(true); BYTE icvHdr_1b; record >> icvHdr_1b; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp index 82fb3c85ecd..8573903da10 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.cpp @@ -100,7 +100,7 @@ const std::wstring CellRef::toString(const bool xlsb) const { column_norm = maxCol; } - return to_string_cache = AUX::loc2str(row_norm, rowRelative, column_norm, colRelative); + return to_string_cache = AUX::loc2str(row_norm, rowRelative, column_norm, colRelative, xlsb); } return to_string_cache; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp index db8f70884fd..cb399831ab8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgStr.cpp @@ -84,7 +84,7 @@ void PtgStr::loadFields(CFRecord& record) { string_ = string_.substr(1, string_.length() - 2); } - else if (pos1 > -1 && pos1 != pos2) + else if (pos1 > -1) {//012_JKH.OPEN.INFO.PRICE.VO... boost::algorithm::replace_all(string_, L"\"", L"\"\""); } diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index 4c0ab99d1af..8fb150fb5af 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -269,7 +269,7 @@ namespace OOX auto ptr = static_cast<XLSB::BeginComment*>(obj.get()); if (ptr != nullptr) { - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); m_oAuthorId = ptr->iauthor; m_oUid = ptr->guid; } diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 79d86ae7d58..1431f37e4cb 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -3446,7 +3446,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->pruleheaderdata.rfxLoc.toString().empty() && (ptr->pruleheaderdata.rfxLoc.rowFirst!=0 || ptr->pruleheaderdata.rfxLoc.columnFirst!=0)) - m_oOffsetRef = ptr->pruleheaderdata.rfxLoc.toString(); + m_oOffsetRef = ptr->pruleheaderdata.rfxLoc.toString(true, true); if(!ptr->pruleheaderdata.fLineMode) m_oOutline = ptr->pruleheaderdata.fLineMode; @@ -3570,7 +3570,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oRowPageCount = ptr->crwPage; if(!ptr->rfxGeom.toString().empty()) - m_oRef = ptr->rfxGeom.toString(); + m_oRef = ptr->rfxGeom.toString(true, true); } } //------------------------------------ @@ -6271,8 +6271,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->sheetName.value().empty()) m_oSheet = ptr->sheetName.value(); - if(!ptr->range.toString().empty() && ptr->range.toString() != L"A1") - m_oRef = ptr->range.toString(); + if(!ptr->range.toString().empty() && ptr->range.toString(true, true) != L"A1") + m_oRef = ptr->range.toString(true, true); if(!ptr->namedRange.value().empty()) m_oName = ptr->namedRange.value(); @@ -6594,7 +6594,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oSheet = ptr->irstSheet.value(); if(!ptr->rfx.toString().empty()) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); if(!ptr->irstName.value().empty()) m_oName = ptr->irstName.value(); diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index c21590a25eb..9cc5103b088 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -171,7 +171,7 @@ namespace OOX if(ptr != nullptr) { m_oDescending = ptr->fSortDes; - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); switch (ptr->sortOn) { case 0: @@ -199,7 +199,7 @@ namespace OOX if(ptr != nullptr) { m_oDescending = ptr->fSortDes; - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); switch (ptr->sortOn) { case 0: @@ -1549,7 +1549,7 @@ namespace OOX auto ptr = static_cast<XLSB::BeginAFilter*>(obj.get()); if(ptr != nullptr) { - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } } diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index 1e3d32d8a91..d31eb4cc950 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -1326,7 +1326,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oCount = ptr->m_arEXTCONNECTION.size(); for (auto &connection : ptr->m_arEXTCONNECTION) + { auto connPtr = new CConnection(connection); + if(connPtr->m_oType.IsInit() &&(connPtr->m_oType.get() == 0x66)) + { + delete connPtr; + continue; + } m_arrItems.push_back(new CConnection(connection)); + } } } XLS::BaseObjectPtr CConnections::toBin() @@ -1412,7 +1419,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } void CConnectionsFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if (false == m_oConnections.IsInit()) return; + if (false == m_oConnections.IsInit() || !m_oConnections.get().m_arrItems.size()) return; CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 0408e1abc7c..27b6a733f92 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -822,7 +822,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") auto ptr = static_cast<XLSB::BeginList*>(obj.get()); if(ptr != nullptr) { - m_oRef = ptr->rfxList.toString(); + m_oRef = ptr->rfxList.toString(true, true); if(!ptr->stName.value().empty()) m_oName = ptr->stName.value(); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 58e26148561..5a130637e10 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -951,9 +951,16 @@ namespace OOX WritingStringNullableAttrBool(L"ca", m_oCa); WritingStringNullableAttrInt(L"si", m_oSi, m_oSi->GetValue()); WritingStringNullableAttrBool(L"bx", m_oBx); - writer.WriteString(_T(">")); - writer.WriteEncodeXmlStringHHHH(m_sText); - writer.WriteString(_T("</f>")); + if(!m_sText.empty()) + { + writer.WriteString(_T(">")); + writer.WriteEncodeXmlStringHHHH(m_sText); + writer.WriteString(_T("</f>")); + } + else + { + writer.WriteString(_T("/>")); + } } void CFormula::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream) { diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 3b4bd4a027d..ca389ed65a0 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -122,7 +122,7 @@ namespace OOX m_oDisplay = ptr->display.value(); m_oRid = ptr->relId.value.value(); m_oLocation = ptr->location.value(); - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); m_oTooltip = ptr->tooltip.value(); } From ab829fa8db520905e8928cfb39fedef783c171f0 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 28 May 2024 11:28:19 +0300 Subject: [PATCH 716/794] fix bug #68213 --- .../Format/Logic/Biff_structures/DXFFntD.cpp | 28 +++++++++++-------- .../Format/Logic/Biff_structures/DXFN.cpp | 2 +- .../Logic/Biff_structures/FullColorExt.cpp | 10 +++++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp index 7a15dcc92ac..2a04747dec8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp @@ -73,33 +73,37 @@ int DXFFntD::serialize(std::wostream & stream) { std::map<ExtProp::_type, ExtProp>::iterator pFind; + if (parent && parent->xfext) + pFind = parent->xfext->mapRgExt.find(ExtProp::FontScheme); + CP_XML_WRITER(stream) { CP_XML_NODE(L"font") - { - if (!stFontName.value().empty()) + { + std::wstring name = stFontName.value(); + + if (parent && parent->xfext) { - std::wstring name = stFontName.value(); - - if (parent->xfext) - pFind = parent->xfext->mapRgExt.find(ExtProp::FontScheme); - - BYTE font_scheme = (parent->xfext && pFind != parent->xfext->mapRgExt.end()) ? pFind->second.extPropData.font_scheme : 0; + BYTE font_scheme = (pFind != parent->xfext->mapRgExt.end()) ? pFind->second.extPropData.font_scheme : 0; - if (global_info->m_pTheme && font_scheme == 0x01) + if (global_info && global_info->m_pTheme && font_scheme == 0x01) { name = global_info->m_pTheme->themeElements.fontScheme.majorFont.latin.typeface; } - else if (global_info->m_pTheme && font_scheme == 0x02) + else if (global_info && global_info->m_pTheme && font_scheme == 0x02) { name = global_info->m_pTheme->themeElements.fontScheme.minorFont.latin.typeface; } + } + if (!name.empty()) + { CP_XML_NODE(L"name") { CP_XML_ATTR(L"val", name.substr(0, 31)); } } + if (stxp.twpHeight > 20) { CP_XML_NODE(L"sz") @@ -107,10 +111,10 @@ int DXFFntD::serialize(std::wostream & stream) CP_XML_ATTR(L"val", stxp.twpHeight/20.f); } } - if (parent->xfext) + if ((parent && parent->xfext) && (pFind == parent->xfext->mapRgExt.end())) pFind = parent->xfext->mapRgExt.find(ExtProp::ForeColor); - if (parent->xfext && pFind != parent->xfext->mapRgExt.end()) + if ((parent && parent->xfext) && pFind != parent->xfext->mapRgExt.end()) { pFind->second.extPropData.color.serialize(CP_XML_STREAM(), L"color"); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp index f3e48b2d9f4..c80ebba7abe 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp @@ -122,7 +122,7 @@ int DXFN::serialize(std::wostream & stream) { CP_XML_NODE(L"dxf") { - if(ibitAtrFnt) + if (ibitAtrFnt || (xfext && (xfext->mapRgExt.end() != xfext->mapRgExt.find(ExtProp::FontScheme)))) { dxffntd.serialize(CP_XML_STREAM()); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp index 1c7f8b1194a..1dc16fc1779 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp @@ -62,8 +62,14 @@ int FullColorExt::serialize(std::wostream & stream, const std::wstring &node_nam case 0: CP_XML_ATTR(L"auto", 1); break; case 1: CP_XML_ATTR(L"indexed", xclrValue); break; case 3: CP_XML_ATTR(L"theme", xclrValue); break; - default: - CP_XML_ATTR(L"rgb", xclrValue); break; + default: + { + BYTE r = GETBITS(xclrValue, 0, 7); + BYTE g = GETBITS(xclrValue, 8, 15); + BYTE b = GETBITS(xclrValue, 16, 23); + BYTE a = GETBITS(xclrValue, 24, 31); + CP_XML_ATTR(L"rgb", STR::toARGB(r, g, b, a)); + }break; } if (nTintShade != 0) { From 8e3df68ffcfe03b1feff93e591fbae817c45667f Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 28 May 2024 15:27:12 +0300 Subject: [PATCH 717/794] fix bug #50594 --- Common/OfficeFileFormatChecker2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index d4aa195f15b..8fce91db664 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -864,7 +864,7 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_PDF; else if (0 == sExt.compare(L".doct")) // случай архива с html viewer nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY; - else if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml") || 0 == sExt.compare(L".rtf") || 0 == sExt.compare(L".doc") || 0 == sExt.compare(L".docx")) + else if (0 == sExt.compare(L".txt") || 0 == sExt.compare(L".xml") || 0 == sExt.compare(L".rtf") || 0 == sExt.compare(L".doc") || 0 == sExt.compare(L".docx") || 0 == sExt.compare(L".md")) nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) From 0050c6148c732e77a2ce6f8e0b319e84f5941d11 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 28 May 2024 16:33:41 +0300 Subject: [PATCH 718/794] Fix bug 68225 --- PdfFile/PdfEditor.cpp | 27 +++- PdfFile/SrcWriter/Pages.cpp | 179 +++++----------------- PdfFile/SrcWriter/Pages.h | 12 +- PdfFile/SrcWriter/ResourcesDictionary.cpp | 37 +++-- 4 files changed, 92 insertions(+), 163 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 11b072449cc..4e2635d2362 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -949,7 +949,32 @@ bool CPdfEditor::EditPage(int nPageIndex) Object oTemp; char* chKey = pageObj.dictGetKey(nIndex); if (strcmp("Resources", chKey) == 0) - pageObj.dictGetVal(nIndex, &oTemp); + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, true, false); + pPage->Add("Resources", pDict); + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oRes; + char* chKey2 = oTemp.dictGetKey(nIndex); + if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) + oTemp.dictGetVal(nIndex, &oRes); + else + oTemp.dictGetValNF(nIndex, &oRes); + DictToCDictObject(&oRes, pDict, false, chKey2); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } else if (strcmp("Annots", chKey) == 0) { // ВРЕМЕНО удаление Link аннотаций при редактировании diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 991b3f9e31f..55a1f19823d 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -385,32 +385,10 @@ namespace PdfWriter if (pRotate && pRotate->GetType() == object_type_NUMBER) Add("Rotate", ((CNumberObject*)pRotate)->Get() % 360); - CDictObject* pResources = GetResourcesItem(); + CResourcesDict* pResources = GetResourcesItem(); if (pResources) { - // Инициализация текущего fonts - CObjectBase* pFonts = pResources->Get("Font"); - if (pFonts && pFonts->GetType() == object_type_DICT) - { - m_pFonts = (CDictObject*)pFonts; - m_unFontsCount = 0; - } - - // Инициализация текущего ExtGStates - CObjectBase* pExtGStates = pResources->Get("ExtGState"); - if (pExtGStates && pExtGStates->GetType() == object_type_DICT) - { - m_pExtGStates = (CDictObject*)pExtGStates; - m_unExtGStatesCount = m_pExtGStates->GetSize(); - } - - // Инициализация текущего XObject - CObjectBase* pXObject = pResources->Get("XObject"); - if (pXObject && pXObject->GetType() == object_type_DICT) - { - m_pXObjects = (CDictObject*)pXObject; - m_unXObjectsCount = m_pXObjects->GetSize(); - } + pResources->Fix(); // Инициализация текущего Shading CObjectBase* pShading = pResources->Get("Shading"); @@ -465,13 +443,7 @@ namespace PdfWriter m_eGrMode = grmode_PAGE; m_pGrState = new CGrState(NULL); - m_pExtGStates = NULL; - m_unExtGStatesCount = 0; - m_pFonts = NULL; m_pFont = NULL; - m_unFontsCount = 0; - m_pXObjects = NULL; - m_unXObjectsCount = 0; m_pShadings = NULL; m_unShadingsCount = 0; m_pPatterns = NULL; @@ -542,7 +514,7 @@ namespace PdfWriter { return (CArrayObject*)Get("MediaBox"); } - CDictObject* CPage::GetResourcesItem() + CResourcesDict* CPage::GetResourcesItem() { CObjectBase* pObject = Get("Resources"); @@ -564,7 +536,7 @@ namespace PdfWriter } } - return (CDictObject*)pObject; + return (CResourcesDict*)pObject; } CObjectBase* CPage::GetCropBoxItem() { @@ -1085,46 +1057,17 @@ namespace PdfWriter // Operator : gs // Description: устанавливаем сразу все настройки данного графического состояния(ExtGState) - const char* sGsName = GetExtGrStateName(pState); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + + const char* sGsName = pResources->GetExtGrStateName(pState); if (!sGsName) return; m_pStream->WriteEscapeName(sGsName); m_pStream->WriteStr(" gs\012"); } - const char* CPage::GetExtGrStateName(CExtGrState* pState) - { - const char *sKey; - - if (!m_pExtGStates) - { - CDictObject* pResources = (CDictObject*)GetResourcesItem(); - if (!pResources) - return NULL; - - m_pExtGStates = new CDictObject(); - if (!m_pExtGStates) - return NULL; - - pResources->Add("ExtGState", m_pExtGStates); - } - - sKey = m_pExtGStates->GetKey(pState); - if (!sKey) - { - // Если ExtGState не зарегистрирован в Resource, регистрируем. - char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); - ItoA(pPointer, ++m_unExtGStatesCount, pEndPointer); - m_pExtGStates->Add(sExtGrStateName, pState); - sKey = m_pExtGStates->GetKey(pState); - } - - return sKey; - } void CPage::AddAnnotation(CDictObject* pAnnot) { CArrayObject* pArray = (CArrayObject*)Get("Annots"); @@ -1321,7 +1264,11 @@ namespace PdfWriter // Description: Устанавливаем фонт и размер фонта dSize = std::min((double)MAX_FONTSIZE, std::max(0.0, dSize)); - const char* sFontName = GetLocalFontName(pFont); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + + const char* sFontName = pResources->GetFontName(pFont); if (!sFontName) return; @@ -1332,46 +1279,6 @@ namespace PdfWriter m_pFont = pFont; } - const char* CPage::GetLocalFontName(CFontDict* pFont) - { - if (!m_pFonts) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pFonts = new CDictObject(); - if (!m_pFonts) - return NULL; - - pResources->Add("Font", m_pFonts); - } - - const char *sKey = m_pFonts->GetKey(pFont); - if (!sKey) - { - // если фонт не зарегистрирован в ресурсах, тогда регистрируем его - char sFontName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer = NULL; - char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; - - ++m_unFontsCount; - while (m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) - { - if (m_pFonts->Get("F" + std::to_string(m_unFontsCount))) - ++m_unFontsCount; - else - break; - } - - pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); - ItoA(pPointer, m_unFontsCount, pEndPointer); - m_pFonts->Add(sFontName, pFont); - sKey = m_pFonts->GetKey(pFont); - } - - return sKey; - } void CPage::SetTextRenderingMode(ETextRenderingMode eMode) { // Operator : Tr @@ -1409,8 +1316,11 @@ namespace PdfWriter } void CPage::ExecuteXObject(CXObject* pXObject) { - const char* sXObjectName = GetXObjectName(pXObject); + CResourcesDict* pResources = GetResourcesItem(); + if (!pResources) + return; + const char* sXObjectName = pResources->GetXObjectName(pXObject); if (!sXObjectName) return; @@ -1424,36 +1334,6 @@ namespace PdfWriter ExecuteXObject(pImage); GrRestore(); } - const char* CPage::GetXObjectName(CXObject* pObject) - { - if (!m_pXObjects) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pXObjects = new CDictObject(); - if (!m_pXObjects) - return NULL; - - pResources->Add("XObject", m_pXObjects); - } - - const char* sKey = m_pXObjects->GetKey(pObject); - if (!sKey) - { - char sXObjName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); - ItoA(pPointer, ++m_unXObjectsCount, pEndPointer); - m_pXObjects->Add(sXObjName, pObject); - sKey = m_pXObjects->GetKey(pObject); - } - - return sKey; - } void CPage::DrawShading(CShading* pShading) { // Operator : sh @@ -1500,8 +1380,17 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sShadingName + LIMIT_MAX_NAME_LEN; + ++m_unShadingsCount; + while (m_unShadingsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (m_pShadings->Get("S" + std::to_string(m_unShadingsCount))) + ++m_unShadingsCount; + else + break; + } + pPointer = (char*)StrCpy(sShadingName, "S", pEndPointer); - ItoA(pPointer, ++m_unShadingsCount, pEndPointer); + ItoA(pPointer, m_unShadingsCount, pEndPointer); m_pShadings->Add(sShadingName, pShading); sKey = m_pShadings->GetKey(pShading); } @@ -1530,9 +1419,17 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sPatternName + LIMIT_MAX_NAME_LEN; + ++m_unPatternsCount; + while (m_unPatternsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (m_pPatterns->Get("P" + std::to_string(m_unPatternsCount))) + ++m_unPatternsCount; + else + break; + } + pPointer = (char*)StrCpy(sPatternName, "P", pEndPointer); - ItoA(pPointer, m_unPatternsCount + 1, pEndPointer); - m_unPatternsCount++; + ItoA(pPointer, m_unPatternsCount, pEndPointer); m_pPatterns->Add(sPatternName, pPattern); sKey = m_pPatterns->GetKey(pPattern); } diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 1bcaa9e4f6b..7defc057b7d 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -55,6 +55,7 @@ namespace PdfWriter class CTextWord; class CFieldBase; class CPage; + class CResourcesDict; //---------------------------------------------------------------------------------------- // CPageTree //---------------------------------------------------------------------------------------- @@ -173,7 +174,7 @@ namespace PdfWriter void Init(CDocument* pDocument); void EllipseArc(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection); CArrayObject* GetMediaBoxItem(); - CDictObject* GetResourcesItem(); + CResourcesDict* GetResourcesItem(); CObjectBase* GetCropBoxItem(); CObjectBase* GetRotateItem(); TBox GetMediaBox(); @@ -182,9 +183,6 @@ namespace PdfWriter void SetGrMode(EGrMode eMode); void CheckGrMode(EGrMode eMode); void WriteText(const BYTE* sText, unsigned int unLen); - const char* GetExtGrStateName(CExtGrState* pState); - const char* GetLocalFontName(CFontDict* pFont); - const char* GetXObjectName(CXObject* pObject); const char* GetLocalShadingName(CShading* pShading); const char* GetLocalPatternName(CImageTilePattern* pPattern); @@ -199,15 +197,9 @@ namespace PdfWriter CArrayObject* m_pContents; CStream* m_pStream; unsigned int m_unCompressionMode; - CDictObject* m_pExtGStates; - unsigned int m_unExtGStatesCount; EGrMode m_eGrMode; CGrState* m_pGrState; - CDictObject* m_pFonts; - unsigned int m_unFontsCount; CFontDict* m_pFont; // Текущий шрифт - CDictObject* m_pXObjects; - unsigned int m_unXObjectsCount; CDictObject* m_pShadings; unsigned int m_unShadingsCount; CDictObject* m_pPatterns; diff --git a/PdfFile/SrcWriter/ResourcesDictionary.cpp b/PdfFile/SrcWriter/ResourcesDictionary.cpp index fdca7a9e50f..a4a94413646 100644 --- a/PdfFile/SrcWriter/ResourcesDictionary.cpp +++ b/PdfFile/SrcWriter/ResourcesDictionary.cpp @@ -80,14 +80,19 @@ namespace PdfWriter const char *sKey = m_pFonts->GetKey(pFont); if (!sKey) { - // ���� ���� �� ��������������� � ��������, ����� ������������ ��� + // если фонт не зарегистрирован в ресурсах, тогда регистрируем его char sFontName[LIMIT_MAX_NAME_LEN + 1]; char *pPointer = NULL; char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; + while (++m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pFonts->Get("F" + std::to_string(m_unFontsCount))) + break; + } + pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); - ItoA(pPointer, m_unFontsCount + 1, pEndPointer); - m_unFontsCount++; + ItoA(pPointer, m_unFontsCount, pEndPointer); m_pFonts->Add(sFontName, pFont); sKey = m_pFonts->GetKey(pFont); } @@ -108,14 +113,19 @@ namespace PdfWriter const char* sKey = m_pExtGStates->GetKey(pState); if (!sKey) { - // ���� ExtGState �� ��������������� � Resource, ������������ + // Если ExtGState не зарегистрирован в Resource, регистрируем. char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; char *pPointer; char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; + while (++m_unExtGStatesCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pExtGStates->Get("E" + std::to_string(m_unExtGStatesCount))) + break; + } + pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); - ItoA(pPointer, m_unExtGStatesCount + 1, pEndPointer); - m_unExtGStatesCount++; + ItoA(pPointer, m_unExtGStatesCount, pEndPointer); m_pExtGStates->Add(sExtGrStateName, pState); sKey = m_pExtGStates->GetKey(pState); } @@ -140,9 +150,14 @@ namespace PdfWriter char *pPointer; char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; + while (++m_unXObjectsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (!m_pXObjects->Get("X" + std::to_string(m_unXObjectsCount))) + break; + } + pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); - ItoA(pPointer, m_unXObjectsCount + 1, pEndPointer); - m_unXObjectsCount++; + ItoA(pPointer, m_unXObjectsCount, pEndPointer); m_pXObjects->Add(sXObjName, pObject); sKey = m_pXObjects->GetKey(pObject); } @@ -169,7 +184,7 @@ namespace PdfWriter if (pFonts && pFonts->GetType() == object_type_DICT) { m_pFonts = (CDictObject*)pFonts; - m_unFontsCount = m_pFonts->GetSize(); + m_unFontsCount = 0; } // Инициализация текущего ExtGStates @@ -177,7 +192,7 @@ namespace PdfWriter if (pExtGStates && pExtGStates->GetType() == object_type_DICT) { m_pExtGStates = (CDictObject*)pExtGStates; - m_unExtGStatesCount = m_pExtGStates->GetSize(); + m_unExtGStatesCount = 0; } // Инициализация текущего XObject @@ -185,7 +200,7 @@ namespace PdfWriter if (pXObject && pXObject->GetType() == object_type_DICT) { m_pXObjects = (CDictObject*)pXObject; - m_unXObjectsCount = m_pXObjects->GetSize(); + m_unXObjectsCount = 0; } } } From 11ddc0ab4f8440959dadc4e8fe0b8ecbbccf9131 Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy <mikhail.lobotskiy@onlyoffice.com> Date: Tue, 28 May 2024 23:50:21 +0400 Subject: [PATCH 719/794] Set contexts inspectable for JSC --- DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm index 3bde66eefd1..d0fefa6b6ba 100644 --- a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm +++ b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm @@ -219,6 +219,13 @@ bool IsOldVersion() { m_internal->context = [[JSContext alloc] init]; +#ifdef _DEBUG + if (@available(macOS 10.11, iOS 16.0, *)) + { + JSGlobalContextSetInspectable(m_internal->context.JSGlobalContextRef, true); + } +#endif + ASC_THREAD_ID nThreadId = NSThreads::GetCurrentThreadId(); MoveToThread(&nThreadId); if (CGlobalContext::GetInstance().IsOldVersion()) From e8ae960a263c6b5a530a44273f3529b772073052 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Wed, 29 May 2024 01:32:54 +0300 Subject: [PATCH 720/794] Fix bug #68235 --- .../html/css/src/xhtml/CDocumentStyle.cpp | 18 ++++++++++++------ .../html/css/src/xhtml/CDocumentStyle.h | 4 ++-- HtmlFile2/htmlfile2.cpp | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index b544b161159..1c51ef95002 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -299,9 +299,10 @@ namespace NSCSS oElement.AddBasicProperties(BProperties::B_CustomStyle, L"1"); } - void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) + void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite) { - ConvertStyle(oStyle, oXmlElement, true); + if (!bIsLite) + ConvertStyle(oStyle, oXmlElement, true); if (oStyle.Empty()) return; @@ -464,9 +465,10 @@ namespace NSCSS return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"" + std::to_wstring(nSpace) + L"\" w:color=\"" + wsColor + L"\""; } - void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement) + void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite) { - ConvertStyle(oStyle, oXmlElement, false); + if (!bIsLite) + ConvertStyle(oStyle, oXmlElement, false); if (oStyle.Empty() && oXmlElement.Empty()) return; @@ -536,11 +538,13 @@ namespace NSCSS bool CDocumentStyle::WriteLitePStyle(const CCompiledStyle &oStyle) { + Clear(); + if (oStyle.Empty()) return false; CXmlElement oXmlElement; - SetPStyle(oStyle, oXmlElement); + SetPStyle(oStyle, oXmlElement, true); if (oXmlElement.Empty()) return false; @@ -551,11 +555,13 @@ namespace NSCSS bool CDocumentStyle::WriteLiteRStyle(const CCompiledStyle &oStyle) { + Clear(); + if (oStyle.Empty()) return false; CXmlElement oXmlElement; - SetRStyle(oStyle, oXmlElement); + SetRStyle(oStyle, oXmlElement, true); if (oXmlElement.Empty()) return false; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h index 470e306e7bd..4d9a349db21 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.h @@ -40,8 +40,8 @@ namespace NSCSS void CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement); void ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle); - void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); - void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement); + void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false); + void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false); void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty); public: diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 1d51ff07e7d..7186380400f 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1672,10 +1672,10 @@ class CHtmlFile2_Private { std::wstring sName = m_oLightReader.GetName(); if(sName == L"class") - oNode.m_wsClass = m_oLightReader.GetText(); + oNode.m_wsClass = EncodeXmlString(m_oLightReader.GetText()); else if(sName == L"id") { - oNode.m_wsId = m_oLightReader.GetText(); + oNode.m_wsId = EncodeXmlString(m_oLightReader.GetText()); WriteBookmark(oXml, oNode.m_wsId); } else if(sName == L"style") From 49d1426831b5ea28e815c321508ea610ac6f77e2 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Wed, 29 May 2024 01:33:56 +0300 Subject: [PATCH 721/794] Fix bug #68230 --- Common/3dParty/html/htmltoxhtml.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index ff28c84dc7c..c941a6a724b 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -23,21 +23,21 @@ static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6", - "ul", "ol", "li","table","tr","td","th","br","form","input", - "button","section","nav","header","footer","main","figure", - "figcaption","strong","em","i", "b", "u","pre","code","blockquote", - "hr","script","link","meta","style","title","head","body","html", - "legend","optgroup","option","select","dl","dt","dd","time", - "data","abbr","address","area","base","bdi","bdo","cite","col", - "iframe","video","source","track","textarea","label","fieldset", - "colgroup","del","ins","details","summary","dialog","embed", - "kbd","map","mark","menu","meter","object","output","param", - "progress","q","samp","small","sub","sup","var","wbr","acronym", - "applet","article","aside","audio","basefont","bgsound","big", - "blink","canvas","caption","center","command","comment","datalist", - "dfn","dir","font","frame","frameset","hgroup","isindex","keygen", - "marquee","nobr","noembed","noframes","noscript","plaintext","rp", - "rt","ruby","s","strike","tt","tfoot","thead","xmp"}; + "ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th", + "br","form","input","button","section","nav","header","footer", + "main","figure","figcaption","strong","em","i", "b", "u","pre", + "code","blockquote","hr","script","link","meta","style","title", + "head","body","html","legend","optgroup","option","select","dl", + "dt","dd","time","data","abbr","address","area","base","bdi", + "bdo","cite","col","iframe","video","source","track","textarea", + "label","fieldset","colgroup","del","ins","details","summary", + "dialog","embed","kbd","map","mark","menu","meter","object", + "output","param","progress","q","samp","small","sub","sup","var", + "wbr","acronym","applet","article","aside","audio","basefont", + "bgsound","big","blink","canvas","caption","center","command", + "comment","datalist","dfn","dir","font","frame","frameset", + "hgroup","isindex","keygen","marquee","nobr","noembed","noframes", + "noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"}; static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder); static std::string mhtTohtml(const std::string &sFileContent); From 5e560528a48b62208276ebfe734b32795d809d77 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 29 May 2024 15:08:32 +0300 Subject: [PATCH 722/794] Fix bug 68233 --- PdfFile/SrcReader/RendererOutputDev.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 27876b4651a..9b9c609a26e 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3095,6 +3095,9 @@ namespace PdfReader pRenderer->put_Width (nWidth * 25.4 / 72.0); pRenderer->put_Height(nHeight * 25.4 / 72.0); pRenderer->CommandLong(c_nPenWidth0As1px, 1); +#ifndef BUILDING_WASM_MODULE + pRenderer->SetSwapRGB(false); +#endif PDFRectangle box; box.x1 = pBBox[0]; From a2b8fcc5e15184b8608091242ff1693313d659ae Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Wed, 29 May 2024 20:03:17 +0300 Subject: [PATCH 723/794] for bug #61035 --- OdfFile/DataTypes/common_attlists.cpp | 1 + OdfFile/Formulas/formulasconvert_oox.cpp | 2 +- OdfFile/Writer/Converter/XlsxConverter.cpp | 20 +++++++++++---- OdfFile/Writer/Format/ods_table_state.cpp | 30 ++++++++++------------ 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/OdfFile/DataTypes/common_attlists.cpp b/OdfFile/DataTypes/common_attlists.cpp index 00dec9e10d3..8fcff8aa423 100644 --- a/OdfFile/DataTypes/common_attlists.cpp +++ b/OdfFile/DataTypes/common_attlists.cpp @@ -439,6 +439,7 @@ void common_value_and_type_attlist::apply_from(const common_value_and_type_attli void common_value_and_type_attlist::serialize(CP_ATTR_NODE) { CP_XML_ATTR_OPT(L"office:value-type", office_value_type_); + CP_XML_ATTR_OPT(L"calcext:value-type", office_value_type_); CP_XML_ATTR_OPT(L"office:value", office_value_); if (office_value_) { diff --git a/OdfFile/Formulas/formulasconvert_oox.cpp b/OdfFile/Formulas/formulasconvert_oox.cpp index ab1bae259ec..a45a6928c67 100644 --- a/OdfFile/Formulas/formulasconvert_oox.cpp +++ b/OdfFile/Formulas/formulasconvert_oox.cpp @@ -773,7 +773,7 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) std::wstring res = boost::regex_replace( res1, - boost::wregex(L"(?!([А-Яа-яÀ-ÿ\\w^0-9]+\\d*\\())(([[А-Яа-яÀ-ÿ\\w^0-9]+\\!)?\\$?[\\w^0-9]*\\$?\\d*(\\:\\$?[\\w^0-9]*\\$?\\d*){0,1})"), + boost::wregex(L"(?!([[:Unicode:]\\w^0-9]+\\d*\\())(((\[[0-9]+\])?[[[:Unicode:]\\w^0-9]+\\!)?\\$?[\\w^0-9]*\\$?\\d*(\\:\\$?[\\w^0-9]*\\$?\\d*){0,1})"), &oox2odf_converter::Impl::replace_arguments, boost::match_default | boost::format_all); //SUBTOTAL(109,Expense31[Amount]) diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 0cff665696d..ec9c8a1dcf5 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -1157,6 +1157,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CRow *oox_row, OOX::Spreadsheet::C { if (oox_row_prev->m_oCollapsed.IsInit()) { + if (oox_row->m_oCollapsed->GetValue() != oox_row_prev->m_oCollapsed->GetValue()) bEqual = false; } else bEqual = false; } @@ -1274,8 +1275,8 @@ void XlsxConverter::convert(OOX::Spreadsheet::CRow *oox_row, OOX::Spreadsheet::C ods_context->start_row(row_number, 1, level, _default); - if (oox_row->m_oHidden.IsInit()) ods_context->current_table()->set_row_hidden(true); - if (oox_row->m_oCollapsed.IsInit()) ods_context->current_table()->set_row_hidden(true); + if (oox_row->m_oHidden.IsInit() && oox_row->m_oHidden->ToBool()) ods_context->current_table()->set_row_hidden(true); + if (oox_row->m_oCollapsed.IsInit() && oox_row->m_oCollapsed->ToBool()) ods_context->current_table()->set_row_hidden(true); std::wstring style_cell_name; if (oox_row->m_oS.IsInit() && ( oox_row->m_oCustomFormat.IsInit() && oox_row->m_oCustomFormat->GetValue()==1)) @@ -1352,8 +1353,7 @@ void XlsxConverter::convert(OOX::Spreadsheet::CCell *oox_cell) if (value_type >=0) ods_context->current_table()->set_cell_type (value_type); - ods_context->current_table()->set_cell_value (oox_cell->m_oValue->m_sText); - //ods_context->current_table()->set_cell_cache (oox_cell->m_oValue->m_sText); + ods_context->current_table()->set_cell_value (oox_cell->m_oValue->m_sText, oox_cell->m_oFormula.IsInit()); } } @@ -1407,9 +1407,19 @@ void XlsxConverter::convert(OOX::Spreadsheet::CExternalLink *oox_external_link) smart_ptr<OOX::External> fileExternal = file.smart_dynamic_cast<OOX::External>(); if (fileExternal.IsInit()) { - ods_context->add_external_reference(fileExternal->Uri().GetPath()); + std::wstring filePath = fileExternal->Uri().GetPath(); + + if (std::wstring::npos == filePath.find(L"file://")) + filePath = L"file://" + filePath; + ods_context->add_external_reference(filePath); } } + //todooo + } + if (oox_external_link->m_oFileKey.IsInit() || oox_external_link->m_oInstanceId.IsInit()) + { + //todooo + } xlsx_current_container = old_container; } diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index 2ca0c6170b0..745d154b720 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -997,16 +997,17 @@ void ods_table_state::set_cell_formula(std::wstring & formula) ods_conversion_context* ods_context = dynamic_cast<ods_conversion_context*>(context_); - //test external link + std::wstring odfFormula = formulas_converter_table.convert_formula(formula); + +//test external link bool bExternal = !ods_context->externals_.empty(); boost::wregex re(L"([\\[]\\d+[\\]])+"); while(bExternal) { boost::wsmatch result; - bExternal = boost::regex_search(formula, result, re); + bExternal = boost::regex_search(odfFormula, result, re); if (!bExternal) break; - std::wstring refExternal = result[1].str(); int idExternal = XmlUtils::GetInteger(refExternal.substr(1, refExternal.length() - 1)) - 1; @@ -1015,33 +1016,28 @@ void ods_table_state::set_cell_formula(std::wstring & formula) while(idExternal >= 0 && idExternal < (int)ods_context->externals_.size()) { - size_t pos = formula.find(refExternal); + size_t pos = odfFormula.find(refExternal); if (pos == std::wstring::npos) break; std::wstring new_formula; - if (pos > 0 && formula[pos - 1] == L'\'') + if (pos > 0 && odfFormula[pos - 1] == L'\'') { - new_formula = formula.substr(0, pos - 1); - new_formula += L"'EXTERNALREF" + ods_context->externals_[idExternal].ref + L"'#"; + new_formula = odfFormula.substr(0, pos - 1); + new_formula += L"'" + ods_context->externals_[idExternal].ref + L"'#"; new_formula += L"'"; } else { - new_formula = formula.substr(0, pos); - new_formula += L"'EXTERNALREF" + ods_context->externals_[idExternal].ref + L"'#"; + new_formula = odfFormula.substr(0, pos); + new_formula += L"'" + ods_context->externals_[idExternal].ref + L"'#"; } pos += refExternal.length(); - new_formula += formula.substr(pos, formula.length() - pos); - formula = new_formula; + new_formula += odfFormula.substr(pos, odfFormula.length() - pos); + odfFormula = new_formula; } } - - std::wstring odfFormula = formulas_converter_table.convert_formula(formula); - - XmlUtils::replace_all(odfFormula, L"EXTERNALREF", L"file://");//снятие экранирования - if ((false == table_parts_.empty()) && (std::wstring::npos != odfFormula.find(L"["))) { for (size_t i = 0; i < table_parts_.size(); i++) @@ -1389,7 +1385,7 @@ void ods_table_state::set_cell_value(const std::wstring & value, bool need_cash) bool need_test_cach = false; - if (cell->attlist_.common_value_and_type_attlist_->office_value_type_) + if (!need_cash && cell->attlist_.common_value_and_type_attlist_->office_value_type_) { if (cell->attlist_.common_value_and_type_attlist_->office_value_type_->get_type() == office_value_type::Float || cell->attlist_.common_value_and_type_attlist_->office_value_type_->get_type() == office_value_type::Currency || From a66fdc73a56d465e0226e7fba43efe1c09ad9265 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Wed, 29 May 2024 20:35:44 +0300 Subject: [PATCH 724/794] fix bug #68264 --- OdfFile/Writer/Format/odt_conversion_context.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index 28d20c9bf80..bdebe6ca243 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -780,7 +780,10 @@ void odt_conversion_context::set_field_instr() if (std::wstring::npos != res1 && current_fields.back().type == 0) { current_fields.back().type = fieldRef; - std::map<std::wstring, std::wstring> options = parse_instr_options(instr.substr(4)); + + std::wstring options_str; + if (instr.size() > 3) options_str = instr.substr(4); + std::map<std::wstring, std::wstring> options = parse_instr_options(options_str); for (std::map<std::wstring, std::wstring>::iterator it = options.begin(); it != options.end(); ++it) { From 8d6a13b24a9c25ac868dfbf72ffc1ea4e74cca0b Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 30 May 2024 15:41:52 +0600 Subject: [PATCH 725/794] Fix bug #68229 --- .../Format/Logic/Biff_records/FileSharing.cpp | 26 ++++++++ .../Format/Logic/Biff_records/FileSharing.h | 1 + .../Logic/Biff_structures/StringPtgParser.cpp | 36 ++++++++--- .../Logic/Biff_structures/SyntaxPtg.cpp | 19 +++++- .../Format/Logic/Biff_structures/SyntaxPtg.h | 1 + .../Format/Logic/GlobalWorkbookInfo.cpp | 1 + .../XlsFile/Format/Logic/GlobalWorkbookInfo.h | 1 + OOXML/XlsbFormat/Xlsb.cpp | 61 +++++++++++++++++++ OOXML/XlsbFormat/Xlsb.h | 1 + OOXML/XlsxFormat/Styles/TableStyles.cpp | 10 ++- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 49 +++++++++++---- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 13 ++++ .../Worksheets/WorksheetChildOther.cpp | 2 +- X2tConverter/src/lib/xlsx.h | 1 + 14 files changed, 195 insertions(+), 27 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp index c9ded9db072..8c55bdc17cf 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp @@ -70,5 +70,31 @@ void FileSharing::readFields(CFRecord& record) } } +void FileSharing::writeFields(CFRecord& record) +{ + if(record.getGlobalWorkbookInfo()->Version == 0x0800) + { + auto readOnlyrec = fReadOnlyRec.value(); + if(readOnlyrec.is_initialized() &&(readOnlyrec.get() == 1 || readOnlyrec.get() == 0)) + record << fReadOnlyRec; + else + { + UINT16 defaulTRec = 0; + record << defaulTRec; + } + if(!wResPass.empty()) + { + try + { + wResPassNum = std::stoi(wResPass, nullptr, 16); + } + catch(const std::exception&) + { + wResPassNum = 0; + } + } + record << wResPassNum << stUserName; + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h index d2d31729e23..080f5a6d5df 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h @@ -51,6 +51,7 @@ class FileSharing: public BiffRecord BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record) override; static const ElementType type = typeFileSharing; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index c0dffe80b04..cd8c40cd792 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -251,6 +251,7 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R #pragma region Comma and PtgUnion else if(SyntaxPtg::extract_comma(it, itEnd)) { + SyntaxPtg::remove_extraSymbols(it, itEnd); PtgParenPtr left_p; if(ptg_stack.size() && (left_p = boost::dynamic_pointer_cast<PtgParen>(ptg_stack.top())) && operand_expected) { @@ -488,26 +489,41 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) auto refArgs = PosValArgs(funcPtr->getFuncIndex()); for(auto j = paramsNum-1; j >= 0; j--) { - if(refArgs.size() > j && refArgs.at(j)) - SetPtgType(functionStack.back(), 3); - functionStack.pop_back(); + if(!functionStack.empty()) + { + if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } } } functionStack.push_back(i); } else if(ptgId > 1 && ptgId < 15) { - SetPtgType(functionStack.back(), 3); - functionStack.pop_back(); - SetPtgType(functionStack.back(), 3); + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 3); + } } else if(ptgId > 14 && ptgId < 18) { - SetPtgType(functionStack.back(), 1); - functionStack.pop_back(); - SetPtgType(functionStack.back(), 1); + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 1); + functionStack.pop_back(); + } + if(!functionStack.empty()) + { + SetPtgType(functionStack.back(), 1); + } } - else if(ptgId > 17 && ptgId < 21) + else if(ptgId > 17 && ptgId < 21 && !functionStack.empty()) { SetPtgType(functionStack.back(), 3); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index bbad79043b3..ecd56dff23e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -296,8 +296,9 @@ const bool SyntaxPtg::extract_PtgUnion(std::wstring::const_iterator& first, std: const bool SyntaxPtg::is_PtgIsect(std::wstring::const_iterator& first, std::wstring::const_iterator last) { static boost::wregex reg_before_comma(L"^ *[,()]"); + static boost::wregex reg_before_space(L"[,(\\n] *$"); static boost::wregex reg_isect(L"^ "); - return !boost::regex_search(first, last, reg_before_comma) && + return !boost::regex_search(first, last, reg_before_comma) && !boost::regex_search(first, last, reg_before_space) && boost::regex_search(first, last, reg_isect); } @@ -458,6 +459,14 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: if (XMLSTUFF::isTableFmla(tableName, indexTable)) { + for(auto i:XLS::GlobalWorkbookInfo::mapXtiTables_static) + { + for(auto tablIndex:i.second) + { + if(tablIndex == indexTable) + ixti = i.first; + } + } ptgList.listIndex = indexTable; ptgList.squareBracketSpace = false; ptgList.commaSpace = false; @@ -822,6 +831,14 @@ const bool SyntaxPtg::extract_PtgFunc(std::wstring::const_iterator& first, std:: return false; } +// static +const void SyntaxPtg::remove_extraSymbols(std::wstring::const_iterator& first, std::wstring::const_iterator& last) +{ + while(first != last && (first[0] == L' ' || first[0] == L'\n')) + { + first++; + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h index d2b9fb3f950..90becefd32b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h @@ -86,6 +86,7 @@ class SyntaxPtg static const bool extract_RightParenthesis(std::wstring::const_iterator& first, std::wstring::const_iterator last); static const bool extract_PtgFunc(std::wstring::const_iterator& first, std::wstring::const_iterator last, std::wstring& out_str); + static const void remove_extraSymbols(std::wstring::const_iterator& first, std::wstring::const_iterator& last); }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp index 2d6878c420c..d331eb57836 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp @@ -95,6 +95,7 @@ std::vector<GlobalWorkbookInfo::_xti> GlobalWorkbookInfo::arXti_External_stat std::unordered_map<int, std::wstring> GlobalWorkbookInfo::mapTableNames_static; std::unordered_map<int, std::vector<std::wstring>> GlobalWorkbookInfo::mapTableColumnNames_static; std::vector<std::wstring> GlobalWorkbookInfo::arDefineNames_static; +std::unordered_map<int, std::vector<int>> GlobalWorkbookInfo::mapXtiTables_static; GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConverter * converter) : CodePage(code_page), xls_converter(converter) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h index c2ceff53d71..ebacd3e197d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h @@ -221,6 +221,7 @@ class GlobalWorkbookInfo static std::unordered_map<int, std::wstring> mapTableNames_static; static std::unordered_map<int, std::vector<std::wstring>> mapTableColumnNames_static; std::unordered_map<std::wstring, int> mapTableGuidsIndex; + static std::unordered_map<int, std::vector<int>> mapXtiTables_static; std::unordered_map<int, std::vector<XLS::ElementType>> pivotCacheRecordType; int currentPivotCacheRecord; diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 3aa80e3b93d..b229dc7ba09 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -347,6 +347,67 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() } } +void OOX::Spreadsheet::CXlsb::LinkTables() +{ + { + bool tablesExist = false; + for(auto worksheet:m_arWorksheets) + { + if(worksheet->m_oTableParts.IsInit()) + tablesExist = true; + } + if(!tablesExist) + return; + } + for(auto xti:XLS::GlobalWorkbookInfo::arXti_External_static) + { + if(xti.itabFirst != xti.itabLast) + { + continue; + } + auto sheetName = xti.link; + if(!m_pWorkbook || !m_pWorkbook->m_oSheets.IsInit()) + continue; + OOX::Spreadsheet::CSheet * bundle; + for(auto i:m_pWorkbook->m_oSheets->m_arrItems) + { + if(i->m_oName.IsInit() && i->m_oName.get() == sheetName) + { + bundle = i; + } + } + if(!bundle || !bundle->m_oRid.IsInit()) + continue; + auto FilePtr = m_pWorkbook->Find(bundle->m_oRid->GetValue()); + if(!FilePtr.IsInit() || !(OOX::Spreadsheet::FileTypes::Worksheet == FilePtr->type())) + continue; + auto WorksheetFile = static_cast<OOX::Spreadsheet::CWorksheet*>(FilePtr.GetPointer()); + if(!WorksheetFile->m_oTableParts.IsInit()) + continue; + for(auto tablePart : WorksheetFile->m_oTableParts->m_arrItems) + { + if(tablePart->m_oRId.IsInit()) + { + auto tableFilePtr = WorksheetFile->Find(tablePart->m_oRId->GetValue()); + if(tableFilePtr.IsInit() && OOX::Spreadsheet::FileTypes::Table == tableFilePtr->type()) + { + auto tableFile = static_cast<OOX::Spreadsheet::CTableFile*>(tableFilePtr.GetPointer()); + if(tableFile->m_oTable.IsInit() && tableFile->m_oTable->m_oId.IsInit()) + { + if(!XLS::GlobalWorkbookInfo::mapXtiTables_static.count(xti.itabFirst)) + { + XLS::GlobalWorkbookInfo::mapXtiTables_static.emplace(xti.itabFirst, std::vector<int>()); + } + XLS::GlobalWorkbookInfo::mapXtiTables_static.at(xti.itabFirst).push_back(tableFile->m_oTable->m_oId->GetValue()); + + } + } + } + } + } +} + + diff --git a/OOXML/XlsbFormat/Xlsb.h b/OOXML/XlsbFormat/Xlsb.h index 40a8689541a..71610640a73 100644 --- a/OOXML/XlsbFormat/Xlsb.h +++ b/OOXML/XlsbFormat/Xlsb.h @@ -69,6 +69,7 @@ namespace OOX XLS::GlobalWorkbookInfo* GetGlobalinfo(); void PrepareSi(); void PrepareTableFormula(); + void LinkTables(); void ReadSheetData(); void WriteSheetData(); void SetPropForWriteSheet(const std::wstring &sPath, OOX::CContentTypes& oContentTypes); diff --git a/OOXML/XlsxFormat/Styles/TableStyles.cpp b/OOXML/XlsxFormat/Styles/TableStyles.cpp index 19d128b637f..46bab13cfe4 100644 --- a/OOXML/XlsxFormat/Styles/TableStyles.cpp +++ b/OOXML/XlsxFormat/Styles/TableStyles.cpp @@ -446,8 +446,14 @@ namespace OOX for(auto i:m_arrItems) ptr->m_arTABLESTYLE.push_back(i->toBin()); ptr1->cts = ptr->m_arTABLESTYLE.size(); - ptr1->rgchDefTableStyle = m_oDefaultTableStyle.get(); - ptr1->rgchDefPivotStyle = m_oDefaultPivotStyle.get(); + if(m_oDefaultTableStyle.IsInit()) + ptr1->rgchDefTableStyle = m_oDefaultTableStyle.get(); + else + ptr1->rgchDefTableStyle = L""; + if(m_oDefaultPivotStyle.IsInit()) + ptr1->rgchDefPivotStyle = m_oDefaultPivotStyle.get(); + else + ptr1->rgchDefPivotStyle = L""; return objectPtr; } EElementType CTableStyles::getType () const diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index e7a7eed4e66..b868f1f7c56 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -420,22 +420,37 @@ namespace OOX if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); - ptr->stUserName = m_oUserName.get(); - ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); - ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oUserName.IsInit()) + ptr->stUserName = m_oUserName.get(); + else + ptr->stUserName = L""; + if(m_oAlgorithmName.IsInit()) + ptr->ipdPasswordData.szAlgName = m_oAlgorithmName->GetValue(); + else + ptr->ipdPasswordData.szAlgName = L""; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + else + ptr->dwSpinCount = 0; auto len = 0; - auto bytes = ptr->ipdPasswordData.rgbHash.rgbData.data(); - std::string strData = {m_oHashValue.get().begin(), m_oHashValue.get().end()}; - NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), - bytes, len); + if(m_oHashValue.IsInit()) + { + auto bytes = ptr->ipdPasswordData.rgbHash.rgbData.data(); + std::string strData = {m_oHashValue.get().begin(), m_oHashValue.get().end()}; + NSFile::CBase64Converter::Decode(strData.c_str(), strData.size(), + bytes, len); + } ptr->ipdPasswordData.rgbHash.cbLength = len; auto len1 = 0; - auto bytes1 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); - std::string strData1 = {m_oSaltValue.get().begin(), m_oSaltValue.get().end()}; - NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), - bytes1, len1); + if(m_oSaltValue.IsInit()) + { + auto bytes1 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + std::string strData1 = {m_oSaltValue.get().begin(), m_oSaltValue.get().end()}; + NSFile::CBase64Converter::Decode(strData1.c_str(), strData1.size(), + bytes1, len1); + } ptr->ipdPasswordData.rgbSalt.cbLength = len1; } @@ -445,8 +460,16 @@ namespace OOX objectPtr = XLS::BaseObjectPtr{ptr}; if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); - ptr->stUserName = m_oUserName.get(); - ptr->wResPass = m_oPassword.get(); + else + ptr->fReadOnlyRec = false; + if(m_oUserName.IsInit()) + ptr->stUserName = m_oUserName.get(); + else + ptr->stUserName.setSize(0xFFFFFFFF); + if(m_oPassword.IsInit()) + ptr->wResPass = m_oPassword.get(); + else + ptr->wResPass = L""; } return objectPtr; } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 58e26148561..adae0c2fe9c 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1143,6 +1143,19 @@ namespace OOX formula->formula = m_sText; if(m_oRef.IsInit()) formula->rfx = m_oRef.get(); + if(!formula->formula.rgce.sequence.empty()) + { + auto lastValType = GETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } + else if(formula->formula.rgce.sequence.rbegin()->get()->ptg_id.get() == 6424) + { + auto list = static_cast<XLS::PtgList*>(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } } break; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 6e37538140c..433bc03d85f 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -1392,7 +1392,7 @@ namespace OOX if (m_oShowFormulas.IsInit()) pWsView->fDspFmlaRt = m_oShowFormulas->m_eValue; else - pWsView->fDspFmlaRt = true; + pWsView->fDspFmlaRt = false; if (m_oShowGridLines.IsInit()) pWsView->fDspGridRt = m_oShowGridLines->m_eValue; else diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 5a894bff43e..0c8a12b7cd8 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -164,6 +164,7 @@ namespace NExtractTools OOX::Spreadsheet::CXlsb oXlsb; oXlsb.m_bWriteToXlsb = true; oXlsb.Read(oox_path); + oXlsb.LinkTables(); OOX::CContentTypes oContentTypes; oXlsb.SetPropForWriteSheet(sTo, oContentTypes); From 6ba5d1141e5d4573d1e9d9193bb22aec4d271b5a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 30 May 2024 12:45:17 +0300 Subject: [PATCH 726/794] Fix bug 68256 --- PdfFile/PdfReader.cpp | 139 ++++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 54 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 538b6503ae0..677b44ff6c5 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -107,7 +107,7 @@ CPdfReader::~CPdfReader() RELEASEINTERFACE(m_pFontManager); } -bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nDepth) +bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nDepth, std::vector<int>& arrUniqueResources) { if (nDepth > 5) return false; @@ -126,7 +126,7 @@ bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nD char* sName = oEncoding.getName(); if (std::find(arrCMap.begin(), arrCMap.end(), sName) != arrCMap.end()) { - oEncoding.free();oFonts.free(); + oEncoding.free(); oFonts.free(); return true; } oEncoding.free(); @@ -134,80 +134,109 @@ bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nD } oFonts.free(); - auto fScanFonts = [pResources, &arrCMap, &nDepth](const char* sName) + auto fScanFonts = [pResources, nDepth, &arrUniqueResources](const std::vector<std::string>& arrCMap, const char* sName) { Object oObject; - if (pResources->lookup(sName, &oObject)->isDict()) + if (!pResources->lookup(sName, &oObject)->isDict()) { - for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i) + oObject.free(); + return false; + } + for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i) + { + Object oXObj, oResources; + if (!oObject.dictGetVal(i, &oXObj)->isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources)->isDict()) { - Object oXObj, oResources; - if (!oObject.dictGetVal(i, &oXObj)->isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources)->isDict()) - { - oXObj.free(); oResources.free(); - continue; - } - oXObj.free(); - if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1)) - { - oResources.free(); oObject.free(); - return true; - } - oResources.free(); + oXObj.free(); oResources.free(); + continue; + } + Object oRef; + if (oXObj.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + oXObj.free(); oResources.free(); oRef.free(); + continue; + } + arrUniqueResources.push_back(oRef.getRef().num); + oXObj.free(); oRef.free(); + if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1, arrUniqueResources)) + { + oResources.free(); oObject.free(); + return true; } + oResources.free(); } oObject.free(); return false; }; - if (fScanFonts("XObject") || fScanFonts("Pattern")) + if (fScanFonts(arrCMap, "XObject") || fScanFonts(arrCMap, "Pattern")) return true; Object oExtGState; - if (pResources->lookup("ExtGState", &oExtGState)->isDict()) + if (!pResources->lookup("ExtGState", &oExtGState)->isDict()) { - for (int i = 0, nLength = oExtGState.dictGetLength(); i < nLength; ++i) + oExtGState.free(); + return false; + } + for (int i = 0, nLength = oExtGState.dictGetLength(); i < nLength; ++i) + { + Object oGS, oSMask, oSMaskGroup, oResources; + if (!oExtGState.dictGetVal(i, &oGS)->isDict() || !oGS.dictLookup("SMask", &oSMask)->isDict() || !oSMask.dictLookup("G", &oSMaskGroup)->isStream() || !oSMaskGroup.streamGetDict()->lookup("Resources", &oResources)->isDict()) { - Object oGS, oSMask, oSMaskGroup, oResources; - if (!oExtGState.dictGetVal(i, &oGS)->isDict() || !oGS.dictLookup("SMask", &oSMask)->isDict() || !oSMask.dictLookup("G", &oSMaskGroup)->isStream() || !oSMaskGroup.streamGetDict()->lookup("Resources", &oResources)->isDict()) - { - oGS.free(); oSMask.free(); oSMaskGroup.free(); oResources.free(); - continue; - } - oGS.free(); oSMask.free(); oSMaskGroup.free(); - if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1)) - { - oResources.free(); oExtGState.free(); - return true; - } - oResources.free(); + oGS.free(); oSMask.free(); oSMaskGroup.free(); oResources.free(); + continue; } + oGS.free(); oSMask.free(); + Object oRef; + if (oSMaskGroup.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + oSMaskGroup.free(); oResources.free(); oRef.free(); + continue; + } + arrUniqueResources.push_back(oRef.getRef().num); + oSMaskGroup.free(); oRef.free(); + if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1, arrUniqueResources)) + { + oResources.free(); oExtGState.free(); + return true; + } + oResources.free(); } oExtGState.free(); return false; } -bool scanAPfonts(Object* oAnnot, const std::vector<std::string>& arrCMap) +bool scanAPfonts(Object* oAnnot, const std::vector<std::string>& arrCMap, std::vector<int>& arrUniqueResources) { Object oAP; - if (oAnnot->dictLookup("AP", &oAP)->isDict()) + if (!oAnnot->dictLookup("AP", &oAP)->isDict()) + { + oAP.free(); + return false; + } + auto fScanAPView = [&arrUniqueResources](Object* oAP, const std::vector<std::string>& arrCMap, const char* sName) { - auto fScanAPView = [&oAP, &arrCMap](const char* sName) + Object oAPi, oRes; + if (!oAP->dictLookup(sName, &oAPi)->isStream() || !oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict()) { - Object oAPi, oRes; - if (oAP.dictLookup(sName, &oAPi)->isStream() && oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict() && scanFonts(oRes.getDict(), arrCMap, 0)) - { - oAPi.free(); oRes.free(); oAP.free(); - return true; - } oAPi.free(); oRes.free(); return false; - }; - if (fScanAPView("N") || fScanAPView("D") || fScanAPView("R")) - return true; - } + } + Object oRef; + if (oAPi.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + oAPi.free(); oRes.free(); oRef.free(); + return false; + } + arrUniqueResources.push_back(oRef.getRef().num); + oAPi.free(); oRef.free(); + bool bRes = scanFonts(oRes.getDict(), arrCMap, 0, arrUniqueResources); + oRes.free(); + return bRes; + }; + bool bRes = fScanAPView(&oAP, arrCMap, "N") || fScanAPView(&oAP, arrCMap, "D") || fScanAPView(&oAP, arrCMap, "R"); oAP.free(); - return false; + return bRes; } bool CPdfReader::IsNeedCMap() { @@ -234,11 +263,13 @@ bool CPdfReader::IsNeedCMap() if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return false; + std::vector<int> arrUniqueResources; + for (int nPage = 1, nLastPage = m_pPDFDocument->getNumPages(); nPage <= nLastPage; ++nPage) { Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage); Dict* pResources = pPage->getResourceDict(); - if (pResources && scanFonts(pResources, arrCMap, 0)) + if (pResources && scanFonts(pResources, arrCMap, 0, arrUniqueResources)) return true; Object oAnnots; @@ -257,14 +288,14 @@ bool CPdfReader::IsNeedCMap() } Object oDR; - if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); oAnnot.free(); oAnnots.free(); return true; } oDR.free(); - if (scanAPfonts(&oAnnot, arrCMap)) + if (scanAPfonts(&oAnnot, arrCMap, arrUniqueResources)) { oAnnot.free(); oAnnots.free(); return true; @@ -279,7 +310,7 @@ bool CPdfReader::IsNeedCMap() return false; Object oDR; Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; @@ -290,7 +321,7 @@ bool CPdfReader::IsNeedCMap() { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; @@ -302,7 +333,7 @@ bool CPdfReader::IsNeedCMap() oWidgetRef.fetch(m_pPDFDocument->getXRef(), &oWidget); oWidgetRef.free(); - if (scanAPfonts(&oWidget, arrCMap)) + if (scanAPfonts(&oWidget, arrCMap, arrUniqueResources)) { oWidget.free(); return true; From dfb0aeefcb200d87052fa834d063fdb39041612f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 30 May 2024 12:45:56 +0300 Subject: [PATCH 727/794] Fix read/write tilingPattern in pdf --- PdfFile/PdfWriter.cpp | 3 ++- PdfFile/SrcReader/RendererOutputDev.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 3af47625d1d..f54c646b5e4 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -3338,9 +3338,10 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w // Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования. PdfWriter::CMatrix* pMatrix = m_pPage->GetTransform(); pMatrix->Apply(dL, dT); + pMatrix->Apply(dR, dB); PdfWriter::CMatrix oPatternMatrix = *pMatrix; oPatternMatrix.x = dL; - oPatternMatrix.y = dT; + oPatternMatrix.y = c_BrushTextureModeStretch == lTextureMode ? dT : dB; m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage, &oPatternMatrix, PdfWriter::imagetilepatterntype_Default, dXStepSpacing, dYStepSpacing)); } } diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 9b9c609a26e..deef98022e7 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3123,8 +3123,10 @@ namespace PdfReader double xMin, yMin, xMax, yMax; Transform(matrix, pBBox[0], pBBox[1], &xMin, &yMin); Transform(matrix, pBBox[2], pBBox[3], &xMax, &yMax); - xMax *= (nX1 - nX0); - yMax *= (nY1 - nY0); + xMin += nX0 * (xMax - xMin); + xMax += nX1 * (xMax - xMin); + yMin += nY0 * (yMax - yMin); + yMax += nY1 * (yMax - yMin); pGState->moveTo(xMin, yMin); pGState->lineTo(xMax, yMin); pGState->lineTo(xMax, yMax); From b209e00333481ddefc69f9020ecf17511f94fbbd Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 30 May 2024 16:30:59 +0300 Subject: [PATCH 728/794] fix bug #68276 --- .../Format/Logic/Biff_structures/DXFFntD.cpp | 97 ++++++++++--------- .../Format/Logic/Biff_structures/DXFFntD.h | 19 ++-- .../Format/Logic/Biff_structures/DXFN.cpp | 2 +- .../Format/Logic/Biff_structures/ExtProp.h | 6 +- .../Logic/Biff_structures/FullColorExt.h | 8 +- .../Format/Logic/Biff_structures/Stxp.h | 13 ++- .../Logic/Biff_structures/XFExtGradient.h | 2 +- 7 files changed, 74 insertions(+), 73 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp index 2a04747dec8..cca859c48c3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp @@ -69,7 +69,7 @@ void DXFFntD::load(CFRecord& record) record >> ich >> cch >> iFnt; } -int DXFFntD::serialize(std::wostream & stream) +int DXFFntD::serialize(std::wostream & stream, bool extOnly) { std::map<ExtProp::_type, ExtProp>::iterator pFind; @@ -104,7 +104,7 @@ int DXFFntD::serialize(std::wostream & stream) } } - if (stxp.twpHeight > 20) + if (!extOnly && stxp.twpHeight > 20) { CP_XML_NODE(L"sz") { @@ -125,68 +125,71 @@ int DXFFntD::serialize(std::wostream & stream) CP_XML_ATTR(L"indexed", icvFore); } } - CP_XML_NODE(L"charset") - { - CP_XML_ATTR(L"val", stxp.bCharSet); - } - //CP_XML_NODE(L"condense") - //{ - // CP_XML_ATTR(L"val", 1); - //} - //CP_XML_NODE(L"extend") - //{ - // CP_XML_ATTR(L"val", stxp.fExtend); - //} - CP_XML_NODE(L"family") + if (!extOnly) { - CP_XML_ATTR(L"val", stxp.bFamily); - } - if (tsNinch.ftsItalic == 0) - { - CP_XML_NODE(L"i") + CP_XML_NODE(L"charset") { - CP_XML_ATTR(L"val", stxp.ts.ftsItalic); + CP_XML_ATTR(L"val", stxp.bCharSet); } - } - if (fBlsNinch == 0) - { - CP_XML_NODE(L"b") + //CP_XML_NODE(L"condense") + //{ + // CP_XML_ATTR(L"val", 1); + //} + //CP_XML_NODE(L"extend") + //{ + // CP_XML_ATTR(L"val", stxp.fExtend); + //} + CP_XML_NODE(L"family") { - CP_XML_ATTR(L"val", stxp.bls == 700 ? 1 : 0); - } - } - if (tsNinch.ftsStrikeout == 0) - { - CP_XML_NODE(L"strike") + CP_XML_ATTR(L"val", stxp.bFamily); + } + if (tsNinch.ftsItalic == 0) { - CP_XML_ATTR(L"val", stxp.ts.ftsStrikeout); - } - } - if (fUlsNinch == 0) - { - CP_XML_NODE(L"u") + CP_XML_NODE(L"i") + { + CP_XML_ATTR(L"val", stxp.ts.ftsItalic); + } + } + if (fBlsNinch == 0) { - switch(stxp.uls) + CP_XML_NODE(L"b") { + CP_XML_ATTR(L"val", stxp.bls == 700 ? 1 : 0); + } + } + if (tsNinch.ftsStrikeout == 0) + { + CP_XML_NODE(L"strike") + { + CP_XML_ATTR(L"val", stxp.ts.ftsStrikeout); + } + } + if (fUlsNinch == 0) + { + CP_XML_NODE(L"u") + { + switch (stxp.uls) + { case 0: CP_XML_ATTR(L"val", L"none"); break; case 1: CP_XML_ATTR(L"val", L"single"); break; case 2: CP_XML_ATTR(L"val", L"double"); break; - case 33: CP_XML_ATTR(L"val", L"singleAccounting");break; - case 34: CP_XML_ATTR(L"val", L"doubleAccounting");break; + case 33: CP_XML_ATTR(L"val", L"singleAccounting"); break; + case 34: CP_XML_ATTR(L"val", L"doubleAccounting"); break; + } } } - } - if (fSssNinch == 0) - { - CP_XML_NODE(L"vertAlign") + if (fSssNinch == 0) { - switch(stxp.sss) + CP_XML_NODE(L"vertAlign") { + switch (stxp.sss) + { case 0: CP_XML_ATTR(L"val", L"baseline"); break; - case 1: CP_XML_ATTR(L"val", L"superscript");break; + case 1: CP_XML_ATTR(L"val", L"superscript"); break; case 2: CP_XML_ATTR(L"val", L"subscript"); break; + } + } - } } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h index c04f7b7da51..49e238b7560 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h @@ -50,26 +50,25 @@ class DXFFntD : public BiffStructure public: BiffStructurePtr clone(); - static const ElementType type = typeDXFFntD; + static const ElementType type = typeDXFFntD; virtual void load(CFRecord& record); - int serialize(std::wostream & stream); + int serialize(std::wostream & stream, bool extOnly = false); XLUnicodeStringNoCch stFontName; Stxp stxp; - _INT32 icvFore; + _INT32 icvFore = 0; Ts tsNinch; - _UINT32 fSssNinch; - _UINT32 fUlsNinch; - _UINT32 fBlsNinch; - - _INT32 ich; - _INT32 cch; - _UINT16 iFnt; + _UINT32 fSssNinch = 0; + _UINT32 fUlsNinch = 0; + _UINT32 fBlsNinch = 0; + _INT32 ich = 0; + _INT32 cch = 0; + _UINT16 iFnt = 0; //------------------------------------------------ GlobalWorkbookInfoPtr global_info; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp index c80ebba7abe..0c3bad5a250 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp @@ -124,7 +124,7 @@ int DXFN::serialize(std::wostream & stream) { if (ibitAtrFnt || (xfext && (xfext->mapRgExt.end() != xfext->mapRgExt.find(ExtProp::FontScheme)))) { - dxffntd.serialize(CP_XML_STREAM()); + dxffntd.serialize(CP_XML_STREAM(), ibitAtrFnt == false); } if(ibitAtrNum) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h index 3a92ac9dfdb..f601576bc3d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h @@ -48,7 +48,7 @@ class ExtProp : public BiffStructure virtual void load(CFRecord& record); - static const ElementType type = typeExtProp; + static const ElementType type = typeExtProp; unsigned short cb; @@ -72,8 +72,8 @@ class ExtProp : public BiffStructure { FullColorExt color; XFExtGradient gradient_fill; - unsigned char font_scheme; - unsigned short indent_level; + unsigned char font_scheme = 0; + unsigned short indent_level = 0; } extPropData; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h index e29191fc84c..d707b102fa8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h @@ -49,11 +49,11 @@ class FullColorExt : public BiffStructure virtual void load(CFRecord& record); int serialize(std::wostream & stream, const std::wstring &sNode); - static const ElementType type = typeFullColorExt; + static const ElementType type = typeFullColorExt; - unsigned short xclrType; - short nTintShade; - _UINT32 xclrValue; + unsigned short xclrType = 0; + short nTintShade = 0; + _UINT32 xclrValue = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h index d5eac707798..230b81b0b4a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h @@ -49,15 +49,14 @@ class Stxp : public BiffStructure virtual void load(CFRecord& record); - - int twpHeight; + int twpHeight = 0; Ts ts; - short bls; - short sss; + short bls = 0; + short sss = 0; - unsigned char uls; - unsigned char bFamily; - unsigned char bCharSet; + unsigned char uls = 0; + unsigned char bFamily = 0; + unsigned char bCharSet = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h index 4ba604eb83c..23482a781e4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h @@ -53,7 +53,7 @@ class XFExtGradient : public BiffStructure static const ElementType type = typeXFExtGradient; XFPropGradient gradient; - _UINT32 cGradStops; + _UINT32 cGradStops = 0; std::vector<GradStop> rgGradStops; }; From 4eaf500040c89e2f47da70977c84efd41e10e82a Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 30 May 2024 23:20:35 +0600 Subject: [PATCH 729/794] Fix bug #65172 --- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 4 ++-- OOXML/XlsbFormat/Xlsb.cpp | 20 +++++++++++++++----- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index bdd0eb0e1e3..46c4db44ba3 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -359,6 +359,7 @@ namespace OOX } else if ((sName == L"dataDisplayOptions16") && (false == oReader.IsEmptyNode())) { + m_sAdditionalNamespace = L"xmlns:c16r3=\"http://schemas.microsoft.com/office/drawing/2017/03/chart\""; int nCurDepth1 = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nCurDepth1)) { @@ -597,8 +598,7 @@ namespace OOX writer.StartNode(L"c16r3:dispNaAsBlank"); writer.StartAttributes(); writer.WriteAttribute(L"val", *m_oDataDisplayNaAsBlank); - writer.EndAttributes(); - writer.EndNode(L"c16r3:dispNaAsBlank"); + writer.EndAttributesAndNode(); writer.EndNode(L"c16r3:dataDisplayOptions16"); sResult += writer.GetData().c_str(); } diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index b229dc7ba09..81a5d08fda4 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -268,11 +268,9 @@ void OOX::Spreadsheet::CXlsb::WriteSheet(CWorksheet* worksheet) } void OOX::Spreadsheet::CXlsb::PrepareTableFormula() { - for(auto &worksheet : m_arWorksheets) - { - auto lambdaFormula = [&](std::wstring& formula) { + auto lambdaFormula = [&](std::wstring& formula) { auto str = STR::guidFromStr(formula); - if(!str.empty()) + while(!str.empty()) { auto guidTableIndex = this->xls_global_info->mapTableGuidsIndex.find(str); if (guidTableIndex != this->xls_global_info->mapTableGuidsIndex.end()) @@ -284,9 +282,11 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() formula.replace(formula.find(str), str.size(), tableName); } } + str = STR::guidFromStr(formula); } }; - + for(auto &worksheet : m_arWorksheets) + { if(worksheet->m_oTableParts.IsInit()) { for(size_t i = 0, length = worksheet->m_oTableParts->m_arrItems.size(); i < length; ++i) @@ -345,6 +345,16 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() }*/ } } + if(m_pWorkbook && m_pWorkbook->m_oDefinedNames.IsInit()) + { + for(auto defName:m_pWorkbook->m_oDefinedNames->m_arrItems) + { + if(defName->m_oRef.IsInit()) + { + lambdaFormula(defName->m_oRef.get()); + } + } + } } void OOX::Spreadsheet::CXlsb::LinkTables() diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 88b174f1593..b806fa472aa 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2426,7 +2426,7 @@ namespace OOX { m_oRow = ptr->m_Row; auto pCELLMETA = static_cast<XLSB::CELLMETA*>(ptr->m_CELLMETA.get()); - if(pCELLMETA != nullptr) + if(pCELLMETA != nullptr && false) // not convert without metadata file conversion { auto pCellMeta = static_cast<XLSB::CellMeta*>(pCELLMETA->m_BrtCellMeta.get()); if(pCellMeta != nullptr && pCellMeta->icmb) From 17bd0f99dd85d1f065f548c8b44ef5fe9e3fe1f4 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 31 May 2024 11:49:05 +0300 Subject: [PATCH 730/794] Fix default color --- PdfFile/PdfEditor.cpp | 61 +++++++++++--------------------- PdfFile/SrcWriter/Annotation.cpp | 5 ++- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 4e2635d2362..bc6114f0b07 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -62,17 +62,17 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, { bool b = obj->getBool(); AddToObject(b) - break; + break; } case objInt: { AddToObject(obj->getInt()) - break; + break; } case objReal: { AddToObject(obj->getReal()) - break; + break; } case objString: { @@ -98,18 +98,17 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, case objName: { AddToObject(obj->getName()) - break; + break; } case objNull: { AddToObject(new PdfWriter::CNullObject()) - break; + break; } case objArray: { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); AddToObject(pArray) - for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) { obj->arrayGetNF(nIndex, &oTemp); @@ -122,7 +121,6 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, { PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); AddToObject(pDict); - for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) { char* chKey = obj->dictGetKey(nIndex); @@ -137,12 +135,12 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); pBase->SetRef(obj->getRefNum(), obj->getRefGen()); AddToObject(new PdfWriter::CProxyObject(pBase, true)) - break; + break; } case objNone: { AddToObject("None") - break; + break; } case objStream: case objCmd: @@ -153,15 +151,14 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, } PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) { + if (!pParentRef || !pParentRef->isRef() || !pdfDoc) + return NULL; PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum()); if (pParent) return pParent; - if (!pParentRef || !pParentRef->isRef() || !pdfDoc) - return pParent; - XRef* xref = pdfDoc->getXRef(); Object oParent; - if (!pParentRef->fetch(xref, &oParent)->isDict()) + if (!pParentRef->fetch(pdfDoc->getXRef(), &oParent)->isDict()) { oParent.free(); return pParent; @@ -200,7 +197,6 @@ PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pD } oParent.free(); - return pParent; } HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter) @@ -525,19 +521,16 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa // Получение каталога и дерева страниц из reader Object catDict, catRefObj, pagesRefObj; - if (!xref->getCatalog(&catDict) || !catDict.isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) + if (!xref->getCatalog(&catDict)->isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) { - pagesRefObj.free(); - catDict.free(); + pagesRefObj.free(); catDict.free(); nError = 3; // Не удалось получить каталог и дерево страниц return; } Object* trailer = xref->getTrailerDict(); - if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj) || !catRefObj.isRef()) + if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj)->isRef()) { - pagesRefObj.free(); - catDict.free(); - catRefObj.free(); + pagesRefObj.free(); catDict.free(); catRefObj.free(); nError = 3; // Не удалось получить каталог и дерево страниц return; } @@ -548,17 +541,14 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, catRef.num); if (!pXref) { - pagesRefObj.free(); - catDict.free(); + pagesRefObj.free(); catDict.free(); nError = 1; return; } PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); if (!pCatalog) { - pagesRefObj.free(); - catDict.free(); - RELEASEOBJECT(pXref); + pagesRefObj.free(); catDict.free(); RELEASEOBJECT(pXref); nError = 1; return; } @@ -580,8 +570,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa char* chKey = oAcroForm.dictGetKey(nIndex); if (strcmp("DR", chKey) == 0) { - oAcroForm.dictGetVal(nIndex, &oTemp2); - if (!oTemp2.isDict()) + if (!oAcroForm.dictGetVal(nIndex, &oTemp2)->isDict()) { oTemp2.free(); continue; @@ -601,9 +590,9 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa for (int nIndex2 = 0; nIndex2 < oTemp2.dictGetLength(); ++nIndex2) { Object oTemp; - char* chKey = oTemp2.dictGetKey(nIndex2); + char* chKey2 = oTemp2.dictGetKey(nIndex2); oTemp2.dictGetVal(nIndex2, &oTemp); - DictToCDictObject(&oTemp, pDR, false, chKey); + DictToCDictObject(&oTemp, pDR, false, chKey2); oTemp.free(); } oTemp2.free(); @@ -835,22 +824,14 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj) if (!pPagesRefObj || !xref || !pDoc) return; - Object typeDict, pagesObj; - if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict()) - { - pagesObj.free(); - return; - } - if (pagesObj.dictLookup("Type", &typeDict)->isName() && !typeDict.isName("Pages")) + Object pagesObj; + if (!pPagesRefObj->isRef() || !pPagesRefObj->fetch(xref, &pagesObj)->isDict("Pages")) { pagesObj.free(); - typeDict.free(); return; } - typeDict.free(); Ref topPagesRef = pPagesRefObj->getRef(); - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); if (!pXref) { diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 7c6f2ba1847..3b3db864c95 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1075,7 +1075,10 @@ namespace PdfWriter CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); const char* sFontName = pFieldsResources->GetFontName(pFont); - std::string sDA = GetColor(arrC, false); + std::vector<double> _arrC = arrC; + if (arrC.empty()) + _arrC = {0}; + std::string sDA = GetColor(_arrC, false); if (sFontName) { sDA.append(" /"); From 600fd26e30da901d7543420d1b9b72de55a497e3 Mon Sep 17 00:00:00 2001 From: Elena Subbotina <Elena.Subbotina@onlyoffice.com> Date: Fri, 31 May 2024 13:45:15 +0300 Subject: [PATCH 731/794] fix build --- MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp index 8c55bdc17cf..a0fe84b4c2c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.cpp @@ -79,7 +79,7 @@ void FileSharing::writeFields(CFRecord& record) record << fReadOnlyRec; else { - UINT16 defaulTRec = 0; + _UINT16 defaulTRec = 0; record << defaulTRec; } if(!wResPass.empty()) From 742cfde6200cd315547c921bfc069df20e4359bc Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 31 May 2024 16:39:41 +0300 Subject: [PATCH 732/794] Fix rotate point --- PdfFile/PdfWriter.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index f54c646b5e4..ff6056a5436 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -3221,6 +3221,8 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w if (m_pDocument->HasImage(wsTexturePath, nAlpha)) { pImage = m_pDocument->GetImage(wsTexturePath, nAlpha); + nImageH = pImage->GetHeight(); + nImageW = pImage->GetWidth(); } else if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) { @@ -3333,15 +3335,16 @@ void CPdfWriter::UpdateBrush(NSFonts::IApplicationFonts* pAppFonts, const std::w // Размеры картинки заданы в пикселях. Размеры тайла - это размеры картинки в пунктах. dW = (double)nImageW * 72.0 / 96.0; dH = (double)nImageH * 72.0 / 96.0; + + dT = dB; } // Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования. PdfWriter::CMatrix* pMatrix = m_pPage->GetTransform(); pMatrix->Apply(dL, dT); - pMatrix->Apply(dR, dB); PdfWriter::CMatrix oPatternMatrix = *pMatrix; oPatternMatrix.x = dL; - oPatternMatrix.y = c_BrushTextureModeStretch == lTextureMode ? dT : dB; + oPatternMatrix.y = dT; m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage, &oPatternMatrix, PdfWriter::imagetilepatterntype_Default, dXStepSpacing, dYStepSpacing)); } } From 7a1a59a88334b6498cb2dae32a08c1de82b2a4cb Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Sun, 2 Jun 2024 10:20:52 +0300 Subject: [PATCH 733/794] For bug 68028 --- DesktopEditor/fontengine/js/libfont.json | 4 ++- .../EmfInterpretator/CEmfInterpretatorSvg.cpp | 2 ++ .../CInterpretatorSvgBase.cpp | 2 ++ .../Metafile/test/MetafileToSvg/main.cpp | 34 +++++++++---------- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/DesktopEditor/fontengine/js/libfont.json b/DesktopEditor/fontengine/js/libfont.json index d720f09f4c4..3d4028e04b4 100644 --- a/DesktopEditor/fontengine/js/libfont.json +++ b/DesktopEditor/fontengine/js/libfont.json @@ -110,7 +110,9 @@ "_getcwd=getcwd", "NO_CONSOLE_IO", "BUILD_ZLIB_AS_SOURCES", - "IMAGE_CHECKER_DISABLE_XML" + "IMAGE_CHECKER_DISABLE_XML", + + "BUILDING_WASM_MODULE" ], "compile_files_array": [ { diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp index dc66cba25d9..e3d1d134337 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp @@ -1169,6 +1169,7 @@ namespace MetaFile std::wstring wsFontName = pFont->GetFaceName(); +#ifndef BUILDING_WASM_MODULE if (!wsFontName.empty()) { NSFonts::CFontSelectFormat oFormat; @@ -1179,6 +1180,7 @@ namespace MetaFile if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; } +#endif if (!wsFontName.empty()) arNodeAttributes.push_back({L"font-family", wsFontName}); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index 57a4d1e134d..1c860b7517e 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -283,6 +283,7 @@ namespace MetaFile std::wstring wsFontName = pFont->GetFaceName(); +#ifndef BUILDING_WASM_MODULE if (!wsFontName.empty()) { NSFonts::CFontSelectFormat oFormat; @@ -293,6 +294,7 @@ namespace MetaFile if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; } +#endif if (!wsFontName.empty()) arNodeAttributes.push_back({L"font-family", wsFontName}); diff --git a/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp b/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp index 05c54979c33..ca3c658d0e6 100644 --- a/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp +++ b/DesktopEditor/raster/Metafile/test/MetafileToSvg/main.cpp @@ -29,35 +29,33 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -//#include <QCoreApplication> +// #include <QCoreApplication> +#include "../../../../fontengine/ApplicationFontsWorker.h" #include "../../../../graphics/pro/Fonts.h" #include "../../../../graphics/pro/Graphics.h" -#include "../../../../fontengine/ApplicationFontsWorker.h" -#include "../../../../raster/BgraFrame.h" #include "../../../../common/Directory.h" +#include "../../../../raster/BgraFrame.h" -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - // Check system fonts - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); + // Check system fonts + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker.m_bIsNeedThumbnails = false; - NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + if (!NSDirectory::Exists(oWorker.m_sDirectory)) + NSDirectory::CreateDirectory(oWorker.m_sDirectory); - MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); - pMetafile->LoadFromFile(L"PATH_TO_METAFILE"); + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); - std::wstring wsData; + MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts); + pMetafile->LoadFromFile(L"D:/image1.wmf"); - pMetafile->ConvertToSvg(wsData); + std::wstring wsData = pMetafile->ConvertToSvg(); pMetafile->Release(); - pFonts->Release(); - return 0; + pFonts->Release(); + return 0; } From cd5ca284e1b0a4e1bd3d1bb62888c880cbdffcfe Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Sun, 2 Jun 2024 15:37:04 +0300 Subject: [PATCH 734/794] Change IsDouble method: return true if value has integer type --- DesktopEditor/doctrenderer/json/json_values.cpp | 2 +- DesktopEditor/doctrenderer/test/json/main.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp index 049ef75531e..3b745cbbb8e 100644 --- a/DesktopEditor/doctrenderer/json/json_values.cpp +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -65,7 +65,7 @@ namespace NSJSON bool CPrimitive::isDouble() const { - return m_type == ptDouble; + return m_type == ptDouble || m_type == ptInteger; } bool CPrimitive::isStringA() const diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp index 021e7341d91..be3ada49085 100644 --- a/DesktopEditor/doctrenderer/test/json/main.cpp +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -247,7 +247,8 @@ TEST_F(CJSONTest, bool_) TEST_F(CJSONTest, int_) { CValue val = 42; - EXPECT_FALSE(val.IsDouble()); + EXPECT_TRUE(val.IsDouble()); + EXPECT_TRUE(val.IsInt()); JSSmart<CJSValue> jsVal = CJSContext::createInt(42); EXPECT_TRUE(compare(val, jsVal)); val = 100; From d83930bf67626394937043ec9c9d79ddd578b7a9 Mon Sep 17 00:00:00 2001 From: Elena Subbotina <Elena.Subbotina@onlyoffice.com> Date: Sun, 2 Jun 2024 16:59:20 +0300 Subject: [PATCH 735/794] fix bug #68307 --- MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index 3f8de98f722..831f83be9a2 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -182,6 +182,12 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring& strInput, const st } if (strExts == L".tmp" || strExts.empty()) strExts = strDefaultExt; + if (strDefaultExt == L"sfil") + { + strExts = L".wav"; + //todooo - detect format by file + } + std::wstring strMediaName = Template + std::to_wstring(++Indexer); std::wstring strOutput = m_strDstMedia + strMediaName + strExts; From 803fcf360262f2a269636ed352ad912f5df1332e Mon Sep 17 00:00:00 2001 From: Elena Subbotina <Elena.Subbotina@onlyoffice.com> Date: Sun, 2 Jun 2024 17:35:48 +0300 Subject: [PATCH 736/794] fix bug #68304 --- OdfFile/Writer/Converter/ConvertDrawing.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 590eb17451e..ef306f719be 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -451,6 +451,11 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) } //-------------------------------------------------------------------------------------- odf_ref_image = bExternal ? pathImage : odf_context()->add_image(pathImage); + + if (bExternal && std::wstring::npos == odf_ref_image.find(L"\\") && std::wstring::npos == odf_ref_image.find(L"/")) + { + odf_ref_image = L"../" + odf_ref_image; + } odf_context()->drawing_context()->start_image(odf_ref_image); { From d843cf1fe1d229de0320373ed3aa0ddb3ce76de3 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov <kamil.kerimov@onlyoffice.com> Date: Wed, 29 May 2024 17:11:42 +0500 Subject: [PATCH 737/794] Fix bug #63489 Convert text divided into columns --- OdfFile/Reader/Converter/oox_drawing.cpp | 7 ++++++ OdfFile/Reader/Format/draw_frame_pptx.cpp | 3 +++ .../Format/style_graphic_properties.cpp | 7 +++--- .../Reader/Format/style_graphic_properties.h | 1 + OdfFile/Reader/Format/styles.cpp | 9 ++++++++ OdfFile/Reader/Format/styles.h | 2 ++ OdfFile/Writer/Converter/ConvertDrawing.cpp | 7 ++++-- OdfFile/Writer/Format/odf_drawing_context.cpp | 22 +++++++++++++++++++ OdfFile/Writer/Format/odf_drawing_context.h | 4 ++++ .../Format/style_graphic_properties.cpp | 8 +++++++ .../Writer/Format/style_graphic_properties.h | 5 +++++ .../Writer/Format/style_section_properties.h | 4 ++++ 12 files changed, 74 insertions(+), 5 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_drawing.cpp b/OdfFile/Reader/Converter/oox_drawing.cpp index 19b7ec51135..819f7160e16 100644 --- a/OdfFile/Reader/Converter/oox_drawing.cpp +++ b/OdfFile/Reader/Converter/oox_drawing.cpp @@ -579,16 +579,23 @@ void _oox_drawing::serialize_bodyPr(std::wostream & strm, const std::wstring & n CP_XML_NODE(namespace_ + L":bodyPr") { _CP_OPT(double)dPaddingLeft, dPaddingRight, dPaddingTop, dPaddingBottom; + _CP_OPT(int) numCol, spcCol; odf_reader::GetProperty(prop,L"text-padding-left" , dPaddingLeft); odf_reader::GetProperty(prop,L"text-padding-right" , dPaddingRight); odf_reader::GetProperty(prop,L"text-padding-top" , dPaddingTop); odf_reader::GetProperty(prop,L"text-padding-bottom" , dPaddingBottom); + odf_reader::GetProperty(prop, L"style_columns_count", numCol); + odf_reader::GetProperty(prop, L"style_columns_gap" , spcCol); + if (dPaddingLeft) CP_XML_ATTR(L"lIns", (int)(*dPaddingLeft)); if (dPaddingTop) CP_XML_ATTR(L"tIns", (int)(*dPaddingTop)); if (dPaddingRight) CP_XML_ATTR(L"rIns", (int)(*dPaddingRight)); if (dPaddingBottom) CP_XML_ATTR(L"bIns", (int)(*dPaddingBottom)); + CP_XML_ATTR_OPT(L"numCol" , numCol); + CP_XML_ATTR_OPT(L"spcCol" , spcCol); + if (inGroup == false) { _CP_OPT(bool) bAutoGrowWidth; diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index c4bc03f11d8..13bee1236f1 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -179,6 +179,9 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().set_property(odf_reader::_property(L"border_width_top", Compute_BorderWidth(properties, sideTop))); Context.get_slide_context().set_property(odf_reader::_property(L"border_width_right", Compute_BorderWidth(properties, sideRight))); Context.get_slide_context().set_property(odf_reader::_property(L"border_width_bottom", Compute_BorderWidth(properties, sideBottom))); + + if (properties->style_columns_) + properties->style_columns_->pptx_convert(Context); } Context.get_slide_context().set_fill(fill); diff --git a/OdfFile/Reader/Format/style_graphic_properties.cpp b/OdfFile/Reader/Format/style_graphic_properties.cpp index 99a0e223aad..485c2b29d2b 100644 --- a/OdfFile/Reader/Format/style_graphic_properties.cpp +++ b/OdfFile/Reader/Format/style_graphic_properties.cpp @@ -249,6 +249,7 @@ void graphic_format_properties::apply_from(const graphic_format_properties * Oth _CP_APPLY_PROP(style_background_image_, Other->style_background_image_); + _CP_APPLY_PROP(style_columns_, Other->style_columns_); } @@ -263,10 +264,10 @@ void style_graphic_properties::add_attributes( const xml::attributes_wc_ptr & At void style_graphic_properties::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { - if (L"style" == Ns && L"background-image" == Name) - { + if (L"style" == Ns && L"background-image" == Name) CP_CREATE_ELEMENT(content_.style_background_image_); - } + else if(L"style" == Ns && L"columns" == Name) + CP_CREATE_ELEMENT(content_.style_columns_); //if (CP_CHECK_NAME(L"text", L"list-style") // styles_.add_child_element(Reader, Ns, Name, getContext()); он тут и не нужен по сути... описание есть и в другом сместе diff --git a/OdfFile/Reader/Format/style_graphic_properties.h b/OdfFile/Reader/Format/style_graphic_properties.h index dafe02a5bfa..5c23a515538 100644 --- a/OdfFile/Reader/Format/style_graphic_properties.h +++ b/OdfFile/Reader/Format/style_graphic_properties.h @@ -131,6 +131,7 @@ class graphic_format_properties _CP_OPT(odf_types::wrap_option) fo_wrap_option_; office_element_ptr style_background_image_; + office_element_ptr style_columns_; }; typedef boost::shared_ptr<graphic_format_properties> graphic_format_properties_ptr; diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index df767c64426..54350581f67 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -867,6 +867,15 @@ void style_columns::add_child_element( xml::sax * Reader, const std::wstring & N } } +void style_columns::pptx_convert(oox::pptx_conversion_context& Context) +{ + if(fo_column_count_) + Context.get_slide_context().set_property(odf_reader::_property(L"style_columns_count", (int)fo_column_count_.get())); + + if(fo_column_gap_) + Context.get_slide_context().set_property(odf_reader::_property(L"style_columns_gap", (int)fo_column_gap_->get_value_unit(length::emu))); +} + ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * style_column::ns = L"style"; const wchar_t * style_column::name = L"column"; diff --git a/OdfFile/Reader/Format/styles.h b/OdfFile/Reader/Format/styles.h index a68f51ff38d..4cf374d9dc5 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -676,6 +676,8 @@ class style_columns : public office_element_impl<style_columns> static const ElementType type = typeStyleColumns; CPDOCCORE_DEFINE_VISITABLE(); + virtual void pptx_convert(oox::pptx_conversion_context& Context); + private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index ef306f719be..69b6c8857a4 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -1680,8 +1680,11 @@ void OoxConverter::convert(PPTX::Logic::BodyPr *oox_bodyPr) if ((oox_bodyPr->numCol.IsInit()) && (oox_bodyPr->numCol.get() > 1)) { - //+ style section - //+element text:section в котором параграфы + int cols = oox_bodyPr->numCol.get(); + int gap_cms = oox_bodyPr->spcCol.IsInit() ? oox_bodyPr->spcCol.get() / 360000 : 0; + + odf_context()->drawing_context()->start_style_columns(cols, gap_cms); + odf_context()->drawing_context()->end_style_columns(); } if (oox_bodyPr->rot.IsInit()) { diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index ef9018a1bb2..7bd677c38a3 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -3173,6 +3173,28 @@ void odf_drawing_context::end_action() end_element(); end_element(); } + +void odf_drawing_context::start_style_columns(int cols, int gap) +{ + graphic_format_properties* graphic_props = get_graphic_properties(); + if (!graphic_props) + return; + + if (!graphic_props->style_columns_) + graphic_props->style_columns_ = boost::make_shared<style_columns>(); + + graphic_props->style_columns_->fo_column_count_ = cols; + graphic_props->style_columns_->fo_column_gap_ = length(gap, length::cm); +} + +void odf_drawing_context::add_style_column() +{ +} + +void odf_drawing_context::end_style_columns() +{ +} + void odf_drawing_context::set_text_box_min_size(double w_pt, double h_pt) { if (impl_->current_drawing_state_.elements_.empty()) return; diff --git a/OdfFile/Writer/Format/odf_drawing_context.h b/OdfFile/Writer/Format/odf_drawing_context.h index c38725eb433..28949e0cf82 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.h +++ b/OdfFile/Writer/Format/odf_drawing_context.h @@ -322,6 +322,10 @@ class odf_drawing_context void add_link (std::wstring href); void end_action(); + void start_style_columns(int cols, int gap); + void add_style_column(); + void end_style_columns(); + private: class Impl; _CP_PTR(Impl) impl_; diff --git a/OdfFile/Writer/Format/style_graphic_properties.cpp b/OdfFile/Writer/Format/style_graphic_properties.cpp index 6a4743b41ca..6bc7e7f32ed 100644 --- a/OdfFile/Writer/Format/style_graphic_properties.cpp +++ b/OdfFile/Writer/Format/style_graphic_properties.cpp @@ -110,6 +110,11 @@ void graphic_format_properties::apply_from(const graphic_format_properties & Oth _CP_APPLY_PROP(style_background_image_, Other.style_background_image_); } +void graphic_format_properties::add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) +{ + +} + void graphic_format_properties::serialize(std::wostream & _Wostream ,const wchar_t * ns, const wchar_t * name ) { CP_XML_WRITER(_Wostream) @@ -175,6 +180,9 @@ void graphic_format_properties::serialize(std::wostream & _Wostream ,const wchar common_border_line_width_attlist_.serialize(CP_GET_XML_NODE()); common_padding_attlist_.serialize(CP_GET_XML_NODE()); common_background_color_attlist_.serialize(CP_GET_XML_NODE()); + + if(style_columns_) + style_columns_->serialize(CP_XML_STREAM()); } } } diff --git a/OdfFile/Writer/Format/style_graphic_properties.h b/OdfFile/Writer/Format/style_graphic_properties.h index d8f97ba0459..6095cbdb440 100644 --- a/OdfFile/Writer/Format/style_graphic_properties.h +++ b/OdfFile/Writer/Format/style_graphic_properties.h @@ -38,6 +38,7 @@ #include <xml/nodetype.h> #include "office_elements_create.h" +#include "style_section_properties.h" #include "../../DataTypes/common_attlists.h" #include "../../DataTypes/lengthorpercent.h" @@ -66,6 +67,8 @@ class graphic_format_properties graphic_format_properties(); //for defaults set void apply_from(const graphic_format_properties & Other); + void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); + void serialize(std::wostream & strm, const wchar_t * ns, const wchar_t * name ); _CP_OPT(odf_types::length_or_percent) fo_min_width_; @@ -140,8 +143,10 @@ class graphic_format_properties _CP_OPT(std::wstring) style_mirror_; _CP_OPT(std::wstring) fo_clip_; + //------------------------------------------------------------------------------------- office_element_ptr style_background_image_; + style_columns_ptr style_columns_; }; typedef boost::shared_ptr<graphic_format_properties> graphic_format_properties_ptr; diff --git a/OdfFile/Writer/Format/style_section_properties.h b/OdfFile/Writer/Format/style_section_properties.h index 75847996a2a..670d9a176cf 100644 --- a/OdfFile/Writer/Format/style_section_properties.h +++ b/OdfFile/Writer/Format/style_section_properties.h @@ -67,6 +67,7 @@ class style_columns : public office_element_impl<style_columns> office_element_ptr_array style_column_; }; +typedef shared_ptr<style_columns>::Type style_columns_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_columns); @@ -91,6 +92,7 @@ class style_column : public office_element_impl<style_column> _CP_OPT(odf_types::length) fo_space_after_; }; +typedef shared_ptr<style_column>::Type style_column_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column); @@ -115,6 +117,7 @@ class style_column_sep : public office_element_impl<style_column_sep> _CP_OPT(odf_types::vertical_align) style_vertical_align_; // default top _CP_OPT(odf_types::color) style_color_; // default #000000 }; +typedef shared_ptr<style_column_sep>::Type style_column_sep_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column_sep); @@ -144,6 +147,7 @@ class style_section_properties : public office_element_impl<style_section_proper office_element_ptr style_columns_; office_element_ptr style_background_image_; }; +typedef shared_ptr<style_section_properties>::Type style_section_properties_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_section_properties); } From acbf5b0c400cdaad69be722671663dd47309f616 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov <kamil.kerimov@onlyoffice.com> Date: Wed, 29 May 2024 17:14:10 +0500 Subject: [PATCH 738/794] Fix bug #68170 Add image alternative text and description --- OdfFile/Common/odf_elements_type.h | 1 + OdfFile/Reader/Converter/docx_drawing.cpp | 14 ++++++++ OdfFile/Reader/Format/draw_frame.cpp | 8 +++++ OdfFile/Reader/Format/draw_frame.h | 3 ++ OdfFile/Reader/Format/draw_frame_docx.cpp | 5 +++ OdfFile/Reader/Format/font_face.cpp | 44 +++++++++++++++++++++++ OdfFile/Reader/Format/font_face.h | 27 ++++++++++++++ 7 files changed, 102 insertions(+) diff --git a/OdfFile/Common/odf_elements_type.h b/OdfFile/Common/odf_elements_type.h index f1032012248..cc0aa85cd9a 100644 --- a/OdfFile/Common/odf_elements_type.h +++ b/OdfFile/Common/odf_elements_type.h @@ -307,6 +307,7 @@ enum ElementType typeStyleFontFace, + typeSvgTitle, typeSvgDesc, typeSvgFontFaceUri, typeSvgFontFaceFormat, diff --git a/OdfFile/Reader/Converter/docx_drawing.cpp b/OdfFile/Reader/Converter/docx_drawing.cpp index f4bdd4e3e28..4499362aeda 100644 --- a/OdfFile/Reader/Converter/docx_drawing.cpp +++ b/OdfFile/Reader/Converter/docx_drawing.cpp @@ -288,9 +288,16 @@ void docx_serialize_image_child(std::wostream & strm, _docx_drawing & val) { CP_XML_NODE(L"pic:cNvPr") { + _CP_OPT(std::wstring) title, descr; + GetProperty(val.additional, L"svg:title", title); + GetProperty(val.additional, L"svg:desc", descr); + //CP_XML_ATTR(L"desc text",L""); CP_XML_ATTR(L"id", val.id + 1); CP_XML_ATTR(L"name", val.name); + + CP_XML_ATTR_OPT(L"title", title); + CP_XML_ATTR_OPT(L"descr", descr); //oox_serialize_action(CP_XML_STREAM(), val.action); } @@ -399,8 +406,15 @@ void docx_serialize_common(std::wostream & strm, _docx_drawing & val) { CP_XML_NODE(L"wp:docPr") { + _CP_OPT(std::wstring) title, descr; + GetProperty(val.additional, L"svg:title", title); + GetProperty(val.additional, L"svg:desc", descr); + CP_XML_ATTR(L"name", val.name); CP_XML_ATTR(L"id", 0xf000 + val.id + 1); + + CP_XML_ATTR_OPT(L"title", title); + CP_XML_ATTR_OPT(L"descr", descr); oox_serialize_action(CP_XML_STREAM(), val.action); } diff --git a/OdfFile/Reader/Format/draw_frame.cpp b/OdfFile/Reader/Format/draw_frame.cpp index 89eed08178e..53a0079c753 100644 --- a/OdfFile/Reader/Format/draw_frame.cpp +++ b/OdfFile/Reader/Format/draw_frame.cpp @@ -299,6 +299,14 @@ void draw_frame::add_child_element( xml::sax * Reader, const std::wstring & Ns, { CP_CREATE_ELEMENT(draw_contour_); } + else if (CP_CHECK_NAME(L"svg", L"title")) + { + CP_CREATE_ELEMENT(svg_title_); + } + else if (CP_CHECK_NAME(L"svg", L"desc")) + { + CP_CREATE_ELEMENT(svg_desc_); + } else { CP_NOT_APPLICABLE_ELM(); diff --git a/OdfFile/Reader/Format/draw_frame.h b/OdfFile/Reader/Format/draw_frame.h index 0a8dbe524ee..6325d12a709 100644 --- a/OdfFile/Reader/Format/draw_frame.h +++ b/OdfFile/Reader/Format/draw_frame.h @@ -177,6 +177,9 @@ class draw_frame : public office_element_impl<draw_frame> office_element_ptr draw_contour_; // draw-contour-polygon or draw-contour-path + office_element_ptr svg_title_; + office_element_ptr svg_desc_; + friend class odf_document; friend class draw_image; friend class draw_chart; diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index d66a4a97da2..010bc35fe7e 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -1578,6 +1578,11 @@ void draw_frame::docx_convert(oox::docx_conversion_context & Context) drawing->id = Context.get_drawing_context().get_current_frame_id(); drawing->name = Context.get_drawing_context().get_current_object_name(); drawing->inGroup = Context.get_drawing_context().in_group(); + + if (svg_title_) + svg_title_->docx_convert(Context); + if(svg_desc_) + svg_desc_->docx_convert(Context); common_draw_docx_convert(Context, common_draw_attlists_, drawing); //----------------------------------------------------------------------------------------------------- diff --git a/OdfFile/Reader/Format/font_face.cpp b/OdfFile/Reader/Format/font_face.cpp index cc8982460aa..f2bbd64a754 100644 --- a/OdfFile/Reader/Format/font_face.cpp +++ b/OdfFile/Reader/Format/font_face.cpp @@ -32,15 +32,59 @@ #include "font_face.h" +#include "draw_frame.h" + #include <xml/xmlchar.h> #include "serialize_elements.h" namespace cpdoccore { namespace odf_reader { +// svg:title +//--------------------------------------------------------------------------------------- +const wchar_t* svg_title::ns = L"svg"; +const wchar_t* svg_title::name = L"title"; + +void svg_title::docx_convert(oox::docx_conversion_context& Context) +{ + odf_reader::draw_frame* current_frame = Context.get_drawing_context().get_current_frame(); + + if (current_frame && current_frame->oox_drawing_) + { + current_frame->oox_drawing_->additional.push_back(odf_reader::_property(L"svg:title", text_)); + } +} + +std::wostream& svg_title::text_to_stream(std::wostream& _Wostream, bool bXmlEncode) const +{ + _Wostream << text_; + return _Wostream; +} + +void svg_title::add_text(const std::wstring& Text) +{ + text_ += Text; +} +void svg_title::add_space(const std::wstring& Text) +{ + text_ += Text; +} +// svg:desc +//--------------------------------------------------------------------------------------- + const wchar_t * svg_desc::ns = L"svg"; const wchar_t * svg_desc::name = L"desc"; +void svg_desc::docx_convert(oox::docx_conversion_context& Context) +{ + odf_reader::draw_frame* current_frame = Context.get_drawing_context().get_current_frame(); + + if (current_frame && current_frame->oox_drawing_) + { + current_frame->oox_drawing_->additional.push_back(odf_reader::_property(L"svg:desc", text_)); + } +} + std::wostream & svg_desc::text_to_stream(std::wostream & _Wostream, bool bXmlEncode) const { _Wostream << text_ ; diff --git a/OdfFile/Reader/Format/font_face.h b/OdfFile/Reader/Format/font_face.h index 5c78d56b4bd..7ff84f9b132 100644 --- a/OdfFile/Reader/Format/font_face.h +++ b/OdfFile/Reader/Format/font_face.h @@ -78,6 +78,31 @@ class svg_font_face_uri : public office_element_impl<svg_font_face_uri> }; CP_REGISTER_OFFICE_ELEMENT2(svg_font_face_uri); +// svg:title +class svg_title : public office_element_impl<svg_title> +{ +public: + static const wchar_t* ns; + static const wchar_t* name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeSvgTitle; + + CPDOCCORE_DEFINE_VISITABLE(); + + void docx_convert(oox::docx_conversion_context& Context); + + virtual std::wostream& text_to_stream(std::wostream& _Wostream, bool bXmlEncode = true) const; + + std::wstring text_; + +private: + virtual void add_attributes(const xml::attributes_wc_ptr& Attributes) {} + virtual void add_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name) {} + virtual void add_text(const std::wstring& Text); + virtual void add_space(const std::wstring& Text); +}; +CP_REGISTER_OFFICE_ELEMENT2(svg_title); + // svg:desc class svg_desc : public office_element_impl<svg_desc> { @@ -89,6 +114,8 @@ class svg_desc : public office_element_impl<svg_desc> CPDOCCORE_DEFINE_VISITABLE(); + void docx_convert(oox::docx_conversion_context& Context); + virtual std::wostream & text_to_stream(std::wostream & _Wostream, bool bXmlEncode = true) const; std::wstring text_; From 7c501fe5a3cd6173a3537d748f0458b0b9d82227 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Mon, 3 Jun 2024 12:06:29 +0300 Subject: [PATCH 739/794] Fix bug #68252 --- .../html/css/src/CCssCalculator_Private.cpp | 10 +- .../3dParty/html/css/src/StyleProperties.cpp | 8 +- .../html/css/src/xhtml/CDocumentStyle.cpp | 13 +- .../html/css/src/xhtml/CXmlElement.cpp | 14 +-- HtmlFile2/htmlfile2.cpp | 116 +++++++++++------- 5 files changed, 96 insertions(+), 65 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index d4d6621dba2..fd4852a583c 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -510,22 +510,22 @@ namespace NSCSS std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors); std::vector<std::wstring> arPrevNodes; bool bInTable = false; - + for (size_t i = 0; i < arSelectors.size(); ++i) { oStyle.AddParent(arSelectors[i].m_wsName); // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются if (L"table" == arSelectors[i].m_wsName) + bInTable = true; + + if (bInTable) { oStyle.m_oFont.GetLineHeight().Clear(); oStyle.m_oPadding.Clear(); oStyle.m_oMargin.Clear(); - bInTable = true; - } - - if (bInTable) oStyle.m_oBorder.Clear(); + } CCompiledStyle oTempStyle; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c380779c338..786f5e09578 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -2009,10 +2009,10 @@ namespace NSCSS CIndent &CIndent::operator+=(const CIndent &oIndent) { - m_oTop = oIndent.m_oTop; - m_oRight = oIndent.m_oRight; - m_oBottom = oIndent.m_oBottom; - m_oLeft = oIndent.m_oLeft; + if (!oIndent.m_oTop.Empty()) m_oTop = oIndent.m_oTop; + if (!oIndent.m_oRight.Empty()) m_oRight = oIndent.m_oRight; + if (!oIndent.m_oBottom.Empty()) m_oBottom = oIndent.m_oBottom; + if (!oIndent.m_oLeft.Empty()) m_oLeft = oIndent.m_oLeft; return *this; } diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index 1c51ef95002..a326c97f393 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -11,6 +11,11 @@ #define DEFAULT_LINEHEIGHT 240 #define LINEHEIGHTSCALE 10 // Значение LineHeight в OOXML должно быть в 10 раз больше чем указано в стиле +#define VALUE_TO_INT(value, unit_measure) \ + (NSCSS::UnitMeasure::None != value.GetUnitMeasure()) ? \ + value.ToInt(unit_measure) : \ + static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(value.ToDouble(), unit_measure, 96) + 0.5) + namespace NSCSS { CStyleUsed::CStyleUsed(const CCompiledStyle &oStyle, bool bIsPStyle) @@ -336,10 +341,12 @@ namespace NSCSS sSpacingValue.reserve(128); if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero()) - sSpacingValue += L"w:before=\"" + std::to_wstring(oStyle.m_oMargin.GetTop().ToInt(NSCSS::Twips)) + L"\" "; + sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"0\" "; if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero()) - sSpacingValue += L"w:after=\"" + std::to_wstring(oStyle.m_oMargin.GetBottom().ToInt(NSCSS::Twips)) + L"\" "; + sSpacingValue += L"w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"0\" "; + else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable) + sSpacingValue += L"w:after=\"0\" "; if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero()) { @@ -348,6 +355,8 @@ namespace NSCSS sSpacingValue += L" w:line=\"" + wsLine + L"\" w:lineRule=\"" + wsLineRule + L"\""; } + else if (oStyle.m_oFont.GetLineHeight().Zero() || bInTable) + sSpacingValue += L"w:lineRule=\"auto\" w:line=\"240\""; if (!sSpacingValue.empty()) oXmlElement.AddPropertiesInP(PProperties::P_Spacing, sSpacingValue); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index 199e1f2dd4b..cd997a203e0 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -45,7 +45,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true"); AddBasicProperties(CSSProperties::BasicProperties::B_SemiHidden, L"true"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"li") { @@ -67,7 +67,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"0"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h2") { @@ -78,7 +78,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"1"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h3") { @@ -89,7 +89,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"2"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h4") { @@ -100,7 +100,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"3"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h5") { @@ -111,7 +111,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"4"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h6") @@ -123,7 +123,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6-c"); AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"5"); - AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); +// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\""); } else if (sNameDefaultElement == L"h1-c") { diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 7186380400f..090face8322 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -174,6 +174,7 @@ typedef enum struct TTableStyles { NSCSS::NSProperties::CIndent m_oPadding; + NSCSS::NSProperties::CIndent m_oMargin; NSCSS::NSProperties::CBorder m_oBorder; NSCSS::NSProperties::CDigit m_oWidth; @@ -188,7 +189,7 @@ struct TTableStyles bool Empty() const { - return m_oPadding.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && false == m_bHaveBorderAttribute && m_wsAlign.empty(); + return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && false == m_bHaveBorderAttribute && m_wsAlign.empty(); } }; @@ -665,6 +666,11 @@ class CTable m_oStyles.m_oPadding = oPadding; } + void SetMargin(const NSCSS::NSProperties::CIndent& oMargin) + { + m_oStyles.m_oMargin = oMargin; + } + const NSCSS::NSProperties::CIndent& GetPadding() const { return m_oStyles.m_oPadding; @@ -791,19 +797,19 @@ class CTable if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) oTable += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>"; else - { - int nWidth; - if (NSCSS::UnitMeasure::None != m_oStyles.m_oWidth.GetUnitMeasure()) - nWidth = m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips); - else - nWidth = static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(m_oStyles.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5); - - oTable += L"<w:tblW w:w=\"" + std::to_wstring(nWidth) + L"\" w:type=\"dxa\"/>"; - } + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>"; } else oTable += L"<w:tblW w:w=\"0\" w:type=\"auto\"/>"; + if (!m_oStyles.m_oMargin.GetLeft().Empty() && !m_oStyles.m_oMargin.GetLeft().Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oMargin.GetLeft().GetUnitMeasure()) + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>"; + else + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>"; + } + if (!m_oStyles.m_wsAlign.empty()) oTable += L"<w:jc w:val=\"" + m_oStyles.m_wsAlign + L"\"/>"; @@ -1176,7 +1182,7 @@ class CHtmlFile2_Private m_oStylesXml += L"<w:lang w:val=\"" + ((!wsCurrentLanguage.empty()) ? wsCurrentLanguage : DEFAULT_LANGUAGE) + L"\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\"/>"; m_oStylesXml += L"</w:rPr></w:rPrDefault>"; - m_oStylesXml += L"<w:pPrDefault><w:pPr><w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>"; +// m_oStylesXml += L"<w:pPrDefault><w:pPr><w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>"; } // normal по умолчанию @@ -1740,15 +1746,16 @@ class CHtmlFile2_Private readStream(&m_oDocXml, sSelectors, { false, false, true, false, -1, L"", L"" }); } - void readInside (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& sName) + bool readInside (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& sName) { + //TODO:: обработать все варианты return'а + if(sName == L"#text") { std::wstring sText = m_oLightReader.GetText(); - size_t find = sText.find_first_not_of(L" \n\t\r"); - if (find == std::wstring::npos) - return; + if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})) + return false; bool bInT = m_bInT; @@ -1812,7 +1819,7 @@ class CHtmlFile2_Private } if (sText.empty()) - return; + return true; } else ReplaceSpaces(sText); @@ -1834,11 +1841,11 @@ class CHtmlFile2_Private CloseR(oXml); } - return; + return true; } std::wstring sNote = GetSubClass(oXml, sSelectors); - + bool bResult = true; // Ссылка // Область ссылки if(sName == L"a" || sName == L"area") @@ -1849,7 +1856,7 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:b/><w:bCs/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Направление текста else if(sName == L"bdo") @@ -1862,21 +1869,21 @@ class CHtmlFile2_Private CTextSettings oTSBdo(oTS); oTSBdo.bBdo = (sDir == L"rtl"); - readStream(oXml, sSelectors, oTSBdo); + bResult = readStream(oXml, sSelectors, oTSBdo); } // Отмена направления текста else if(sName == L"bdi") { CTextSettings oTSBdo(oTS); oTSBdo.bBdo = false; - readStream(oXml, sSelectors, oTSBdo); + bResult = readStream(oXml, sSelectors, oTSBdo); } // Увеличивает размер шрифта else if(sName == L"big") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:sz w:val=\"26\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Перенос строки else if(sName == L"br") @@ -1898,7 +1905,7 @@ class CHtmlFile2_Private { CTextSettings oTSP(oTS); oTSP.AddPStyle(L"<w:jc w:val=\"center\"/>"); - readStream(oXml, sSelectors, oTSP); + bResult = readStream(oXml, sSelectors, oTSP); } // Цитата, обычно выделяется курсивом // Новый термин, обычно выделяется курсивом @@ -1909,7 +1916,7 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:i/><w:iCs/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Код // Моноширинный шрифт, например, Consolas @@ -1918,14 +1925,14 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Зачеркнутый текст else if(sName == L"del" || sName == L"s") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:strike/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } else if(sName == L"font") { @@ -1966,7 +1973,7 @@ class CHtmlFile2_Private } } m_oLightReader.MoveToElement(); - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); } // Картинки else if(sName == L"img") @@ -1976,14 +1983,14 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:u w:val=\"single\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Выделенный текст, обычно выделяется желтым else if(sName == L"mark") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:highlight w:val=\"yellow\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Цитата, выделенная кавычками, обычно выделяется курсивом else if(sName == L"q") @@ -2014,21 +2021,21 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:vertAlign w:val=\"superscript\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Уменьшает размер шрифта else if(sName == L"small") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:sz w:val=\"18\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Текст нижнего регистра else if(sName == L"sub") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:vertAlign w:val=\"subscript\"/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Векторная картинка else if(sName == L"svg" || (sName.length() > 3 && sName.compare(sName.length() - 3, 3, L"svg") == 0)) @@ -2047,28 +2054,28 @@ class CHtmlFile2_Private { WriteEmptyParagraph(oXml, false, m_bInP); sSelectors.pop_back(); - return; + return true; } else if (sName == L"span") { if (sSelectors.back().m_wsClass == L"MsoFootnoteReference") { sSelectors.pop_back(); - return; + return false; } - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); } else if (sName == L"nobr") { CTextSettings oTSPre(oTS); oTSPre.bPre = true; - readStream(oXml, sSelectors, oTSPre); + bResult = readStream(oXml, sSelectors, oTSPre); } // Без нового абзаца else if(sName == L"basefont" || sName == L"button" || sName == L"label" || sName == L"data" || sName == L"object" || sName == L"noscript" || sName == L"output" || sName == L"abbr" || sName == L"time" || sName == L"ruby" || sName == L"progress" || sName == L"hgroup" || sName == L"meter" || sName == L"acronym") - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); // С нового абзаца else { @@ -2079,14 +2086,14 @@ class CHtmlFile2_Private { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:i/><w:iCs/>"); - readStream(oXml, sSelectors, oTSR); + bResult = readStream(oXml, sSelectors, oTSR); } // Определение термина, отступ от левого края else if(sName == L"dd") { CTextSettings oTSP(oTS); oTSP.sPStyle += L"<w:ind w:left=\"567\"/>"; - readStream(oXml, sSelectors, oTSP); + bResult = readStream(oXml, sSelectors, oTSP); } // aside возможно использовать для сносок в epub else if (sName == L"aside" || sName == L"div") @@ -2123,7 +2130,7 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L"</w:footnote>"); } else - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); } // С нового абзаца else if(sName == L"article" || sName == L"header" || sName == L"blockquote" || sName == L"main" || sName == L"dir" || @@ -2131,7 +2138,7 @@ class CHtmlFile2_Private sName == L"details" || sName == L"option" || sName == L"dt" || sName == L"p" || sName == L"section" || sName == L"figure" || sName == L"dl" || sName == L"legend" || sName == L"map" || sName == L"h1" || sName == L"h2" || sName == L"h3" || sName == L"h4" || sName == L"h5" || sName == L"h6") - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); // Горизонтальная линия else if(sName == L"hr") { @@ -2168,7 +2175,7 @@ class CHtmlFile2_Private CTextSettings oTSPre(oTS); sSelectors.back().m_wsStyle += L"; font-family:Consolas"; oTSPre.bPre = true; - readStream(oXml, sSelectors, oTSPre); + bResult = readStream(oXml, sSelectors, oTSPre); } // Таблицы else if(sName == L"table") @@ -2178,16 +2185,16 @@ class CHtmlFile2_Private { CTextSettings oTSP(oTS); oTSP.AddPStyle(L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"); - readStream(oXml, sSelectors, oTSP); + bResult = readStream(oXml, sSelectors, oTSP); } else if (sName == L"xml") { sSelectors.pop_back(); - return; + return false; } // Неизвестный тэг. Выделять ли его абзацем? else - readStream(oXml, sSelectors, oTS); + bResult =readStream(oXml, sSelectors, oTS); readNote(oXml, sSelectors, sNote); sNote = L""; @@ -2196,6 +2203,7 @@ class CHtmlFile2_Private } readNote(oXml, sSelectors, sNote); sSelectors.pop_back(); + return bResult; } bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, bool bInsertEmptyP = false) @@ -2212,11 +2220,24 @@ class CHtmlFile2_Private } return false; } + + bool bResult = false; + do { - readInside(oXml, sSelectors, oTS, m_oLightReader.GetName()); + if (readInside(oXml, sSelectors, oTS, m_oLightReader.GetName())) + bResult = true; } while(m_oLightReader.ReadNextSiblingNode2(nDeath)); - return true; + + if (!bResult && bInsertEmptyP) + { + wrP(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + m_bInP = false; + } + + return bResult; } void CalculateCellStyles(CTableCell* pCell, const std::vector<NSCSS::CNode>& arSelectors) @@ -2410,6 +2431,7 @@ class CHtmlFile2_Private oTable.SetWidth(oStyle.m_oDisplay.GetWidth()); oTable.SetBorder(oStyle.m_oBorder); oTable.SetPadding(oStyle.m_oPadding); + oTable.SetMargin(oStyle.m_oMargin); oTable.SetAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); //------ From 4f28d8d3d8f13be1fdfadf9607f1b9679beb12bf Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 4 Jun 2024 09:55:42 +0300 Subject: [PATCH 740/794] For bug 68349 --- PdfFile/SrcWriter/Pages.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 55a1f19823d..b3920322206 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1479,13 +1479,7 @@ namespace PdfWriter { // The value shall be a multiple of 90 if (nRotate > 0 && nRotate % 90 == 0) - { - CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); - if (pRotate) - Add("Rotate", (nRotate + pRotate->Get()) % 360); - else - Add("Rotate", nRotate % 360); - } + Add("Rotate", nRotate % 360); } void CPage::ClearContent(CXref* pXref) { From 15247d39f0776f051878f8eb4d9ef792a13dca52 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 4 Jun 2024 12:22:21 +0300 Subject: [PATCH 741/794] Fix bug 63346 --- PdfFile/SrcReader/RendererOutputDev.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index deef98022e7..b3b00bfa473 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3123,10 +3123,12 @@ namespace PdfReader double xMin, yMin, xMax, yMax; Transform(matrix, pBBox[0], pBBox[1], &xMin, &yMin); Transform(matrix, pBBox[2], pBBox[3], &xMax, &yMax); - xMin += nX0 * (xMax - xMin); - xMax += nX1 * (xMax - xMin); - yMin += nY0 * (yMax - yMin); - yMax += nY1 * (yMax - yMin); + double dW = xMax - xMin; + double dH = yMax - yMin; + xMin += (double)nX0 * dW; + xMax += (double)nX1 * dW; + yMin += (double)nY0 * dH; + yMax += (double)nY1 * dH; pGState->moveTo(xMin, yMin); pGState->lineTo(xMax, yMin); pGState->lineTo(xMax, yMax); From 29ef74770ac776d370f0de64ed754dab54fc4f10 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 4 Jun 2024 13:22:18 +0300 Subject: [PATCH 742/794] Fix bug 66523 --- PdfFile/SrcReader/RendererOutputDev.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index b3b00bfa473..bb8d604ad74 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3077,8 +3077,8 @@ namespace PdfReader dWidth = dWidth * dDpiX / 25.4; dHeight = dHeight * dDpiY / 25.4; - int nWidth = round(dXStep * dWidth / pGState->getPageWidth()); - int nHeight = round(dYStep * dHeight / pGState->getPageHeight()); + int nWidth = dXStep * dWidth / pGState->getPageWidth(); + int nHeight = dYStep * dHeight / pGState->getPageHeight(); BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; memset(pBgraData, 0, nWidth * nHeight * 4); From 66d48673cfffcb8c06875d4ae0697c208a6a050a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 4 Jun 2024 15:41:58 +0300 Subject: [PATCH 743/794] Fix min tilingPattern --- PdfFile/SrcReader/RendererOutputDev.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index bb8d604ad74..02f3d6259ec 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3077,8 +3077,11 @@ namespace PdfReader dWidth = dWidth * dDpiX / 25.4; dHeight = dHeight * dDpiY / 25.4; - int nWidth = dXStep * dWidth / pGState->getPageWidth(); - int nHeight = dYStep * dHeight / pGState->getPageHeight(); + dWidth *= (dXStep / pGState->getPageWidth()); + dHeight *= (dYStep / pGState->getPageHeight()); + + int nWidth = round(dWidth); + int nHeight = round(dHeight); BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; memset(pBgraData, 0, nWidth * nHeight * 4); @@ -3092,8 +3095,8 @@ namespace PdfReader NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); pRenderer->SetFontManager(m_pFontManager); pRenderer->CreateFromBgraFrame(pFrame); - pRenderer->put_Width (nWidth * 25.4 / 72.0); - pRenderer->put_Height(nHeight * 25.4 / 72.0); + pRenderer->put_Width (dWidth * 25.4 / 72.0); + pRenderer->put_Height(dHeight * 25.4 / 72.0); pRenderer->CommandLong(c_nPenWidth0As1px, 1); #ifndef BUILDING_WASM_MODULE pRenderer->SetSwapRGB(false); From 115a60c273cccaa418e5fdaad613ca8cf4bda891 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Wed, 5 Jun 2024 02:26:58 +0300 Subject: [PATCH 744/794] For bug 68216 --- Common/3dParty/html/fetch.py | 1 - DesktopEditor/graphics/GraphicsRenderer.cpp | 6 +++--- DesktopEditor/graphics/structures.h | 2 ++ DocxRenderer/DocxRenderer.cpp | 19 +++++++++++++++++-- DocxRenderer/src/logic/Document.cpp | 5 ++++- DocxRenderer/src/logic/elements/Shape.cpp | 7 +++++-- PdfFile/SrcReader/RendererOutputDev.cpp | 5 +++++ 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/Common/3dParty/html/fetch.py b/Common/3dParty/html/fetch.py index e9a44930c5b..4a0d3f5068f 100644 --- a/Common/3dParty/html/fetch.py +++ b/Common/3dParty/html/fetch.py @@ -5,7 +5,6 @@ import config import base import os -import build base_directory = os.getcwd() diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index d1ad0fc7265..b989524cc23 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.cpp +++ b/DesktopEditor/graphics/GraphicsRenderer.cpp @@ -563,11 +563,11 @@ HRESULT CGraphicsRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) } HRESULT CGraphicsRenderer::put_BrushTextureImage(Aggplus::CImage *pImage) { - if (NULL == pImage) - return S_FALSE; - RELEASEINTERFACE(m_oBrush.Image); + if (NULL == pImage) + return S_OK; + m_oBrush.Image = pImage; m_oBrush.Image->AddRef(); diff --git a/DesktopEditor/graphics/structures.h b/DesktopEditor/graphics/structures.h index c32a946028c..532c27e193a 100644 --- a/DesktopEditor/graphics/structures.h +++ b/DesktopEditor/graphics/structures.h @@ -442,6 +442,8 @@ namespace NSStructures Alpha2 = other.Alpha2; Image = other.Image; + if (Image) + ((IGrObject*)Image)->AddRef(); Transform = other.Transform; TexturePath = other.TexturePath; diff --git a/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index befcdad7d2f..b1f7243f99e 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -473,8 +473,23 @@ HRESULT CDocxRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions // TODO: return S_OK; } -HRESULT CDocxRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) { return S_OK; } -HRESULT CDocxRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) { return S_OK; } +HRESULT CDocxRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) +{ + *pImage = m_pInternal->m_oDocument.m_oBrush.Image; + return S_OK; +} +HRESULT CDocxRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) +{ + RELEASEINTERFACE(m_pInternal->m_oDocument.m_oBrush.Image); + + if (NULL == pImage) + return S_FALSE; + + m_pInternal->m_oDocument.m_oBrush.Image = pImage; + m_pInternal->m_oDocument.m_oBrush.Image->AddRef(); + + return S_OK; +} HRESULT CDocxRenderer::get_BrushTransform(Aggplus::CMatrix& oMatrix) { return S_OK; } HRESULT CDocxRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; } //---------------------------------------------------------------------------------------- diff --git a/DocxRenderer/src/logic/Document.cpp b/DocxRenderer/src/logic/Document.cpp index e49c498d4ca..36e2aed13ef 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -635,7 +635,10 @@ namespace NSDocxRenderer double y = 0; double w = 0; double h = 0; - pInfo = m_oImageManager.WriteImage(m_oBrush.TexturePath, x, y, w, h); + if (m_oBrush.Image) + pInfo = m_oImageManager.WriteImage(m_oBrush.Image, x, y, w, h); + else + pInfo = m_oImageManager.WriteImage(m_oBrush.TexturePath, x, y, w, h); } m_oCurrentPage.DrawPath(nType, pInfo); diff --git a/DocxRenderer/src/logic/elements/Shape.cpp b/DocxRenderer/src/logic/elements/Shape.cpp index 77c6c8ff0d1..51769617ae7 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -709,6 +709,8 @@ namespace NSDocxRenderer void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const { + // TODO: Clip path as geometry + tile!!! + oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); oWriter.WriteString(L"<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); @@ -944,9 +946,10 @@ namespace NSDocxRenderer } void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const { - if (m_eType == eShapeType::stPicture) + if (m_eType == eShapeType::stPicture || + m_eType == eShapeType::stVectorTexture) { - // TODO: + // TODO: Clip path as geometry + tile!!! oWriter.WriteString(L"<p:pic>"); oWriter.WriteString(L"<p:nvPicPr>"); oWriter.WriteString(L"<p:cNvPr id=\""); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index deef98022e7..c25b144d89b 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3152,6 +3152,10 @@ namespace PdfReader m_pRenderer->DrawPath(c_nWindingFillMode); GRenderer->SetSwapRGB(true); } + else + { + m_pRenderer->DrawPath(c_nWindingFillMode); + } #else m_pRenderer->DrawPath(c_nWindingFillMode); #endif @@ -3159,6 +3163,7 @@ namespace PdfReader m_pRenderer->PathCommandEnd(); m_pRenderer->EndCommand(c_nImageType); m_pRenderer->put_BrushType(brush); + m_pRenderer->put_BrushTextureImage(NULL); pGState->clearPath(); RELEASEINTERFACE(oImage); From 96008085d64be5c55100c7474e4ca9c36ee2385e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Wed, 5 Jun 2024 11:46:30 +0300 Subject: [PATCH 745/794] Fix swap RGB --- PdfFile/SrcReader/RendererOutputDev.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 102161cb7f6..1c724faa64d 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -3098,9 +3098,7 @@ namespace PdfReader pRenderer->put_Width (dWidth * 25.4 / 72.0); pRenderer->put_Height(dHeight * 25.4 / 72.0); pRenderer->CommandLong(c_nPenWidth0As1px, 1); -#ifndef BUILDING_WASM_MODULE pRenderer->SetSwapRGB(false); -#endif PDFRectangle box; box.x1 = pBBox[0]; @@ -3149,21 +3147,8 @@ namespace PdfReader m_pRenderer->put_BrushTextureMode(c_BrushTextureModeTile); m_pRenderer->put_BrushTextureAlpha(alpha); m_pRenderer->BeginCommand(c_nImageType); -#ifdef BUILDING_WASM_MODULE - if (NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast<NSGraphics::IGraphicsRenderer*>(m_pRenderer)) - { - // oImage BGRA - GRenderer->SetSwapRGB(false); - m_pRenderer->DrawPath(c_nWindingFillMode); - GRenderer->SetSwapRGB(true); - } - else - { - m_pRenderer->DrawPath(c_nWindingFillMode); - } -#else + m_pRenderer->DrawPath(c_nWindingFillMode); -#endif m_pRenderer->PathCommandEnd(); m_pRenderer->EndCommand(c_nImageType); From c7612a259d34e1c9bac5e8c2fe8a7525d9d3f829 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Wed, 5 Jun 2024 14:41:41 +0300 Subject: [PATCH 746/794] Add support create & save pdf forms --- DesktopEditor/doctrenderer/common_deploy.h | 1 + DesktopEditor/doctrenderer/docbuilder.h | 1 + .../doctrenderer/docbuilder.net/src/docbuilder.net.cpp | 3 ++- .../doctrenderer/docbuilder.python/src/docbuilder.py | 1 + DesktopEditor/doctrenderer/docbuilder_p.cpp | 6 +++++- DesktopEditor/doctrenderer/docbuilder_p.h | 7 ++++++- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/common_deploy.h b/DesktopEditor/doctrenderer/common_deploy.h index cbfff54c603..81ffc9d1fb8 100644 --- a/DesktopEditor/doctrenderer/common_deploy.h +++ b/DesktopEditor/doctrenderer/common_deploy.h @@ -16,6 +16,7 @@ #define OFFICESTUDIO_FILE_DOCUMENT_DOTX OFFICESTUDIO_FILE_DOCUMENT + 0x000c #define OFFICESTUDIO_FILE_DOCUMENT_OTT OFFICESTUDIO_FILE_DOCUMENT + 0x000f #define OFFICESTUDIO_FILE_DOCUMENT_HTML OFFICESTUDIO_FILE_DOCUMENT + 0x0012 +#define OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF OFFICESTUDIO_FILE_DOCUMENT + 0x0017 #define OFFICESTUDIO_FILE_PRESENTATION 0x0080 #define OFFICESTUDIO_FILE_PRESENTATION_PPTX OFFICESTUDIO_FILE_PRESENTATION + 0x0001 diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index 0d20fb73b03..0f564810409 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -357,6 +357,7 @@ namespace NSDoctRenderer /** * Creates a new file. The type of the file which will be created needs to be set. * @param type The type of the file to be created set as a hexadecimal integer for the C++ code or docx, xlsx or pptx for the .docbuilder script file (see AVS_OFFICESTUDIO_FILE_XXX values). + * Possible values for wchar_t version: "docx", "pptx", "xlsx", "pdf", "form" * @return True if the operation is successful */ bool CreateFile(const int& type); diff --git a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp index 436a3e3eb3c..f5022fbde76 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp @@ -50,7 +50,8 @@ namespace docbuilder_net TXT = MASK + 0x0005, DOTX = MASK + 0x000c, OTT = MASK + 0x000f, - HTML = MASK + 0x0012 + HTML = MASK + 0x0012, + OFORM_PDF = MASK + 0x0017 }; public enum class Spreadsheet : int diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index c71994853e9..978b306176c 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -559,6 +559,7 @@ class Document: DOTX = _MASK + 0x000c OTT = _MASK + 0x000f HTML = _MASK + 0x0012 + OFORM_PDF = _MASK + 0x0017 class Presentation: _MASK = 0x0080 diff --git a/DesktopEditor/doctrenderer/docbuilder_p.cpp b/DesktopEditor/doctrenderer/docbuilder_p.cpp index a3e4192a941..ea742b5ac9b 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -1440,7 +1440,11 @@ namespace NSDoctRenderer bIsNoError = (0 == this->OpenFile(_builder_params[0].c_str(), _builder_params[1].c_str())); else if ("CreateFile" == sFuncNum) { - if (L"docx" == _builder_params[0] || L"docxf" == _builder_params[0] || L"oform" == _builder_params[0]) + if (L"docx" == _builder_params[0] || + L"docxf" == _builder_params[0] || + L"oform" == _builder_params[0] || + L"pdf" == _builder_params[0] || + L"form" == _builder_params[0]) bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); else if (L"pptx" == _builder_params[0]) bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX); diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index f4cb3affb09..c0b3a5190a5 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -110,6 +110,8 @@ namespace NSDoctRenderer nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM; else if (L"html" == sExt) nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER; + else if (L"form" == sExt) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF; return nFormat; } } @@ -619,7 +621,10 @@ namespace NSDoctRenderer if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) { - sEmptyPath = sEmptyPath + L"new.docx"; + if (type == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) + sEmptyPath = sEmptyPath + L"new.pdf"; + else + sEmptyPath = sEmptyPath + L"new.docx"; m_nFileType = 0; } else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) From cd74ef4ded400ac2f9cb7f184220c0457bc20b32 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Wed, 5 Jun 2024 15:52:33 +0300 Subject: [PATCH 747/794] fix bug 68328 --- .../StarMath2OOXML/TestSMConverter/main.cpp | 10 ++ .../StarMath2OOXML/cconversionsmtoooxml.cpp | 17 ++- .../StarMath2OOXML/cconversionsmtoooxml.h | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 107 +++++++++++++----- .../Converter/StarMath2OOXML/cstarmathpars.h | 1 + OdfFile/Reader/Format/draw_frame_pptx.cpp | 4 +- OdfFile/Reader/Format/draw_frame_xlsx.cpp | 4 +- 7 files changed, 101 insertions(+), 44 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index d7c371117a1..9cb145de3cd 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -1404,6 +1404,16 @@ TEST(SMConvectorTest,FuctionWithAttributeAndIndex) EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } +TEST(SMConvectorTest,UnarPlusMinus) +{ + std::wstring wsString = L"2 color red + - 4 over 10"; + StarMath::CParserStarMathString oTemp; + StarMath::CConversionSMtoOOXML oTest; + oTest.StartConversion(oTemp.Parse(wsString)); + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>-</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + EXPECT_EQ(oTest.GetOOXML(),wsXmlString); +} + //TEST(SMConvectorTest,AttributeMatrix) //{ // std::wstring wsString = L""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 8d24c1c2993..acbbd32cff1 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -221,9 +221,6 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"typeface",pAttribute->GetFontName()); else pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); - // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); - // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); - // pXmlWrite->WriteAttribute(L"charset",L"0"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"a:rPr",false); } @@ -234,21 +231,18 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"w",true,false); pXmlWrite->WriteNodeBegin(L"a:latin",true); pXmlWrite->WriteAttribute(L"typeface",L"Cambria Math"); - // pXmlWrite->WriteAttribute(L"panose",L"02040503050406030204"); - // pXmlWrite->WriteAttribute(L"pitchFamily",L"18"); - // pXmlWrite->WriteAttribute(L"charset",L"0"); pXmlWrite->WriteNodeEnd(L"w",true,true); pXmlWrite->WriteNodeEnd(L"a:rPr",false); } } } - void CConversionSMtoOOXML::PropertiesMFPR(bool bType, XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesMFPR(const std::wstring &wsType, XmlUtils::CXmlWriter* pXmlWrite, CAttribute* pAttribute, const TypeConversion &enTypeConversion) { pXmlWrite->WriteNodeBegin(L"m:fPr",false); - if(bType) + if(!wsType.empty()) { pXmlWrite->WriteNodeBegin(L"m:type",true); - pXmlWrite->WriteAttribute(L"m:val",L"lin"); + pXmlWrite->WriteAttribute(L"m:val",wsType); pXmlWrite->WriteNodeEnd(L"w",true,true); } WriteCtrlPrNode(pXmlWrite,pAttribute,enTypeConversion); @@ -360,11 +354,14 @@ namespace StarMath { BracketTypeNotation(L"\u23A3",L"\u23A6",pXmlWrite); break; case TypeElement::lline: - BracketTypeNotation(L"\u23AA",L"\u23AA",pXmlWrite); + BracketTypeNotation(L"\u007C",L"\u007C",pXmlWrite); break; case TypeElement::ldline: BracketTypeNotation(L"\u2016",L"\u2016",pXmlWrite); break; + case TypeElement::abs: + BracketTypeNotation(L"\u007C",L"\u007C",pXmlWrite); + break; } pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); StandartProperties(pXmlWrite,pAttribute,enTypeConversion); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index c054c8ef362..b0a2ff2a3b0 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -44,7 +44,7 @@ namespace StarMath { ~CConversionSMtoOOXML(); void StartConversion(std::vector<CElement*> arPars, const unsigned int& iAlignment = 1); static void StandartProperties(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion& enTypeConversion); - static void PropertiesMFPR(bool bType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesMFPR(const std::wstring& wsType,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 7d73d57196a..9a68f5a12e5 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -48,14 +48,9 @@ namespace StarMath std::wstring::iterator itStart = wsParseString.begin(),itEnd = wsParseString.end(); CStarMathReader* pReader = new CStarMathReader(itStart,itEnd,enTypeConvers); pReader->SetBaseAttribute(m_stBaseAttribute); -// if(m_stBaseAttribute != nullptr && (m_stBaseAttribute->base_alignment >= 0 && m_stBaseAttribute->base_alignment <= 2)) -// SetAlignment(m_stBaseAttribute->base_alignment); while(pReader->CheckIteratorPosition()) { - if(!m_arEquation.empty()) - CElementBinOperator::UnaryCheck(pReader,m_arEquation.back()); - CElement* pTempElement = ParseElement(pReader); - AddingAnElementToAnArray(m_arEquation,pTempElement,pReader); + ParsElementAddingToArray(pReader,m_arEquation); } if(!pReader->EmptyString()) { @@ -273,6 +268,13 @@ namespace StarMath else return wsLowerCase; } + void CParserStarMathString::ParsElementAddingToArray(CStarMathReader *pReader, std::vector<CElement *> &arElements) + { + if(!arElements.empty()) + CElementBinOperator::UnaryCheck(pReader,arElements.back()); + CElement* pTempElement = ParseElement(pReader); + AddingAnElementToAnArray(arElements,pTempElement,pReader); + } //class methods CAttribute CAttribute::CAttribute(): m_bBold(false),m_bItal(false),m_bPhantom(false),m_bStrike(false),m_bParent(false),m_iSize(0),m_iAlignment(0),m_unCount(0) { @@ -893,20 +895,20 @@ namespace StarMath { if(m_enTypeBinOp == TypeElement::frac) { - SetLeftArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); - SetRightArg(CParserStarMathString::ReadingWithoutBracket(pReader,false)); + m_pLeftArgument = CParserStarMathString::ReadingWithoutBracket(pReader,false); + m_pRightArgument = CParserStarMathString::ReadingWithoutBracket(pReader,false); if(GetAttribute() != nullptr) SetAttribute(GetAttribute()); } else if(m_enTypeBinOp == TypeElement::neg) { - SetRightArg(CParserStarMathString::ParseElement(pReader)); + m_pRightArgument = CParserStarMathString::ParseElement(pReader); if(GetAttribute()!= nullptr) SetAttribute(GetAttribute()); } else if((pReader->GetMarkForUnar() || GetAttribute()!=nullptr)&& MixedOperators(m_enTypeBinOp)) { - SetRightArg(CParserStarMathString::ParseElement(pReader)); + m_pRightArgument = CParserStarMathString::ParseElement(pReader); } else { @@ -917,18 +919,20 @@ namespace StarMath { CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); } - SetRightArg(pTempElement); + m_pRightArgument = pTempElement; } } void CElementBinOperator::ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) { - if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division || TypeElement::frac == m_enTypeBinOp) + if(m_enTypeBinOp == TypeElement::over || m_enTypeBinOp ==TypeElement::division || TypeElement::frac == m_enTypeBinOp || TypeElement::wideslash == m_enTypeBinOp) { pXmlWrite->WriteNodeBegin(L"m:f",false); if(m_enTypeBinOp == TypeElement::division) - CConversionSMtoOOXML::PropertiesMFPR(true,pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesMFPR(L"lin",pXmlWrite,GetAttribute(),GetTypeConversion()); + else if(m_enTypeBinOp == TypeElement::wideslash) + CConversionSMtoOOXML::PropertiesMFPR(L"skw",pXmlWrite,GetAttribute(),GetTypeConversion()); else - CConversionSMtoOOXML::PropertiesMFPR(false,pXmlWrite,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesMFPR(L"",pXmlWrite,GetAttribute(),GetTypeConversion()); CConversionSMtoOOXML::WriteNodeConversion(L"m:num",m_pLeftArgument,pXmlWrite); CConversionSMtoOOXML::WriteNodeConversion(L"m:den",m_pRightArgument,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:f",false,false); @@ -989,6 +993,9 @@ namespace StarMath case TypeElement::neg: pXmlWrite->WriteString(L"\u00AC"); break; + case TypeElement::circ: + pXmlWrite->WriteString(L"\u2218"); + break; default: break; } @@ -1058,7 +1065,11 @@ namespace StarMath void CElementBinOperator::UnaryCheck(CStarMathReader *pReader, CElement *pLastElement) { pReader->ReadingTheNextToken(); - pReader->SetMarkForUnar(!(!CParserStarMathString::CheckNewline(pLastElement) && MixedOperators(pReader->GetLocalType()))); + if(!CParserStarMathString::CheckNewline(pLastElement) && MixedOperators(pReader->GetLocalType())) + if(pReader->GetAttribute() != nullptr) + pReader->SetMarkForUnar(true); + else pReader->SetMarkForUnar(false); + else pReader->SetMarkForUnar(true); } bool CElementBinOperator::IsBinOperatorLowPrior() { @@ -1146,10 +1157,7 @@ namespace StarMath pReader->FindingTheEndOfParentheses(); while(pReader->CheckIteratorPosition()) { - if(!m_arBrecketValue.empty()) - CElementBinOperator::UnaryCheck(pReader,m_arBrecketValue.back()); - CElement* pTempElement = CParserStarMathString::ParseElement(pReader); - CParserStarMathString::AddingAnElementToAnArray(m_arBrecketValue,pTempElement,pReader); + CParserStarMathString::ParsElementAddingToArray(pReader,m_arBrecketValue); } if(!pReader->EmptyString()) { @@ -1236,8 +1244,15 @@ namespace StarMath switch(m_enTypeSpecial) { case TypeElement::fact: + case TypeElement::abs: { - SetValue(CParserStarMathString::ParseElement(pReader)); + CElement* pTempElement = CParserStarMathString::ParseElement(pReader); + pReader->ReadingTheNextToken(); + while(pReader->GetGlobalType() == TypeElement::Index && (pReader->GetLocalType()!=TypeElement::nroot && pReader->GetLocalType()!=TypeElement::sqrt)) + { + CParserStarMathString::ReadingElementsWithPriorities(pReader,pTempElement); + } + m_pValue = pTempElement; break; } default: @@ -1261,10 +1276,10 @@ namespace StarMath else if(L"##" == wsToken) return TypeElement::transition; else if(L"emptyset" == wsToken) return TypeElement::emptyset; else if(L"aleph" == wsToken) return TypeElement::aleph; - else if(L"setN" == wsToken) return TypeElement::setN; - else if(L"setZ" == wsToken) return TypeElement::setZ; - else if(L"setQ" == wsToken) return TypeElement::setQ; - else if(L"setR" == wsToken) return TypeElement::setR; + else if(L"setn" == wsToken) return TypeElement::setN; + else if(L"setz" == wsToken) return TypeElement::setZ; + else if(L"setq" == wsToken) return TypeElement::setQ; + else if(L"setr" == wsToken) return TypeElement::setR; else if(L"setc" == wsToken) return TypeElement::setC; else if(L"infinity" == wsToken) return TypeElement::infinity; else if(L"infty" == wsToken) return TypeElement::infinity; @@ -1279,8 +1294,8 @@ namespace StarMath else if(L"forall" == wsToken) return TypeElement::forall; else if(L"hbar" == wsToken) return TypeElement::hbar; else if(L"lambdabar" == wsToken) return TypeElement::lambdabar; - else if(L"Re" == wsToken) return TypeElement::Re; - else if(L"Im" == wsToken) return TypeElement::Im; + else if(L"re" == wsToken) return TypeElement::Re; + else if(L"im" == wsToken) return TypeElement::Im; else if(L"wp" == wsToken) return TypeElement::wp; else if(L"laplace" == wsToken) return TypeElement::laplace; else if(L"fourier" == wsToken) return TypeElement::fourier; @@ -1400,6 +1415,14 @@ namespace StarMath { break; } + case TypeElement::abs: + { + pXmlWrite->WriteNodeBegin(L"m:d",false); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,TypeElement::abs,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:d",false,false); + break; + } default: { if(!m_wsType.empty()) @@ -1664,10 +1687,10 @@ namespace StarMath m_wsType = L"\u2190"; break; case TypeElement::uparrow: - m_wsType = L"\uF871"; + m_wsType = L"\U0001F809"; break; case TypeElement::downarrow: - m_wsType = L"\uF873"; + m_wsType = L"\U0001F80B"; break; case TypeElement::dotsaxis: m_wsType = L"\u22EF"; @@ -1684,6 +1707,27 @@ namespace StarMath case TypeElement::dotslow: m_wsType = L"\u2026"; break; + case TypeElement::emptyset: + m_wsType = L"\u2205"; + break; + case TypeElement::aleph: + m_wsType = L"\u2135"; + break; + case TypeElement::setN: + m_wsType = L"\u2115"; + break; + case TypeElement::setZ: + m_wsType = L"\u2124"; + break; + case TypeElement::setQ: + m_wsType = L"\u211A"; + break; + case TypeElement::setR: + m_wsType = L"\u211D"; + break; + case TypeElement::setC: + m_wsType = L"\u2102"; + break; default: break; } @@ -1872,12 +1916,18 @@ namespace StarMath case TypeElement::learrowequals: pXmlWrite->WriteString(L"\u2264"); break; + case TypeElement::leslant: + pXmlWrite->WriteString(L"\u2A7D"); + break; case TypeElement::riarrow: pXmlWrite->WriteString(L">"); break; case TypeElement::riarrowequals: pXmlWrite->WriteString(L"\u2265"); break; + case TypeElement::geslant: + pXmlWrite->WriteString(L"\u2A7E"); + break; case TypeElement::dllearrow: pXmlWrite->WriteString(L"\u226A"); break; @@ -2115,7 +2165,6 @@ namespace StarMath CParserStarMathString::AddLeftArgument(m_pValueIndex,pElement,pReader); m_pValueIndex = pElement; } -// m_pLeftArg = m_pValueIndex; } else { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index f3bd2c3cdc8..4ed26e9fddb 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -459,6 +459,7 @@ namespace StarMath static void ReadingElementsWithPriorities(CStarMathReader* pReader,CElement*& pLeftElement); //method for parsing indexes with attributes. If there is an attribute present when indexes are read, then all subsequent indexes are applied to the index with the attribute. static void ReadingElementsWithAttributes(CStarMathReader* pReader,CElement*& pSavingElement); + static void ParsElementAddingToArray(CStarMathReader* pReader, std::vector<CElement*>& arElements); void SetAlignment(const unsigned int& iAlignment); const unsigned int& GetAlignment(); void SetBaseFont(const std::wstring& wsNameFont); diff --git a/OdfFile/Reader/Format/draw_frame_pptx.cpp b/OdfFile/Reader/Format/draw_frame_pptx.cpp index 83927b78982..a161f58bbc8 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -441,9 +441,9 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context) if (!math_content.empty()) { std::wstring text_content = L"<a:p><a14:m xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">"; - text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; +// text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; text_content += math_content; - text_content += L"</m:oMathPara></a14:m></a:p>"; + text_content += L"</a14:m></a:p>"; if (bNewObject) { diff --git a/OdfFile/Reader/Format/draw_frame_xlsx.cpp b/OdfFile/Reader/Format/draw_frame_xlsx.cpp index 5aabe7921e9..0a030d4bd4a 100644 --- a/OdfFile/Reader/Format/draw_frame_xlsx.cpp +++ b/OdfFile/Reader/Format/draw_frame_xlsx.cpp @@ -404,9 +404,9 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context) if (!math_content.empty()) { std::wstring text_content = L"<a:p><a14:m xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">"; - text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; +// text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; text_content += math_content; - text_content += L"</m:oMathPara></a14:m></a:p>"; + text_content += L"</a14:m></a:p>"; if (bNewObject) { From 6000944cc9845d97bd5d1d2dbd3a4397e8b9eb3e Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Wed, 5 Jun 2024 19:20:58 +0600 Subject: [PATCH 748/794] Fix bug #68238 --- .../Format/Logic/Biff_structures/PtgArea.cpp | 5 ++- .../Logic/Biff_structures/PtgArea3d.cpp | 2 +- .../Format/Logic/Biff_structures/PtgAreaN.cpp | 2 +- .../Format/Logic/Biff_structures/PtgRef.cpp | 2 +- .../Format/Logic/Biff_structures/PtgRef3d.cpp | 2 +- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 45 +++++++++++++++---- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 22 ++++++++- .../Worksheets/ConditionalFormatting.cpp | 6 +-- 8 files changed, 68 insertions(+), 18 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp index 82067026678..04502bede0f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.cpp @@ -148,7 +148,10 @@ void PtgArea::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool ful } } } - ptg_stack.push(range.toString()); + if(global_info->Version < 0x0800) + ptg_stack.push(range.toString()); + else + ptg_stack.push(range.toString(true, true)); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp index 38aef91d89b..c66cc962d98 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea3d.cpp @@ -153,7 +153,7 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f if(global_info->Version < 0x0800) range_ref = area.toString(); else - range_ref = areaXlsb.toString(); + range_ref = areaXlsb.toString(true, true); if (global_info->Version < 0x0600) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp index f539ad77647..4d07224ec8f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgAreaN.cpp @@ -141,7 +141,7 @@ void PtgAreaN::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu else { - ptg_stack.push((areaXlsb + cell_base_ref).toString(true)); + ptg_stack.push((areaXlsb + cell_base_ref).toString(true, true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp index c598e654317..277ab3696fa 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.cpp @@ -113,7 +113,7 @@ void PtgRef::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full } else { - ptg_stack.push(loc_xlsb.toString()); + ptg_stack.push(loc_xlsb.toString(true)); } } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp index 5245262d0bb..b1f1a9b0045 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef3d.cpp @@ -147,7 +147,7 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu } else { - cell_ref = rgce_loc_xlsb.toString(); + cell_ref = rgce_loc_xlsb.toString(true); } if (global_info->Version < 0x0600) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 325fb23ffd6..54af846621c 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -5619,14 +5619,40 @@ void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) { double dValue = 0; - try - { - dValue = XmlUtils::GetDouble(oCell.m_oValue->ToString()); - } - catch(...) - { //1.3912059045063478e-310 - //Lighting Load Calculation.xls - } + if(oCell.m_oType.IsInit() && oCell.m_oType->m_eValue == SimpleTypes::Spreadsheet::celltypeError) + { + auto errorText = oCell.m_oValue->m_sText; + if(errorText == L"#NULL!") + dValue = 0x00; + else if(errorText == L"#DIV/0!") + dValue = 0x07; + else if(errorText == L"#VALUE!") + dValue = 0x0F; + else if(errorText == L"#REF!") + dValue = 0x17; + else if(errorText == L"#NAME?") + dValue = 0x1D; + else if(errorText == L"#NUM!") + dValue = 0x24; + else if(errorText == L"#N/A") + dValue = 0x2A; + else if(errorText == L"#GETTING_DATA") + dValue = 0x2B; + else + dValue = 0x0; + } + else + { + try + { + dValue = XmlUtils::GetDouble(oCell.m_oValue->ToString()); + } + catch(...) + { //1.3912059045063478e-310 + //Lighting Load Calculation.xls + } + } + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Value); m_oBcw.m_oStream.WriteDoubleReal(dValue); @@ -5953,7 +5979,8 @@ void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorkshee pFormControlPr = pFileCtrlProp->m_oFormControlPr.GetPointer(); } else - { + { //using controls without activeX causes bugs + continue; smart_ptr<OOX::ActiveX_xml> pActiveX_xml = pFileControl.smart_dynamic_cast<OOX::ActiveX_xml>(); if ((pActiveX_xml.IsInit()) && (pActiveX_xml->m_oObject.IsInit())) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 5b9d8f61d8a..bd4047514f9 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -6301,7 +6301,7 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul bMoveText = true; oCell.m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); } - if (bMoveText) + if (bMoveText && SimpleTypes::Spreadsheet::celltypeSharedString == eCellType) { int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); @@ -6320,6 +6320,26 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul } } } + else if(bMoveText && SimpleTypes::Spreadsheet::celltypeError == eCellType) + { + int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); + std::wstring errText; + switch(nValue) + { + case 0x00: errText = L"#NULL!"; break; + case 0x07: errText = L"#DIV/0!"; break; + case 0x0F: errText = L"#VALUE!"; break; + case 0x17: errText = L"#REF!"; break; + case 0x1D: errText = L"#NAME?"; break; + case 0x24: errText = L"#NUM!"; break; + case 0x2A: errText = L"#N/A"; break; + case 0x2B: errText = L"#GETTING_DATA"; break; + default: + errText = L"#NULL!"; + break; + }; + oCell.m_oValue->m_sText = errText; + } } if (NULL == m_oSaveParams.pCSVWriter) { diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 70f2e68c21b..ea5e43f93c9 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -1862,7 +1862,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellR else ptr->strParam.setSize(0xFFFFFFFF); - if(!m_arrFormula.empty()) + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) { ptr->rgce1 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); @@ -1872,7 +1872,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellR { ptr->cbFmla1 = 0; } - if(!m_arrFormula.empty()) + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) { ptr->rgce2 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); @@ -1882,7 +1882,7 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes(const XLS::CellR { ptr->cbFmla2 = 0; } - if(!m_arrFormula.empty()) + if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) { ptr->rgce3 = m_arrFormula.front()->m_sText; m_arrFormula.erase(m_arrFormula.begin()); From 33da43b2f4b4da38a797cdc5479640e5febdbb14 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Wed, 5 Jun 2024 19:57:56 +0300 Subject: [PATCH 749/794] Fix bug 67747 --- DocxRenderer/src/logic/Page.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index 39ebf05f04f..5c770a4ef8f 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1028,6 +1028,8 @@ namespace NSDocxRenderer { for (auto& pCont : line->m_arConts) { + if (!pCont) + continue; if (base_line->m_dLeft > pCont->m_dLeft) base_line->m_dLeft = pCont->m_dLeft; if (base_line->m_dRight < pCont->m_dRight) From ac721572f2a536baa46155ed8aa4b487a4f09258 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Thu, 6 Jun 2024 08:51:59 +0300 Subject: [PATCH 750/794] Fix bug #67967 --- .../3dParty/html/css/src/StyleProperties.cpp | 5 +- .../Metafile/svg/SvgObjects/CGradient.cpp | 69 +++++++++++-------- .../Metafile/svg/SvgObjects/CGradient.h | 3 + 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index c380779c338..0a1a482cce0 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -254,8 +254,9 @@ namespace NSCSS bool CDigit::operator==(const CDigit &oDigit) const { - return (std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON) && - m_enUnitMeasure == oDigit.m_enUnitMeasure; + return (Empty() && oDigit.Empty()) || + ((std::abs(oDigit.m_oValue - m_oValue) <= DBL_EPSILON) && + m_enUnitMeasure == oDigit.m_enUnitMeasure); } bool CDigit::operator!=(const double &oValue) const diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp index 0e3aa5335bf..d20b26f5cc0 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.cpp @@ -52,37 +52,21 @@ namespace SVG bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { - if (NULL == pRenderer) + if (NULL == pRenderer || m_arObjects.empty()) return false; - if (m_arObjects.empty()) - { - if (m_wsXlinkHref.empty() || NULL == pFile) - return false; - - CGradient *pGradiend = dynamic_cast<CGradient*>(pFile->GetMarkedObject(m_wsXlinkHref)); + std::vector<LONG> arColors; + std::vector<double> arPositions; - if (NULL == pGradiend) - return false; - - pGradiend->Apply(pRenderer, pFile, oObjectBounds); - } - else + for (const CStopElement* pStopElement : m_arObjects) { - std::vector<LONG> arColors; - std::vector<double> arPositions; - - for (const CStopElement* pStopElement : m_arObjects) - { - arColors.push_back(((unsigned int)(pStopElement->GetColor().ToInt() | ((unsigned char)(255. * pStopElement->GetColor().GetOpacity()) << 24)))); - arPositions.push_back(pStopElement->GetOffset().ToDouble()); - } - - pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); + arColors.push_back(((unsigned int)(pStopElement->GetColor().ToInt() | ((unsigned char)(255. * pStopElement->GetColor().GetOpacity()) << 24)))); + arPositions.push_back(pStopElement->GetOffset().ToDouble()); } - + + pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); pRenderer->put_BrushTransform(m_oTransform.GetMatrix().GetFinalValue()); - + return true; } @@ -108,6 +92,31 @@ namespace SVG pRenderer->BrushBounds(oNewBounds.m_dLeft, oNewBounds.m_dTop, oNewBounds.m_dRight - oNewBounds.m_dLeft, oNewBounds.m_dBottom - oNewBounds.m_dTop); } + CGradient *CGradient::GetRefGradient(const CSvgFile *pFile) const + { + if (m_wsXlinkHref.empty() || NULL == pFile) + return NULL; + + CGradient *pGradiend = dynamic_cast<CGradient*>(pFile->GetMarkedObject(m_wsXlinkHref)); + + if (NULL == pGradiend) + return NULL; + + CGradient *pRefGradient = pGradiend->GetRefGradient(pFile); + + return (NULL != pRefGradient) ? pRefGradient : pGradiend; + } + + bool CGradient::ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const + { + CGradient *pRefGradient = GetRefGradient(pFile); + + if (NULL == pRefGradient) + return false; + + return pRefGradient->Apply(pRenderer, pFile, oObjectBounds); + } + CLinearGradient::CLinearGradient(XmlUtils::CXmlNode& oNode) : CGradient(oNode) { @@ -120,10 +129,8 @@ namespace SVG bool CLinearGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { if (!CGradient::Apply(pRenderer, pFile, oObjectBounds)) - return false; + return ApplyRefGradient(pRenderer, pFile, oObjectBounds); - pRenderer->put_BrushType(c_BrushTypePathGradient1); - if (m_oX1 == m_oX2 && m_oY1 == m_oY2) { pRenderer->put_BrushType(c_BrushTypeSolid); @@ -132,6 +139,8 @@ namespace SVG return true; } + pRenderer->put_BrushType(c_BrushTypePathGradient1); + double dAngle = 0.; TBounds oNewBounds(oObjectBounds); @@ -171,8 +180,8 @@ namespace SVG bool CRadialGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) { if (!CGradient::Apply(pRenderer, pFile, oObjectBounds) || m_oR.Zero()) - return false; - + return ApplyRefGradient(pRenderer, pFile, oObjectBounds); + double dCX = (oObjectBounds.m_dRight + oObjectBounds.m_dLeft) / 2.; double dCY = (oObjectBounds.m_dBottom + oObjectBounds.m_dTop) / 2.; double dR = oObjectBounds.m_dBottom - oObjectBounds.m_dTop; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h index 0c73ada939e..c5b0b6f4438 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CGradient.h @@ -47,6 +47,9 @@ namespace SVG bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override; void ApplyTransform(IRenderer *pRenderer, const TBounds& oBounds, double& dAngle) const; private: + CGradient* GetRefGradient(const CSvgFile *pFile) const; + bool ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const; + std::wstring m_wsXlinkHref; GradientUnits m_enGradientUnits; SpreadMethod m_enSpreadMethod; From 2e1ccbc985eea5cd4e83b450d7e075a6ed2c4ed8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 6 Jun 2024 10:21:51 +0300 Subject: [PATCH 751/794] For bug 46629 --- DesktopEditor/graphics/Graphics.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 19ba697d178..24ed749aec9 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -625,7 +625,7 @@ namespace Aggplus } double dWidth = pPen->Size; - double dWidthMinSize = 1.0 / sqrt(m_oCoordTransform.m_internal->m_agg_mtx.determinant()); + double dWidthMinSize = 1.0 / sqrt(m_oFullTransform.m_internal->m_agg_mtx.determinant()); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) { @@ -762,6 +762,7 @@ namespace Aggplus } } + dWidthMinSize = 1.0 / sqrt(m_oCoordTransform.m_internal->m_agg_mtx.determinant()); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) dWidth = dWidthMinSize; From 0b77fb2bbad871a955302cc5d4c8b3b5fbf58119 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Thu, 6 Jun 2024 10:38:01 +0300 Subject: [PATCH 752/794] fix bug 68333 --- .../Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp | 2 +- OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index acbbd32cff1..29ae1e553d8 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -62,7 +62,7 @@ namespace StarMath { wsAlignment = L"center"; break; } - if(arPars[0]->GetTypeConversion() == TypeConversion::pptx) + if(arPars[0]->GetTypeConversion() == TypeConversion::pptx || arPars[0]->GetTypeConversion() == TypeConversion::xlsx) { wsNodeMath += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; wsNodeMathPara += L" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\""; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 9a68f5a12e5..775ed6d33af 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1687,10 +1687,10 @@ namespace StarMath m_wsType = L"\u2190"; break; case TypeElement::uparrow: - m_wsType = L"\U0001F809"; + m_wsType = L"\u2191"; break; case TypeElement::downarrow: - m_wsType = L"\U0001F80B"; + m_wsType = L"\u2193"; break; case TypeElement::dotsaxis: m_wsType = L"\u22EF"; From 4014d4914f61db1a2a1ce567f4f688723bf5674e Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Thu, 6 Jun 2024 11:02:30 +0300 Subject: [PATCH 753/794] fix bug 68327 --- OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 8 ++++++-- OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 775ed6d33af..70bb108cc75 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1272,6 +1272,7 @@ namespace StarMath if(wsToken[0] != L'%') { if(L"#" == wsToken) return TypeElement::grid; + else if(L"<?>" == wsToken) return TypeElement::emptySquare; else if(L"mline" == wsToken) return TypeElement::mline; else if(L"##" == wsToken) return TypeElement::transition; else if(L"emptyset" == wsToken) return TypeElement::emptyset; @@ -1728,6 +1729,9 @@ namespace StarMath case TypeElement::setC: m_wsType = L"\u2102"; break; + case TypeElement::emptySquare: + m_wsType = L"\u2751"; + break; default: break; } @@ -2943,11 +2947,11 @@ namespace StarMath m_itStart++; break; } - else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back() && L'<' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back()) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back()) || L'=' == *m_itStart)))) + else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back() && L'<' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back()) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back() && L'?' != m_wsElement.back()) || L'=' == *m_itStart)))) { return m_wsElement; } - else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || ((L'+' == *m_itStart || L'>' == *m_itStart) && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart || L'-' == *m_itStart)) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart )) ) ) ) + else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || ((L'+' == *m_itStart || L'>' == *m_itStart) && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart || L'-' == *m_itStart)) ||(L'?' == m_wsElement.back() && L'>' == *m_itStart) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart )) ) ) ) { m_wsElement.push_back(*m_itStart); m_itStart++; diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 04c58fe3b98..61a2e011ead 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -309,6 +309,7 @@ enum class TypeElement{ dotsdown, dotslow, newline, + emptySquare, //function abs, fact, From 5c7d0a61beb53f0377af4eb037bd9acd6216dfbe Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Thu, 6 Jun 2024 11:59:48 +0300 Subject: [PATCH 754/794] fix bug 68332 --- .../Converter/StarMath2OOXML/cconversionsmtoooxml.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 29ae1e553d8..719cd819ba6 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -336,7 +336,7 @@ namespace StarMath { switch(enTypeBracket) { case TypeElement::langle: - BracketTypeNotation(L"\u2329",L"\u232A",pXmlWrite); + BracketTypeNotation(L"\u27E8",L"\u27E9",pXmlWrite); break; case TypeElement::square: BracketTypeNotation(L"\u005B",L"\u005D",pXmlWrite); @@ -348,10 +348,10 @@ namespace StarMath { BracketTypeNotation(L"\u007B",L"\u007D",pXmlWrite); break; case TypeElement::lceil: - BracketTypeNotation(L"\u23A1",L"\u23A4",pXmlWrite); + BracketTypeNotation(L"\u2308",L"\u2309",pXmlWrite); break; case TypeElement::lfloor: - BracketTypeNotation(L"\u23A3",L"\u23A6",pXmlWrite); + BracketTypeNotation(L"\u230A",L"\u230B",pXmlWrite); break; case TypeElement::lline: BracketTypeNotation(L"\u007C",L"\u007C",pXmlWrite); From 96ea86e3c0ef67f0b3f7aef6436360aa16b3428c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 6 Jun 2024 13:09:07 +0300 Subject: [PATCH 755/794] Fix bug 68123 --- PdfFile/SrcWriter/Document.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index c49b098da1a..0c207d11e2c 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -81,24 +81,22 @@ namespace PdfWriter m_pCurPage = NULL; m_nCurPageNum = -1; m_pCurImage = NULL; - m_unFormFields = 0; m_pInfo = NULL; m_pTrailer = NULL; m_pResources = NULL; + m_pMetaData = NULL; m_bEncrypt = false; m_pEncryptDict = NULL; + m_unFormFields = 0; m_unCompressMode = COMP_NONE; - m_pJbig2 = NULL; memset((void*)m_sTTFontTag, 0x00, 8); + m_pJbig2 = NULL; + m_pDefaultCheckBoxFont = NULL; m_pTransparencyGroup = NULL; m_pFreeTypeLibrary = NULL; + m_bPDFAConformance = false; m_pAcroForm = NULL; m_pFieldsResources = NULL; - m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; - - m_bPDFAConformance = false; } CDocument::~CDocument() { From f366cae6049fb98600e798b857dbc61141da5127 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 6 Jun 2024 16:20:11 +0600 Subject: [PATCH 756/794] Fix bug #68400 --- .../Logic/Biff_structures/StringPtgParser.cpp | 8 ++-- OOXML/XlsxFormat/Table/Tables.cpp | 4 +- .../Worksheets/ConditionalFormatting.cpp | 10 ++++- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 42 ++++++++++++++++--- .../Worksheets/WorksheetChildOther.cpp | 9 ++-- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index cd8c40cd792..c9c635ad9dc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -218,7 +218,8 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R { // EXCEPT::RT::WrongParenthesisSequence(assembled_formula); } - ptg_stack.pop(); // pop PtgParen that is now stored in left_p + if(!ptg_stack.empty()) + ptg_stack.pop(); // pop PtgParen that is now stored in left_p last_ptg = left_p; PtgFuncVarPtr func_var; if(ptg_stack.size() && boost::dynamic_pointer_cast<PtgFunc>(ptg_stack.top())) @@ -237,14 +238,15 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R last_ptg = ptg_stack.top(); ptg_stack.pop(); // pop PtgFuncVar } - else // If there is no function name before the left parenthesis + else if(left_p)// If there is no function name before the left parenthesis { for (size_t i = 0; i < left_p->getParametersNum(); ++i) { rgce.addPtg(PtgPtr(new PtgUnion)); } } - rgce.addPtg(last_ptg); + if(last_ptg) + rgce.addPtg(last_ptg); operand_expected = false; } #pragma endregion diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index 27b6a733f92..07b443d5f1f 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -155,6 +155,8 @@ namespace Spreadsheet XLS::BaseObjectPtr objectPtr(ptr); if(m_oName.IsInit()) ptr->stStyleName = m_oName.get(); + else + ptr->stStyleName.setSize(0xFFFFFFFF); if(m_oShowColumnStripes.IsInit()) ptr->fColumnStripes = m_oShowColumnStripes->GetValue(); if(m_oShowFirstColumn.IsInit()) @@ -287,7 +289,7 @@ namespace Spreadsheet else ptr1->nDxfInsertRow = 0xFFFFFFFF; - if(m_oHeaderRowDxfId.IsInit()) + if(m_oHeaderRowCellStyle.IsInit()) ptr1->stStyleHeader = m_oHeaderRowCellStyle.get(); else ptr1->stStyleHeader.setSize(0xFFFFFFFF); diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 70f2e68c21b..e412cd97b5f 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -2020,7 +2020,10 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::timePeriod) else if (m_oType == SimpleTypes::Spreadsheet::ECfType::aboveAverage) { ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_ABOVEAVERAGE; - ptr->iParam = m_oStdDev->GetValue(); + if(m_oStdDev.IsInit()) + ptr->iParam = m_oStdDev->GetValue(); + else + ptr->iParam = 0; } else if (m_oType == SimpleTypes::Spreadsheet::ECfType::duplicateValues) { @@ -2046,7 +2049,10 @@ else if (m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) else if (m_oType == SimpleTypes::Spreadsheet::ECfType::top10) { ptr->iType = XLSB::CFType::CF_TYPE_FILTER; - ptr->iParam = m_oRank->GetValue(); + if(m_oRank.IsInit()) + ptr->iParam = m_oRank->GetValue(); + else + ptr->iParam = 1; ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FILTER; } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 88b174f1593..eed9af78db0 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2031,7 +2031,14 @@ namespace OOX break; case SimpleTypes::Spreadsheet::celltypeError: { - if (m_oValue->m_sText == L"#NULL!") + if(!m_oValue.IsInit()) + { + auto error = new XLSB::CellError; + error->value = 0x00; + oCell = &error->cell; + pSource = error; + } + else if (m_oValue->m_sText == L"#NULL!") { if(m_oFormula.IsInit()) { auto error = new XLSB::FmlaError; @@ -2205,10 +2212,28 @@ namespace OOX break; case SimpleTypes::Spreadsheet::celltypeSharedString: { - auto pCellIsst(new XLSB::CellIsst); - pCellIsst->value = std::stoi(m_oValue->m_sText); - oCell = &pCellIsst->cell; - pSource = pCellIsst; + if(m_oValue.IsInit()) + { + auto pCellIsst(new XLSB::CellIsst); + pCellIsst->value = std::stoi(m_oValue->m_sText); + oCell = &pCellIsst->cell; + pSource = pCellIsst; + } + else if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + str->value = L""; + oCell = &str->cell; + pSource = str; + + } + else + { + auto pCellblank = new(XLSB::CellBlank); + oCell = &pCellblank->cell; + oCell->fPhShow = false; + pSource = pCellblank; + } } break; case SimpleTypes::Spreadsheet::celltypeInlineStr: @@ -2255,6 +2280,13 @@ namespace OOX pSource = str; } } + else if(m_oFormula.IsInit()) + { + auto str(new XLSB::FmlaString); + str->value = L""; + oCell = &str->cell; + pSource = str; + } else { auto pCellblank = new(XLSB::CellBlank); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 433bc03d85f..647ec071cf9 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -3072,11 +3072,14 @@ namespace OOX if (m_oId.IsInit()) ptr->relId.value = m_oId->GetValue(); + else + ptr->relId.value = L""; if (m_oName.IsInit()) ptr->xstrName = m_oName.get(); else { + ptr->xstrName = L""; ptr->fName = false; ptr->fBuiltin = false; } @@ -3257,15 +3260,15 @@ namespace OOX beginPtr->iiftab = m_oFunction->GetValue(); else beginPtr->iiftab = 0; - if(m_oFunction.IsInit()) + if(m_oLink.IsInit()) beginPtr->fLinkConsol = m_oLink->GetValue(); else beginPtr->fLinkConsol = false; - if(m_oFunction.IsInit()) + if(m_oStartLabels.IsInit()) beginPtr->fLeftCat = m_oStartLabels->GetValue(); else beginPtr->fLeftCat = false; - if(m_oFunction.IsInit()) + if(m_oTopLabels.IsInit()) beginPtr->fTopCat = m_oTopLabels->GetValue(); else beginPtr->fTopCat = false; From dea44f18298d1b3ba26c687f5e1b74be507b31be Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 6 Jun 2024 16:57:06 +0600 Subject: [PATCH 757/794] Fix bug #68402 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 6 +++--- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 88b174f1593..013c7240d6e 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1920,9 +1920,9 @@ namespace OOX { if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); - else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10) + else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10 && m_oValue->m_sText.size() > 0) { - if(m_oValue->m_sText.size() < 10) + if(m_oValue->m_sText.size() < 10 ) { intCache = std::stoi(m_oValue->m_sText); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); @@ -1939,7 +1939,7 @@ namespace OOX } if((m_oValue->m_sText.find(L".") == std::string::npos || m_oValue->m_sText.find(L".") == m_oValue->m_sText.rfind(L".")) - && m_oValue->m_sText.size() <=17) + && m_oValue->m_sText.size() <=17 && m_oValue->m_sText.size() > 0) { if(m_oValue->m_sText.size() < 17) { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 433bc03d85f..da7cec7b01e 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2862,7 +2862,7 @@ namespace OOX { auto ptr(new XLSB::CsProtection); objectPtr = XLS::BaseObjectPtr{ptr}; - ptr->protpwd = std::stoul(m_oPassword.get()); + ptr->protpwd = std::stoul(m_oPassword.get(), nullptr, 16); if(m_oObjects.IsInit()) ptr->fObjects = m_oObjects->GetValue(); else From 4ed4c5596f50c13245b005a48772180d9d4928a2 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Thu, 6 Jun 2024 17:38:26 +0600 Subject: [PATCH 758/794] Fix bug #68404 --- .../ExternalLinks/ExternalLinks.cpp | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index b17e9e43ad1..63a059d58d4 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -1497,10 +1497,16 @@ namespace Spreadsheet ptr->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; auto castedBook = static_cast<XLSB::BeginSupBook*>(ptr->m_BrtBeginSupBook.get()); if (m_oDdeService.IsInit()) - castedBook->string1 = m_oDdeService.get(); + castedBook->string1 = m_oDdeService.get(); + else + castedBook->string1 = L""; if (m_oDdeTopic.IsInit()) - castedBook->string2 = m_oDdeTopic.get(); - ptr->m_DDEOLELINK = m_oDdeItems->toBin(); + castedBook->string2 = m_oDdeTopic.get(); + else + castedBook->string2 = L""; + if(m_oDdeItems.IsInit()) + ptr->m_DDEOLELINK = m_oDdeItems->toBin(); + castedBook->sbt = 0x0001; return ptr; } @@ -1764,13 +1770,18 @@ namespace Spreadsheet XLSB::EXTERNALLINKPtr COleLink(new XLSB::EXTERNALLINK); COleLink->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; auto castedBook = static_cast<XLSB::BeginSupBook*>(COleLink->m_BrtBeginSupBook.get()); - + castedBook->sbt = 0x0002; if(m_oRid.IsInit()) castedBook->string1 = m_oRid->ToString(); + else + castedBook->string1 = L""; if(m_oProgId.IsInit()) castedBook->string2 = m_oProgId.get(); + else + castedBook->string2 = L""; - COleLink->m_DDEOLELINK = m_oOleItems->toBin(); + if(m_oOleItems.IsInit()) + COleLink->m_DDEOLELINK = m_oOleItems->toBin(); return COleLink; } void COleLink::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -1885,9 +1896,9 @@ namespace Spreadsheet { if (m_oExternalBook.IsInit()) externalLinkStreamStream->m_EXTERNALLINK = m_oExternalBook->toBin(); - if (m_oDdeLink.IsInit()) + else if (m_oDdeLink.IsInit()) externalLinkStreamStream->m_EXTERNALLINK = m_oDdeLink->toBin(); - if (m_oOleLink.IsInit()) + else if (m_oOleLink.IsInit()) externalLinkStreamStream->m_EXTERNALLINK = m_oOleLink->toBin(); } return externalLinkStreamStream; From 2e6d5450b4f0a39886cdae0ea0d95264ee900035 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 6 Jun 2024 16:22:04 +0300 Subject: [PATCH 759/794] fix bug #66811 --- MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index 46cb8ddbb43..d4c1d52c57e 100644 --- a/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp +++ b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp @@ -229,8 +229,9 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn { if (reset_default) { - pElement->m_oBrush.Type = c_BrushTypeTexture; // or 3000 set ??? + pElement->m_bIsFilled = false; pElement->m_bLine = false; + pElement->m_oBrush.Type = c_BrushTypeTexture; // or 3000 set ??? } for (size_t i = 0; i < lCount; ++i) { @@ -249,6 +250,7 @@ void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideIn { if (reset_default) { + pElement->m_bIsFilled = false; pElement->m_bLine = false; } for (size_t i = 0; i < lCount; ++i) From 4af39960da84c371b71f52166449f1b1d499e304 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Thu, 6 Jun 2024 09:44:19 +0300 Subject: [PATCH 760/794] Fix bug #50286 --- .../html/css/src/CCssCalculator_Private.cpp | 25 ++++++++++++++----- Common/3dParty/html/css/src/ConstValues.h | 1 + .../3dParty/html/css/src/StyleProperties.cpp | 10 ++++++++ Common/3dParty/html/css/src/StyleProperties.h | 4 ++- .../html/css/src/xhtml/CDocumentStyle.cpp | 15 +++++++---- .../html/css/src/xhtml/CXmlElement.cpp | 6 +++++ 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index fd4852a583c..13742628af5 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -16,8 +16,9 @@ #define MaxNumberRepetitions 6 -inline static std::wstring StringifyValueList(const KatanaArray* oValues); -inline static std::wstring StringifyValue(const KatanaValue* oValue); +inline static std::wstring StringifyValueList(const KatanaArray* oValues); +inline static std::wstring StringifyValue(const KatanaValue* oValue); +inline static bool IsTableElement(const std::wstring& wsNameTag); bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vector<NSCSS::CNode> &arRightSelectors) { @@ -510,23 +511,28 @@ namespace NSCSS std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors); std::vector<std::wstring> arPrevNodes; bool bInTable = false; - + for (size_t i = 0; i < arSelectors.size(); ++i) { oStyle.AddParent(arSelectors[i].m_wsName); // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются if (L"table" == arSelectors[i].m_wsName) - bInTable = true; - - if (bInTable) { oStyle.m_oFont.GetLineHeight().Clear(); oStyle.m_oPadding.Clear(); oStyle.m_oMargin.Clear(); + bInTable = true; + } + + if (bInTable) + { + oStyle.m_oBackground.Clear(); oStyle.m_oBorder.Clear(); } + bInTable = IsTableElement(arSelectors[i].m_wsName); + CCompiledStyle oTempStyle; oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); @@ -780,4 +786,11 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue) return str; } +inline static bool IsTableElement(const std::wstring& wsNameTag) +{ + return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag || + L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag || + L"th" == wsNameTag; +} + diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index ea8cd0772de..4e7f8ab9fe5 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -87,6 +87,7 @@ namespace NSCSS R_Color, R_U, R_Highlight, + R_Shd, R_SmallCaps, R_Kern } RunnerProperties; diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 090cbb4b032..4c9e5b1711c 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -610,6 +610,11 @@ namespace NSCSS return ColorNone == m_oValue.m_enType; } + bool CColor::Url() const + { + return ColorUrl == m_oValue.m_enType; + } + void CColor::Clear() { m_oValue.Clear(); @@ -1285,6 +1290,11 @@ namespace NSCSS { return m_oColor; } + + void CBackground::Clear() + { + m_oColor.Clear(); + } bool CBackground::Empty() const { diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 066bcb68c89..8f81ff8175b 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -136,7 +136,7 @@ namespace NSCSS void Clear() override; void ConvertTo(UnitMeasure enUnitMeasure, double dPrevValue = 0.); - + int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; @@ -230,6 +230,7 @@ namespace NSCSS bool Empty() const override; bool None() const; + bool Url() const; void Clear() override; ColorType GetType() const; @@ -384,6 +385,7 @@ namespace NSCSS const CColor& GetColor() const; + void Clear(); bool Empty() const; bool IsNone() const; diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index a326c97f393..19bd8087b7d 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -488,15 +488,20 @@ namespace NSCSS if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); + if (!oStyle.m_oBackground.GetColor().Empty() && !oStyle.m_oBackground.GetColor().None() && !oStyle.m_oBackground.GetColor().Url()) + oXmlElement.AddPropertiesInR(RProperties::R_Shd, oStyle.m_oBackground.GetColor().ToWString()); + + /* const std::wstring wsHighlight{oStyle.m_oBackground.GetColor().EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"}, - {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, - {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, - {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, - {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, - {{211, 211, 211}, L"lightGray"}})}; + {{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"}, + {{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"}, + {{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"}, + {{139, 0, 0}, L"darkRed"}, {{128, 128, 0}, L"darkYellow"},{{169, 169, 169}, L"darkGray"}, + {{211, 211, 211}, L"lightGray"}})}; if (L"none" != wsHighlight) oXmlElement.AddPropertiesInR(RProperties::R_Highlight, wsHighlight); + */ oXmlElement.AddPropertiesInR(RProperties::R_Color, oStyle.m_oText.GetColor().ToWString()); diff --git a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp index cd997a203e0..5f9db690586 100644 --- a/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp +++ b/Common/3dParty/html/css/src/xhtml/CXmlElement.cpp @@ -454,6 +454,12 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const sRStyle += L"<w:highlight w:val=\"" + oItem.second + L"\"/>"; break; } + case CSSProperties::RunnerProperties::R_Shd: + { + if (!oItem.second.empty()) + sRStyle += L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"" + oItem.second + L"\"/>"; + break; + } case CSSProperties::RunnerProperties::R_SmallCaps: { if (oItem.second == L"smallCaps") From 24fb53ac6fd2131c3526d87938e04c23fa16a487 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Fri, 7 Jun 2024 11:34:23 +0300 Subject: [PATCH 761/794] Fix bug #68426 --- HtmlFile2/htmlfile2.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 090face8322..6298fd5e661 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -2706,6 +2706,9 @@ class CHtmlFile2_Private if (sExtention == L"octet-stream") sExtention = L"jpg"; + if (NotValidExtension(sExtention)) + return bRes; + nBase = sSrcM.find(L"base64", nEndBase); if (nBase == std::wstring::npos) return bRes; From 2da89c8b03d9d1d0ac1b23b363b9c4a6fba986c4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Fri, 7 Jun 2024 15:59:35 +0600 Subject: [PATCH 762/794] Fix bug #68390 --- OOXML/XlsxFormat/Pivot/Pivots.cpp | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 1431f37e4cb..32e6e7dadf3 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -145,11 +145,36 @@ #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include <codecvt> +#include "boost/date_time/gregorian/gregorian.hpp" namespace OOX { namespace Spreadsheet { + std::wstring getDateFromExcelTime(double excelDate) + { + boost::gregorian::date date(1899, boost::gregorian::Dec, 30); + XLSB::PCDIDateTime datetime; + _UINT64 days = std::floor(excelDate); + excelDate -= days; + date += boost::gregorian::date_duration(days); + datetime.yr = date.year(); + datetime.mon = date.month(); + datetime.dom = date.day(); + if(excelDate > 0) + { + excelDate *= 24; + datetime.hr = std::floor(excelDate); + excelDate -= datetime.hr; + excelDate *= 60; + datetime.min = std::floor(excelDate); + excelDate -= datetime.min; + datetime.sec = std::floor(excelDate*60); + } + return datetime.value(); + + } + //struct NullDeleter {template<typename T> void operator()(T*) {} }; void CPivotTableFile::readBin(const CPath& oPath) { @@ -4695,8 +4720,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->fDateInField && !ptr->fMixedTypesIgnoringBlanks && ptr->fNumMinMaxValid) { - m_oMinDate = std::to_wstring(ptr->xnumMin.data.value); - m_oMaxDate = std::to_wstring(ptr->xnumMax.data.value); + m_oMinDate = getDateFromExcelTime(ptr->xnumMin.data.value); + m_oMaxDate = getDateFromExcelTime(ptr->xnumMax.data.value); } else if(ptr->fNumField && ptr->fNumMinMaxValid) { @@ -5093,8 +5118,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->fDates) { - m_oStartDate = std::to_wstring(ptr->xnumStart.data.value); - m_oEndDate = std::to_wstring(ptr->xnumEnd.data.value); + m_oStartDate = getDateFromExcelTime(ptr->xnumStart.data.value); + m_oEndDate = getDateFromExcelTime(ptr->xnumEnd.data.value); } else { From a98ee52dc52576c78738e972002eb1a0c2878ff7 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 7 Jun 2024 17:32:55 +0300 Subject: [PATCH 763/794] Fix bug 68186 --- PdfFile/SrcWriter/FontCidTT.cpp | 32 ++++++++++++++++++++---------- PdfFile/SrcWriter/FontTTWriter.cpp | 10 +++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/PdfFile/SrcWriter/FontCidTT.cpp b/PdfFile/SrcWriter/FontCidTT.cpp index 062c2d6db5f..72ba7d2632d 100644 --- a/PdfFile/SrcWriter/FontCidTT.cpp +++ b/PdfFile/SrcWriter/FontCidTT.cpp @@ -470,7 +470,16 @@ namespace PdfWriter for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) { if (unGID == m_vCodeToGid.at(ushCurCode)) + { + if (m_vUnicodes.at(ushCurCode).empty() && unCount) + { + std::vector<unsigned int> vUnicodes; + for (unsigned int i = 0; i < unCount; i++) + vUnicodes.push_back(pUnicodes[i]); + m_vUnicodes[ushCurCode] = vUnicodes; + } return ushCurCode; + } } if (!OpenFontFace()) @@ -492,6 +501,17 @@ namespace PdfWriter // Если данный символ составной (CompositeGlyf), тогда мы должны учесть все его дочерные символы (subglyfs) if (0 == FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE)) { + if (0 != m_pFace->units_per_EM) + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + else + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + for (int nSubIndex = 0; nSubIndex < m_pFace->glyph->num_subglyphs; nSubIndex++) { FT_Int nSubGID; @@ -502,17 +522,9 @@ namespace PdfWriter FT_Get_SubGlyph_Info(m_pFace->glyph, nSubIndex, &nSubGID, &unFlags, &nArg1, &nArg2, &oMatrix); m_mGlyphs.insert(std::pair<unsigned short, bool>(nSubGID, true)); - } - if (0 != m_pFace->units_per_EM) - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); - } - else - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + EncodeGID(nSubGID, NULL, 0); // TODO необходимо верно указать Unicode для случая записи подсимволов + FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE); } } else diff --git a/PdfFile/SrcWriter/FontTTWriter.cpp b/PdfFile/SrcWriter/FontTTWriter.cpp index a21f0a337f2..25d4685e99e 100644 --- a/PdfFile/SrcWriter/FontTTWriter.cpp +++ b/PdfFile/SrcWriter/FontTTWriter.cpp @@ -321,7 +321,6 @@ namespace PdfWriter 0, 0, // idDelta[0] 0, 0 // pad to a mulitple of four bytes }; - static char arrNameTab[8] = { 0, 0, // format @@ -491,6 +490,7 @@ namespace PdfWriter } pLocaTable[m_nGlyphs].nLen = 0; qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); + pLocaTable[m_nGlyphs].nLen = 0; nPos = 0; for (i = 0; i <= m_nGlyphs; ++i) @@ -623,11 +623,11 @@ namespace PdfWriter arrNewCmapTable[0] = 0; // table version number = 0 arrNewCmapTable[1] = 0; // arrNewCmapTable[2] = 0; // number of encoding tables = 1 - arrNewCmapTable[3] = 1; // + arrNewCmapTable[3] = 1; // arrNewCmapTable[4] = 0; // platform ID = 1 (MacOS) // Эти два поля обязательно должны arrNewCmapTable[5] = 1; // // иметь таки значения, иначе, Adobe arrNewCmapTable[6] = 0; // encoding ID = 0 // Acrobat может открыть данный шрифт. - arrNewCmapTable[7] = 0; // // + arrNewCmapTable[7] = 0; // arrNewCmapTable[8] = 0; // offset of subtable arrNewCmapTable[9] = 0; // arrNewCmapTable[10] = 0; // @@ -645,8 +645,8 @@ namespace PdfWriter for (i = 0; i < unCodesCount; ++i) { - arrNewCmapTable[22 + 2 * i] = pCodeToGID[i] >> 8; - arrNewCmapTable[22 + 2 * i + 1] = pCodeToGID[i] & 0xff; + arrNewCmapTable[22 + 2 * i] = (char)(pCodeToGID[i] >> 8); + arrNewCmapTable[22 + 2 * i + 1] = (char)(pCodeToGID[i] & 0xff); } } else From c82c8743f8331a29b57b779b1370f32fc5b2cb98 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Mon, 10 Jun 2024 10:08:23 +0300 Subject: [PATCH 764/794] improvement of parsing and bracket conversion --- .../StarMath2OOXML/TestSMConverter/main.cpp | 8 +- .../StarMath2OOXML/cconversionsmtoooxml.cpp | 57 +++---- .../StarMath2OOXML/cconversionsmtoooxml.h | 2 +- .../StarMath2OOXML/cstarmathpars.cpp | 145 ++++++++++++++++-- .../Converter/StarMath2OOXML/cstarmathpars.h | 9 +- .../Converter/StarMath2OOXML/typeselements.h | 2 + 6 files changed, 163 insertions(+), 60 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp index 9cb145de3cd..b1d512c0278 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/TestSMConverter/main.cpp @@ -660,7 +660,7 @@ TEST(SMConvectorTest,BracketLangle) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2329\" /><m:endChr m:val=\"\u232A\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u27E8\" /><m:endChr m:val=\"\u27E9\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -670,7 +670,7 @@ TEST(SMConvectorTest,BracketLceil) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u23A1\" /><m:endChr m:val=\"\u23A4\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>12</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229613</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2308\" /><m:endChr m:val=\"\u2309\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>12</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229613</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -680,7 +680,7 @@ TEST(SMConvectorTest,BracketLfloor) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u23A3\" /><m:endChr m:val=\"\u23A6\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>14</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u230A\" /><m:endChr m:val=\"\u230B\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>14</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } @@ -690,7 +690,7 @@ TEST(SMConvectorTest,BracketLline) StarMath::CParserStarMathString oTemp; StarMath::CConversionSMtoOOXML oTest; oTest.StartConversion(oTemp.Parse(wsString)); - std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u23AA\" /><m:endChr m:val=\"\u23AA\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>16</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>17</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + std::wstring wsXmlString = L"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u007C\" /><m:endChr m:val=\"\u007C\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>16</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>17</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; EXPECT_EQ(oTest.GetOOXML(),wsXmlString); } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 719cd819ba6..2b43665e1e5 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -330,39 +330,10 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } - void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion) + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsOpenBracket, std::wstring &wsCloseBracket, CAttribute* pAttribute, const TypeConversion &enTypeConversion, const TypeElement &enTypeBracket) { pXmlWrite->WriteNodeBegin(L"m:dPr",false); - switch(enTypeBracket) - { - case TypeElement::langle: - BracketTypeNotation(L"\u27E8",L"\u27E9",pXmlWrite); - break; - case TypeElement::square: - BracketTypeNotation(L"\u005B",L"\u005D",pXmlWrite); - break; - case TypeElement::ldbracket: - BracketTypeNotation(L"\u27E6",L"\u27E7",pXmlWrite); - break; - case TypeElement::lbrace: - BracketTypeNotation(L"\u007B",L"\u007D",pXmlWrite); - break; - case TypeElement::lceil: - BracketTypeNotation(L"\u2308",L"\u2309",pXmlWrite); - break; - case TypeElement::lfloor: - BracketTypeNotation(L"\u230A",L"\u230B",pXmlWrite); - break; - case TypeElement::lline: - BracketTypeNotation(L"\u007C",L"\u007C",pXmlWrite); - break; - case TypeElement::ldline: - BracketTypeNotation(L"\u2016",L"\u2016",pXmlWrite); - break; - case TypeElement::abs: - BracketTypeNotation(L"\u007C",L"\u007C",pXmlWrite); - break; - } + BracketTypeNotation(wsOpenBracket,wsCloseBracket,pXmlWrite); pXmlWrite->WriteNodeBegin(L"m:ctrlPr"); StandartProperties(pXmlWrite,pAttribute,enTypeConversion); pXmlWrite->WriteNodeEnd(L"m:ctrlPr",false,false); @@ -370,12 +341,24 @@ namespace StarMath { } void CConversionSMtoOOXML::BracketTypeNotation(const std::wstring &wsOpenBracket, const std::wstring &wsCloseBracket, XmlUtils::CXmlWriter *pXmlWrite) { - pXmlWrite->WriteNodeBegin(L"m:begChr", true); - pXmlWrite->WriteAttribute(L"m:val",wsOpenBracket); - pXmlWrite->WriteNodeEnd(L"w",true,true); - pXmlWrite->WriteNodeBegin(L"m:endChr", true); - pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); - pXmlWrite->WriteNodeEnd(L"w",true,true); + if(!wsOpenBracket.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:begChr", true); + if(wsOpenBracket == L"none") + pXmlWrite->WriteAttribute(L"m:val",L""); + else + pXmlWrite->WriteAttribute(L"m:val",wsOpenBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } + if(!wsCloseBracket.empty()) + { + pXmlWrite->WriteNodeBegin(L"m:endChr", true); + if(wsCloseBracket == L"none") + pXmlWrite->WriteAttribute(L"m:val",L""); + else + pXmlWrite->WriteAttribute(L"m:val", wsCloseBracket); + pXmlWrite->WriteNodeEnd(L"w",true,true); + } } void CConversionSMtoOOXML::PropertiesMPr(XmlUtils::CXmlWriter *pXmlWrite, const TypeElement &enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion) { diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index b0a2ff2a3b0..fc971362f3e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -48,7 +48,7 @@ namespace StarMath { static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsOpenBracket,std::wstring& wsCloseBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion,const TypeElement& enTypeBracket); static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 70bb108cc75..9849f2ff9ad 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -732,7 +732,12 @@ namespace StarMath return new CElementFunction(pReader->GetLocalType(),pReader->GetTypeConversion()); } case TypeElement::Bracket: - return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); + { + if(pReader->GetLocalType() == TypeElement::left) + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion(),true); + else + return new CElementBracket(pReader->GetLocalType(),pReader->GetTypeConversion()); + } case TypeElement::Operation: { if(pReader->GetLocalType() == TypeElement::oper) @@ -996,6 +1001,9 @@ namespace StarMath case TypeElement::circ: pXmlWrite->WriteString(L"\u2218"); break; + case TypeElement::widebslash: + pXmlWrite->WriteString(L"\u2216"); + break; default: break; } @@ -1107,8 +1115,8 @@ namespace StarMath return m_enTypeBinOp; } //class methods CElementBracket - CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion) - :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType) + CElementBracket::CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion,const bool& bScalability) + :CElement(TypeElement::Bracket,enTypeConversion),m_enTypeBracket(enType),m_bScalability(bScalability) { } CElementBracket::~CElementBracket() @@ -1124,6 +1132,7 @@ namespace StarMath if(L"{" == wsToken) return TypeElement::brace; else if(L"(" == wsToken) return TypeElement::round; else if(L"[" == wsToken) return TypeElement::square; + else if(L"left" == wsToken) return TypeElement::left; else if(L"ldbracket" == wsToken) return TypeElement::ldbracket; else if(L"lbrace" == wsToken) return TypeElement::lbrace; else if(L"langle" == wsToken) return TypeElement::langle; @@ -1146,6 +1155,7 @@ namespace StarMath else if(L"rline" == wsToken) return TypeElement::rline; else if(L"rdline" == wsToken) return TypeElement::rdline; else if(L"right" == wsToken) return TypeElement::right; + else if(L"none" == wsToken) return TypeElement::none; else return TypeElement::undefine; } std::vector<CElement*> CElementBracket::GetBracketValue() @@ -1154,30 +1164,82 @@ namespace StarMath } void CElementBracket::Parse(CStarMathReader* pReader) { + TypeElement enOpen,enClose; + if(m_enTypeBracket == TypeElement::left) + { + pReader->ReadingTheNextToken(); + enOpen = GetBracketOpen(pReader->GetLowerCaseString()); + enClose = GetBracketClose(pReader->GetLowerCaseString()); + if(enOpen != TypeElement::undefine) + { + m_enLeftBracket = enOpen; + pReader->ClearReader(); + } + else if(enClose != TypeElement::undefine) + { + m_enLeftBracket = enClose; + pReader->ClearReader(); + } + } pReader->FindingTheEndOfParentheses(); while(pReader->CheckIteratorPosition()) { + pReader->ReadingTheNextToken(); + if(pReader->GetLowerCaseString() == L"right") + { + pReader->ClearReader(); + continue; + } CParserStarMathString::ParsElementAddingToArray(pReader,m_arBrecketValue); } - if(!pReader->EmptyString()) + if(!pReader->EmptyString() && pReader->GetLowerCaseString() != L"right") { if(pReader->GetLocalType() == TypeElement::newline) { m_arBrecketValue.push_back(new CElementSpecialSymbol(pReader->GetLocalType(),pReader->GetTypeConversion())); pReader->ClearReader(); } - CElement* pTempElement =CParserStarMathString::ParseElement(pReader); - if(nullptr != pTempElement) - m_arBrecketValue.push_back(pTempElement); + else + { + CElement* pTempElement =CParserStarMathString::ParseElement(pReader); + if(nullptr != pTempElement) + m_arBrecketValue.push_back(pTempElement); + } + } + pReader->SettingTheIteratorToTheClosingBracket(); + pReader->ClearReader(); + pReader->ReadingTheNextToken(); + enOpen = GetBracketOpen(pReader->GetLowerCaseString()); + enClose = GetBracketClose(pReader->GetLowerCaseString()); + if(enOpen != TypeElement::undefine) + { + m_enRightBracket = enOpen; + pReader->ClearReader(); + } + else if(enClose != TypeElement::undefine) + { + m_enRightBracket = enClose; + pReader->ClearReader(); } pReader->IteratorNullification(); } void CElementBracket::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) { + std::wstring wsOpenBracket,wsCloseBracket; + if(m_bScalability) + { + wsOpenBracket = DefiningBracket(m_enLeftBracket); + wsCloseBracket = DefiningBracket(m_enRightBracket); + } + else + { + wsOpenBracket = DefiningBracket(m_enTypeBracket); + wsCloseBracket = DefiningBracket(m_enRightBracket); + } if(m_enTypeBracket != TypeElement::brace) { pXmlWrite->WriteNodeBegin(L"m:d",false); - CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,m_enTypeBracket,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,wsOpenBracket,wsCloseBracket,GetAttribute(),GetTypeConversion(),m_enTypeBracket); pXmlWrite->WriteNodeBegin(L"m:e",false); for(CElement* pTemp:m_arBrecketValue) { @@ -1230,6 +1292,46 @@ namespace StarMath pTempElement->SetAttribute(pAttribute); } } + std::wstring CElementBracket::DefiningBracket(const TypeElement &enTypeBracket) + { + switch(enTypeBracket) + { + case TypeElement::langle: + return L"\u27E8"; + case TypeElement::rangle: + return L"\u27E9"; + case TypeElement::square: + return L"\u005B"; + case TypeElement::rsquare: + return L"\u005D"; + case TypeElement::ldbracket: + return L"\u27E6"; + case TypeElement::rdbracket: + return L"\u27E7"; + case TypeElement::lbrace: + return L"\u007B"; + case TypeElement::rbrace: + return L"\u007D"; + case TypeElement::lceil: + return L"\u2308"; + case TypeElement::rceil: + return L"\u2309"; + case TypeElement::lfloor: + return L"\u230A"; + case TypeElement::rfloor: + return L"\u230B"; + case TypeElement::lline: + case TypeElement::rline: + return L"\u007C"; + case TypeElement::ldline: + case TypeElement::rdline: + return L"\u2016"; + case TypeElement::none: + return L"none"; + default: + return L""; + } + } //class methods CElementSpecialSymbol CElementSpecialSymbol::CElementSpecialSymbol(const TypeElement &enType,const TypeConversion &enTypeConversion) :CElement(TypeElement::SpecialSymbol,enTypeConversion),m_pValue(nullptr),m_enTypeSpecial(enType),m_wsType(L"") @@ -1273,6 +1375,8 @@ namespace StarMath { if(L"#" == wsToken) return TypeElement::grid; else if(L"<?>" == wsToken) return TypeElement::emptySquare; + else if(L"<?" == wsToken) return TypeElement::emptySquare; + else if(L"?>" == wsToken) return TypeElement::emptySquare; else if(L"mline" == wsToken) return TypeElement::mline; else if(L"##" == wsToken) return TypeElement::transition; else if(L"emptyset" == wsToken) return TypeElement::emptyset; @@ -1419,7 +1523,7 @@ namespace StarMath case TypeElement::abs: { pXmlWrite->WriteNodeBegin(L"m:d",false); - CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,TypeElement::abs,GetAttribute(),GetTypeConversion()); +// CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,TypeElement::abs,GetAttribute(),GetTypeConversion()); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:d",false,false); break; @@ -2763,8 +2867,6 @@ namespace StarMath } if(m_pAttribute != nullptr && !m_pAttribute->CheckAttribute()) m_pAttribute = nullptr; - if(m_wsLowerCaseToken == L"left") TokenProcessing(); - else if(L"right" == m_wsLowerCaseToken ) TokenProcessing(); return true; } return false; @@ -3031,12 +3133,19 @@ namespace StarMath } if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine) { - inBracketInside +=1; + if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) == TypeElement::left) + continue; + else + inBracketInside +=1; } + else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) == TypeElement::right) + continue; else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) != TypeElement::undefine && inBracketInside == 0) { m_stBracket.push(m_itEnd); + m_stCloseBracket.push(m_itStart); m_itEnd = itStartBracketClose; +// m_itEnd = m_itStart; break; } else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) != TypeElement::undefine && inBracketInside != 0) @@ -3054,10 +3163,14 @@ namespace StarMath m_itEnd = m_stBracket.top(); m_stBracket.pop(); } - while(TypeElement::undefine == CElementBracket::GetBracketClose(GetLowerCaseString()) && CheckIteratorPosition()) + ClearReader(); + } + void CStarMathReader::SettingTheIteratorToTheClosingBracket() + { + if(!m_stCloseBracket.empty()) { - if (false == GetToken()) - break; + m_itEnd = m_stCloseBracket.top(); + m_stCloseBracket.pop(); } ClearReader(); } @@ -3100,6 +3213,8 @@ namespace StarMath { if(L'%' == cLastToken) return false; +// else if(L'\u2030' == cLastToken) +// return false; if(iswalpha(cLastToken)) return false; } diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h index 4ed26e9fddb..3e4218ad2b2 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -135,6 +135,7 @@ namespace StarMath void SetString(const std::wstring& wsToken); void FindingTheEndOfParentheses(); void IteratorNullification(); + void SettingTheIteratorToTheClosingBracket(); void ReadingTheNextToken(); void SetMarkForUnar(const bool& bMark); bool GetMarkForUnar(); @@ -150,7 +151,7 @@ namespace StarMath CAttribute* m_pAttribute; CAttribute* m_pBaseAttribute; TypeConversion m_enTypeCon; - std::stack<std::wstring::iterator> m_stBracket; + std::stack<std::wstring::iterator> m_stBracket,m_stCloseBracket; }; class CElement @@ -296,7 +297,7 @@ namespace StarMath class CElementBracket: public CElement { public: - CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion); + CElementBracket(const TypeElement& enType,const TypeConversion &enTypeConversion,const bool& bScalability = false); virtual ~CElementBracket(); void SetBracketValue(const std::vector<CElement*>& arValue); static TypeElement GetBracketOpen(const std::wstring& wsToken); @@ -307,8 +308,10 @@ namespace StarMath void Parse(CStarMathReader* pReader) override; void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; bool CheckMline(CElement* pElement); - TypeElement m_enTypeBracket; + std::wstring DefiningBracket(const TypeElement& enTypeBracket); + TypeElement m_enTypeBracket,m_enLeftBracket,m_enRightBracket; std::vector<CElement*> m_arBrecketValue; + bool m_bScalability; }; class CElementBracketWithIndex: public CElement diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h index 61a2e011ead..3ee93a9fe15 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -105,6 +105,7 @@ enum class TypeElement{ lfloor, lline, ldline, + left, //attribute ital, bold, @@ -358,6 +359,7 @@ enum class TypeElement{ rline, rdline, right, + none, //op from, to, From a81fb19e1a074ff5334bf2cce665d4b5622972db Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Mon, 10 Jun 2024 10:35:08 +0300 Subject: [PATCH 765/794] fix bug 68445 --- .../Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 9849f2ff9ad..c368a50eb6a 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1247,13 +1247,8 @@ namespace StarMath continue; if(CheckMline(pTemp)) { - pXmlWrite->WriteNodeBegin(L"m:r",false); - CConversionSMtoOOXML::StandartProperties(pXmlWrite,GetAttribute(),GetTypeConversion()); - pXmlWrite->WriteNodeBegin(L"m:t",false); - pXmlWrite->WriteString(L"\u007C"); - pXmlWrite->WriteNodeEnd(L"m:t",false,false); - pXmlWrite->WriteNodeEnd(L"m:r",false,false); - continue; + pXmlWrite->WriteNodeEnd(L"m:e",false,false); + pXmlWrite->WriteNodeBegin(L"m:e",false); } CConversionSMtoOOXML::ElementConversion(pXmlWrite,pTemp); } From 29788a5d1b7ddb3a3f40559b75cca13171cbd19f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Mon, 10 Jun 2024 11:14:55 +0300 Subject: [PATCH 766/794] Fix bug 68479 --- DesktopEditor/graphics/Graphics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 24ed749aec9..5e2e072c4bb 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -625,7 +625,7 @@ namespace Aggplus } double dWidth = pPen->Size; - double dWidthMinSize = 1.0 / sqrt(m_oFullTransform.m_internal->m_agg_mtx.determinant()); + double dWidthMinSize = 1.0 / sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) { @@ -762,7 +762,7 @@ namespace Aggplus } } - dWidthMinSize = 1.0 / sqrt(m_oCoordTransform.m_internal->m_agg_mtx.determinant()); + dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) dWidth = dWidthMinSize; From 95f91b816a16325af2bdef595dba31f03387f987 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Sat, 8 Jun 2024 13:25:11 +0300 Subject: [PATCH 767/794] Fix bug #64722 --- Common/3dParty/html/htmltoxhtml.h | 26 ++++++++++++++++++-------- EpubFile/src/CBookItem.cpp | 5 +---- EpubFile/src/CEpubFile.cpp | 14 ++++++++++---- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index c941a6a724b..2e5ba1eaef2 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -39,7 +39,9 @@ static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2 "hgroup","isindex","keygen","marquee","nobr","noembed","noframes", "noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"}; -static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder); +static std::vector<std::string> unchecked_nodes_new = {"svg"}; + +static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true); static std::string mhtTohtml(const std::string &sFileContent); // Заменяет в строке s все символы s1 на s2 @@ -53,6 +55,11 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } +static bool IsUnckeckedNodes(const std::string& sValue) +{ + return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue); +} + static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert) { if (bNeedConvert) @@ -527,7 +534,7 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr } } -static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents) +static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode) { std::string key = "|" + get_tag_name(node) + "|"; bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; @@ -558,7 +565,7 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA contents.WriteString(val); } else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE)) - prettyprint(child, contents); + prettyprint(child, contents, bCheckValidNode); else if (child->type == GUMBO_NODE_WHITESPACE) { if (keep_whitespace || is_inline || is_like_inline) @@ -573,21 +580,24 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA } } -static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder) +static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode) { // special case the document node if (node->type == GUMBO_NODE_DOCUMENT) { build_doctype(node, oBuilder); - prettyprint_contents(node, oBuilder); + prettyprint_contents(node, oBuilder, bCheckValidNode); return; } std::string tagname = get_tag_name(node); - if (html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname)) + if (bCheckValidNode) + bCheckValidNode = !IsUnckeckedNodes(tagname); + + if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname)) { - prettyprint_contents(node, oBuilder); + prettyprint_contents(node, oBuilder, bCheckValidNode); return; } @@ -612,7 +622,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde oBuilder.WriteString(close + ">"); // prettyprint your contents - prettyprint_contents(node, oBuilder); + prettyprint_contents(node, oBuilder, bCheckValidNode); oBuilder.WriteString(closeTag); } diff --git a/EpubFile/src/CBookItem.cpp b/EpubFile/src/CBookItem.cpp index 69c3ea39702..e25c16ec43d 100644 --- a/EpubFile/src/CBookItem.cpp +++ b/EpubFile/src/CBookItem.cpp @@ -63,10 +63,7 @@ bool CBookItem::ReadItem(XmlUtils::CXmlLiteReader& oXmlLiteReader, int depth) std::wstring sAttributeValue = oXmlLiteReader.GetText(); if (sAttributeName == L"href") - { - sAttributeValue = URLDecode(sAttributeValue); - m_sRef = NSFile::GetFileName(sAttributeValue); - } + m_sRef = URLDecode(sAttributeValue); else if (sAttributeName == L"id") m_sID = sAttributeValue; else if (sAttributeName == L"media-type") diff --git a/EpubFile/src/CEpubFile.cpp b/EpubFile/src/CEpubFile.cpp index 7ef264aef4e..587fa3fda56 100644 --- a/EpubFile/src/CEpubFile.cpp +++ b/EpubFile/src/CEpubFile.cpp @@ -69,19 +69,25 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s COfficeUtils oOfficeUtils; wchar_t* password = NULL; - if (oOfficeUtils.ExtractToDirectory(sInputFile, m_sTempDir.c_str(), password, 1) != S_OK) + if (oOfficeUtils.ExtractToDirectory(sInputFile, m_sTempDir.c_str(), password, 0) != S_OK) return S_FALSE; std::wstring sFileContent; std::wstring sContent; - if (!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/container.xml", sFileContent)) + if (!NSFile::CFileBinary::ReadAllTextUtf8(m_sTempDir + L"/META-INF/container.xml", sFileContent)) return S_FALSE; size_t nContent = sFileContent.find(L"full-path"); if (nContent != std::wstring::npos) { nContent += 11; - sContent = NSFile::GetFileName(sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent)); + sContent = sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent); } + + std::wstring sContentPath; + + if (std::wstring::npos != sContent.find(L'/') || std::wstring::npos != sContent.find(L'\\')) + sContentPath = NSFile::GetDirectoryName(sContent); + sContent = m_sTempDir + (sContent.empty() ? L"/content.opf" : L'/' + sContent); XmlUtils::CXmlLiteReader oXmlLiteReader; @@ -155,7 +161,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s { std::wstring sFile = m_mapRefs[oContent.m_sID].GetRef(); replace_all(sFile, L"%20", L" "); - arFiles.push_back(m_sTempDir + L"/" + sFile); + arFiles.push_back(m_sTempDir + ((!sContentPath.empty()) ? (L"/" + sContentPath) : L"" ) + L"/" + sFile); } #ifdef _DEBUG From 9a5e1464bd44443be63e70d68a7f9fa0be179c11 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Tue, 11 Jun 2024 12:32:39 +0600 Subject: [PATCH 768/794] Fix bug #68485 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 6f8d98bb3e9..2c87c69f185 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2212,7 +2212,7 @@ namespace OOX break; case SimpleTypes::Spreadsheet::celltypeSharedString: { - if(m_oValue.IsInit()) + if(m_oValue.IsInit() && !m_oFormula.IsInit()) { auto pCellIsst(new XLSB::CellIsst); pCellIsst->value = std::stoi(m_oValue->m_sText); From 14b66e2bb306e687ce64280df54bc29924956207 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Tue, 11 Jun 2024 11:39:04 +0300 Subject: [PATCH 769/794] Fix bug 68532 --- PdfFile/PdfEditor.cpp | 2 +- PdfFile/PdfReader.cpp | 2 +- PdfFile/PdfReader.h | 2 +- PdfFile/SrcReader/PdfAnnot.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index bc6114f0b07..8bc470e8a3b 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1110,7 +1110,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); else if (oType.isName("FreeText")) { - std::map<std::wstring, std::wstring> mapFont = pReader->AnnotFonts(&oAnnotRef); + std::map<std::wstring, std::wstring> mapFont = pReader->GetAnnotFonts(&oAnnotRef); m_mFonts.insert(mapFont.begin(), mapFont.end()); pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); } diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 677b44ff6c5..a0c4f7bb4f0 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -981,7 +981,7 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } -std::map<std::wstring, std::wstring> CPdfReader::AnnotFonts(Object* pRefAnnot) +std::map<std::wstring, std::wstring> CPdfReader::GetAnnotFonts(Object* pRefAnnot) { return PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, pRefAnnot, m_pFontManager, m_pFontList, 3); } diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 36d14ae5d4d..3cf92ad79e2 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -82,7 +82,7 @@ class CPdfReader BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); - std::map<std::wstring, std::wstring> AnnotFonts(Object* pRefAnnot); + std::map<std::wstring, std::wstring> GetAnnotFonts(Object* pRefAnnot); private: PDFDoc* m_pPDFDocument; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index fa5dcceabe3..7a19c8c809b 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2444,9 +2444,10 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object continue; std::string sFontName = arrRC[i]->sFontFamily; + std::wstring wsFontName = UTF8_TO_U(sFontName); bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); - bool bBase = sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats"; + bool bBase = isBaseFont(wsFontName) || sFontName == "Times New Roman"; if ((nTypeFonts & 2) && bBase) { if (sFontName == "Times New Roman") @@ -2472,7 +2473,6 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object const unsigned char* pData14 = NULL; unsigned int nSize14 = 0; - std::wstring wsFontName = UTF8_TO_U(sFontName); if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Add(wsFontName, (BYTE*)pData14, nSize14, false); std::string sFontNameBefore = arrRC[i]->sFontFamily; @@ -2496,7 +2496,7 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object oFontSelect.bBold = new INT(1); if (bItalic) oFontSelect.bItalic = new INT(1); - oFontSelect.wsName = new std::wstring(UTF8_TO_U(sFontName)); + oFontSelect.wsName = new std::wstring(wsFontName); NSFonts::CFontInfo* pFontInfo = pAppFontList->GetByParams(oFontSelect); if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) From 5dfeeeb80929d2cc8c40352757d7f75c4f76a245 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Tue, 11 Jun 2024 15:52:14 +0600 Subject: [PATCH 770/794] Fix bug #68503 --- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp | 2 +- .../XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 38bbc1fdeb5..3bf7f063c0b 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -102,7 +102,7 @@ const int normalizeRow(const int row, const bool xlsb) maxRow = 65536; } int norm_row = row; - while(norm_row > maxRow) + while(norm_row >= maxRow) { norm_row -= maxRow; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp index 8a878792835..0b885ee1158 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtPtgArea3D.cpp @@ -60,7 +60,11 @@ void ExtPtgArea3D::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, boo { std::wstring strRange; - std::wstring range_ref = area.toString(); + std::wstring range_ref; + if (global_info->Version < 0x0800) + range_ref = area.toString(); + else + range_ref = area.toString(true, true); if(-1 == iTabs.itabFirst) { From 407072551551c7254c844d34b7eb7ae77d6007ff Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Tue, 11 Jun 2024 18:34:27 +0600 Subject: [PATCH 771/794] Fix bug #68510 --- .../Format/Logic/Biff_structures/StringPtgParser.cpp | 10 +++++++--- OOXML/XlsxFormat/Controls/Controls.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index c9c635ad9dc..43359c6508c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -478,9 +478,13 @@ const void StringPtgParser::parsePtgTypes(Rgce& rgce) auto paramsNum = funcPtr->getParametersNum(); auto refArgs = PosValArgs(funcPtr->getFuncIndex()); for(auto j = paramsNum-1; j >= 0; j--) - { if(refArgs.size() > j && refArgs.at(j)) - SetPtgType(functionStack.back(), 3); - functionStack.pop_back(); + { + if(!functionStack.empty()) + { + if(refArgs.size() > j && refArgs.at(j)) + SetPtgType(functionStack.back(), 3); + functionStack.pop_back(); + } } ///check and change fixed num of args } diff --git a/OOXML/XlsxFormat/Controls/Controls.cpp b/OOXML/XlsxFormat/Controls/Controls.cpp index c0dc716b6d0..b0d80959d0f 100644 --- a/OOXML/XlsxFormat/Controls/Controls.cpp +++ b/OOXML/XlsxFormat/Controls/Controls.cpp @@ -210,7 +210,7 @@ namespace OOX ptr->shapeId = m_oShapeId->GetValue(); else ptr->shapeId = 1; - if (!m_oName.IsInit()) + if (m_oName.IsInit()) ptr->strName = m_oName.get(); else ptr->strName = L""; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 6f8d98bb3e9..2c87c69f185 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2212,7 +2212,7 @@ namespace OOX break; case SimpleTypes::Spreadsheet::celltypeSharedString: { - if(m_oValue.IsInit()) + if(m_oValue.IsInit() && !m_oFormula.IsInit()) { auto pCellIsst(new XLSB::CellIsst); pCellIsst->value = std::stoi(m_oValue->m_sText); From 3316216f8e3629f45470c97f1e9947e32cdc12a3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev <viktor.andreev@onlyoffice.com> Date: Tue, 11 Jun 2024 19:35:41 +0600 Subject: [PATCH 772/794] Fix bug #68404 --- OOXML/XlsxFormat/Ole/OleObjects.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OOXML/XlsxFormat/Ole/OleObjects.cpp b/OOXML/XlsxFormat/Ole/OleObjects.cpp index 9406977c9b6..c4adf6178ef 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.cpp +++ b/OOXML/XlsxFormat/Ole/OleObjects.cpp @@ -323,12 +323,17 @@ namespace OOX ptr->strProgID = m_oProgId.get(); if(m_oLink.IsInit()) + { + ptr->fLinked = true; ptr->link = m_oLink.get(); + } else ptr->fLinked = false; if(m_oRid.IsInit()) ptr->strRelID.value = m_oRid->GetValue(); + else + ptr->strRelID.value.setSize(0); return objectPtr; } From 505d8093ef214cfa670f050dc4aa0343e1ada218 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 11 Jun 2024 19:42:41 +0300 Subject: [PATCH 773/794] fix bug #68238 --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 92 ++++++++++----------- OOXML/XlsbFormat/WorkSheetStream.cpp | 4 +- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 54af846621c..6f12f442e63 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -5979,8 +5979,7 @@ void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorkshee pFormControlPr = pFileCtrlProp->m_oFormControlPr.GetPointer(); } else - { //using controls without activeX causes bugs - continue; + { smart_ptr<OOX::ActiveX_xml> pActiveX_xml = pFileControl.smart_dynamic_cast<OOX::ActiveX_xml>(); if ((pActiveX_xml.IsInit()) && (pActiveX_xml->m_oObject.IsInit())) @@ -6091,257 +6090,256 @@ void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorkshee void BinaryWorksheetTableWriter::WriteControlPr(OOX::Spreadsheet::CControlPr* pControlPr, OOX::Spreadsheet::CFormControlPr* pFormControlPr) { - if (!pControlPr) return; - if (!pFormControlPr) return; + if (!pControlPr && !pFormControlPr) return; int nCurPos = 0; - if (pFormControlPr->m_oObjectType.IsInit()) + if (pFormControlPr && pFormControlPr->m_oObjectType.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ObjectType); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oObjectType->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAltText.IsInit()) + if (pControlPr && pControlPr->m_oAltText.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::AltText); m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oAltText); } - if (pControlPr->m_oAutoFill.IsInit()) + if (pControlPr && pControlPr->m_oAutoFill.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoFill); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoFill); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAutoLine.IsInit()) + if (pControlPr && pControlPr->m_oAutoLine.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoLine); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoLine); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oAutoPict.IsInit()) + if (pControlPr && pControlPr->m_oAutoPict.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoPict); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoPict); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oDefaultSize.IsInit()) + if (pControlPr && pControlPr->m_oDefaultSize.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DefaultSize); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDefaultSize); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oDisabled.IsInit()) + if (pControlPr && pControlPr->m_oDisabled.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Disabled); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDisabled); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oLocked.IsInit()) + if (pControlPr && pControlPr->m_oLocked.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Locked); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oLocked); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oPrint.IsInit()) + if (pControlPr && pControlPr->m_oPrint.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Print); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oPrint); m_oBcw.WriteItemEnd(nCurPos); } - if (pControlPr->m_oRecalcAlways.IsInit()) + if (pControlPr && pControlPr->m_oRecalcAlways.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::RecalcAlways); m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oRecalcAlways); m_oBcw.WriteItemEnd(nCurPos); } - if(pControlPr->m_oMacro.IsInit()) + if(pControlPr && pControlPr->m_oMacro.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Macro); m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oMacro); } - if(pFormControlPr->m_oFmlaGroup.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaGroup.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaGroup); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaGroup); } - if(pFormControlPr->m_oFmlaLink.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaLink.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaLink); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaLink); } - if(pFormControlPr->m_oFmlaRange.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaRange.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaRange); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaRange); } - if(pFormControlPr->m_oFmlaTxbx.IsInit()) + if(pFormControlPr && pFormControlPr->m_oFmlaTxbx.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaTxbx); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaTxbx); } - if (pFormControlPr->m_oDropLines.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDropLines.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropLines); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDropLines->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oChecked.IsInit()) + if (pFormControlPr && pFormControlPr->m_oChecked.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Checked); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oChecked->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oDropStyle.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDropStyle.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropStyle); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oDropStyle->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oDx.IsInit()) + if (pFormControlPr && pFormControlPr->m_oDx.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Dx); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDx->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oInc.IsInit()) + if (pFormControlPr && pFormControlPr->m_oInc.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Inc); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oInc->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oMin.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMin.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Min); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMin->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oMax.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMax.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Max); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMax->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oPage.IsInit()) + if (pFormControlPr && pFormControlPr->m_oPage.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Page); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oPage->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oSel.IsInit()) + if (pFormControlPr && pFormControlPr->m_oSel.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Sel); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oSel->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oSelType.IsInit()) + if (pFormControlPr && pFormControlPr->m_oSelType.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::SelType); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oSelType->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oTextHAlign.IsInit()) + if (pFormControlPr && pFormControlPr->m_oTextHAlign.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextHAlign); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextHAlign->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oTextVAlign.IsInit()) + if (pFormControlPr && pFormControlPr->m_oTextVAlign.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextVAlign); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextVAlign->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oVal.IsInit()) + if (pFormControlPr && pFormControlPr->m_oVal.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Val); m_oBcw.m_oStream.WriteLONG(*pFormControlPr->m_oVal); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oWidthMin.IsInit()) + if (pFormControlPr && pFormControlPr->m_oWidthMin.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::WidthMin); m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oWidthMin->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oEditVal.IsInit()) + if (pFormControlPr && pFormControlPr->m_oEditVal.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::EditVal); m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oEditVal->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oColored.IsInit()) + if (pFormControlPr && pFormControlPr->m_oColored.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Colored); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oColored); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oFirstButton.IsInit()) + if (pFormControlPr && pFormControlPr->m_oFirstButton.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::FirstButton); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oFirstButton); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oHoriz.IsInit()) + if (pFormControlPr && pFormControlPr->m_oHoriz.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Horiz); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oHoriz); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oJustLastX.IsInit()) + if (pFormControlPr && pFormControlPr->m_oJustLastX.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::JustLastX); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oJustLastX); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oLockText.IsInit()) + if (pFormControlPr && pFormControlPr->m_oLockText.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::LockText); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oLockText); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oNoThreeD.IsInit()) + if (pFormControlPr && pFormControlPr->m_oNoThreeD.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oNoThreeD2.IsInit()) + if (pFormControlPr && pFormControlPr->m_oNoThreeD2.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD2); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD2); m_oBcw.WriteItemEnd(nCurPos); } - if(pFormControlPr->m_oMultiSel.IsInit()) + if(pFormControlPr && pFormControlPr->m_oMultiSel.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::MultiSel); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oMultiSel); } - if (pFormControlPr->m_oMultiLine.IsInit()) + if (pFormControlPr && pFormControlPr->m_oMultiLine.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::MultiLine); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oMultiLine); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oVerticalBar.IsInit()) + if (pFormControlPr && pFormControlPr->m_oVerticalBar.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::VerticalBar); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oVerticalBar); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oPasswordEdit.IsInit()) + if (pFormControlPr && pFormControlPr->m_oPasswordEdit.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::PasswordEdit); m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oPasswordEdit); m_oBcw.WriteItemEnd(nCurPos); } - if (pFormControlPr->m_oText.IsInit()) + if (pFormControlPr && pFormControlPr->m_oText.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Text); m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oText); } - if(pFormControlPr->m_oItemLst.IsInit()) + if(pFormControlPr && pFormControlPr->m_oItemLst.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ItemLst); for (size_t i = 0; i < pFormControlPr->m_oItemLst->m_arrItems.size(); ++i) diff --git a/OOXML/XlsbFormat/WorkSheetStream.cpp b/OOXML/XlsbFormat/WorkSheetStream.cpp index 410b7de2cac..44a2bf4ed2e 100644 --- a/OOXML/XlsbFormat/WorkSheetStream.cpp +++ b/OOXML/XlsbFormat/WorkSheetStream.cpp @@ -182,13 +182,13 @@ const bool WorkSheetStream::loadContent(BinProcessor& proc) }*/ m_SheetaDataPosition = proc.GetRecordPosition(); while (proc.getNextRecordType() != rt_EndSheetData) - proc.SkipRecord(); + proc.SkipRecord(false); }break; case rt_BeginUserShViews: { while (proc.getNextRecordType() != rt_EndUserShViews) - proc.SkipRecord(); + proc.SkipRecord(false); }break; case rt_WsFmtInfo: From e16578c3a1df04a313009747839362d538e45f37 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 11 Jun 2024 21:36:15 +0300 Subject: [PATCH 774/794] fix bug #65788 --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 12 ++++++++++-- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 6f12f442e63..9f28194c7ab 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -74,6 +74,7 @@ #include "../../../XlsxFormat/Workbook/Metadata.h" #include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../Common/OfficeFileFormatChecker.h" namespace BinXlsxRW { @@ -8587,11 +8588,18 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring //write dummy header and main table oXlsbWriter.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64)); oXlsbWriter.WriteReserved(GetMainTableSize()); - int nDataStartPos = oXlsbWriter.GetPositionAbsolute(); + int nDataStartPos = oXlsbWriter.GetPositionAbsolute(); + + // retest fileType - 1 || 4 + COfficeFileFormatChecker checker; + if (checker.isOOXFormatFile(sInputDir, true)) + { + fileType = (checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB) ? 4 : 1; + } if (fileType == 1) { - pXlsx->m_pXlsbWriter = &oXlsbWriter; + pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder } //parse pXlsx->Read(OOX::CPath(sInputDir)); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 2c87c69f185..b808b46cb7d 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2691,7 +2691,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - nRow--; + //nRow--; nCol--; } } From e03b3e9f1b729d68348bc3da2a0ca61dbd25f228 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Tue, 11 Jun 2024 22:01:06 +0300 Subject: [PATCH 775/794] fix bug #68540 --- .../Format/style_paragraph_properties_pptx.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp index 1735eb6972d..8e40c414893 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp @@ -470,13 +470,16 @@ void paragraph_format_properties::pptx_convert(oox::pptx_conversion_context & Co if (last_paragraph_style) { const style_paragraph_properties* last_style_paragraph_props = last_paragraph_style->content()->get_style_paragraph_properties(); - const paragraph_format_properties& last_paragraph_props = last_paragraph_style->content()->get_style_paragraph_properties()->content_; - length_or_percent last_margin_bottom = last_paragraph_props.fo_margin_bottom_.get_value_or(length_or_percent(length(0.0, length::cm))); + if (last_style_paragraph_props) + { + const paragraph_format_properties& last_paragraph_props = last_style_paragraph_props->content_; + length_or_percent last_margin_bottom = last_paragraph_props.fo_margin_bottom_.get_value_or(length_or_percent(length(0.0, length::cm))); - if (fo_margin_top_->get_length().get_value_unit(length::cm) > last_margin_bottom.get_length().get_value_unit(length::cm)) - margin_top = _CP_OPT(length_or_percent)(length(fo_margin_top_->get_length().get_value_unit(length::cm) - last_margin_bottom.get_length().get_value_unit(length::cm), length::cm)); - else - margin_top = _CP_OPT(length_or_percent)(length(0.0, length::cm)); + if (fo_margin_top_->get_length().get_value_unit(length::cm) > last_margin_bottom.get_length().get_value_unit(length::cm)) + margin_top = _CP_OPT(length_or_percent)(length(fo_margin_top_->get_length().get_value_unit(length::cm) - last_margin_bottom.get_length().get_value_unit(length::cm), length::cm)); + else + margin_top = _CP_OPT(length_or_percent)(length(0.0, length::cm)); + } } std::wstring w_before = pptx_process_margin(margin_top, length::pt, 100.0); From a6e87b589c628a76f559e3ea0043a512354f8038 Mon Sep 17 00:00:00 2001 From: "Elena.Subbotina" <Elena.Subbotina@onlyoffice.com> Date: Thu, 13 Jun 2024 11:56:10 +0300 Subject: [PATCH 776/794] add props to binary --- OOXML/Binary/Document/BinReader/Readers.cpp | 13 ++++++++++++- .../Document/BinWriter/BinReaderWriterDefines.h | 6 ++++-- OOXML/Binary/Document/BinWriter/BinWriters.cpp | 13 ++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/Readers.cpp b/OOXML/Binary/Document/BinReader/Readers.cpp index 53f19b99a8e..6ea8b89951c 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/Readers.cpp @@ -875,7 +875,13 @@ int Binary_rPrReader::ReadContent(BYTE type, long length, void* poResult) pRPr->m_oSnapToGrid.Init(); pRPr->m_oSnapToGrid->m_oVal.FromBool(m_oBufferedStream.GetBool()); }break; - default: + case c_oSerProp_rPrType::Kern: + { + pRPr->m_oKern.Init(); pRPr->m_oKern->m_oVal.Init(); + pRPr->m_oKern->m_oVal->FromHps(m_oBufferedStream.GetLong()); + }break; + + default: res = c_oSerConstants::ReadUnknown; break; } @@ -1041,6 +1047,11 @@ int Binary_pPrReader::ReadContent(BYTE type, long length, void* poResult) pPPr->m_oSnapToGrid.Init(); pPPr->m_oSnapToGrid->m_oVal.FromBool(m_oBufferedStream.GetBool()); }break; + case c_oSerProp_pPrType::Bidi: + { + pPPr->m_oBidi.Init(); + pPPr->m_oBidi->m_oVal.FromBool(m_oBufferedStream.GetBool()); + }break; default: res = c_oSerConstants::ReadUnknown; break; diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index e3966154bea..d3a7032942f 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -357,7 +357,8 @@ extern int g_nCurFormatVersion; Tab_Item_Val = 43, SuppressLineNumbers = 44, CnfStyle = 45, - SnapToGrid = 46 + SnapToGrid = 46, + Bidi = 47 };} namespace c_oSerProp_rPrType{enum c_oSerProp_rPrType { @@ -416,7 +417,8 @@ extern int g_nCurFormatVersion; Reflection = 52, Glow = 53, Props3d = 54, - Scene3d = 55 + Scene3d = 55, + Kern = 56 };} namespace c_oSerProp_rowPrType{enum c_oSerProp_rowPrType { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index 035a051f719..3dfe6e90e7b 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -913,6 +913,12 @@ void Binary_rPrWriter::Write_rPr(OOX::Logic::CRunProperty* rPr) m_oBcw.m_oStream.WriteRecord1(0, *rPr->m_oScene3d); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + if (rPr->m_oKern.IsInit() && rPr->m_oKern->m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_rPrType::Kern); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(rPr->m_oKern.get().m_oVal.get().ToHps()); + } } void Binary_rPrWriter::Write_rPrChange(const OOX::Logic::CRPrChange& rPrChange) { @@ -1138,7 +1144,12 @@ void Binary_pPrWriter::Write_pPr(const OOX::Logic::CParagraphProperty& pPr) m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); m_oBcw.m_oStream.WriteBOOL(pPr.m_oSnapToGrid->m_oVal.ToBool()); } -} + if (pPr.m_oBidi.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProp_pPrType::Bidi); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(pPr.m_oBidi->m_oVal.ToBool()); + }} void Binary_pPrWriter::WritePPrChange(const OOX::Logic::CPPrChange& pPrChange) { int nCurPos = 0; From 04419326f4dd82547c7b59930ac03918661b544d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 13 Jun 2024 13:00:13 +0300 Subject: [PATCH 777/794] Fix bug 68545 --- DesktopEditor/graphics/Graphics.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 5e2e072c4bb..68a2c3c1980 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -624,14 +624,9 @@ namespace Aggplus default: break; } - double dWidth = pPen->Size; - double dWidthMinSize = 1.0 / sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); - - if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) - { - if (m_bIs0PenWidthAs1px) - dWidth = dWidthMinSize; - } + double dWidth = pPen->Size; + if (0 == dWidth && !m_bIntegerGrid && m_bIs0PenWidthAs1px) + dWidth = 1.0 / sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); double dblMiterLimit = pPen->MiterLimit; @@ -762,7 +757,7 @@ namespace Aggplus } } - dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); + double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) dWidth = dWidthMinSize; From ca17a96d3206fef8623a0ef06728b8f46c1d18aa Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 13 Jun 2024 13:08:21 +0300 Subject: [PATCH 778/794] Fix null --- DesktopEditor/graphics/Graphics.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 68a2c3c1980..246cd38f759 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -626,7 +626,11 @@ namespace Aggplus double dWidth = pPen->Size; if (0 == dWidth && !m_bIntegerGrid && m_bIs0PenWidthAs1px) - dWidth = 1.0 / sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); + { + double dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); + if (0 != dSqrtDet) + dWidth = 1.0 / dSqrtDet; + } double dblMiterLimit = pPen->MiterLimit; From 17bc68d102dfa03b358e10bf0af44a4db0ca423e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 13 Jun 2024 16:49:13 +0300 Subject: [PATCH 779/794] Fix bug 68545 --- PdfFile/SrcReader/RendererOutputDev.cpp | 40 +++++++++++++++++++++++-- PdfFile/SrcReader/RendererOutputDev.h | 1 + 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 1c724faa64d..981201e0fef 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -763,7 +763,35 @@ namespace PdfReader } void RendererOutputDev::updateLineWidth(GfxState *pGState) { - m_pRenderer->put_PenSize(PDFCoordsToMM(pGState->getLineWidth())); + double dWidth = pGState->getLineWidth(); + double* ctm = pGState->getCTM(); + double dDet = ctm[0] * ctm[3] - ctm[1] * ctm[2]; + + if (abs(dDet) < 0.000001) + { + m_pRenderer->put_PenSize(PDFCoordsToMM(dWidth)); + return; + } + + double inverse_ctm[4] = {}; + dDet = 1.0 / dDet; + inverse_ctm[0] = ctm[3] * dDet; + inverse_ctm[1] = -ctm[1] * dDet; + inverse_ctm[2] = -ctm[2] * dDet; + inverse_ctm[3] = ctm[0] * dDet; + + double dX = dWidth, dY = dWidth; + Distance(ctm, dX, dY, &dX, &dY); + if ((abs(dX) <= 1.0 && abs(dY) <= 1.0) || dWidth == 0) + { + dX = dY = 72.0 / 600.0; + Distance(inverse_ctm, dX, dY, &dX, &dY); + double dWidthMinSize = std::min(abs(dX), abs(dY)); + if (dWidth < dWidthMinSize) + dWidth = dWidthMinSize; + } + + m_pRenderer->put_PenSize(PDFCoordsToMM(dWidth)); } void RendererOutputDev::updateStrokeAdjust(GfxState *pGState) { @@ -4970,8 +4998,14 @@ namespace PdfReader } void RendererOutputDev::Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY) { - *pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2] + pMatrix[4]; - *pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3] + pMatrix[5]; + Distance(pMatrix, dUserX, dUserY, pdDeviceX, pdDeviceY); + *pdDeviceX += pMatrix[4]; + *pdDeviceY += pMatrix[5]; + } + void RendererOutputDev::Distance(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY) + { + *pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2]; + *pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3]; } void RendererOutputDev::DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM, GfxClipMatrix* pCTM2) { diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index b8fa2c3d0fa..8877ab35d24 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -299,6 +299,7 @@ namespace PdfReader private: void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); + void Distance(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); void DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM, GfxClipMatrix* pCTM2 = NULL); void ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double* pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth = 0, double dHeight = 0, double dBaseLineOffset = 0); void updateClip(GfxState *pGState); From a49811774850a8bb58f13f1afe7e697178b1738b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 13 Jun 2024 17:54:14 +0300 Subject: [PATCH 780/794] Fix bug 68546 --- PdfFile/SrcReader/RendererOutputDev.cpp | 73 +++++++++---------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 981201e0fef..7b3c60ab3a6 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -1158,15 +1158,13 @@ namespace PdfReader if (oFontObject.isDict()) { - char *sFontName = NULL, *sFontFamily = NULL, *sFontStretch = NULL; - int nFontWeight = 0, nItalicAngle = 0, nAscent = 0, nDescent = 0, nLeading = 0; - int nCapHeight = 0, nXHeight = 0, nStemV = 0, nStemH = 0, nAvgWidth = 0, nMaxWidth = 0, nMissingWidth = 0; - Array *pBBox = NULL; - int arrBBox[4] ={ 0, 0, 0, 0 }; + std::string sFontName, sFontFamily; + int nFontWeight = 0, nItalicAngle = 0, nAscent = 0, nDescent = 0; + int nCapHeight = 0, nXHeight = 0, nStemV = 0, nStemH = 0, nMissingWidth = 0; + int arrBBox[4] = { 0, 0, 0, 0 }; - Dict *pFontDict = oFontObject.getDict(); Object oFontDescriptor; - if (pFontDict->lookup("FontDescriptor", &oFontDescriptor)->isDict()) + if (oFontObject.dictLookup("FontDescriptor", &oFontDescriptor)->isDict()) { Object oDictItem; // FontName @@ -1180,9 +1178,9 @@ namespace PdfReader oDictItem.free(); // FontStretch - oFontDescriptor.dictLookup("FontStretch", &oDictItem); - if (oDictItem.isName()) sFontStretch = oDictItem.getName(); - oDictItem.free(); + // oFontDescriptor.dictLookup("FontStretch", &oDictItem); + // if (oDictItem.isName()) sFontStretch = oDictItem.getName(); + // oDictItem.free(); // FontWeight oFontDescriptor.dictLookup("FontWeight", &oDictItem); @@ -1190,17 +1188,13 @@ namespace PdfReader oDictItem.free(); // FontBBox - oFontDescriptor.dictLookup("FontBBox", &oDictItem); - if (oDictItem.isArray()) pBBox = oDictItem.getArray(); - if (4 == pBBox->getLength()) + if (oFontDescriptor.dictLookup("FontBBox", &oDictItem)->isArray() && oDictItem.arrayGetLength() == 4) { for (int nIndex = 0; nIndex < 4; nIndex++) { Object oArrayItem; - pBBox->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) + if (oDictItem.arrayGet(nIndex, &oArrayItem)->isInt()) arrBBox[nIndex] = oArrayItem.getInt(); - oArrayItem.free(); } } @@ -1217,9 +1211,9 @@ namespace PdfReader oDictItem.free(); // Leading - oFontDescriptor.dictLookup("Leading", &oDictItem); - if (oDictItem.isInt()) nLeading = oDictItem.getInt(); - oDictItem.free(); + // oFontDescriptor.dictLookup("Leading", &oDictItem); + // if (oDictItem.isInt()) nLeading = oDictItem.getInt(); + // oDictItem.free(); // CapHeight oFontDescriptor.dictLookup("CapHeight", &oDictItem); @@ -1247,14 +1241,14 @@ namespace PdfReader oDictItem.free(); // AvgWidth - oFontDescriptor.dictLookup("AvgWidth", &oDictItem); - if (oDictItem.isInt()) nAvgWidth = oDictItem.getInt(); - oDictItem.free(); + // oFontDescriptor.dictLookup("AvgWidth", &oDictItem); + // if (oDictItem.isInt()) nAvgWidth = oDictItem.getInt(); + // oDictItem.free(); // MaxWidth - oFontDescriptor.dictLookup("MaxWidth", &oDictItem); - if (oDictItem.isInt()) nMaxWidth = oDictItem.getInt(); - oDictItem.free(); + // oFontDescriptor.dictLookup("MaxWidth", &oDictItem); + // if (oDictItem.isInt()) nMaxWidth = oDictItem.getInt(); + // oDictItem.free(); // MissingWidth oFontDescriptor.dictLookup("MissingWidth", &oDictItem); @@ -1265,8 +1259,8 @@ namespace PdfReader oFontDescriptor.free(); fprintf(pFile, "StartFontMetrics 3.0\n"); - if (NULL != sFontName) fprintf(pFile, "FontName %s\n", sFontName); - if (NULL != sFontFamily) fprintf(pFile, "FamilyName %s\n", sFontFamily); + if (!sFontName.empty()) fprintf(pFile, "FontName %s\n", sFontName.c_str()); + if (!sFontFamily.empty()) fprintf(pFile, "FamilyName %s\n", sFontFamily.c_str()); if (nFontWeight >= 550) fprintf(pFile, "Weight Bold\n"); fprintf(pFile, "ItalicAngle %d\n", nItalicAngle); @@ -1282,38 +1276,24 @@ namespace PdfReader int nFirstChar = 0; Object oDictItem; - pFontDict->lookup("FirstChar", &oDictItem); - if (oDictItem.isInt()) nFirstChar = oDictItem.getInt(); - oDictItem.free(); - - int nLastChar = nFirstChar; - pFontDict->lookup("LastChar", &oDictItem); - if (oDictItem.isInt()) nLastChar = oDictItem.getInt(); + if (oFontObject.dictLookup("FirstChar", &oDictItem)->isInt()) nFirstChar = oDictItem.getInt(); oDictItem.free(); - Array *pWidths = NULL; - pFontDict->lookup("Widths", &oDictItem); - if (oDictItem.isArray()) pWidths = oDictItem.getArray(); - - int nCount = nLastChar - nFirstChar + 1; Gfx8BitFont *pT1Font = (Gfx8BitFont *)pFont; - - if (NULL != pWidths) + if (oFontObject.dictLookup("Widths", &oDictItem)->isArray()) { - int nWidthsCount = pWidths->getLength(); + int nWidthsCount = oDictItem.arrayGetLength(); fprintf(pFile, "StartCharMetrics %d\n", nWidthsCount); for (int nIndex = 0; nIndex < nWidthsCount; nIndex++) { int nWidth = nMissingWidth; Object oArrayItem; - pWidths->get(nIndex, &oArrayItem); - if (oArrayItem.isInt()) nWidth = oArrayItem.getInt(); + if (oDictItem.arrayGet(nIndex, &oArrayItem)->isInt()) nWidth = oArrayItem.getInt(); oArrayItem.free(); char **ppEncoding = pT1Font->getEncoding(); - - if (NULL != ppEncoding && NULL != ppEncoding[nIndex]) + if (ppEncoding && ppEncoding[nIndex]) fprintf(pFile, "C %d ; WX %d ; N %s ;\n", nIndex + nFirstChar, nWidth, ppEncoding[nIndex]); else fprintf(pFile, "C %d ; WX %d ;\n", nIndex + nFirstChar, nWidth); @@ -1322,6 +1302,7 @@ namespace PdfReader } oDictItem.free(); } + oFontObject.free(); } fclose(pFile); } From aae80a161ca9796ebdd467c01d953b22495f4df9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Thu, 13 Jun 2024 18:04:39 +0300 Subject: [PATCH 781/794] Clear --- PdfFile/SrcReader/RendererOutputDev.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 7b3c60ab3a6..8a1004d59c1 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -1177,11 +1177,6 @@ namespace PdfReader if (oDictItem.isName()) sFontFamily = oDictItem.getName(); oDictItem.free(); - // FontStretch - // oFontDescriptor.dictLookup("FontStretch", &oDictItem); - // if (oDictItem.isName()) sFontStretch = oDictItem.getName(); - // oDictItem.free(); - // FontWeight oFontDescriptor.dictLookup("FontWeight", &oDictItem); if (oDictItem.isInt()) nFontWeight = oDictItem.getInt(); @@ -1210,11 +1205,6 @@ namespace PdfReader if (oDictItem.isInt()) nAscent = oDictItem.getInt(); oDictItem.free(); - // Leading - // oFontDescriptor.dictLookup("Leading", &oDictItem); - // if (oDictItem.isInt()) nLeading = oDictItem.getInt(); - // oDictItem.free(); - // CapHeight oFontDescriptor.dictLookup("CapHeight", &oDictItem); if (oDictItem.isInt()) nCapHeight = oDictItem.getInt(); @@ -1240,16 +1230,6 @@ namespace PdfReader if (oDictItem.isInt()) nDescent = oDictItem.getInt(); oDictItem.free(); - // AvgWidth - // oFontDescriptor.dictLookup("AvgWidth", &oDictItem); - // if (oDictItem.isInt()) nAvgWidth = oDictItem.getInt(); - // oDictItem.free(); - - // MaxWidth - // oFontDescriptor.dictLookup("MaxWidth", &oDictItem); - // if (oDictItem.isInt()) nMaxWidth = oDictItem.getInt(); - // oDictItem.free(); - // MissingWidth oFontDescriptor.dictLookup("MissingWidth", &oDictItem); if (oDictItem.isInt()) nMissingWidth = oDictItem.getInt(); From 8c081c83c9e6c5325571285ea329e8111cb69f19 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Thu, 13 Jun 2024 19:31:38 +0300 Subject: [PATCH 782/794] fix bug 68586 --- .../Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp | 2 +- OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h | 2 +- OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 2b43665e1e5..686418713a5 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -330,7 +330,7 @@ namespace StarMath { pXmlWrite->WriteNodeEnd(L"m:funcPr",false,false); } - void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsOpenBracket, std::wstring &wsCloseBracket, CAttribute* pAttribute, const TypeConversion &enTypeConversion, const TypeElement &enTypeBracket) + void CConversionSMtoOOXML::PropertiesDPr(XmlUtils::CXmlWriter *pXmlWrite, const std::wstring &wsOpenBracket,const std::wstring &wsCloseBracket, CAttribute* pAttribute, const TypeConversion &enTypeConversion, const TypeElement &enTypeBracket) { pXmlWrite->WriteNodeBegin(L"m:dPr",false); BracketTypeNotation(wsOpenBracket,wsCloseBracket,pXmlWrite); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h index fc971362f3e..a3010f5ec3d 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.h @@ -48,7 +48,7 @@ namespace StarMath { static void PropertiesNaryPr(const TypeElement& enTypeOp,bool bEmptySub,bool bEmptySup,XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void PropertiesFuncPr(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void WriteNodeConversion(const std::wstring& wsNameBlock,CElement* pValueBlock,XmlUtils::CXmlWriter* pXmlWrite); - static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsOpenBracket,std::wstring& wsCloseBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion,const TypeElement& enTypeBracket); + static void PropertiesDPr(XmlUtils::CXmlWriter* pXmlWrite,const std::wstring& wsOpenBracket,const std::wstring& wsCloseBracket,CAttribute* pAttribute,const TypeConversion &enTypeConversion,const TypeElement& enTypeBracket); static void PropertiesMPr(XmlUtils::CXmlWriter* pXmlWrite,const TypeElement& enTypeMatrix,CAttribute* pAttribute,const TypeConversion &enTypeConversion); static void NodeGrade(XmlUtils::CXmlWriter* pXmlWrite,CElement* pValueGrade,CAttribute* pAttribute); static void WriteCtrlPrNode(XmlUtils::CXmlWriter* pXmlWrite,CAttribute* pAttribute,const TypeConversion &enTypeConversion); diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index c368a50eb6a..b51baa53b00 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1518,7 +1518,7 @@ namespace StarMath case TypeElement::abs: { pXmlWrite->WriteNodeBegin(L"m:d",false); -// CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,TypeElement::abs,GetAttribute(),GetTypeConversion()); + CConversionSMtoOOXML::PropertiesDPr(pXmlWrite,L"\u007C",L"\u007C",GetAttribute(),GetTypeConversion(),TypeElement::abs); CConversionSMtoOOXML::WriteNodeConversion(L"m:e",m_pValue,pXmlWrite); pXmlWrite->WriteNodeEnd(L"m:d",false,false); break; From 272b69ae70498d0e13abe4be9e65c89661220db0 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Thu, 13 Jun 2024 19:43:25 +0300 Subject: [PATCH 783/794] Fix bug #68609 --- HtmlFile2/htmlfile2.cpp | 161 +++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 75 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 6298fd5e661..17fda948829 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -962,12 +962,19 @@ class CHtmlFile2_Private NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml - bool m_bInP; // <w:p> открыт? - bool m_bInR; // <w:r> открыт? - bool m_bInT; // <w:t> открыт? - bool m_bWasPStyle; // <w:pStyle> записан? - bool m_bWasSpace; // Был пробел? - bool m_bInHyperlink; // <w:hyperlink> открыт? + struct TState + { + bool m_bInP; // <w:p> открыт? + bool m_bInR; // <w:r> открыт? + bool m_bInT; // <w:t> открыт? + bool m_bWasPStyle; // <w:pStyle> записан? + bool m_bWasSpace; // Был пробел? + bool m_bInHyperlink; // <w:hyperlink> открыт? + + TState() + : m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false) + {} + } m_oState; std::vector<std::wstring> m_arrImages; // Картинки std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски @@ -975,8 +982,7 @@ class CHtmlFile2_Private public: CHtmlFile2_Private() - : m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), - m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false) + : m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1) { m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true); m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true); @@ -1240,7 +1246,7 @@ class CHtmlFile2_Private oRelsWriter.CloseFile(); } - if (m_bInP) + if (m_oState.m_bInP) m_oDocXml.WriteString(L"</w:p>"); m_oDocXml.WriteString(L"<w:sectPr w:rsidR=\"0007083F\" w:rsidRPr=\"0007083F\" w:rsidSect=\"0007612E\">"); @@ -1522,12 +1528,12 @@ class CHtmlFile2_Private void PageBreakBefore() { - if (!m_bInP) + if (!m_oState.m_bInP) m_oDocXml.WriteString(L"<w:p>"); m_oDocXml.WriteString(L"<w:pPr><w:pageBreakBefore/></w:pPr>"); - if (!m_bInP) + if (!m_oState.m_bInP) m_oDocXml.WriteString(L"</w:p>"); } @@ -1572,75 +1578,75 @@ class CHtmlFile2_Private bool OpenP(NSStringUtils::CStringBuilder* pXml) { - if (m_bInP) + if (m_oState.m_bInP) return false; pXml->WriteString(L"<w:p>"); - m_bInP = true; - m_bWasPStyle = false; + m_oState.m_bInP = true; + m_oState.m_bWasPStyle = false; return true; } bool OpenR(NSStringUtils::CStringBuilder* pXml) { - if (m_bInR) + if (m_oState.m_bInR) return false; pXml->WriteString(L"<w:r>"); - m_bInR = true; + m_oState.m_bInR = true; return true; } void CloseR(NSStringUtils::CStringBuilder* pXml) { - if (!m_bInR) + if (!m_oState.m_bInR) return; pXml->WriteString(L"</w:r>"); - m_bInR = false; + m_oState.m_bInR = false; } bool OpenT(NSStringUtils::CStringBuilder* pXml) { - if (m_bInT) + if (m_oState.m_bInT) return false; pXml->WriteString(L"<w:t xml:space=\"preserve\">"); - m_bInT = true; + m_oState.m_bInT = true; return true; } void CloseT(NSStringUtils::CStringBuilder* pXml) { - if (!m_bInT) + if (!m_oState.m_bInT) return; pXml->WriteString(L"</w:t>"); - m_bInT = false; + m_oState.m_bInT = false; } void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector<NSCSS::CNode>& arSelectors) { - m_bWasSpace = true; + m_oState.m_bWasSpace = true; - if (!m_bInP) + if (!m_oState.m_bInP) return; CloseT(pXml); CloseR(pXml); - if (m_bInHyperlink) + if (m_oState.m_bInHyperlink) { if (arSelectors.rend() != std::find_if(arSelectors.rbegin(), arSelectors.rend(), [](const NSCSS::CNode& oNode) { return L"a" == oNode.m_wsName; })) { pXml->WriteString(L"</w:hyperlink>"); - m_bInHyperlink = false; + m_oState.m_bInHyperlink = false; } } pXml->WriteString(L"</w:p>"); - m_bInP = false; + m_oState.m_bInP = false; } void WriteBookmark(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsId) @@ -1757,7 +1763,7 @@ class CHtmlFile2_Private if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})) return false; - bool bInT = m_bInT; + bool bInT = m_oState.m_bInT; if (!oTS.sRStyle.empty() || oTS.bPre) { @@ -1765,10 +1771,10 @@ class CHtmlFile2_Private CloseR(oXml); } - if (oTS.bAddSpaces && m_bInP && !m_bInR && !iswspace(sText.front()) && !m_bWasSpace) + if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace) { oXml->WriteString(L"<w:r><w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t></w:r>"); - m_bWasSpace = true; + m_oState.m_bWasSpace = true; } std::wstring sPStyle = wrP(oXml, sSelectors, oTS); @@ -1824,14 +1830,14 @@ class CHtmlFile2_Private else ReplaceSpaces(sText); - if (std::iswspace(sText.front()) && m_bWasSpace) + if (std::iswspace(sText.front()) && m_oState.m_bWasSpace) sText.erase(0, 1); - if (oTS.bMergeText && !m_bWasSpace && bInT) + if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT) oXml->WriteEncodeXmlString(L" "); if (!sText.empty()) - m_bWasSpace = std::iswspace(sText.back()); + m_oState.m_bWasSpace = std::iswspace(sText.back()); oXml->WriteEncodeXmlString(sText); @@ -1888,7 +1894,7 @@ class CHtmlFile2_Private // Перенос строки else if(sName == L"br") { - if (m_bInP) + if (m_oState.m_bInP) { oXml->WriteString(L"<w:r>"); NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); @@ -1897,9 +1903,9 @@ class CHtmlFile2_Private oXml->WriteString(L"<w:br/></w:r>"); } else - WriteEmptyParagraph(oXml, false, m_bInP); + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); - m_bWasSpace = true; + m_oState.m_bWasSpace = true; } else if(sName == L"center") { @@ -2052,7 +2058,7 @@ class CHtmlFile2_Private sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" || sName == L"comment" || sName == L"title" || sName == L"style") { - WriteEmptyParagraph(oXml, false, m_bInP); + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); sSelectors.pop_back(); return true; } @@ -2079,21 +2085,24 @@ class CHtmlFile2_Private // С нового абзаца else { - CloseP(oXml, sSelectors); + NSStringUtils::CStringBuilder oXmlData; + TState oCurentState{m_oState}; + + CloseP(&oXmlData, sSelectors); // Адрес if(sName == L"address") { CTextSettings oTSR(oTS); oTSR.AddRStyle(L"<w:i/><w:iCs/>"); - bResult = readStream(oXml, sSelectors, oTSR); + bResult = readStream(&oXmlData, sSelectors, oTSR); } // Определение термина, отступ от левого края else if(sName == L"dd") { CTextSettings oTSP(oTS); oTSP.sPStyle += L"<w:ind w:left=\"567\"/>"; - bResult = readStream(oXml, sSelectors, oTSP); + bResult = readStream(&oXmlData, sSelectors, oTSP); } // aside возможно использовать для сносок в epub else if (sName == L"aside" || sName == L"div") @@ -2130,7 +2139,7 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L"</w:footnote>"); } else - bResult = readStream(oXml, sSelectors, oTS); + bResult = readStream(&oXmlData, sSelectors, oTS); } // С нового абзаца else if(sName == L"article" || sName == L"header" || sName == L"blockquote" || sName == L"main" || sName == L"dir" || @@ -2138,7 +2147,7 @@ class CHtmlFile2_Private sName == L"details" || sName == L"option" || sName == L"dt" || sName == L"p" || sName == L"section" || sName == L"figure" || sName == L"dl" || sName == L"legend" || sName == L"map" || sName == L"h1" || sName == L"h2" || sName == L"h3" || sName == L"h4" || sName == L"h5" || sName == L"h6") - bResult = readStream(oXml, sSelectors, oTS); + bResult = readStream(&oXmlData, sSelectors, oTS); // Горизонтальная линия else if(sName == L"hr") { @@ -2153,39 +2162,39 @@ class CHtmlFile2_Private } if (bPrint) { - const bool bOpenedP = OpenP(oXml); - OpenR(oXml); - WriteLine(oXml, 1.5, L"a0a0a0"); - CloseR(oXml); + const bool bOpenedP = OpenP(&oXmlData); + OpenR(&oXmlData); + WriteLine(&oXmlData, 1.5, L"a0a0a0"); + CloseR(&oXmlData); if (bOpenedP) - CloseP(oXml, sSelectors); + CloseP(&oXmlData, sSelectors); } // oXml->WriteString(L"<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr></w:pPr></w:p>"); } // Меню // Маркированный список else if(sName == L"menu" || sName == L"ul" || sName == L"select" || sName == L"datalist") - readLi(oXml, sSelectors, oTS, true); + readLi(&oXmlData, sSelectors, oTS, true); // Нумерованный список else if(sName == L"ol") - readLi(oXml, sSelectors, oTS, false); + readLi(&oXmlData, sSelectors, oTS, false); // Предварительно форматированный текст else if(sName == L"pre" || sName == L"xmp") { CTextSettings oTSPre(oTS); sSelectors.back().m_wsStyle += L"; font-family:Consolas"; oTSPre.bPre = true; - bResult = readStream(oXml, sSelectors, oTSPre); + bResult = readStream(&oXmlData, sSelectors, oTSPre); } // Таблицы else if(sName == L"table") - ParseTable(oXml, sSelectors, oTS); + ParseTable(&oXmlData, sSelectors, oTS); // Текст с границами else if(sName == L"textarea" || sName == L"fieldset") { CTextSettings oTSP(oTS); oTSP.AddPStyle(L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"); - bResult = readStream(oXml, sSelectors, oTSP); + bResult = readStream(&oXmlData, sSelectors, oTSP); } else if (sName == L"xml") { @@ -2194,12 +2203,17 @@ class CHtmlFile2_Private } // Неизвестный тэг. Выделять ли его абзацем? else - bResult =readStream(oXml, sSelectors, oTS); + bResult = readStream(&oXmlData, sSelectors, oTS); - readNote(oXml, sSelectors, sNote); + readNote(&oXmlData, sSelectors, sNote); sNote = L""; - CloseP(oXml, sSelectors); + CloseP(&oXmlData, sSelectors); + + if (bResult) + oXml->WriteString(oXmlData.GetData()); + else + m_oState = oCurentState; } readNote(oXml, sSelectors, sNote); sSelectors.pop_back(); @@ -2216,7 +2230,7 @@ class CHtmlFile2_Private wrP(oXml, sSelectors, oTS); wrRPr(oXml, sSelectors, oTS); CloseP(oXml, sSelectors); - m_bInP = false; + m_oState.m_bInP = false; } return false; } @@ -2234,7 +2248,7 @@ class CHtmlFile2_Private wrP(oXml, sSelectors, oTS); wrRPr(oXml, sSelectors, oTS); CloseP(oXml, sSelectors); - m_bInP = false; + m_oState.m_bInP = false; } return bResult; @@ -2345,7 +2359,7 @@ class CHtmlFile2_Private } m_oLightReader.MoveToElement(); - m_bWasPStyle = false; + m_oState.m_bWasPStyle = false; // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") @@ -2365,9 +2379,9 @@ class CHtmlFile2_Private if (pRow->GetIndex() == MAXCOLUMNSINTABLE - 1) { CTextSettings oTrTS{oTS}; - oTrTS.bMergeText = true; - oTrTS.bAddSpaces = true; - m_bWasSpace = true; + oTrTS.bMergeText = true; + oTrTS.bAddSpaces = true; + m_oState.m_bWasSpace = true; while (m_oLightReader.ReadNextSiblingNode(nTrDepth) && (L"td" == m_oLightReader.GetName() || L"th" == m_oLightReader.GetName())) { @@ -2610,14 +2624,12 @@ class CHtmlFile2_Private if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); - const bool bInP(m_bInP); - wrP(oXml, sSelectors, oTS); // Перекрестная ссылка внутри файла if(bCross) { - m_bInHyperlink = true; + m_oState.m_bInHyperlink = true; oXml->WriteString(L"<w:hyperlink w:tooltip=\"Current Document\" w:anchor=\""); size_t nSharp = sRef.find('#'); if(nSharp == std::wstring::npos) @@ -2638,7 +2650,7 @@ class CHtmlFile2_Private oRelationshipXml->WriteEncodeXmlString(sRef); oRelationshipXml->WriteString(L"\" TargetMode=\"External\"/>"); - m_bInHyperlink = true; + m_oState.m_bInHyperlink = true; // Пишем в document.xml oXml->WriteString(L"<w:hyperlink w:tooltip=\""); oXml->WriteEncodeXmlString(sNote); @@ -2652,16 +2664,16 @@ class CHtmlFile2_Private oXml->WriteString(L"<w:r>"); wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"); - oXml->WriteEncodeXmlString(sAlt); + oXml->WriteEncodeXmlString(!sAlt.empty() ? sAlt : L" "); oXml->WriteString(L"</w:t></w:r>"); } - if (m_bInP) + if (m_oState.m_bInP) { - if (m_bInHyperlink) + if (m_oState.m_bInHyperlink) { oXml->WriteString(L"</w:hyperlink>"); - m_bInHyperlink = false; + m_oState.m_bInHyperlink = false; } bool bFootnote = false; @@ -2686,8 +2698,7 @@ class CHtmlFile2_Private oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteRef/></w:r>"); } - if (!bInP) - CloseP(oXml, sSelectors); + CloseP(oXml, sSelectors); } sNote.clear(); @@ -2778,7 +2789,7 @@ class CHtmlFile2_Private { //TODO:: реализовать отображение того, что картинку не удалось получить if (wsSrc.empty()) - WriteEmptyParagraph(oXml, false, m_bInP); + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); else { m_oDocXmlRels.WriteString(L"<Relationship Id=\"rId"); @@ -2910,7 +2921,7 @@ class CHtmlFile2_Private { OpenP(oXml); - if (m_bWasPStyle) + if (m_oState.m_bWasPStyle) return L""; std::vector<std::pair<size_t, NSCSS::CNode>> temporary; @@ -2969,14 +2980,14 @@ class CHtmlFile2_Private oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); oXml->WriteNodeEnd(L"w:pPr"); - m_bWasPStyle = true; + m_oState.m_bWasPStyle = true; return sPStyle; } std::wstring wrRPr(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) + if (!m_oState.m_bInP) return L""; NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); From d0b6c5534791a15f53833668f20ae79b3ce8f9a1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 14 Jun 2024 09:16:09 +0300 Subject: [PATCH 784/794] For bug 68237 --- .../graphics/pro/js/wasm/src/pdfwriter.cpp | 1 - PdfFile/PdfEditor.cpp | 102 ++++++++++++------ PdfFile/PdfEditor.h | 5 +- PdfFile/PdfFile.cpp | 5 +- PdfFile/PdfWriter.cpp | 4 - PdfFile/PdfWriter.h | 1 - 6 files changed, 77 insertions(+), 41 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index dcefa78387a..8aca52fb2ca 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -143,7 +143,6 @@ HRESULT CPdfWriter::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2 bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) { return false; } bool CPdfWriter::AddPage(int nPageIndex) { return false; } bool CPdfWriter::EditClose() { return false; } -void CPdfWriter::PageClear() {} void CPdfWriter::PageRotate(int nRotate) {} void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) {} HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory) { return 0; } diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 8bc470e8a3b..ec49c354509 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -469,7 +469,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa wsPassword = _wsPassword; pReader = _pReader; pWriter = _pWriter; - bEditPage = false; + m_nEditPage = -1; nError = 0; PDFDoc* pPDFDocument = pReader->GetPDFDocument(); @@ -812,7 +812,7 @@ void CPdfEditor::Close() pReader = NULL; pWriter = NULL; - bEditPage = false; + m_nEditPage = -1; } int CPdfEditor::GetError() { @@ -958,20 +958,13 @@ bool CPdfEditor::EditPage(int nPageIndex) } else if (strcmp("Annots", chKey) == 0) { - // ВРЕМЕНО удаление Link аннотаций при редактировании if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); pPage->Add("Annots", pArray); for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) { - Object oAnnot, oSubtype; - if (oTemp.arrayGet(nIndex, &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Link")) - { - oAnnot.free(); oSubtype.free(); - continue; - } - oAnnot.free(); oSubtype.free(); + Object oAnnot; oTemp.arrayGetNF(nIndex, &oAnnot); DictToCDictObject(&oAnnot, pArray, false, ""); oAnnot.free(); @@ -1012,7 +1005,7 @@ bool CPdfEditor::EditPage(int nPageIndex) // Применение редактирования страницы для writer if (pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) { - bEditPage = true; + m_nEditPage = nPageIndex; pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); return true; } @@ -1261,7 +1254,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::DeleteAnnot(int nID) +bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = pWriter->GetDocument(); @@ -1269,27 +1262,33 @@ bool CPdfEditor::DeleteAnnot(int nID) return false; XRef* xref = pPDFDocument->getXRef(); - std::pair<int, int> pPageRef; - pPageRef.first = pDoc->GetCurPage()->GetObjId(); - pPageRef.second = pDoc->GetCurPage()->GetGenNo(); - if (!xref || pPageRef.first == 0) - return false; - - // Получение объекта аннотации - Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) + bool bClear = false; + if (!oAnnots) { - pageRefObj.free(); pageObj.free(); oAnnots.free(); - return false; + std::pair<int, int> pPageRef = pDoc->GetPageRef(m_nEditPage); + if (pPageRef.first == 0) + return false; + + oAnnots = new Object(); + bClear = true; + + // Получение объекта аннотации + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", oAnnots)->isArray()) + { + pageRefObj.free(); pageObj.free(); oAnnots->free(); + RELEASEOBJECT(oAnnots); + return false; + } + pageRefObj.free(); pageObj.free(); } - pageRefObj.free(); pageObj.free(); bool bRes = false; - for (int i = 0; i < oAnnots.arrayGetLength(); ++i) + for (int i = 0; i < oAnnots->arrayGetLength(); ++i) { Object oAnnotRef, oAnnot; - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + if (oAnnots->arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) { bRes = pDoc->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) @@ -1300,16 +1299,21 @@ bool CPdfEditor::DeleteAnnot(int nID) oPopupRef.free(); } } - else if (oAnnots.arrayGet(i, &oAnnot)->isDict()) + else if (oAnnots->arrayGet(i, &oAnnot)->isDict()) { Object oIRTRef; if (oAnnot.dictLookupNF("IRT", &oIRTRef)->isRef() && oIRTRef.getRefNum() == nID) - DeleteAnnot(oAnnotRef.getRefNum()); + DeleteAnnot(oAnnotRef.getRefNum(), oAnnots); oIRTRef.free(); } oAnnotRef.free(); oAnnot.free(); } - oAnnots.free(); + + if (bClear) + { + oAnnots->free(); + RELEASEOBJECT(oAnnots); + } return bRes; } @@ -1369,7 +1373,43 @@ int CPdfEditor::GetRotate(int nPageIndex) } bool CPdfEditor::IsEditPage() { - return bEditPage; + return m_nEditPage >= 0; +} +void CPdfEditor::ClearPage() +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + std::pair<int, int> pPageRef = pDoc->GetPageRef(m_nEditPage); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); pageRefObj.free(); + return; + } + pageRefObj.free(); + + Object oAnnots; + // ВРЕМЕННО удаление Link аннотаций при редактировании + if (pageObj.dictLookup("Annots", &oAnnots)->isArray()) + { + for (int nIndex = 0; nIndex < oAnnots.arrayGetLength(); ++nIndex) + { + Object oAnnot, oSubtype, oAnnotRef; + if (oAnnots.arrayGet(nIndex, &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Link")) + { + oAnnots.arrayGetNF(nIndex, &oAnnotRef); + DeleteAnnot(oAnnotRef.getRefNum(), &oAnnots); + } + oAnnot.free(); oSubtype.free(); oAnnotRef.free(); + } + } + pageObj.free(); + + pDoc->ClearPage(); } void CPdfEditor::AddShapeXML(const std::string& sXML) { diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 8331d377c04..c87f7df1857 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -48,12 +48,13 @@ class CPdfEditor bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool EditAnnot(int nPageIndex, int nID); - bool DeleteAnnot(int nID); + bool DeleteAnnot(int nID, Object* oAnnots = NULL); bool EditWidgets(IAdvancedCommand* pCommand); int GetPagesCount(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); int GetRotate(int nPageIndex); bool IsEditPage(); + void ClearPage(); void AddShapeXML(const std::string& sXML); void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); @@ -69,7 +70,7 @@ class CPdfEditor CPdfWriter* pWriter; int nError; - bool bEditPage; + int m_nEditPage; }; #endif // _PDF_EDITOR_H diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index de42f8f7e55..2a9a375c453 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -53,12 +53,13 @@ class CPdfEditor bool DeletePage(int nPageIndex) { return false; } bool AddPage(int nPageIndex) { return false; } bool EditAnnot(int nPageIndex, int nID) { return false; } - bool DeleteAnnot(int nID) { return false; } + bool DeleteAnnot(int nID, Object* oAnnots = NULL) { return false; } bool EditWidgets(IAdvancedCommand* pCommand) { return false; } int GetPagesCount() { return 0; } void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} int GetRotate(int nPageIndex) { return 0; } bool IsEditPage() { return false; } + void ClearPage() {} void AddShapeXML(const std::string& sXML) {} void EndMarkedContent() {} bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; } @@ -1257,7 +1258,7 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::PageClear: { if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) - m_pInternal->pWriter->PageClear(); + m_pInternal->pEditor->ClearPage(); return S_OK; } case IAdvancedCommand::AdvancedCommandType::PageRotate: diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index ff6056a5436..7a207d7765e 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2750,10 +2750,6 @@ bool CPdfWriter::EditClose() return true; } -void CPdfWriter::PageClear() -{ - m_pDocument->ClearPage(); -} void CPdfWriter::PageRotate(int nRotate) { if (m_pPage) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 8cbe0301f7c..d8113852ca5 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -211,7 +211,6 @@ class CPdfWriter bool EditPage(PdfWriter::CPage* pNewPage); bool AddPage(int nPageIndex); bool EditClose(); - void PageClear(); void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); From 79c7fced0aa6b7ba41bab3207156afa1118d4d14 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 14 Jun 2024 11:15:33 +0300 Subject: [PATCH 785/794] For bug 68629 --- PdfFile/PdfFile.cpp | 11 +++--- PdfFile/PdfWriter.cpp | 65 +++++++++++++++++++++++++--------- PdfFile/PdfWriter.h | 2 +- PdfFile/SrcReader/PdfAnnot.cpp | 8 ++++- 4 files changed, 61 insertions(+), 25 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 2a9a375c453..05242f18e5b 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -886,13 +886,12 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) { if (!m_pInternal->pWriter) return S_FALSE; - std::wstring wsFontName = wsName; - if (m_pInternal->pEditor && wsFontName.find(L"Embedded: ") == 0) + if (m_pInternal->pEditor && wsName.find(L"Embedded: ") == 0) { - wsFontName.erase(0, 10); + std::wstring sSub = wsName.substr(0, 10); bool bBold = false, bItalic = false; std::wstring wsFontPath; - if (m_pInternal->pEditor->IsBase14(wsFontName, bBold, bItalic, wsFontPath) && (bBold || bItalic)) + if (m_pInternal->pEditor->IsBase14(sSub, bBold, bItalic, wsFontPath) && (bBold || bItalic)) { LONG lStyle = 0; if (bBold) @@ -901,9 +900,9 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) lStyle |= 2; put_FontStyle(lStyle); } - m_pInternal->pWriter->AddFont(wsFontName, bBold, bItalic, wsFontPath, 0); + m_pInternal->pWriter->AddFont(wsName, bBold, bItalic, wsFontPath, 0); } - return m_pInternal->pWriter->put_FontName(wsFontName); + return m_pInternal->pWriter->put_FontName(wsName); } HRESULT CPdfFile::get_FontPath(std::wstring* wsPath) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 7a207d7765e..55d337c4a71 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2924,35 +2924,38 @@ bool CPdfWriter::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen m_oPath.AddText(m_pFont, pCodes, unLen * 2, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), m_oFont.GetSize(), MM_2_PT(m_oFont.GetCharSpace())); return true; } -int CPdfWriter::IsBase14(const std::wstring& wsName) +int CPdfWriter::IsEmbeddedBase14(const std::wstring& wsName) { - if (wsName == L"Helvetica") + if (wsName.find(L"Embedded: ") != 0) + return -1; + std::wstring sSub = wsName.substr(0, 10); + if (sSub == L"Helvetica") return 0; - if (wsName == L"Helvetica-Bold") + if (sSub == L"Helvetica-Bold") return 1; - if (wsName == L"Helvetica-Oblique") + if (sSub == L"Helvetica-Oblique") return 2; - if (wsName == L"Helvetice-BoldOblique") + if (sSub == L"Helvetice-BoldOblique") return 3; - if (wsName == L"Courier") + if (sSub == L"Courier") return 4; - if (wsName == L"Courier-Bold") + if (sSub == L"Courier-Bold") return 5; - if (wsName == L"Courier-Oblique") + if (sSub == L"Courier-Oblique") return 6; - if (wsName == L"Courier-BoldOblique") + if (sSub == L"Courier-BoldOblique") return 7; - if (wsName == L"Times") + if (sSub == L"Times") return 8; - if (wsName == L"Times-Bold") + if (sSub == L"Times-Bold") return 9; - if (wsName == L"Times-Oblique") + if (sSub == L"Times-Oblique") return 10; - if (wsName == L"Times-BoldOblique") + if (sSub == L"Times-BoldOblique") return 11; - if (wsName == L"Symbol") + if (sSub == L"Symbol") return 12; - if (wsName == L"ZapfDingbats") + if (sSub == L"ZapfDingbats") return 13; return -1; } @@ -2972,14 +2975,18 @@ bool CPdfWriter::UpdateFont() { m_bNeedUpdateTextFont = false; m_pFont14 = NULL; + std::wstring wsFontPath = m_oFont.GetPath(); LONG lFaceIndex = m_oFont.GetFaceIndex(); if (L"" == wsFontPath) { std::wstring wsFontName = m_oFont.GetName(); - int nBase14 = IsBase14(wsFontName); + int nBase14 = IsEmbeddedBase14(wsFontName); if (nBase14 >= 0 && GetBaseFont14(wsFontName, nBase14)) + { + m_pFont = NULL; return true; + } if (!GetFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) { m_pFont = NULL; @@ -2987,10 +2994,10 @@ bool CPdfWriter::UpdateFont() } } + m_pFont = NULL; m_oFont.SetNeedDoBold(false); m_oFont.SetNeedDoItalic(false); - m_pFont = NULL; if (L"" != wsFontPath) { m_pFont = GetFont(wsFontPath, lFaceIndex); @@ -3458,6 +3465,30 @@ unsigned char* CPdfWriter::EncodeString(const unsigned int *pUnicodes, const uns return NULL; } + if (m_pFont14) + { + unsigned char* pCodes = new unsigned char[unCount * 2]; + if (!pCodes) + return NULL; + + for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) + { + bool bNew = false; + if (pGIDs) + m_pFont14->EncodeUnicode(pGIDs[unIndex], pUnicodes[unIndex], bNew); + if (bNew) + { + TBBoxAdvance oBox = m_pFontManager->MeasureChar2(*pUnicodes); + double dWidth = oBox.fAdvanceX / m_oFont.GetSize() * 1000.0; + m_pFont14->AddWidth(dWidth); + } + + pCodes[2 * unIndex + 0] = (pUnicodes[unIndex] >> 8) & 0xFF; + pCodes[2 * unIndex + 1] = pUnicodes[unIndex] & 0xFF; + } + return pCodes; + } + if (!m_pFont) return NULL; diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index d8113852ca5..1f1eec9426a 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -224,7 +224,7 @@ class CPdfWriter bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); - int IsBase14(const std::wstring& wsFontName); + int IsEmbeddedBase14(const std::wstring& wsFontName); bool GetBaseFont14(const std::wstring& wsFontName, int nBase14); bool UpdateFont(); bool FindFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 7a19c8c809b..43643794fe2 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2504,7 +2504,13 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object std::wstring sFontPath = pFontInfo->m_wsFontPath; bool bFreeText = false; for (std::map<std::wstring, std::wstring>::iterator it = arrFontFreeText.begin(); it != arrFontFreeText.end(); it++) - bFreeText = it->second == sFontPath; + { + if (it->second == sFontPath) + { + bFreeText = true; + break; + } + } std::wstring wsFontBaseName = pFontInfo->m_wsFontName; if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') { From ad4ba02895bd68d67bf52fa868e7621ad06e4662 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 14 Jun 2024 11:16:08 +0300 Subject: [PATCH 786/794] For bug 65310 --- PdfFile/test/test.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- PdfFile/test/test.pro | 2 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 6f6fa3b900a..9b512f9c754 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -37,6 +37,7 @@ #include "../../DesktopEditor/xmlsec/src/include/CertificateCommon.h" #include "../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" #include "../PdfFile.h" +#include "../../DjVuFile/DjVu.h" class CPdfFileTest : public testing::Test { @@ -142,6 +143,42 @@ CApplicationFontsWorker* CPdfFileTest::oWorker = NULL; NSFonts::IApplicationFonts* CPdfFileTest::pApplicationFonts = NULL; std::wstring CPdfFileTest::wsTempDir; +TEST_F(CPdfFileTest, DjVuToPdf) +{ + GTEST_SKIP(); + + CDjVuFile* pFile = new CDjVuFile(pApplicationFonts); + + ASSERT_TRUE(pFile->LoadFromFile(NSFile::GetProcessDirectory() + L"/test.djvu")); + + pdfFile->CreatePdf(); + + int nPagesCount = pFile->GetPagesCount(); + for (int i = 0; i < nPagesCount; ++i) + { + pdfFile->NewPage(); + pdfFile->BeginCommand(c_nPageType); + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + pdfFile->put_Width(dWidth); + pdfFile->put_Height(dHeight); + + pFile->DrawPageOnRenderer(pdfFile, i, NULL); + + pdfFile->EndCommand(c_nPageType); + } + + pdfFile->SaveToFile(wsDstFile); + + RELEASEOBJECT(pFile); +} + TEST_F(CPdfFileTest, GetMetaData) { GTEST_SKIP(); @@ -199,7 +236,7 @@ TEST_F(CPdfFileTest, PdfBinToPng) TEST_F(CPdfFileTest, PdfFromBin) { - GTEST_SKIP(); + //GTEST_SKIP(); pdfFile->CreatePdf(); EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); @@ -290,7 +327,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - //GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); diff --git a/PdfFile/test/test.pro b/PdfFile/test/test.pro index d409fdea222..354e3658b57 100644 --- a/PdfFile/test/test.pro +++ b/PdfFile/test/test.pro @@ -13,7 +13,7 @@ include($$CORE_ROOT_DIR/Common/base.pri) include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfFile, ooxmlsignature) +ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfFile, ooxmlsignature, DjVuFile) SOURCES += test.cpp From 6cf95e6151aab6c9bf231790de9abf127e321f58 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Fri, 14 Jun 2024 11:59:50 +0300 Subject: [PATCH 787/794] Fix bug #68638 --- DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp index 51d77955801..13a77b341df 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp @@ -50,7 +50,7 @@ namespace SVG { if (oNode->m_wsClass.find(L' ') != std::wstring::npos) { - std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, L" "); + std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); if (arClasses.size() > 1) arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); @@ -82,7 +82,7 @@ namespace SVG if (arWords.back()[0] == L'.') { - arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), L" "); + arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); arNextNodes.push_back(arWords.back()); arWords.pop_back(); } From cc27db504f6dcf01f9d3e292a34ce80cacd249b8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Fri, 14 Jun 2024 12:34:34 +0300 Subject: [PATCH 788/794] Fix embedded fonts --- PdfFile/PdfFile.cpp | 26 ++++++++++++++++---------- PdfFile/PdfWriter.cpp | 2 +- PdfFile/SrcReader/PdfAnnot.cpp | 1 + 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 05242f18e5b..6524ec080de 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -886,23 +886,29 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName) { if (!m_pInternal->pWriter) return S_FALSE; + std::wstring wsFont = wsName; if (m_pInternal->pEditor && wsName.find(L"Embedded: ") == 0) { - std::wstring sSub = wsName.substr(0, 10); + std::wstring sSub = wsName.substr(10); bool bBold = false, bItalic = false; std::wstring wsFontPath; - if (m_pInternal->pEditor->IsBase14(sSub, bBold, bItalic, wsFontPath) && (bBold || bItalic)) + if (m_pInternal->pEditor->IsBase14(sSub, bBold, bItalic, wsFontPath)) { - LONG lStyle = 0; - if (bBold) - lStyle |= 1; - if (bItalic) - lStyle |= 2; - put_FontStyle(lStyle); + if (bBold || bItalic) + { + LONG lStyle = 0; + if (bBold) + lStyle |= 1; + if (bItalic) + lStyle |= 2; + put_FontStyle(lStyle); + } } - m_pInternal->pWriter->AddFont(wsName, bBold, bItalic, wsFontPath, 0); + else + wsFont = sSub; + m_pInternal->pWriter->AddFont(wsFont, bBold, bItalic, wsFontPath, 0); } - return m_pInternal->pWriter->put_FontName(wsName); + return m_pInternal->pWriter->put_FontName(wsFont); } HRESULT CPdfFile::get_FontPath(std::wstring* wsPath) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 55d337c4a71..52bc1d4bf4a 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2928,7 +2928,7 @@ int CPdfWriter::IsEmbeddedBase14(const std::wstring& wsName) { if (wsName.find(L"Embedded: ") != 0) return -1; - std::wstring sSub = wsName.substr(0, 10); + std::wstring sSub = wsName.substr(10); if (sSub == L"Helvetica") return 0; if (sSub == L"Helvetica-Bold") diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 43643794fe2..02c1621bb53 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2470,6 +2470,7 @@ std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object else if (bItalic) sFontName += "-Oblique"; } + wsFontName = UTF8_TO_U(sFontName); const unsigned char* pData14 = NULL; unsigned int nSize14 = 0; From ef530fea0b7fe01839cca0e1baa0077779ec2770 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev <Dmitriy.Okunev@onlyoffice.com> Date: Fri, 14 Jun 2024 14:10:51 +0300 Subject: [PATCH 789/794] fix bug 68587 --- .../Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp index 686418713a5..eb9524d4849 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -207,6 +207,8 @@ namespace StarMath { pXmlWrite->WriteAttribute(L"b",L"1"); if(pAttribute->GetItal()) pXmlWrite->WriteAttribute(L"i",L"1"); + if(pAttribute->GetStrike()) + pXmlWrite->WriteAttribute(L"strike",L"sngStrike"); pXmlWrite->WriteNodeEnd(L"w",true,false); if(!pAttribute->GetColor().empty()) { From 76623ec66d20e3b31addbf78ddffc50b1bb78c01 Mon Sep 17 00:00:00 2001 From: Oleg Korshul <Oleg.Korshul@onlyoffice.com> Date: Fri, 14 Jun 2024 15:51:28 +0300 Subject: [PATCH 790/794] [pdf=>image] Support orientation --- X2tConverter/src/lib/pdf_image.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/X2tConverter/src/lib/pdf_image.h b/X2tConverter/src/lib/pdf_image.h index 464b703a282..6372629d20e 100644 --- a/X2tConverter/src/lib/pdf_image.h +++ b/X2tConverter/src/lib/pdf_image.h @@ -564,6 +564,10 @@ namespace NExtractTools } sFileToExt = getExtentionByRasterFormat(nRasterFormat); } + + int nSaveFlags = (nSaveType & 0xF0) >> 4; + nSaveType = nSaveType & 0x0F; + int nPagesCount = pReader->GetPagesCount(); if (bIsOnlyFirst) nPagesCount = 1; @@ -572,12 +576,23 @@ namespace NExtractTools int nRasterWCur = nRasterW; int nRasterHCur = nRasterH; - if (1 == nSaveType) + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + if (nSaveFlags & 0x0F) { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + if (((dWidth < dHeight) && (nRasterWCur > nRasterHCur)) || + ((dWidth > dHeight) && (nRasterWCur < nRasterHCur))) + { + int nTmp = nRasterWCur; + nRasterWCur = nRasterHCur; + nRasterHCur = nTmp; + } + } + if (1 == nSaveType) + { double dKoef1 = nRasterWCur / dWidth; double dKoef2 = nRasterHCur / dHeight; if (dKoef1 > dKoef2) From e5559e4cf86e178cc7ca0ea0038690c69082045f Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Mon, 17 Jun 2024 14:22:19 +0300 Subject: [PATCH 791/794] Fix bug #68638 --- .../3dParty/html/css/src/StyleProperties.cpp | 20 +++++++++++++ Common/3dParty/html/css/src/StyleProperties.h | 5 ++++ .../raster/Metafile/svg/SvgObjects/CText.cpp | 28 ++++++++++++++----- .../raster/Metafile/svg/SvgObjects/CText.h | 2 ++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 4c9e5b1711c..513d4d604bc 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -1350,6 +1350,26 @@ namespace NSCSS return true; } + void CTransform::Translate(double dOffsetX, double dOffsetY) + { + m_oMatrix.AddValue({dOffsetX, dOffsetY}, TransformTranslate); + } + + void CTransform::Scale(double dScaleX, double dScaleY) + { + m_oMatrix.AddValue({dScaleX, dScaleY}, TransformScale); + } + + void CTransform::Rotate(double dValue) + { + m_oMatrix.AddValue({dValue}, TransformRotate); + } + + void CTransform::RotateAt(double dValue, double dX, double dY) + { + m_oMatrix.AddValue({dValue, dX, dY}, TransformRotate); + } + const CMatrix& CTransform::GetMatrix() const { return m_oMatrix; diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 8f81ff8175b..13ea54f67cf 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -408,6 +408,11 @@ namespace NSCSS bool SetMatrix(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); bool SetMatrix(const Aggplus::CMatrix &oMatrix); + void Translate(double dOffsetX, double dOffsetY); + void Scale(double dScaleX, double dScaleY); + void Rotate(double dValue); + void RotateAt(double dValue, double dX, double dY); + const CMatrix& GetMatrix() const; bool Empty() const; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index 9447a8a9c23..9c6f1165fd8 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -129,6 +129,14 @@ namespace SVG if (mAttributes.end() != mAttributes.find(L"text-decoration")) m_oText.SetDecoration(mAttributes.at(L"text-decoration"), ushLevel, bHardMode); + + //POSITION + if (mAttributes.end() != mAttributes.find(L"rotate")) + { + double dX, dY; + CalculatePosition(dX, dY); + m_oTransformtaion.m_oTransform.RotateAt(NSCSS::NS_STATIC_FUNCTIONS::ReadDouble(mAttributes.at(L"rotate")), dX, dY); + } } bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const @@ -141,10 +149,8 @@ namespace SVG if (!StartPath(pRenderer, pFile, oOldMatrix, oMode)) return false; - TBounds oBounds{(NULL != m_pParent) ? m_pParent->GetBounds() : TBounds{0., 0., 0., 0.}}; - - double dX = m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft); - double dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); + double dX, dY; + CalculatePosition(dX, dY); ApplyFont(pRenderer, dX, dY); @@ -181,10 +187,10 @@ namespace SVG void CTSpan::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) nTypePath += c_nWindingFillMode; } @@ -366,12 +372,20 @@ namespace SVG } } + void CTSpan::CalculatePosition(double &dX, double &dY) const + { + TBounds oBounds{(NULL != m_pParent) ? m_pParent->GetBounds() : TBounds{0., 0., 0., 0.}}; + + dX = m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft); + dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); + } + void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight) const { if (NULL == pRenderer) return; - Aggplus::CMatrix oCurrentMatrix(m_oTransformtaion.m_oTransform.GetMatrix().GetFinalValue(NSCSS::NSProperties::TransformRotate)); + Aggplus::CMatrix oCurrentMatrix(m_oTransformtaion.m_oTransform.GetMatrix().GetFinalValue()); double dXScale = 1., dYScale = 1.; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h index 63f7af4e0b4..b67e5390fe5 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h @@ -36,6 +36,8 @@ namespace SVG double GetWidth() const; void CorrectFontFamily(std::wstring& wsFontFamily) const; + void CalculatePosition(double& dX, double& dY) const; + void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const; void SetPosition(const Point& oPosition); From 90c1ffe7de4dd76f150716e3c291cf9b3ff1f0b8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Mon, 17 Jun 2024 17:08:18 +0300 Subject: [PATCH 792/794] Fix bugs 68688, 68689 Related bugs 46629, 61014, 68479, 68545 --- DesktopEditor/graphics/Graphics.cpp | 15 +++++++++---- PdfFile/SrcReader/RendererOutputDev.cpp | 30 +------------------------ 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 246cd38f759..ab0abf482fc 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -625,11 +625,18 @@ namespace Aggplus } double dWidth = pPen->Size; - if (0 == dWidth && !m_bIntegerGrid && m_bIs0PenWidthAs1px) + if (!m_bIntegerGrid && m_bIs0PenWidthAs1px) { - double dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); - if (0 != dSqrtDet) - dWidth = 1.0 / dSqrtDet; + double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); + if (0 == dWidth) + { + double dX = 0.72, dY = 0.72; + agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx; + invert.transform_2x2(&dX, &dY); + dWidth = std::min(abs(dX), abs(dY)); + } + else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet)) + dWidth = dWidthMinSize; } double dblMiterLimit = pPen->MiterLimit; diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 8a1004d59c1..c8ce8b5732b 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -763,35 +763,7 @@ namespace PdfReader } void RendererOutputDev::updateLineWidth(GfxState *pGState) { - double dWidth = pGState->getLineWidth(); - double* ctm = pGState->getCTM(); - double dDet = ctm[0] * ctm[3] - ctm[1] * ctm[2]; - - if (abs(dDet) < 0.000001) - { - m_pRenderer->put_PenSize(PDFCoordsToMM(dWidth)); - return; - } - - double inverse_ctm[4] = {}; - dDet = 1.0 / dDet; - inverse_ctm[0] = ctm[3] * dDet; - inverse_ctm[1] = -ctm[1] * dDet; - inverse_ctm[2] = -ctm[2] * dDet; - inverse_ctm[3] = ctm[0] * dDet; - - double dX = dWidth, dY = dWidth; - Distance(ctm, dX, dY, &dX, &dY); - if ((abs(dX) <= 1.0 && abs(dY) <= 1.0) || dWidth == 0) - { - dX = dY = 72.0 / 600.0; - Distance(inverse_ctm, dX, dY, &dX, &dY); - double dWidthMinSize = std::min(abs(dX), abs(dY)); - if (dWidth < dWidthMinSize) - dWidth = dWidthMinSize; - } - - m_pRenderer->put_PenSize(PDFCoordsToMM(dWidth)); + m_pRenderer->put_PenSize(PDFCoordsToMM(pGState->getLineWidth())); } void RendererOutputDev::updateStrokeAdjust(GfxState *pGState) { From 5503208e9575f127c703639daa1b832db8d14931 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova <Svetlana.Kulikova@onlyoffice.com> Date: Mon, 17 Jun 2024 17:29:04 +0300 Subject: [PATCH 793/794] Fix bug 68237 --- PdfFile/SrcWriter/Pages.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index b3920322206..82d27c384a8 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1478,7 +1478,7 @@ namespace PdfWriter void CPage::SetRotate(int nRotate) { // The value shall be a multiple of 90 - if (nRotate > 0 && nRotate % 90 == 0) + if (nRotate % 90 == 0) Add("Rotate", nRotate % 360); } void CPage::ClearContent(CXref* pXref) From ff52afecc9744d9b3910db1ad42adbf1a4922578 Mon Sep 17 00:00:00 2001 From: Kirill Polyakov <Kirill.Poljakov@onlyoffice.com> Date: Mon, 17 Jun 2024 17:50:50 +0300 Subject: [PATCH 794/794] Fix bug #68252 --- .../html/css/src/CCssCalculator_Private.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 13742628af5..e6a9160dd08 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -516,14 +516,8 @@ namespace NSCSS { oStyle.AddParent(arSelectors[i].m_wsName); - // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются - if (L"table" == arSelectors[i].m_wsName) - { - oStyle.m_oFont.GetLineHeight().Clear(); - oStyle.m_oPadding.Clear(); - oStyle.m_oMargin.Clear(); - bInTable = true; - } + if (!bInTable) + bInTable = IsTableElement(arSelectors[i].m_wsName); if (bInTable) { @@ -531,8 +525,6 @@ namespace NSCSS oStyle.m_oBorder.Clear(); } - bInTable = IsTableElement(arSelectors[i].m_wsName); - CCompiledStyle oTempStyle; oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); @@ -559,6 +551,14 @@ namespace NSCSS oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); oStyle += oTempStyle; + + // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются + if (bInTable && i < arSelectors.size() - 1) + { + oStyle.m_oFont.GetLineHeight().Clear(); + oStyle.m_oPadding.Clear(); + oStyle.m_oMargin.Clear(); + } } oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes));